* docs(#457): rewrite ADR-457 to ground truth and accept build-at-publish The prior draft asserted a codebase state that never existed (13 tsc-generated files, src/ trees, a tests/cjs-ts-parity.test.cjs). Corrected to verified ground truth (84 bin/lib .cjs, 1 value-baked package-identity.cjs, no tsc pipeline), distinguished value-baking from transpilation so package-identity stops being miscited as precedent, made check-in-the-artifact vs build-at-publish the central decision, and flipped status to Accepted (build-at-publish). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * build(#537): pilot TS build-at-publish for bin/lib (semver-compare) First hand-written module collapsed to a TypeScript source of truth per ADR-457. src/semver-compare.cts compiles (tsc, strict, noEmitOnError) to a gitignored get-shit-done/bin/lib/semver-compare.cjs. build:lib is wired into build, pretest, pretest:coverage, and prepublishOnly so the artifact is built before test and shipped on publish. Type-aware ESLint on src/**/*.cts immediately caught the params were over-typed as `unknown` (no-base-to-string); narrowed to a honest VersionInput domain type. Behavior preserved: semver-compare.test.cjs (14) and bug-10 (4) pass against the generated output; runtime consumer changeset/cli.cjs unaffected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#537): make build-at-publish robust across all CI paths (codex review) Adversarial review found the pilot's generated artifact would be missing on clean CI checkouts. `pretest`/`pretest:coverage` only fire for `npm test`, but CI runs `test:unit`/`test:integration`/`test:install` and `node run-tests.cjs` directly — none of which built the artifact, so any suite requiring semver-compare.cjs would hit module-not-found on a clean checkout, and install-smoke's `npm pack` could ship without it. - Add a `prepare` script (`npm run build:lib`). `npm ci` runs it automatically, so every CI test job and install-smoke's pack emit the artifact before use. This is the idiomatic npm mechanism for compiled-output-not-in-git and fixes both the test and pack paths in one place. - Add `src/` + `tsconfig.build.json` to ci-test-scope and the install-smoke / mutation path filters, so a source-only edit to a migrated module still triggers its tests and mutation coverage (prevents silent CI skips). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#537): map src/*.cts to built artifact in mutation changed-files detection Follow-up to the codex re-review. The prior commit added src/**/*.cts to the mutation workflow's path trigger but left its "compute changed core lib files" step diffing only get-shit-done/bin/lib/**/*.cjs — which are now gitignored and never appear in a diff. A source-only edit would trigger the workflow then early-exit ("no core lib files changed"), silently skipping mutation testing. Map each changed src/*.cts to its built get-shit-done/bin/lib/*.cjs path (the on-disk artifact Stryker mutates after prepare/build:lib), merge with the hand-written .cjs diff, and apply the test/excluded-module filters once. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#537): use 'src/' pathspec in mutation diff (git glob doesn't match top-level) Codex review caught that `git diff -- 'src/**/*.cts'` returns empty for a top-level file like src/semver-compare.cts — git's default pathspec glob does not match `**` across zero directories (verified on git 2.50.1). The prior commit's src-detection therefore never fired, so source-only changes still skipped mutation. Switch to the dir-scoped pathspec 'src/' + a `.cts` grep (robust for flat and nested layouts), and broaden the workflow path trigger to 'src/**' to match install-smoke. Verified end-to-end: a change to src/semver-compare.cts now resolves to get-shit-done/bin/lib/semver-compare.cjs in the --mutate list. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(#537): add changeset fragment for build-at-publish pilot Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#537): replace prepare with prepack + build-if-missing; defer mutation wiring CI surfaced three real issues the local run and codex review missed: 1. lockfile-sync failed on every platform. Root cause: `npm ci --dry-run` (the repo's lockfile health check) RUNS the `prepare` script, but in dry-run the devDependencies aren't installed, so `tsc` is not found (exit 127) and the check reports a misleading "out of sync". `prepare` is the wrong hook for a build needing a devDep. Replace it with `prepack` (runs only on pack/publish, when node_modules exists) for the tarball path, and build the artifact inside scripts/run-tests.cjs (build-if-missing) for the test path — the universal chokepoint every CI test invocation funnels through, including the direct `node run-tests.cjs --files-from` step that bypasses npm lifecycle hooks. The guard is a no-op once built, so the run-tests harness test is unaffected. 2. The Stryker mutation gate ran only 1 test against semver-compare (~0% score, 71/71 mutants surviving) — a Stryker test-selection problem orthogonal to the build migration, and raising the score needs property tests (ADR-456). Revert the mutation.yml src wiring; mutation coverage for src-authored modules is a separate follow-up tracked in #537. (The deletion of the gitignored top-level .cjs does not match the workflow's `bin/lib/**/*.cjs` git pathspec, so the gate skips cleanly.) Verified: clean-room `npm ci --dry-run` exits 0; deleting the artifact then running a suite rebuilds it; run-tests harness 22/22 green; `npm pack` includes the built artifact via prepack. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -42,6 +42,16 @@ const RULES = [
|
||||
'tests/bug-3588-npm-audit-clean.test.cjs',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'TS runtime sources (ADR-457 build-at-publish)',
|
||||
// src/*.cts compiles into get-shit-done/bin/lib/*.cjs; a source-only edit must
|
||||
// still trigger the migrated module's tests (otherwise CI silently skips them).
|
||||
match: path => path.startsWith('src/') || path === 'tsconfig.build.json',
|
||||
tests: [
|
||||
'tests/semver-compare.test.cjs',
|
||||
'tests/bug-10-semver-policy-consolidation.test.cjs',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'installer and package layout',
|
||||
match: path => path.startsWith('bin/') ||
|
||||
|
||||
@@ -20,11 +20,32 @@
|
||||
// See docs/TESTING-SUITES.md for full grouping policy.
|
||||
'use strict';
|
||||
|
||||
const { readdirSync } = require('fs');
|
||||
const { readdirSync, existsSync } = require('fs');
|
||||
const { join } = require('path');
|
||||
const { execFileSync } = require('child_process');
|
||||
|
||||
const SUITES = ['all', 'unit', 'integration', 'install', 'security', 'slow'];
|
||||
|
||||
// ADR-457 build-at-publish: get-shit-done/bin/lib/*.cjs is generated from
|
||||
// src/*.cts and gitignored, so on a clean checkout (fresh CI, before any build)
|
||||
// the artifact is absent — yet test files require it. This is the universal
|
||||
// chokepoint every test path funnels through (test:unit, --files-from, direct
|
||||
// invocation), so build the artifact here if missing. It is a no-op once built
|
||||
// (dev, pretest, a prior run in the same job), which keeps the harness test's
|
||||
// spawned invocations side-effect-free. Paths resolve from __dirname (not cwd),
|
||||
// so it works regardless of GSD_TEST_DIR / temp-dir cwd. NOTE: the sentinel is
|
||||
// the pilot module; revisit (or switch to an unconditional quiet build) as more
|
||||
// modules migrate into src/.
|
||||
function ensureBuiltArtifacts() {
|
||||
const root = join(__dirname, '..');
|
||||
const sentinel = join(root, 'get-shit-done', 'bin', 'lib', 'semver-compare.cjs');
|
||||
if (existsSync(sentinel)) return;
|
||||
const tscBin = require.resolve('typescript/bin/tsc');
|
||||
execFileSync(process.execPath, [tscBin, '-p', join(root, 'tsconfig.build.json')], {
|
||||
cwd: root,
|
||||
stdio: 'inherit',
|
||||
});
|
||||
}
|
||||
const MARKED_SUITES = ['integration', 'install', 'security', 'slow'];
|
||||
|
||||
function parseArgs(argv) {
|
||||
@@ -203,6 +224,9 @@ function main() {
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Build the gitignored bin/lib artifact if absent, before any test requires it.
|
||||
ensureBuiltArtifacts();
|
||||
|
||||
// Log selected files to stderr for CI / harness-test visibility.
|
||||
// node:test default reporter doesn't echo filenames, so this gives
|
||||
// operators a single stable line they can grep.
|
||||
|
||||
Reference in New Issue
Block a user