From dc896737ac1dcd90ab96314b2bc2f044ff833b8a Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Wed, 22 Apr 2026 08:44:00 -0700 Subject: [PATCH] fix: apply powershell workspace dependencies to deployed scripts (#8912) * fix: persist powershell workspace deps in deployed script lock Co-Authored-By: Claude Opus 4.5 * fix: trigger dep job for powershell scripts on deploy Co-Authored-By: Claude Opus 4.5 --------- Co-authored-by: Claude Opus 4.5 --- backend/windmill-api-scripts/src/scripts.rs | 1 + backend/windmill-worker/src/pwsh_executor.rs | 27 ++++++++++++++++--- .../windmill-worker/src/worker_lockfiles.rs | 1 + 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/backend/windmill-api-scripts/src/scripts.rs b/backend/windmill-api-scripts/src/scripts.rs index c4b928bcb5..35ca6c5282 100644 --- a/backend/windmill-api-scripts/src/scripts.rs +++ b/backend/windmill-api-scripts/src/scripts.rs @@ -883,6 +883,7 @@ async fn create_script_internal<'c>( || ns.language == ScriptLang::Java || ns.language == ScriptLang::Ruby || ns.language == ScriptLang::Rlang + || ns.language == ScriptLang::Powershell // for related places search: ADD_NEW_LANG ) { Some(String::new()) diff --git a/backend/windmill-worker/src/pwsh_executor.rs b/backend/windmill-worker/src/pwsh_executor.rs index 9924913ad0..b5b8444f56 100644 --- a/backend/windmill-worker/src/pwsh_executor.rs +++ b/backend/windmill-worker/src/pwsh_executor.rs @@ -6,7 +6,9 @@ use sqlx::types::Json; use tokio::process::Command; use windmill_common::client::AuthedClient; use windmill_common::error::Error; +use windmill_common::scripts::ScriptLang; use windmill_common::worker::{to_raw_value, write_file, Connection}; +use windmill_common::workspace_dependencies::clean_lock_from_annotations; use windmill_queue::{ append_logs, CanceledBy, MiniPulledJob, INIT_SCRIPT_PATH_PREFIX, PERIODIC_SCRIPT_PATH_PREFIX, }; @@ -417,10 +419,16 @@ pub async fn handle_powershell_job( // Resolve modules from workspace dependencies and/or script imports let all_modules = match &maybe_lock { MaybeLock::Resolved { lock } if !lock.is_empty() => { - // Deployed script with lock: parse workspace deps from lock, merge with script imports - let ws_modules = parse_modules_json(lock)?; + // Deployed script with lock: strip workspace-dependencies annotation header, + // parse the modules.json body, and merge with script imports. + let cleaned = clean_lock_from_annotations(lock, ScriptLang::Powershell); let script_modules = parse_script_imports(content); - merge_module_requests(ws_modules, script_modules) + if cleaned.trim().is_empty() { + script_modules + } else { + let ws_modules = parse_modules_json(&cleaned)?; + merge_module_requests(ws_modules, script_modules) + } } MaybeLock::Unresolved { workspace_dependencies } => { let script_modules = parse_script_imports(content); @@ -1070,6 +1078,19 @@ mod tests { assert!(parse_modules_json("not json").is_err()); } + #[test] + fn test_parse_modules_json_after_cleaning_header() { + // Simulates the deployed-script lock: workspace-dependencies header + // prepended to the modules.json content. `clean_lock_from_annotations` + // strips header lines so the remaining body can be JSON-parsed. + let lock = "# workspace-dependencies-mode: manual\n# workspace-dependencies: default:abc123\n{\"modules\": {\"PSWriteColor\": \"1.0.0\"}}"; + let cleaned = clean_lock_from_annotations(lock, ScriptLang::Powershell); + let modules = parse_modules_json(&cleaned).unwrap(); + assert_eq!(modules.len(), 1); + assert_eq!(modules[0].name, "PSWriteColor"); + assert_eq!(modules[0].version, Some("1.0.0".to_string())); + } + // --- parse_script_imports tests --- #[test] diff --git a/backend/windmill-worker/src/worker_lockfiles.rs b/backend/windmill-worker/src/worker_lockfiles.rs index 4275bb7014..a6b062b337 100644 --- a/backend/windmill-worker/src/worker_lockfiles.rs +++ b/backend/windmill-worker/src/worker_lockfiles.rs @@ -2881,6 +2881,7 @@ async fn capture_dependency_job( ) .await? } + ScriptLang::Powershell => workspace_dependencies.get_powershell()?.unwrap_or_default(), // for related places search: ADD_NEW_LANG _ => "".to_owned(), };