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
29 changes: 27 additions & 2 deletions .github/scripts/workflow-policy.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const CI_WORKFLOW_URL = new URL("ci.yml", WORKFLOWS_URL);
const COVERAGE_WORKFLOW_URL = new URL("coverage.yml", WORKFLOWS_URL);
const RELEASE_WORKFLOW_URL = new URL("release.yml", WORKFLOWS_URL);
const FALLOW_CONFIG_URL = new URL(".fallowrc.json", ROOT_URL);
const PACKAGE_JSON_URL = new URL("package.json", ROOT_URL);
const WASM_PACK_INSTALL_ACTION = "taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853";
const WASM_PACK_WORKFLOWS = new Map([
["bench.yml", " if: matrix.kind == 'node'\n"],
Expand Down Expand Up @@ -95,6 +96,30 @@ describe("Generated artifact policy", () => {

assert.ok(config.ignoreUnresolvedImports.includes("**/srcmap_*_wasm_bg.wasm"));
});

it("uses one safe bootstrap command for JavaScript test artifacts", async () => {
const packageJson = JSON.parse(await readFile(PACKAGE_JSON_URL, "utf8"));
assert.equal(
packageJson.scripts["build:test-artifacts"],
"pnpm run build:test-artifacts:napi && pnpm run build:test-artifacts:wasm",
);
assert.equal(
packageJson.scripts["build:test-artifacts:napi"],
"pnpm --filter @srcmap/codec exec napi build --release --platform --no-js --dts ../../target/napi-codec.d.ts && pnpm --filter @srcmap/sourcemap exec napi build --release --platform --no-js --dts ../../target/napi-sourcemap.d.ts",
);
assert.equal(
packageJson.scripts["build:test-artifacts:wasm"],
"pnpm --filter @srcmap/sourcemap-wasm build:all && pnpm --filter @srcmap/generator-wasm build:all && pnpm --filter @srcmap/remapping-wasm build:all && pnpm --filter @srcmap/symbolicate-wasm build:all",
);

const workflow = await readFile(CI_WORKFLOW_URL, "utf8");
const job = workflowJob(workflow, "js-runtime");
assert.match(
job,
/ - name: Build JavaScript test artifacts\n run: corepack pnpm run build:test-artifacts/,
);
assert.doesNotMatch(job, /corepack pnpm --filter @srcmap\/.+ build/);
});
});

