diff --git a/scripts/ci-release-publish.test.ts b/scripts/ci-release-publish.test.ts index 21a454534..3f161cbbe 100644 --- a/scripts/ci-release-publish.test.ts +++ b/scripts/ci-release-publish.test.ts @@ -35,6 +35,7 @@ describe("release publish", () => { expect(isVersionAlreadyPublished("npm error code E409\nnpm error Cannot publish over existing version")).toBe( true, ); + expect(isVersionAlreadyPublished("npm ERR! code E409")).toBe(true); expect(isVersionAlreadyPublished("npm error code EPUBLISHCONFLICT")).toBe(true); expect(isVersionAlreadyPublished("You cannot publish over the previously published versions: 1.2.3.")).toBe(true); expect(isVersionAlreadyPublished("cannot publish over the previously published version")).toBe(false); diff --git a/scripts/ci-release-publish.ts b/scripts/ci-release-publish.ts index 147b0b0f1..d9b58fba3 100644 --- a/scripts/ci-release-publish.ts +++ b/scripts/ci-release-publish.ts @@ -263,8 +263,8 @@ async function packAndPublish(dir: string, name: string): Promise { const tarball = (await fs.readdir(packDir)).find(entry => entry.endsWith(".tgz")); if (!tarball) throw new Error(`bun pm pack produced no tarball for ${name} (${path.relative(repoRoot, dir)})`); const packedTarball = await inspectPackedTarball(path.join(packDir, tarball)); - // Preflight the exact packed version so reruns skip deterministically; - // the conflict handling below remains a race fallback. + // Preflight the exact packed version so reruns skip deterministically. + // Fail open on lookup errors; only a confirmed published version may skip publishing. const preflight = await $`npm view ${`${packedTarball.name}@${packedTarball.version}`} version`.quiet().nothrow(); if (preflight.exitCode === 0 && preflight.stdout.toString().trim()) { console.log(`Skipping ${packedTarball.name} (version already published)`); @@ -287,12 +287,12 @@ async function packAndPublish(dir: string, name: string): Promise { } /** - * npm's stable machine codes for an existing exact version, plus npm 11's - * registry-precheck prose when it emits no machine code. + * npm's existing-version machine codes across supported CLI generations, plus + * npm 11's registry-precheck prose when it emits no machine code. */ export function isVersionAlreadyPublished(output: string): boolean { return ( - /npm error code (E409|EPUBLISHCONFLICT)\b/i.test(output) || + /npm (?:error|err!) code (E409|EPUBLISHCONFLICT)\b/i.test(output) || /you cannot publish over (?:the )?previously published versions?\b/i.test(output) ); }