From 7e2ec43e54727b32d6e738683e802fa571f0b8d1 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Wed, 12 Aug 2026 17:08:09 +0800 Subject: [PATCH] fix(ci): keep hosted gate verifier standalone (#122561) Punchcard-Session: silver-valley-orchard-nq --- scripts/verify-pr-hosted-gates.mts | 4 +- test/scripts/verify-pr-hosted-gates.test.ts | 51 +++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/scripts/verify-pr-hosted-gates.mts b/scripts/verify-pr-hosted-gates.mts index 84320c717776..f66bf77b574a 100644 --- a/scripts/verify-pr-hosted-gates.mts +++ b/scripts/verify-pr-hosted-gates.mts @@ -2,7 +2,6 @@ import { execFileSync, spawnSync } from "node:child_process"; import { mkdirSync, readFileSync, writeFileSync } from "node:fs"; import path from "node:path"; -import { parseDateStringTimestampMs } from "@openclaw/normalization-core/number-coercion"; import { isRecord, readStringField } from "@openclaw/normalization-core/record-coerce"; import { minimatch } from "minimatch"; import { parse } from "yaml"; @@ -289,7 +288,8 @@ function latestRun(runs: WorkflowRun[]) { } function runUpdatedAtMs(run: Pick | undefined) { - return parseDateStringTimestampMs(run?.updated_at) ?? null; + const value = Date.parse(run?.updated_at ?? ""); + return Number.isFinite(value) ? value : null; } function isRecentRun(run: WorkflowRun | undefined, nowMs: number) { diff --git a/test/scripts/verify-pr-hosted-gates.test.ts b/test/scripts/verify-pr-hosted-gates.test.ts index 3f04f47e4416..d01650f9365e 100644 --- a/test/scripts/verify-pr-hosted-gates.test.ts +++ b/test/scripts/verify-pr-hosted-gates.test.ts @@ -1,3 +1,7 @@ +import { spawnSync } from "node:child_process"; +import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; import { expectDefined } from "@openclaw/normalization-core"; import { describe, expect, it } from "vitest"; import { @@ -170,6 +174,53 @@ function patchReuseOptions( } describe("verify-pr-hosted-gates", () => { + it("starts from an older target cwd without current normalization helpers", () => { + const targetRoot = mkdtempSync(join(tmpdir(), "openclaw-hosted-gates-old-cwd-")); + try { + const normalizationRoot = join(targetRoot, "packages/normalization-core/src"); + mkdirSync(normalizationRoot, { recursive: true }); + writeFileSync( + join(targetRoot, "tsconfig.json"), + JSON.stringify({ + compilerOptions: { + baseUrl: ".", + paths: { + "@openclaw/normalization-core/*": ["packages/normalization-core/src/*"], + }, + }, + }), + ); + writeFileSync(join(normalizationRoot, "number-coercion.ts"), "export const legacy = true;\n"); + writeFileSync( + join(normalizationRoot, "record-coerce.ts"), + [ + "export function isRecord(value: unknown): value is Record {", + ' return typeof value === "object" && value !== null && !Array.isArray(value);', + "}", + "export function readStringField(record: Record, key: string) {", + " const value = record[key];", + ' return typeof value === "string" ? value : undefined;', + "}", + "", + ].join("\n"), + ); + + const result = spawnSync( + process.execPath, + [join(process.cwd(), "scripts/verify-pr-hosted-gates.mjs"), "--older-cwd-startup-probe"], + { + cwd: targetRoot, + encoding: "utf8", + }, + ); + + expect(result.status).toBe(1); + expect(result.stderr).toContain("Unknown option: --older-cwd-startup-probe"); + } finally { + rmSync(targetRoot, { force: true, recursive: true }); + } + }); + it("derives hosted-gate applicability from declared workflow path filters", () => { expect(notApplicableScheduledHostedWorkflows([".github/workflows/ci.yml"])).toEqual([]); expect(