mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-23 08:00:45 +00:00
Merge branch 'main' into change-057d82f3
This commit is contained in:
+60
@@ -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"
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user