Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/scripts/publish-crate-if-needed.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ case "$status" in
;;
esac

cargo publish -p "$crate_name"
cargo publish -p "$crate_name" --no-verify
2 changes: 1 addition & 1 deletion .github/scripts/publish-crate-if-needed.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ describe("publish-crate-if-needed", () => {
const result = await runPublishHelper({ lookup: "missing" });

assert.equal(result.exitCode, 0);
assert.match(result.commands, /cargo publish -p srcmap-codec/);
assert.match(result.commands, /cargo publish -p srcmap-codec --no-verify/);
});

it("stops when the crates.io lookup fails", async () => {
Expand Down
23 changes: 20 additions & 3 deletions .github/scripts/workflow-policy.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,23 @@ describe("Rust feature coverage", () => {
});

describe("Release supply-chain policy", () => {
it("keeps dependency execution outside the approval-gated publisher", async () => {
const workflow = await readFile(RELEASE_WORKFLOW_URL, "utf8");
const assertPublisher = (job) => {
assert.match(job, /^ environment: release$/m);
assert.doesNotMatch(job, /actions\/checkout@|pnpm exec|pnpm install|npm ci/);
assert.match(job, /sha256sum --check --strict SHA256SUMS/);
for (const line of job.split("\n").filter((line) => /\bnpm publish\b/.test(line))) {
assert.match(line, /--ignore-scripts/);
}
};
const publisher = workflowJob(workflow, "publish-npm");
assertPublisher(publisher);
assert.throws(() => assertPublisher(publisher.replace("--ignore-scripts", "")));
assert.throws(() => assertPublisher(publisher + "\n run: pnpm exec napi artifacts"));
assert.doesNotMatch(workflowJob(workflow, "prepare-npm"), /id-token: write|contents: write/);
});

it("contains no ad hoc npm installs", async () => {
const workflow = await readFile(RELEASE_WORKFLOW_URL, "utf8");

Expand Down Expand Up @@ -398,7 +415,7 @@ describe("Release supply-chain policy", () => {

it("uses ordered frozen tooling for both NAPI artifact moves", async () => {
const workflow = await readFile(RELEASE_WORKFLOW_URL, "utf8");
const publishJob = workflowJob(workflow, "publish-npm");
const publishJob = workflowJob(workflow, "prepare-npm");
const enable = " - name: Enable Corepack\n run: corepack enable";
const install = [
" - name: Install JS dependencies",
Expand All @@ -415,8 +432,8 @@ describe("Release supply-chain policy", () => {
" working-directory: packages/sourcemap",
].join("\n");

assert.ok(publishJob.includes(enable), "publish-npm must enable Corepack");
assert.ok(publishJob.includes(install), "publish-npm must install the frozen workspace");
assert.ok(publishJob.includes(enable), "prepare-npm must enable Corepack");
assert.ok(publishJob.includes(install), "prepare-npm must install the frozen workspace");
assert.ok(publishJob.includes(codecArtifacts), "missing codec artifact move step");
assert.ok(publishJob.includes(sourcemapArtifacts), "missing sourcemap artifact move step");
assert.ok(publishJob.indexOf(enable) < publishJob.indexOf(install));
Expand Down
Loading
Loading