describe("Checkout credential policy", () => {
Expand Down Expand Up @@ -284,7 +309,7 @@ describe("NAPI declaration coverage", () => {
it("checks generated declarations after the NAPI build and before JavaScript tests", async () => {
const workflow = await readFile(CI_WORKFLOW_URL, "utf8");
const job = workflowJob(workflow, "js-runtime");
const build = "corepack pnpm --filter @srcmap/sourcemap build";
const build = "corepack pnpm run build:test-artifacts";
const declarationStep =
" - name: Check N-API declarations\n run: node .github/scripts/check-napi-declarations.mjs";
const check = "node .github/scripts/check-napi-declarations.mjs";
Expand All @@ -300,7 +325,7 @@ describe("WASM package coverage", () => {
it("builds symbolicate WASM targets before JavaScript tests", async () => {
const workflow = await readFile(CI_WORKFLOW_URL, "utf8");
const job = workflowJob(workflow, "js-runtime");
const build = "corepack pnpm --filter @srcmap/symbolicate-wasm build:all";
const build = "corepack pnpm run build:test-artifacts";
const test = "corepack pnpm run test:js";

assert.ok(job.includes(build), "missing symbolicate WASM build");
Expand Down
12 changes: 2 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -225,18 +225,10 @@ jobs:
uses: taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853 # v2.83.2
with:
tool: wasm-pack@0.13.1
- name: Build N-API packages
run: |
corepack pnpm --filter @srcmap/codec build
corepack pnpm --filter @srcmap/sourcemap build
- name: Build JavaScript test artifacts
run: corepack pnpm run build:test-artifacts
- name: Check N-API declarations
run: node .github/scripts/check-napi-declarations.mjs
- name: Build WASM packages
run: |
corepack pnpm --filter @srcmap/sourcemap-wasm build:all
corepack pnpm --filter @srcmap/generator-wasm build:all
corepack pnpm --filter @srcmap/remapping-wasm build:all
corepack pnpm --filter @srcmap/symbolicate-wasm build:all
- name: Run JS tests
run: corepack pnpm run test:js

Expand Down
13 changes: 3 additions & 10 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,8 @@ corepack pnpm install --frozen-lockfile
# Build the Rust workspace
cargo build --workspace

# Build the NAPI packages used by the JavaScript tests
corepack pnpm --filter @srcmap/codec build
corepack pnpm --filter @srcmap/sourcemap build

# Build the Node.js and browser WASM packages used by the JavaScript tests
corepack pnpm --filter @srcmap/sourcemap-wasm build:all
corepack pnpm --filter @srcmap/generator-wasm build:all
corepack pnpm --filter @srcmap/remapping-wasm build:all
corepack pnpm --filter @srcmap/symbolicate-wasm build:all
# Build all generated NAPI and WASM artifacts used by the JavaScript tests
corepack pnpm run build:test-artifacts

# Run all repository checks
corepack pnpm run check
Expand Down Expand Up @@ -90,7 +83,7 @@ corepack pnpm --filter @srcmap/sourcemap-wasm build:all
```bash
cargo test # All Rust tests
cargo test -p srcmap-sourcemap # Single crate
corepack pnpm run test:js # JS/WASM tests (run the binding builds above first)
corepack pnpm run test:js # JS/WASM tests (run build:test-artifacts first)
```

### Benchmarks
Expand Down
184 changes: 184 additions & 0 deletions docs/superpowers/plans/2026-07-14-test-artifact-bootstrap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
# Test Artifact Bootstrap Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Add one root command that safely builds every generated NAPI and WASM artifact required by JavaScript tests in a clean checkout or worktree.

**Architecture:** Define the build contract in root package scripts, use `--no-js` for NAPI builds to preserve tracked loaders, and reuse the command in the JavaScript runtime CI job. Lock the contract with the existing workflow policy test and document it in the contributor quick start.

**Tech Stack:** pnpm 10, Node.js test runner, NAPI-RS CLI, wasm-pack, GitHub Actions.

## Global Constraints

- Add no dependencies.
- Preserve tracked NAPI JavaScript loaders.
- Do not make `pnpm test` rebuild artifacts automatically.
- Keep the existing focused package build commands available.
- Use signed conventional commits without attribution.

---

### Task 1: Define the bootstrap contract test-first

**Files:**
- Modify: `.github/scripts/workflow-policy.test.mjs`
- Modify: `package.json`
- Modify: `.github/workflows/ci.yml`

**Interfaces:**
- Consumes: root `package.json` scripts and the `js-runtime` workflow job.
- Produces: `build:test-artifacts`, `build:test-artifacts:napi`, and `build:test-artifacts:wasm` package scripts used by contributors and CI.

- [ ] **Step 1: Write the failing policy test**

Add `PACKAGE_JSON_URL` and extend `Generated artifact policy` with a test that checks the exact root scripts and CI step:

```js
const PACKAGE_JSON_URL = new URL("package.json", ROOT_URL);

it("uses one safe bootstrap command for JavaScript test artifacts", async () => {
const packageJson = JSON.parse(await readFile(PACKAGE_JSON_URL, "utf8"));
assert.equal(
packageJson.scripts["build:test-artifacts"],
"pnpm run build:test-artifacts:napi && pnpm run build:test-artifacts:wasm",
);
assert.equal(
packageJson.scripts["build:test-artifacts:napi"],
"pnpm --filter @srcmap/codec exec napi build --release --platform --no-js --dts ../../target/napi-codec.d.ts && pnpm --filter @srcmap/sourcemap exec napi build --release --platform --no-js --dts ../../target/napi-sourcemap.d.ts",
);
assert.equal(
packageJson.scripts["build:test-artifacts:wasm"],
"pnpm --filter @srcmap/sourcemap-wasm build:all && pnpm --filter @srcmap/generator-wasm build:all && pnpm --filter @srcmap/remapping-wasm build:all && pnpm --filter @srcmap/symbolicate-wasm build:all",
);

const workflow = await readFile(CI_WORKFLOW_URL, "utf8");
const job = workflowJob(workflow, "js-runtime");
assert.match(
job,
/ - name: Build JavaScript test artifacts\n run: corepack pnpm run build:test-artifacts/,
);
assert.doesNotMatch(job, /corepack pnpm --filter @srcmap\/.+ build/);
});
```

- [ ] **Step 2: Run the policy test and verify red**

Run:

```bash
node --test .github/scripts/workflow-policy.test.mjs
```

Expected: FAIL because `build:test-artifacts` is not defined.

- [ ] **Step 3: Add the root package scripts**

Add these scripts before `check:napi-declarations` in `package.json`:

```json
"build:test-artifacts": "pnpm run build:test-artifacts:napi && pnpm run build:test-artifacts:wasm",
"build:test-artifacts:napi": "pnpm --filter @srcmap/codec exec napi build --release --platform --no-js --dts ../../target/napi-codec.d.ts && pnpm --filter @srcmap/sourcemap exec napi build --release --platform --no-js --dts ../../target/napi-sourcemap.d.ts",
"build:test-artifacts:wasm": "pnpm --filter @srcmap/sourcemap-wasm build:all && pnpm --filter @srcmap/generator-wasm build:all && pnpm --filter @srcmap/remapping-wasm build:all && pnpm --filter @srcmap/symbolicate-wasm build:all"
```

- [ ] **Step 4: Make CI use the root command**

Replace the `Build N-API packages` and `Build WASM packages` steps in the `js-runtime` job with:

```yaml
- name: Build JavaScript test artifacts
run: corepack pnpm run build:test-artifacts
- name: Check N-API declarations
run: node .github/scripts/check-napi-declarations.mjs
```

- [ ] **Step 5: Run the policy test and verify green**

Run:

```bash
node --test .github/scripts/workflow-policy.test.mjs
```

Expected: PASS.

### Task 2: Document and prove clean-worktree setup

**Files:**
- Modify: `CONTRIBUTING.md:15-38,77-96`

**Interfaces:**
- Consumes: `pnpm build:test-artifacts` from Task 1.
- Produces: one contributor-facing setup command and explicit JavaScript test prerequisite.

- [ ] **Step 1: Replace duplicated quick-start build commands**

Keep the Rust workspace build, then replace the package-specific NAPI and WASM command block with:

```bash
# Build all generated NAPI and WASM artifacts used by the JavaScript tests
corepack pnpm run build:test-artifacts
```

- [ ] **Step 2: Update the JavaScript testing note**

Use:

```bash
corepack pnpm run test:js # JS/WASM tests (run build:test-artifacts first)
```

- [ ] **Step 3: Install clean-worktree dependencies**

Run:

```bash
corepack pnpm install --ignore-scripts --frozen-lockfile
```

Expected: the lockfile is unchanged and no generated binding artifacts exist before bootstrap.

- [ ] **Step 4: Execute the bootstrap command**

Run with bounded output:

```bash
corepack pnpm run build:test-artifacts > /tmp/srcmap-test-artifacts-build.log 2>&1
```

Expected: the command exits successfully, both platform NAPI binaries exist, and every listed WASM package has Node and browser outputs.

- [ ] **Step 5: Verify tracked loader hygiene**

Run:

```bash
git status --short
git diff -- packages/codec/index.js packages/sourcemap/index.js
```

Expected: only the intended policy, package, workflow, and contributor documentation files are modified; tracked loader files are unchanged.

- [ ] **Step 6: Run full verification**

Run with bounded logs:

```bash
pnpm check > /tmp/srcmap-test-artifacts-check.log 2>&1
pnpm test > /tmp/srcmap-test-artifacts-test.log 2>&1
git diff --check
```

Expected: all commands exit successfully.

- [ ] **Step 7: Review and commit**

Review `git status --short`, the complete diff, and staged scope. Commit with:

```bash
git commit -S -m "build: add test artifact bootstrap"
```

- [ ] **Step 8: Publish and verify**

Push `codex/test-artifact-bootstrap`, create a ready pull request targeting `main`, require all checks, squash merge with a conventional subject, and verify CI, coverage, benchmarks, and Release Drafter on the exact merge commit.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Test Artifact Bootstrap Design

## Goal

Provide one repository command that prepares every generated NAPI and WASM artifact required by the JavaScript test suite in a clean checkout or isolated worktree.

## Command contract

Add `pnpm build:test-artifacts` at the workspace root. It runs two internal scripts in sequence:

- `build:test-artifacts:napi` builds the codec and sourcemap NAPI binaries with `--no-js`, preserving the tracked JavaScript loaders while still generating the platform binary and declaration outputs.
- `build:test-artifacts:wasm` runs the existing `build:all` scripts for sourcemap, generator, remapping, and symbolicate WASM packages.

The command requires the existing project prerequisites, including `wasm-pack`. It stops on the first failed build and does not install dependencies or run tests implicitly.

## CI ownership

Replace the duplicated NAPI and WASM build commands in the JavaScript runtime workflow with `corepack pnpm run build:test-artifacts`. CI then validates the same public command contributors use locally. Keep the declaration check after the bootstrap command and before the JavaScript tests.

Extend the workflow policy test to require this root command in the JavaScript runtime job and reject reintroduced package-specific build commands in that job.

## Documentation

Update `CONTRIBUTING.md` so quick start uses the single bootstrap command. Keep the existing focused package build examples for contributors working on one binding package. Update the JavaScript testing note to name the bootstrap command explicitly.

## Verification

Use a clean isolated worktree with dependencies installed but no ignored binding artifacts. Run `pnpm build:test-artifacts`, confirm all required NAPI and WASM outputs exist, and confirm tracked loaders remain unchanged. Then run the workflow policy test, JavaScript tests, the full quality gate, and the full repository test suite.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
"analyze:js": "pnpm run analyze:js:dupes && pnpm run analyze:js:health",
"analyze:js:dupes": "fallow dupes --format json --quiet",
"analyze:js:health": "fallow health --format json --quiet --top 20",
"build:test-artifacts": "pnpm run build:test-artifacts:napi && pnpm run build:test-artifacts:wasm",
"build:test-artifacts:napi": "pnpm --filter @srcmap/codec exec napi build --release --platform --no-js --dts ../../target/napi-codec.d.ts && pnpm --filter @srcmap/sourcemap exec napi build --release --platform --no-js --dts ../../target/napi-sourcemap.d.ts",
"build:test-artifacts:wasm": "pnpm --filter @srcmap/sourcemap-wasm build:all && pnpm --filter @srcmap/generator-wasm build:all && pnpm --filter @srcmap/remapping-wasm build:all && pnpm --filter @srcmap/symbolicate-wasm build:all",
"check:napi-declarations": "pnpm --filter @srcmap/sourcemap exec napi build --release --platform --no-js --dts ../../target/napi-sourcemap.d.ts && node .github/scripts/check-napi-declarations.mjs",
"check": "pnpm run fmt:check && pnpm run lint:rust && pnpm run lint:js && pnpm run typos && pnpm run deny",
"fmt:check": "cargo fmt --all --check && pnpm run fmt:js:check",
Expand Down
Loading