From ca1317ca40073e474db10bcdcf0a8557e485773c Mon Sep 17 00:00:00 2001 From: My Name is Tito Date: Fri, 31 Jul 2026 15:12:50 +1200 Subject: [PATCH] fix: stage npm releases with OIDC --- .changeset/every-seals-kick.md | 5 +++ __tests__/release.test.ts | 8 +++-- scripts/publish.ts | 65 ---------------------------------- 3 files changed, 10 insertions(+), 68 deletions(-) create mode 100644 .changeset/every-seals-kick.md diff --git a/.changeset/every-seals-kick.md b/.changeset/every-seals-kick.md new file mode 100644 index 0000000..4c8527f --- /dev/null +++ b/.changeset/every-seals-kick.md @@ -0,0 +1,5 @@ +--- +"@mynameistito/codex-usage": patch +--- + +Fix npm release staging with trusted publishing by skipping the unsupported staged-package listing request. diff --git a/__tests__/release.test.ts b/__tests__/release.test.ts index c1919d0..447bcfb 100644 --- a/__tests__/release.test.ts +++ b/__tests__/release.test.ts @@ -40,11 +40,10 @@ describe("release helpers", () => { expect(calls).toHaveLength(1); }); - test("checks stage-list status and uses supported stage-publish args", async () => { + test("stages directly with trusted publishing", async () => { const calls: string[][] = []; const responses = [ result(1, "", "npm error code E404"), - result(0, "[]"), result(0, "staged"), ]; @@ -58,6 +57,9 @@ describe("release helpers", () => { { name: "example", version: "1.0.0" } ); - expect(calls[2]).toEqual(["npm", "stage", "publish", "."]); + expect(calls).toEqual([ + ["npm", "view", "example@1.0.0", "version"], + ["npm", "stage", "publish", "."], + ]); }); }); diff --git a/scripts/publish.ts b/scripts/publish.ts index 5d9c61e..5780c81 100644 --- a/scripts/publish.ts +++ b/scripts/publish.ts @@ -131,51 +131,6 @@ export const runCommand: CommandRunner = async (command, args) => { return { exitCode, stderr, stdout }; }; -const isStagedEntryForVersion = (entry: unknown, version: string) => { - if (typeof entry === "string") { - return entry === version || entry.endsWith(`@${version}`); - } - - if (!entry || typeof entry !== "object") { - return false; - } - - const record = entry as Record; - const packageRecord = record["package"]; - - return ( - record["version"] === version || - (Boolean(packageRecord) && - typeof packageRecord === "object" && - (packageRecord as Record)["version"] === version) - ); -}; - -/** Returns whether npm staged-version output contains the package version. */ -export const hasStagedVersion = (input: string, version: string) => { - const trimmed = input.trim(); - - if (!trimmed) { - return false; - } - - const parsed = JSON.parse(trimmed) as unknown; - - if (!parsed || typeof parsed !== "object") { - return false; - } - - if ("error" in parsed) { - return false; - } - - const staged = Array.isArray(parsed) - ? parsed - : Object.values(parsed as Record); - - return staged.some((entry) => isStagedEntryForVersion(entry, version)); -}; - /** Stages the package with npm or reports that it is already released. */ export const runNpmRelease = async ( runner: CommandRunner = runCommand, @@ -198,26 +153,6 @@ export const runNpmRelease = async ( ); } - const stagedList = await runner("npm", [ - "stage", - "list", - releasePackage.name, - "--json", - ]); - - if (stagedList.exitCode !== 0) { - const stagedOutput = `${stagedList.stdout}${stagedList.stderr}`; - throw new ReleaseError( - `npm stage list failed with ${stagedList.exitCode}: ${stagedOutput.trim()}` - ); - } - - if (hasStagedVersion(stagedList.stdout, releasePackage.version)) { - console.log(`${spec} is already staged for approval`); - writeGithubOutputs({ ...baseOutputs, staged: "true" }); - return; - } - const stagePublish = await runner("npm", ["stage", "publish", "."]); const publishOutput = `${stagePublish.stdout}${stagePublish.stderr}`;