Skip to content

Commit 1a16cc4

Browse files
ci: enforce safe NAPI artifact consumers
1 parent db0d877 commit 1a16cc4

12 files changed

Lines changed: 70 additions & 691 deletions

.github/dependabot.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ updates:
1313
patterns: ["napi", "napi-derive", "napi-build"]
1414
wasm-bindgen:
1515
patterns: ["wasm-bindgen", "js-sys"]
16+
ignore:
17+
# memchr 2.8.3 regressed the performance gate; retry with the next release.
18+
- dependency-name: memchr
19+
versions: ["2.8.3"]
1620
open-pull-requests-limit: 10
1721

1822
- package-ecosystem: npm

.github/scripts/workflow-policy.test.mjs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@ import { describe, it } from "node:test";
55

66
const ROOT_URL = new URL("../../", import.meta.url);
77
const WORKFLOWS_URL = new URL("workflows/", new URL("../", import.meta.url));
8+
const BENCH_WORKFLOW_URL = new URL("bench.yml", WORKFLOWS_URL);
89
const CI_WORKFLOW_URL = new URL("ci.yml", WORKFLOWS_URL);
910
const COVERAGE_WORKFLOW_URL = new URL("coverage.yml", WORKFLOWS_URL);
1011
const RELEASE_WORKFLOW_URL = new URL("release.yml", WORKFLOWS_URL);
12+
const CONTRIBUTING_URL = new URL("CONTRIBUTING.md", ROOT_URL);
13+
const DEPENDABOT_CONFIG_URL = new URL(".github/dependabot.yml", ROOT_URL);
1114
const FALLOW_CONFIG_URL = new URL(".fallowrc.json", ROOT_URL);
1215
const PACKAGE_JSON_URL = new URL("package.json", ROOT_URL);
16+
const README_URL = new URL("README.md", ROOT_URL);
1317
const WASM_PACK_INSTALL_ACTION = "taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853";
1418
const WASM_PACK_WORKFLOWS = new Map([
1519
["bench.yml", " if: matrix.kind == 'node'\n"],
@@ -70,6 +74,19 @@ const workflowJob = (workflow, jobName) => {
7074
return nextJob === -1 ? remaining : remaining.slice(0, nextJob);
7175
};
7276

77+
const assertSafeNapiConsumer = (name, contents) => {
78+
const unsafeBuilds = [
79+
/\bnapi build\b/,
80+
/\bpnpm\b[^\n]*--filter @srcmap\/(?:codec|sourcemap)(?=\s)[^\n]*\bbuild\b/,
81+
/\b(?:cd|working-directory:)\s+packages\/(?:codec|sourcemap)(?=\s|$)/m,
82+
/\bpnpm\b[^\n]*--dir\s+packages\/(?:codec|sourcemap)(?=\s)[^\n]*\bbuild\b/,
83+
];
84+
85+
for (const unsafeBuild of unsafeBuilds) {
86+
assert.doesNotMatch(contents, unsafeBuild, `${name}: use the no-js bootstrap`);
87+
}
88+
};
89+
7390
describe("JavaScript dependency policy", () => {
7491
it("keeps pnpm-lock.yaml as the only tracked JavaScript lockfile", async () => {
7592
assert.deepEqual(await trackedPackageLocks(), []);
@@ -120,6 +137,50 @@ describe("Generated artifact policy", () => {
120137
);
121138
assert.doesNotMatch(job, /corepack pnpm --filter @srcmap\/.+ build/);
122139
});
140+
141+
it("keeps every non-release NAPI consumer on the no-js bootstrap", async () => {
142+
const ci = await readFile(CI_WORKFLOW_URL, "utf8");
143+
const coverage = await readFile(COVERAGE_WORKFLOW_URL, "utf8");
144+
const bench = await readFile(BENCH_WORKFLOW_URL, "utf8");
145+
const contributing = await readFile(CONTRIBUTING_URL, "utf8");
146+
const readme = await readFile(README_URL, "utf8");
147+
assert.match(workflowJob(ci, "js-runtime"), /corepack pnpm run build:test-artifacts/);
148+
assert.match(workflowJob(coverage, "coverage"), /corepack pnpm run build:test-artifacts:napi/);
149+
assert.match(bench, /corepack pnpm run build:test-artifacts:napi/);
150+
assert.match(contributing, /corepack pnpm run build:test-artifacts:napi/);
151+
assert.match(readme, /corepack pnpm run build:test-artifacts:napi/);
152+
153+
for (const [name, contents] of [
154+
["ci.yml", ci],
155+
["coverage.yml", coverage],
156+
["bench.yml", bench],
157+
["CONTRIBUTING.md", contributing],
158+
["README.md", readme],
159+
]) {
160+
assertSafeNapiConsumer(name, contents);
161+
}
162+
});
163+
164+
it("rejects direct and package-local NAPI build variants", () => {
165+
for (const unsafeBuild of [
166+
"corepack pnpm exec napi build --release",
167+
"run: corepack pnpm run build\nworking-directory: packages/codec",
168+
"corepack pnpm --dir packages/sourcemap run build",
169+
]) {
170+
assert.throws(() => assertSafeNapiConsumer("fixture", unsafeBuild));
171+
}
172+
});
173+
});
174+
175+
describe("Dependabot policy", () => {
176+
it("holds only memchr 2.8.3 after its failed performance gate", async () => {
177+
const config = await readFile(DEPENDABOT_CONFIG_URL, "utf8");
178+
179+
assert.match(
180+
config,
181+
/# memchr 2\.8\.3 regressed the performance gate; retry with the next release\.\n\s+- dependency-name: memchr\n\s+versions: \["2\.8\.3"\]/,
182+
);
183+
});
123184
});
124185

125186
describe("Checkout credential policy", () => {

.github/workflows/bench.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,7 @@ jobs:
107107
- name: Build JS benchmark packages
108108
if: matrix.kind == 'node'
109109
run: |
110-
corepack pnpm --filter @srcmap/codec build
111-
corepack pnpm --filter @srcmap/sourcemap build
110+
corepack pnpm run build:test-artifacts:napi
112111
corepack pnpm --filter @srcmap/sourcemap-wasm build
113112
114113
- name: Download real-world fixtures

.github/workflows/coverage.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,7 @@ jobs:
5858
5959
# Build NAPI packages for JS tests
6060
- name: Build NAPI packages
61-
run: |
62-
corepack pnpm --filter @srcmap/codec build
63-
corepack pnpm --filter @srcmap/sourcemap build
61+
run: corepack pnpm run build:test-artifacts:napi
6462

6563
# Build WASM packages for JS tests
6664
- name: Build WASM packages

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ The experimental `generator`, `remapping` NAPI, and `scopes-wasm` binding crates
7171
cargo build # Debug build
7272
cargo build --release # Optimized build
7373

74-
# Build a specific NAPI package
75-
corepack pnpm --filter @srcmap/sourcemap build
74+
# Build NAPI test artifacts without rewriting tracked loaders
75+
corepack pnpm run build:test-artifacts:napi
7676

7777
# Build a specific WASM package for Node.js and browsers
7878
corepack pnpm --filter @srcmap/sourcemap-wasm build:all

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,7 @@ corepack pnpm --filter @srcmap/remapping-wasm build:all
313313
corepack pnpm --filter @srcmap/symbolicate-wasm build:all
314314

315315
# NAPI packages
316-
corepack pnpm --filter @srcmap/sourcemap build
317-
corepack pnpm --filter @srcmap/codec build
316+
corepack pnpm run build:test-artifacts:napi
318317

319318
# JS benchmarks
320319
corepack pnpm --dir benchmarks run download-fixtures

docs/superpowers/plans/2026-07-14-fetch-fixture-test-hardening.md

Lines changed: 0 additions & 148 deletions
This file was deleted.

0 commit comments

Comments
 (0)