Releases: defprod1/defprod-scripts
Release list
v1.12.0 — sync-tests: real story surface in the dry run; real syncs work again
Added
defprod-sync-tests --dry-run: each entry ininput.statusesnow carries the story's declaredsurface(ui,api,mcp,cli,system,other, ornullwhen the story declares none), next to its lifecyclestoryStatus.
Fixed
defprod-sync-tests: local-only fields (storyStatus,surface) are removed before posting. 1.11.0 sentstoryStatus, which the DefProd API rejects, so every real sync failed withError: Invalid Request.
Upgrade
npm install -g @defprod/scripts or npx @defprod/scripts defprod-sync-tests
v1.11.0 — defprod-stamp skips fail/cancel with no in-progress stage
Changed
defprod-stamp --failand--cancelnow skip any change that has no stage work in progress. They printskipped: no in-progress stage (<stage> is <state>)and send nothing, where previously they sent a call the server could only reject. This removes the burst of rejections a--rangeproduces when a build fails twice in a row and the range baseline stays put.
Compatibility
- No new flags; exit status is unchanged (stamping still exits 0).
- A server whose
getChangedoes not report the stage state still receives the call, exactly as before. - Probe for support with
defprod-stamp --help | grep skips-not-in-progress-fail-cancel.
Upgrade: npm install -g @defprod/scripts or npx @defprod/scripts defprod-stamp.
v1.10.0 — defprod-stamp reports oversight, falling back to driver
Changed
defprod-stampreports stage oversight under its new name. The DefProd server renamed the stage-report fielddrivertooversight, and every start/finish report now sendsoversight(the value is unchanged: alwayscicd, because every report this script makes is automated pipeline reporting).
Compatibility
- A server that predates the rename refuses
oversightas an undeclared key. That refusal, and only that one, is retried once with the same value asdriver. This release therefore works against both older and newer servers, and can be installed before or after the server upgrade.
Upgrade: npm install -g @defprod/scripts, or npx @defprod/scripts defprod-stamp …
Full Changelog: v1.9.1...v1.10.0
v1.9.1 — CI stamping now attests its driver, so the forward-only rule can fire
Fixed
defprod-stampnow sendsdriver: cicdon every commit-attributed stage report. The backend's forward-only rule for pipeline reporting turns ondriver === cicd, and this script never sent the field at all — so the rule was unreachable from CI and shipped inert in v1.9.0. A re-swept commit could still rewind a change mid-review, which is the exact failure that rule was written to stop.
Why it is attested here rather than inferred
The backend cannot fill it in. An agent driving under a person's API key authenticates as that person, so the credential cannot distinguish automated pipeline reporting from a human action. And the value is never in doubt for this script: it derives the change and the stage from a git range on a build box, so every report it makes is automated pipeline reporting by construction.
Compatibility
Behaviour-preserving for the change records you already have. The field rides alongside commitSha on --start and finish only; --cancel and --fail carry no provenance and are unchanged. driver is first-report-wins per stage, so a stage already carrying one is not overwritten.
Pairs with a backend change that logs a warning whenever a commitSha-bearing report names no driver — so this can never again be silently inert for a consumer still pinned to an older version.
Upgrade
```
npx @defprod/scripts defprod-stamp --help
```
npx resolves unpinned by default, so an unpinned caller picks this up on its next invocation. Pinned consumers should move to `1.9.1`.
Full Changelog: v1.9.0...v1.9.1
v1.9.0 — trailer stage ceiling
A commit's Change: trailer claimed the whole change, which is right when the commit is the landing — and wrong for a commit that lands an interim artefact. That commit is permanent, a deploy range can legitimately re-include it, and it could therefore carry the change all the way to ship having delivered none of it.
Added
- Optional stage ceiling on the correlation trailer:
Change: <slug>/CHG-NN:<stage>declares the furthest stage that commit may advance its change to. A stamp beyond every ceiling declared for a change is sent as a no-op — the change is neither advanced nor moved back to the ceiling. - Ceilings are aggregated across a range. If any commit for a change carries no suffix the change is unbounded, so a design commit riding alongside the real landing never blocks a ship.
- The reported commit is sent with the stamp, so the same commit never advances the same stage twice however often a range re-includes it.
- A
supports-trailer-stage-ceilingmarker in--help, so tooling can probe for support before writing a suffix.
Changed
- Ranges are walked per commit, so each trailer keeps its own sha.
Compatibility
Backward compatible. Omitting the suffix keeps the previous meaning — the commit delivers the change in full — so existing history, branches and pipelines are unaffected. Stage ordering deliberately stays server-side; this script passes declared ceilings through rather than comparing them.
Before writing a suffix, check for support. An older copy of this script matches only the trailer prefix, so it silently truncates a suffix and treats the commit as delivering the change in full — the dangerous direction of version skew:
npx @defprod/scripts defprod-stamp --help 2>&1 \
| grep -q 'supports-trailer-stage-ceiling' \
&& echo "suffix supported" || echo "omit the suffix"Upgrade
npm install -g @defprod/scripts
# or
npx @defprod/scripts defprod-stamp --helpv1.8.0 — reuse the change correlation without stamping
Added
-
defprod-stamp --list-changes— runs the identical change correlation as a stamp (both trailer forms, slug → productId, change lookup within the right product) and stops one step short of stamping, printing one JSON object per line:defprod-stamp --list-changes --range "$BEFORE_SHA..$AFTER_SHA" {"key":"CHG-126","slug":"acme-web","productId":"PRODUCT-…","changeId":"CHANGE-…"}Use it when something downstream needs the set of changes a git range carries — recording a deployment run, generating release notes, building a changelog — instead of writing a second implementation of the correlation that has to agree with this one forever.
slugisnullfor a slug-less correlation. stdout carries data only, sojq -r .changeIdgets the ids andjq -s 'map(.changeId)'gets the array a deployment-run API wants. It calls no mutating use case, so a read-scoped API key is enough.Unlike stamping, this mode reports failure: exit 0 when the correlation completed (the list may be legitimately empty), exit 3 when it did not (unreadable range, missing config, a key that did not resolve). Check it — an empty list and a broken run look identical otherwise. It also will not fall back to the configured
DEFPROD_PRODUCT_IDwhen a slug fails to resolve, because aCHG-NNkey is unique only within a product and the fallback can return a real change from a different product the range never carried; it omits the entry and exits 3. Cannot be combined with--stage/--start/--cancel/--fail/--note(exit 2).
Fixed
--helpno longer truncates. The usage block was extracted with an absolute line range whose bounds sat on the first and last lines with no slack, so documenting any new flag silently cut the output short. Since--helpis the documented capability-probe surface for CI callers, the failure mode was a caller not finding a flag the script does ship, and downgrading. The block is now delimited by sentinel comments.
Changed
- The per-change success line (
defprod-stamp: finishChangeStage build stamped for CHG-77) moved from stdout to stderr, so stdout is a clean data channel in every mode. Every message the script prints is now a diagnostic. Only affects a caller that parsed stdout for that progress line; it was never a documented contract.
Compatibility
Stamping is otherwise unchanged — same flags, same RPCs, same exit-0-always contract (a missed stamp is a visibility bug, not a deploy blocker). No existing invocation needs to change.
Upgrade
npx @defprod/scripts defprod-stamp --help
# or
npm install -g @defprod/scriptsv1.7.0 — adopt a test run you already did
If CI already runs your suites, the sync no longer needs to run them again.
Added
--adopt-report <harness>:<dir>:<path>[,<path>...](repeatable; alsoDEFPROD_ADOPT_REPORTS) — parse a report another runner already produced instead of running that suite. The<harness>:<dir>prefix matches atestSuitesentry;<dir>is part of the key because a repo often has several suites on one harness. Several comma-separated paths are unioned, for a run split across passes. A named file that does not exist is an error rather than an empty parse — reporting a whole suite as untested because of a typo is worse than failing.
Changed
- Carry-forward now applies to any run, not just
--skip-run. A covered story with no fresh result keeps its previous one: silence about a story whose spec still exists is not evidence — it may be quarantined or filtered out by a grep — and resetting it would read as a regression to "never tested". An uncovered story is still reset, since nothing is making a claim about it any more.
Fixed
- A whole suite could be reported as unrun. The path matching required a leading
/, but Playwright reportsfilerelative to the common ancestor of the discovered specs, not totestDir. Where specs share a single root — or a pass runs a narrow grep — paths begin at the area segment and matched nothing. --helpwas silently truncated by a hardcoded line range every time an option was added.
Compatibility
No breaking changes. Without --adopt-report the behaviour is exactly as before.
Upgrade
npx @defprod/scripts defprod-sync-tests
# or
npm install -g @defprod/scripts
v1.6.0 — system harness, exempt coverage, safer --skip-run
Reconciles the published script with the copy DefProd runs internally. The two had drifted apart in both directions; they are now identical, so features stop landing on only one side.
Added
systemharness for multi-suite mode — filename-keyed coverage, where a story is covered by a<STORY-KEY>.test.tsfile anywhere under the directory. For unit tests filed by code module rather than by product area, where the directory cannot carry the product link.exemptcoverage bucket, derived from a story'stestExemptReason— an exempt story is no longer reported as uncovered.storyStatusreported alongside coverage and result.
Fixed
--skip-runno longer wipes measured pass/fail. It now fetches the product's existing statuses and carriesresult/ totals /lastRunAtforward, so a coverage-only sync updates only coverage and exemptions.- An all-skipped story reported
passing. Zero active specs is not a pass; it now reports no result. --versionhas reported1.1.0since v1.1.0. TheprepublishOnlystep baked the version by matchingVERSION="dev"exactly, but the baked line had been committed, so the substitution silently stopped matching and every release since shipped the wrong string. It now matches any baked value and is idempotent.
Compatibility
No breaking changes. The .defprod/ config layout, the legacy root .defprod.env fallback, and all existing flags behave exactly as before.
Upgrade
npx @defprod/scripts defprod-sync-tests
# or
npm install -g @defprod/scripts
v1.5.0 — record a failed pipeline stage as failed
Added
defprod-stamp --fail— records the in-progress stage as failed via thefailChangeStagecase. Use it in a CI failure trap: unlike--cancelit does not revert the stage to not-started, so an aborted run is no longer indistinguishable from one that never began. Takes no--stage(the server resolves the in-progress stage); pair it with--notecarrying the reason.defprod-stamp --help/-h— prints usage and exits 0. Also a capability-probe surface: a CI caller can grep--helpfor a flag name to find out whether the installed copy supports it, instead of discovering the gap as a mid-pipelineUnknown argumentfailure.
Changed
- A bad argument now prints usage to stderr alongside the existing
Unknown argumentmessage. - README documents
--failvs--cancel: prefer--failin a failure trap;--cancelis for deliberate abandonment.
Compatibility
No breaking changes. --start, --cancel, --stage and the default finish behaviour are unchanged, and --help previously exited 2, so no working caller relied on its old behaviour.
--fail requires a DefProd backend exposing the failChangeStage case. Against an older backend the call is rejected and logged to stderr — the pipeline still exits 0, as ever.
Upgrade
npm install -g @defprod/scripts
# or
npx @defprod/scripts defprod-stamp --help
v1.4.0 — slug-prefixed change branches
Added
defprod-stamprecognises the product-qualified branch formchg/<slug>/CHG-NN-*and resolves the owning product from the slug segment — so branch-based correlation works in a multi-product monorepo without settingDEFPROD_PRODUCT_ID.
Compatibility
- Behaviour-preserving for existing setups: the legacy bare
chg/CHG-NN-*branch form still correlates and falls back to the configuredDEFPROD_PRODUCT_ID. The uppercaseCHG-can never match the lowercase slug pattern, so legacy branches resolve unchanged.
Upgrade: npx @defprod/scripts defprod-stamp … (no install needed).