gate
The branch gate: the verification sequence that updateVersion runs as its release preflight, available as a command of its own.
Four of the preflight’s checks — format:check, spellcheck, find-overexposed and test:coverage — are reachable by no other routine command. So the natural branch gate (build, lint, test) can be green while the release is still going to fail, and the failure arrives at release time rather than in seconds on the branch.
This module exists so the two are the same code rather than two lists that agree today: updateVersion calls gate, and a check added here is reachable from both. What the gate deliberately leaves to the release path is the clean-repo assertion — a branch gate is run on a dirty tree, which is the whole point of running it before committing — and the integration suite, which is the one preflight step that already has a routine command of its own (npm run test:integration) and so is not in the class this module exists for.
The tests run ONCE, through test:coverage where the project defines it and through test otherwise. Running both, as this did until 2026-09-05, was a duplicate everywhere it mattered: a project scopes its two test scripts to the same vitest projects — every repo in this workspace passes the same projects array to both — so test:coverage is test plus the threshold flags, over the identical files. It buys no fail-fast either, because the coverage run fails on exactly the failures the plain run would have caught. The one thing lost is the ability to switch off only the coverage half: TEST_COVERAGE=0 now turns off the gate’s whole test step rather than demoting it to test.
Interfaces
Section titled “Interfaces”| Interface | Description |
|---|---|
| GateOptions | Options for gate. |
Functions
Section titled “Functions”| Function | Description |
|---|---|
| gate | Runs the verification sequence that npm run version runs as its preflight. The order is deliberate. The lockfile check (assertPackageLockIntegrity) comes first, because it is an in-process JSON read that takes well under a second. Then come the checks that finish in seconds (format:check, spellcheck, lint:md) run first, so a typo fails the gate immediately instead of after the coverage run. Each step is dispatched through the package manager, so a project overriding one of these scripts gets its own version, and each step carries its own environment off switch. Every step but build is run with npmRunOptional, so it is skipped when the project does not define it: a project that chose no formatter, spell checker, markdown linter or linter has nothing to check there, and requiring those scripts made npm run version die on its first step in exactly those projects. build stays required, because a release with nothing built has nothing to ship. The test step is the one place that reads that skip: test:coverage is preferred, and test runs only as its fallback, so the suite is never run twice. The unit tests stay ahead of test:integration for the same fastest-first reason — a broken unit test should fail before an integration suite is started, not after. |
| parseGateArguments | Parses the command-line arguments for the gate script. The two --no- flags switch off steps that are on; --integration is the one that switches a step ON, because GateOptions.shouldRunIntegrationTests is off by default for cost. It exists so that default is a choice the caller can make per run rather than one only a programmatic caller can reach. |