mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-22 00:01:34 +00:00
ae42cbf4a8
Never-deployed "draft only" scripts/flows/apps used to live as a stub row in their own table (draft_only = true) alongside a draft row. They now live solely in the `draft` table. Migration `remove_draft_only`: - ensures every draft_only stub has a matching draft row (ON CONFLICT DO NOTHING preserves the real draft; synthesises one matching the frontend draft JSON shape only for stubs that lost their draft), with email = NULL - deletes the stub rows (FKs to *_version / dependency tables cascade) - drops the draft_only column from script/flow/app The down migration re-adds the (nullable) columns; it is fully reversible schema-wise (deleted stubs are not resurrected — their content lives in draft). Removes every draft_only / include_draft_only reference from the backend: handlers, list filters (draft-only items no longer exist in those tables so the filters are dropped), INSERT/SELECT column lists, NewScript/NewFlow and *WithDraft structs, the deploy no-op comparison, the delete-permission check (deleting always requires admin now), git-sync's draft-only skip, and openapi. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
116 lines
4.0 KiB
Rust
116 lines
4.0 KiB
Rust
#[cfg(all(feature = "python", feature = "private"))]
|
|
mod ci_tests {
|
|
use std::collections::HashMap;
|
|
|
|
use sqlx::{Pool, Postgres};
|
|
use tokio_stream::StreamExt;
|
|
|
|
use windmill_api_client::types::{NewScript, ScriptLang};
|
|
use windmill_test_utils::{in_test_worker, init_client, listen_for_completed_jobs};
|
|
|
|
fn quick_ns(content: &str, path: &str, parent_hash: Option<String>) -> NewScript {
|
|
NewScript {
|
|
content: content.into(),
|
|
language: ScriptLang::Python3,
|
|
lock: None,
|
|
parent_hash,
|
|
path: path.into(),
|
|
concurrent_limit: None,
|
|
concurrency_time_window_s: None,
|
|
cache_ttl: None,
|
|
dedicated_worker: None,
|
|
description: "".to_string(),
|
|
envs: vec![],
|
|
is_template: None,
|
|
kind: None,
|
|
summary: "".to_string(),
|
|
tag: None,
|
|
schema: HashMap::new(),
|
|
ws_error_handler_muted: Some(false),
|
|
priority: None,
|
|
delete_after_secs: None,
|
|
timeout: None,
|
|
restart_unless_cancelled: None,
|
|
deployment_message: None,
|
|
concurrency_key: None,
|
|
visible_to_runner_only: None,
|
|
auto_kind: None,
|
|
codebase: None,
|
|
has_preprocessor: None,
|
|
on_behalf_of_email: None,
|
|
assets: vec![],
|
|
modules: None,
|
|
}
|
|
}
|
|
|
|
/// Test 2: Deploying a script automatically triggers CI test jobs for test scripts
|
|
/// that reference it via the `# test:` annotation.
|
|
#[sqlx::test(fixtures("base"))]
|
|
async fn test_ci_test_trigger_on_deploy(db: Pool<Postgres>) -> anyhow::Result<()> {
|
|
let (client, port, _s) = init_client(db.clone()).await;
|
|
|
|
// Step 1: Create the test script with a CI annotation targeting deploy_target.
|
|
// This inserts a ci_test_reference row.
|
|
client
|
|
.create_script(
|
|
"test-workspace",
|
|
&quick_ns(
|
|
"# test: script/u/test-user/deploy_target\ndef main():\n return True",
|
|
"u/test-user/ci_test_for_deploy",
|
|
None,
|
|
),
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
// Process the test script's dependency (lock generation) job
|
|
let mut completed = listen_for_completed_jobs(&db).await;
|
|
in_test_worker(&db, completed.next(), port).await;
|
|
|
|
// Step 2: Create the target script. Its dependency job, once processed,
|
|
// will call trigger_ci_tests_for_item which finds our test script.
|
|
client
|
|
.create_script(
|
|
"test-workspace",
|
|
&quick_ns(
|
|
"def main():\n return 42",
|
|
"u/test-user/deploy_target",
|
|
None,
|
|
),
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
// Process the target script's dependency job → CI trigger fires in tokio::spawn
|
|
let mut completed = listen_for_completed_jobs(&db).await;
|
|
in_test_worker(&db, completed.next(), port).await;
|
|
|
|
// Give the spawned trigger task time to push the CI test job
|
|
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
|
|
|
// Verify a CI test job was queued
|
|
let ci_jobs = sqlx::query!(
|
|
"SELECT j.id, j.runnable_path, j.trigger_kind::text as trigger_kind \
|
|
FROM v2_job j \
|
|
WHERE j.workspace_id = 'test-workspace' \
|
|
AND j.trigger_kind = 'ci_test'"
|
|
)
|
|
.fetch_all(&db)
|
|
.await?;
|
|
|
|
assert_eq!(ci_jobs.len(), 1, "expected exactly 1 CI test job");
|
|
assert_eq!(
|
|
ci_jobs[0].runnable_path.as_deref(),
|
|
Some("u/test-user/ci_test_for_deploy"),
|
|
"CI test job should run the test script"
|
|
);
|
|
assert_eq!(
|
|
ci_jobs[0].trigger_kind.as_deref(),
|
|
Some("ci_test"),
|
|
"trigger_kind should be ci_test"
|
|
);
|
|
|
|
Ok(())
|
|
}
|
|
}
|