From 18c425855793119719f93afb33cbe8df5d470e20 Mon Sep 17 00:00:00 2001 From: tianxiaochannel-oss88 Date: Fri, 30 Oct 2026 01:09:42 +0800 Subject: [PATCH 1/2] test(ci): stabilize handoff ordering and full-ci dispatch --- .github/workflows/full-ci-label.yml | 2 +- .../daemon/test/channel-workspace.test.mjs | 21 +++++++++++++------ scripts/ci/execution-workflow.test.mjs | 2 +- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/.github/workflows/full-ci-label.yml b/.github/workflows/full-ci-label.yml index 8574c915a..f618b1ce1 100644 --- a/.github/workflows/full-ci-label.yml +++ b/.github/workflows/full-ci-label.yml @@ -34,5 +34,5 @@ jobs: echo "::error::The full-ci label cannot dispatch CI for a forked branch: workflow_dispatch requires a ref in this repository. Push a commit to rerun the pull request with full scope." >&2 exit 1 fi - gh workflow run ci.yml --ref "$HEAD_REF" + gh workflow run ci.yml --ref "$HEAD_REF" --repo "$GITHUB_REPOSITORY" printf 'Full CI dispatched for %s\n' "$HEAD_REF" >> "$GITHUB_STEP_SUMMARY" diff --git a/packages/daemon/test/channel-workspace.test.mjs b/packages/daemon/test/channel-workspace.test.mjs index 78a791b0f..cfeb1d008 100644 --- a/packages/daemon/test/channel-workspace.test.mjs +++ b/packages/daemon/test/channel-workspace.test.mjs @@ -12379,7 +12379,7 @@ test("direct workspace initialization serializes concurrent first replies into o } }); -test("direct workspace handoff waits for initialization and remains the final binding", async () => { +test("direct workspace handoff waits for initialization and remains the final binding", { timeout: ASYNC_SETTLE_TIMEOUT_MS }, async () => { const cwd = await mkdtemp(resolve(tmpdir(), "ling-stack-direct-workspace-handoff-race-")); const managedPath = resolve(cwd, "managed-worktree"); await mkdir(managedPath, { recursive: true }); @@ -12435,14 +12435,22 @@ test("direct workspace handoff waits for initialization and remains the final bi }); await createStarted; + // readJsonBody finishes and the handler queues the mutation in microtasks + // after "end". Cross that boundary before submitting the later reply; + // a fixed sleep does not establish that order on a busy CI runner. + const handoffQueued = new Promise((resolveQueued) => { + daemon.server.prependOnceListener("request", (request) => { + request.once("end", () => setImmediate(resolveQueued)); + }); + }); + let handoffSettled = false; const handoff = postJson(`${daemon.url}/teammates/${encodeURIComponent(teammateId)}/direct-workspace/handoff?cwd=${encodeURIComponent(cwd)}`, { mode: "local", + }).finally(() => { + handoffSettled = true; }); - const earlyHandoff = await Promise.race([ - handoff.then(() => "settled"), - new Promise((resolveWaiting) => setTimeout(() => resolveWaiting("waiting"), 50)), - ]); - assert.equal(earlyHandoff, "waiting"); + await handoffQueued; + assert.equal(handoffSettled, false); let lateFactoryCalls = 0; const replyAfterHandoff = ensureDirectWorkspaceReady({ store, @@ -15755,6 +15763,7 @@ async function startDaemonForTest(runner, dependencies = {}, config = {}) { assert.ok(address && typeof address === "object"); return { url: `http://127.0.0.1:${address.port}`, + server: daemon.server, close: () => daemon.stop(), }; } diff --git a/scripts/ci/execution-workflow.test.mjs b/scripts/ci/execution-workflow.test.mjs index 343d3391d..7fe45af45 100644 --- a/scripts/ci/execution-workflow.test.mjs +++ b/scripts/ci/execution-workflow.test.mjs @@ -32,7 +32,7 @@ function runQuality(overrides = {}) { test("PR transitions and full-ci labels trigger validation while full regression is daily", () => { assert.match(workflow, /types: \[opened, synchronize, reopened, ready_for_review, converted_to_draft\]/u); assert.match(labelWorkflow, /pull_request_target:\n types: \[labeled\]/u); - assert.match(labelWorkflow, /gh workflow run ci\.yml --ref "\$HEAD_REF"/u); + assert.match(labelWorkflow, /gh workflow run ci\.yml --ref "\$HEAD_REF" --repo "\$GITHUB_REPOSITORY"/u); assert.match(workflow, /cron: "17 3 \* \* \*"/u); assert.doesNotMatch(workflow, /^ (?:push|paths|paths-ignore):/mu); assert.match(jobSource("scope"), /--event-file "\$GITHUB_EVENT_PATH"/u); From 4c22eff501e890c084fa0a2dca7cc7358a7bc7ad Mon Sep 17 00:00:00 2001 From: tianxiaochannel-oss88 Date: Fri, 30 Oct 2026 10:54:36 +0800 Subject: [PATCH 2/2] ci: validate merge-ready stability head