diff --git a/scripts/src/ci.ts b/scripts/src/ci.ts index a9fc742f..918afa2c 100644 --- a/scripts/src/ci.ts +++ b/scripts/src/ci.ts @@ -538,8 +538,7 @@ async function run(options: CiOptions): Promise> { async function runRemoteDevE2ELauncher(options: CiDevE2EOptions): Promise { const scriptTimeoutMs = Math.max(options.scriptTimeoutMs, options.waitMs, 60_000); - const remoteTimeoutMs = scriptTimeoutMs + 120_000; - const waitMs = options.waitMs > 0 ? options.waitMs + 30_000 : 0; + const remoteTimeoutMs = 45_000; const command = [ "set -euo pipefail", `run_id=${shellQuote(options.runId)}`, @@ -554,12 +553,15 @@ async function runRemoteDevE2ELauncher(options: CiDevE2EOptions): Promise >(tee -a \"$launcher_log\") 2>&1", + "case \"$script_path\" in scripts/ci/*.sh) ;; *) echo \"invalid_script_path=$script_path\" >&2; exit 2 ;; esac", + "(", + "set -euo pipefail", + "trap '' HUP", + "exec >> \"$launcher_log\" 2>&1", "echo \"launcher_run_id=$run_id\"", "echo \"launcher_repo=$repo_url\"", "echo \"launcher_commit=$commit\"", "echo \"launcher_script_path=$script_path\"", - "case \"$script_path\" in scripts/ci/*.sh) ;; *) echo \"invalid_script_path=$script_path\" >&2; exit 2 ;; esac", "export DOCKER_CONFIG=/tmp/unidesk-ci-docker-config", "mkdir -p \"$DOCKER_CONFIG\"", "printf '{}\\n' > \"$DOCKER_CONFIG/config.json\"", @@ -571,11 +573,21 @@ async function runRemoteDevE2ELauncher(options: CiDevE2EOptions): Promise&2; exit 1; }", @@ -594,8 +606,49 @@ async function runRemoteDevE2ELauncher(options: CiDevE2EOptions): Promise/dev/null || true", + "printf 'launcher_background_pid=%s\\nresult_dir=%s\\n' \"$launcher_pid\" \"$result_dir\"", ].join("\n"); - return dispatchSsh(command, waitMs, remoteTimeoutMs, options.waitMs > 0); + return dispatchSsh(command, 30_000, remoteTimeoutMs); +} + +async function waitForDevE2EResult(runId: string, waitMs: number): Promise { + if (waitMs <= 0) return null; + const deadline = Date.now() + waitMs; + let latest: DispatchResult | null = null; + while (Date.now() < deadline) { + const result = await dispatchSsh([ + "set -euo pipefail", + `run_id=${shellQuote(runId)}`, + "result_dir=\"/home/ubuntu/.unidesk/runs/$run_id\"", + "if [ -f \"$result_dir/result.json\" ]; then cat \"$result_dir/result.json\"; exit 0; fi", + "printf 'RUNNING result_dir=%s\\n' \"$result_dir\"", + "tail -n 40 \"$result_dir/launcher.log\" 2>/dev/null || true", + "tail -n 80 \"$result_dir/runner.log\" 2>/dev/null || true", + ].join("\n"), 30_000, 20_000); + latest = result; + if (result.ok && result.stdout.trimStart().startsWith("{")) { + const parsed = JSON.parse(result.stdout) as { ok?: boolean; status?: string }; + return { + ...result, + ok: parsed.ok === true, + status: parsed.status ?? (parsed.ok === true ? "succeeded" : "failed"), + exitCode: parsed.ok === true ? 0 : 1, + }; + } + await Bun.sleep(5_000); + } + return { + ok: false, + taskId: latest?.taskId ?? null, + status: "timeout", + stdout: latest?.stdout ?? "", + stderr: `dev e2e result did not finish within ${waitMs}ms`, + exitCode: 124, + raw: latest?.raw ?? null, + }; } function resolveDeployDevManifest(desiredRef: string): DeployDevManifestSummary { @@ -643,7 +696,8 @@ function makeRunId(deployCommit: string): string { async function runDevE2E(options: CiDevE2EOptions): Promise> { const result = await runRemoteDevE2ELauncher(options); - const ok = result.ok && (result.exitCode === null || result.exitCode === 0); + const wait = result.ok ? await waitForDevE2EResult(options.runId, options.waitMs) : null; + const ok = result.ok && (result.exitCode === null || result.exitCode === 0) && (wait === null || wait.ok); return { ok, runId: options.runId, @@ -665,6 +719,12 @@ async function runDevE2E(options: CiDevE2EOptions): Promise> { "if [ -f \"$result_dir/pods.log\" ]; then found=1; echo '===== pods.log'; tail -n 240 \"$result_dir/pods.log\"; fi", "if [ \"$found\" = \"0\" ]; then echo \"no_run_files=$result_dir\" >&2; exit 42; fi", ].join("\n"), 60_000, 45_000); - if (result.ok || result.exitCode !== 42) { + if (result.ok || (result.exitCode !== 42 && !result.stderr.includes("no_run_files="))) { return { ok: result.ok, runId: name, diff --git a/src/components/microservices/k3sctl-adapter/k3s/ci/unidesk-ci.pipeline.yaml b/src/components/microservices/k3sctl-adapter/k3s/ci/unidesk-ci.pipeline.yaml index 1b94114e..a6a6ebe8 100644 --- a/src/components/microservices/k3sctl-adapter/k3s/ci/unidesk-ci.pipeline.yaml +++ b/src/components/microservices/k3sctl-adapter/k3s/ci/unidesk-ci.pipeline.yaml @@ -270,7 +270,7 @@ spec: type: string - name: app-image type: string - default: unidesk-code-queue:dev + default: oven/bun:1-debian workspaces: - name: source steps: @@ -844,7 +844,7 @@ spec: containers: - name: smoke-target image: "$(params.app-image)" - imagePullPolicy: Never + imagePullPolicy: IfNotPresent command: - bun - -e