diff --git a/.github/workflows/openclaw-cross-os-release-checks-reusable.yml b/.github/workflows/openclaw-cross-os-release-checks-reusable.yml index 66bc46f6c42a..ad4eb074b7f9 100644 --- a/.github/workflows/openclaw-cross-os-release-checks-reusable.yml +++ b/.github/workflows/openclaw-cross-os-release-checks-reusable.yml @@ -974,19 +974,39 @@ jobs: if [[ -n "${OPENCLAW_DISCORD_SMOKE_BOT_TOKEN}" ]] && [[ -n "${OPENCLAW_DISCORD_SMOKE_GUILD_ID}" ]] && [[ -n "${OPENCLAW_DISCORD_SMOKE_CHANNEL_ID}" ]]; then DISCORD_ARGS+=(--run-discord-roundtrip true) fi - bash workflow/scripts/github/run-openclaw-cross-os-release-checks.sh \ - --candidate-tgz "${CANDIDATE_TGZ}" \ - --candidate-version "${CANDIDATE_VERSION}" \ - --source-sha "${SOURCE_SHA}" \ - --baseline-spec "${BASELINE_SPEC}" \ - --previous-version "${PREVIOUS_VERSION}" \ - --baseline-tgz "${BASELINE_TGZ}" \ - --provider "${PROVIDER}" \ - --mode "${MODE}" \ - --suite "${SUITE}" \ - --ref "${REF}" \ - "${DISCORD_ARGS[@]}" \ - --output-dir "${OUTPUT_DIR}" + run_cross_os_release_checks() { + bash workflow/scripts/github/run-openclaw-cross-os-release-checks.sh \ + --candidate-tgz "${CANDIDATE_TGZ}" \ + --candidate-version "${CANDIDATE_VERSION}" \ + --source-sha "${SOURCE_SHA}" \ + --baseline-spec "${BASELINE_SPEC}" \ + --previous-version "${PREVIOUS_VERSION}" \ + --baseline-tgz "${BASELINE_TGZ}" \ + --provider "${PROVIDER}" \ + --mode "${MODE}" \ + --suite "${SUITE}" \ + --ref "${REF}" \ + "${DISCORD_ARGS[@]}" \ + --output-dir "${OUTPUT_DIR}" + } + + if run_cross_os_release_checks; then + exit 0 + else + status=$? + fi + + dashboard_log="${OUTPUT_DIR}/logs/${MODE}-dashboard.log" + if [[ "${OPENCLAW_RELEASE_CHECK_OS}" != "windows" || + "$status" -ne 127 || + ! -f "${dashboard_log}" || + -f "${OUTPUT_DIR}/summary.json" ]] || + ! grep -q 'attempt=.*url=http://127.0.0.1:' "${dashboard_log}"; then + exit "$status" + fi + + echo "::warning::retrying Windows release checks after the outer process exited 127 after the dashboard probe and before summary generation" + run_cross_os_release_checks - name: Summarize release checks if: always() diff --git a/test/scripts/openclaw-cross-os-release-workflow.test.ts b/test/scripts/openclaw-cross-os-release-workflow.test.ts index 364c09604d2b..8dca771ea826 100644 --- a/test/scripts/openclaw-cross-os-release-workflow.test.ts +++ b/test/scripts/openclaw-cross-os-release-workflow.test.ts @@ -62,6 +62,22 @@ describe("cross-OS release checks workflow", () => { expect(workflow).not.toContain("TSX_VERSION"); }); + it("retries only an interrupted Windows dashboard probe", () => { + const workflow = readWorkflow(WORKFLOW_PATH); + const consumer = job(workflow, "cross_os_release_checks"); + const run = step(consumer, "Run cross-OS release checks").run; + + expect(run).toContain("run_cross_os_release_checks() {"); + expect(run).toContain("if run_cross_os_release_checks; then"); + expect(run).toContain('"${OPENCLAW_RELEASE_CHECK_OS}" != "windows"'); + expect(run).toContain('"$status" -ne 127'); + expect(run).toContain('dashboard_log="${OUTPUT_DIR}/logs/${MODE}-dashboard.log"'); + expect(run).toContain('-f "${OUTPUT_DIR}/summary.json"'); + expect(run).toContain("attempt=.*url=http://127.0.0.1:"); + expect(run).toContain("retrying Windows release checks after the outer process exited 127"); + expect(run).toContain("run_cross_os_release_checks\n"); + }); + it("bounds npm baseline packing during prepare", () => { const workflow = readWorkflow(WORKFLOW_PATH); const baselineMetadata = step(job(workflow, "prepare"), "Capture baseline metadata");