Merge branch 'main' into change-057d82f3

This commit is contained in:
Diego Imbert
2026-06-02 13:38:33 +02:00
committed by GitHub
3 changed files with 198 additions and 1 deletions
@@ -0,0 +1,60 @@
{
"db_name": "PostgreSQL",
"query": "SELECT tag, script_lang AS \"script_lang: ScriptLang\" FROM v2_job WHERE id = $1",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "tag",
"type_info": "Varchar"
},
{
"ordinal": 1,
"name": "script_lang: ScriptLang",
"type_info": {
"Custom": {
"name": "script_lang",
"kind": {
"Enum": [
"python3",
"deno",
"go",
"bash",
"postgresql",
"nativets",
"bun",
"mysql",
"bigquery",
"snowflake",
"graphql",
"powershell",
"mssql",
"php",
"bunnative",
"rust",
"ansible",
"csharp",
"oracledb",
"nu",
"java",
"duckdb",
"ruby",
"rlang"
]
}
}
}
}
],
"parameters": {
"Left": [
"Uuid"
]
},
"nullable": [
false,
true
]
},
"hash": "cce5e3e639faed8e42574730cc66f0322a83c01cc465742f54a21f8fe5f4f037"
}
+122
View File
@@ -0,0 +1,122 @@
/*
* Regression tests for WIN-2007.
*
* Previewing a TypeScript script carrying the `//native` annotation used to be
* pushed with `language = bun` (what the editor sends), so the job was tagged
* `bun` and routed to a regular bun worker. A native-mode worker neither matches
* the `bun` tag nor accepts a non-native `script_lang`, so previewing a `//native`
* script on a native-only worker setup failed even though the *deployed* version
* of the same script runs fine (as `bunnative` / tag `nativets`).
*
* `push` now reconciles the preview language with the `//native` annotation,
* mirroring the deploy-time logic in `worker_lockfiles`. These tests assert the
* queued job ends up with the right `script_lang` and `tag` for every combination
* of declared language and annotation. No worker is spawned — we only inspect the
* row `push` writes.
*/
use sqlx::{Pool, Postgres};
use windmill_common::{
jobs::{JobPayload, RawCode},
scripts::ScriptLang,
};
use windmill_queue::PushIsolationLevel;
async fn push_preview_and_get_row(
db: &Pool<Postgres>,
content: &str,
language: ScriptLang,
) -> (String, Option<ScriptLang>) {
let hm_args = std::collections::HashMap::new();
let job = JobPayload::Code(RawCode {
hash: None,
content: content.to_string(),
path: None,
language,
lock: None,
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
.into(),
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
cache_ttl: None,
cache_ignore_s3_path: None,
dedicated_worker: None,
modules: None,
tag: None,
});
let tx = PushIsolationLevel::IsolatedRoot(db.clone());
let (uuid, tx) = windmill_queue::push(
db,
tx,
"test-workspace",
job,
windmill_queue::PushArgs::from(&hm_args),
/* user */ "test-user",
/* email */ "test@windmill.dev",
/* permissioned_as */ "u/test-user".to_string(),
/* token_prefix */ None,
/* scheduled_for */ None,
/* schedule_path */ None,
/* parent_job */ None,
/* root_job */ None,
/* flow_innermost_root_job */ None,
/* job_id */ None,
/* is_flow_step */ false,
/* same_worker */ false,
None,
true,
None,
None,
None,
None,
None,
false,
None,
None,
None,
)
.await
.expect("push must succeed");
tx.commit().await.unwrap();
let row = sqlx::query!(
r#"SELECT tag, script_lang AS "script_lang: ScriptLang" FROM v2_job WHERE id = $1"#,
uuid
)
.fetch_one(db)
.await
.unwrap();
(row.tag, row.script_lang)
}
const NATIVE_CONTENT: &str = r#"//native
export function main(x: number) {
return x;
}
"#;
const PLAIN_CONTENT: &str = r#"export function main(x: number) {
return x;
}
"#;
/// The reported case: editor sends `bun`, content has `//native`. The preview
/// must be promoted to `bunnative` so it tags `nativets` and a native worker
/// (which rejects non-native `script_lang`) can run it.
#[sqlx::test(fixtures("base"))]
async fn test_bun_with_native_annotation_becomes_nativets(db: Pool<Postgres>) {
let (tag, lang) = push_preview_and_get_row(&db, NATIVE_CONTENT, ScriptLang::Bun).await;
assert_eq!(lang, Some(ScriptLang::Bunnative));
assert_eq!(tag, "nativets");
}
/// Guard: a plain bun preview (no `//native`) must stay `bun` / tag `bun`, so
/// the promotion above doesn't broadly retag normal previews.
#[sqlx::test(fixtures("base"))]
async fn test_bun_without_native_annotation_stays_bun(db: Pool<Postgres>) {
let (tag, lang) = push_preview_and_get_row(&db, PLAIN_CONTENT, ScriptLang::Bun).await;
assert_eq!(lang, Some(ScriptLang::Bun));
assert_eq!(tag, "bun");
}
+16 -1
View File
@@ -5058,7 +5058,7 @@ async fn push_inner<'c, 'd>(
content,
path,
hash,
language,
mut language,
lock,
cache_ttl,
cache_ignore_s3_path,
@@ -5068,6 +5068,21 @@ async fn push_inner<'c, 'd>(
debouncing_settings,
modules,
}) => {
// Reconcile the preview language with the `//native` annotation, mirroring the
// deploy-time logic in `worker_lockfiles`. The editor sends `bun` for a TypeScript
// script even when it carries `//native`, which would otherwise tag the preview as
// `bun` and route it to a regular bun worker. A native-mode worker neither matches
// the `bun` tag nor accepts a non-native `script_lang`, so previewing a `//native`
// script on a native-only worker setup fails. Normalizing to `bunnative` (tag
// `nativets`) makes the preview run exactly like the deployed script would.
if language == ScriptLang::Bun || language == ScriptLang::Bunnative {
let anns = windmill_common::worker::TypeScriptAnnotations::parse(&content);
if anns.native && language == ScriptLang::Bun {
language = ScriptLang::Bunnative;
} else if !anns.native && language == ScriptLang::Bunnative {
language = ScriptLang::Bun;
}
}
// Inject modules into job args as _MODULES so the worker can extract them
if let Some(ref modules) = modules {
match serde_json::to_string(modules).and_then(|s| RawValue::from_string(s)) {