Files
gensokyo-dev 5d6b8a0ab6 fix(release): isolate npm publication from dependency execution (#6681)
Keep dependency execution in read-only release jobs and validate the original qualified archive with Node built-ins before publication. Refresh registry state on every publisher attempt; retain exact bytes/channel verification, v1 read-only recovery, and installed CLI/MCP checks before MCP publication.

Static/docs checks, artifact/registry/recovery tests and real package/rehearsal verification pass. All four hosted package platforms pass. Portable CI retains the independently reproduced main PTX failure in #6675 and fail-fast missing coverage; use the owner-authorized existing PR-only exception, with limitations documented in the PR. Refs #6480.
2026-10-23 12:27:24 +00:00

46 lines
1.5 KiB
JavaScript

import { appendFile } from "node:fs/promises";
import { resolve } from "node:path";
import { fileURLToPath } from "node:url";
import {
validateVerifiedPackageEnvelope,
workflowPackageIdentity,
} from "./qualified-package-envelope.mjs";
import {
readQualifiedNpmRelease,
requireMatchingNpmRelease,
} from "./npm-release-state.mjs";
/** Validate the original artifact and fresh registry state on every publisher attempt. */
export async function prepareNpmPublication(request = fetch) {
const { manifest, tarball } = await validateVerifiedPackageEnvelope({
directory: ".cache/verified-package",
...(await workflowPackageIdentity()),
});
const published = await readQualifiedNpmRelease(
manifest.packageVersion,
manifest.releaseTag,
request,
);
if (published.status === "published")
await requireMatchingNpmRelease(
tarball,
manifest.packageVersion,
published,
);
if (!process.env.GITHUB_OUTPUT)
throw new Error("GITHUB_OUTPUT is required for publication intent");
// Fixed archive path and whitelisted channel; no opaque version enters workflow outputs.
await appendFile(
process.env.GITHUB_OUTPUT,
`tag=${manifest.releaseTag}\npublished=${published.status === "published"}\n`,
);
}
// The complete import graph intentionally uses only Node built-ins.
// Rehearsal validates SemVer/channel semantics on the same immutable artifact first.
if (
process.argv[1] !== undefined &&
resolve(process.argv[1]) === fileURLToPath(import.meta.url)
)
await prepareNpmPublication();