From b7d53800d60d7ce652b8822f73f48ee9b106f554 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Tue, 16 Jun 2026 02:52:31 +0200 Subject: [PATCH] fix(release): require beta smoke run url --- scripts/release-beta-smoke.ts | 83 +++---------------------- test/scripts/release-beta-smoke.test.ts | 34 ++-------- 2 files changed, 14 insertions(+), 103 deletions(-) diff --git a/scripts/release-beta-smoke.ts b/scripts/release-beta-smoke.ts index 47ae1efdaef..eab699de54c 100644 --- a/scripts/release-beta-smoke.ts +++ b/scripts/release-beta-smoke.ts @@ -264,74 +264,17 @@ export function parseWorkflowRunIdFromOutput(output: string): string | undefined return /\/actions\/runs\/(\d+)/u.exec(output)?.[1]; } -type WorkflowRunListEntry = { - createdAt?: string; - created_at?: string; - databaseId?: number | string; - id?: number | string; -}; - -function normalizeRunId(value: unknown): string | undefined { - if (typeof value === "number" && Number.isFinite(value)) { - return String(value); +export function requireWorkflowRunIdFromOutput(output: string, workflow: string): string { + const runId = parseWorkflowRunIdFromOutput(output); + if (!runId) { + throw new Error( + `gh workflow run ${workflow} did not return an Actions run URL; refusing to guess from recent workflow_dispatch runs`, + ); } - if (typeof value === "string" && value.trim()) { - return value.trim(); - } - return undefined; -} - -export function selectNewestDispatchedRunId(params: { - beforeIds: ReadonlySet; - runs: readonly WorkflowRunListEntry[]; -}): string | undefined { - return params.runs - .filter((entry) => { - const id = normalizeRunId(entry.databaseId ?? entry.id); - return id !== undefined && !params.beforeIds.has(id); - }) - .toSorted((a, b) => - (b.createdAt ?? b.created_at ?? "").localeCompare(a.createdAt ?? a.created_at ?? ""), - ) - .map((entry) => normalizeRunId(entry.databaseId ?? entry.id)) - .find((id): id is string => id !== undefined); -} - -function listWorkflowDispatchRuns(repo: string, workflow: string): WorkflowRunListEntry[] { - const encodedWorkflow = encodeURIComponent(workflow); - const response = ghJson( - repo, - `actions/workflows/${encodedWorkflow}/runs?event=workflow_dispatch&per_page=50`, - ) as { workflow_runs?: WorkflowRunListEntry[] }; - return response.workflow_runs ?? []; -} - -async function findDispatchedWorkflowRunId(params: { - beforeIds: ReadonlySet; - repo: string; - workflow: string; -}): Promise { - for (let attempt = 0; attempt < 60; attempt++) { - const runId = selectNewestDispatchedRunId({ - beforeIds: params.beforeIds, - runs: listWorkflowDispatchRuns(params.repo, params.workflow), - }); - if (runId) { - return runId; - } - await new Promise((resolve) => { - setTimeout(resolve, 5_000); - }); - } - throw new Error(`could not find dispatched run for ${params.workflow}`); + return runId; } async function dispatchTelegram(options: Options, packageSpec: string): Promise { - const beforeIds = new Set( - listWorkflowDispatchRuns(options.repo, TELEGRAM_BETA_WORKFLOW_FILE) - .map((entry) => normalizeRunId(entry.databaseId ?? entry.id)) - .filter((id): id is string => id !== undefined), - ); const output = run( "gh", [ @@ -351,15 +294,7 @@ async function dispatchTelegram(options: Options, packageSpec: string): Promise< ], { capture: true }, ); - const runId = parseWorkflowRunIdFromOutput(output); - if (runId) { - return runId; - } - return await findDispatchedWorkflowRunId({ - beforeIds, - repo: options.repo, - workflow: TELEGRAM_BETA_WORKFLOW_FILE, - }); + return requireWorkflowRunIdFromOutput(output, TELEGRAM_BETA_WORKFLOW_FILE); } export async function pollRun( @@ -508,7 +443,7 @@ async function main(): Promise { } if (!options.skipParallels) { - runParallels(options.beta, options.model); + runParallels(version, options.model); } if (telegramRunId) { diff --git a/test/scripts/release-beta-smoke.test.ts b/test/scripts/release-beta-smoke.test.ts index 5fb6a4972d7..747ce1a3d76 100644 --- a/test/scripts/release-beta-smoke.test.ts +++ b/test/scripts/release-beta-smoke.test.ts @@ -6,8 +6,8 @@ import { parseWorkflowRunIdFromOutput, pollRun, readPositiveInt, + requireWorkflowRunIdFromOutput, run, - selectNewestDispatchedRunId, } from "../../scripts/release-beta-smoke.ts"; describe("release-beta-smoke", () => { @@ -54,34 +54,10 @@ describe("release-beta-smoke", () => { ).toBe("1234567890"); }); - it("selects the newest workflow_dispatch run not present before dispatch", () => { - const beforeIds = new Set(["100", "101"]); - - expect( - selectNewestDispatchedRunId({ - beforeIds, - runs: [ - { databaseId: 100, createdAt: "2026-05-04T10:00:00Z" }, - { databaseId: 102, createdAt: "2026-05-04T10:01:00Z" }, - { databaseId: 103, createdAt: "2026-05-04T10:02:00Z" }, - ], - }), - ).toBe("103"); - }); - - it("selects runs returned by the actions workflow runs API", () => { - const beforeIds = new Set(["200"]); - - expect( - selectNewestDispatchedRunId({ - beforeIds, - runs: [ - { id: 200, created_at: "2026-05-04T10:00:00Z" }, - { id: 201, created_at: "2026-05-04T10:02:00Z" }, - { id: 202, created_at: "2026-05-04T10:01:00Z" }, - ], - }), - ).toBe("201"); + it("fails closed when gh dispatch output does not include the run url", () => { + expect(() => + requireWorkflowRunIdFromOutput("✓ Created workflow_dispatch event", "npm-telegram.yml"), + ).toThrow("refusing to guess from recent workflow_dispatch runs"); }); it("replaces stale Telegram proof placeholders", () => {