ci: automate release safety checks and main->dev back-merge - SFS-3247#3410
ci: automate release safety checks and main->dev back-merge - SFS-3247#3410eduardoformiga wants to merge 5 commits into
Conversation
Extend scripts/verify-publish-manifests.mjs to fail the build when a publishable package is missing/mismatched on repository.url (compared to the root repo) or has a repository.directory that does not point at the package. A missing repository.url fails npm provenance with E422 — the exact failure that hit @faststore/diagnostics during the v4 launch.
In fixed-version mode all packages must move together. Use --force-conventional-graduate on `release` (plain --force-publish is ignored when combined with --conventional-graduate) and --force-publish on `release:v3`, so the latest / v3-latest tags never end up with a partially published set of packages.
Add a non-blocking diagnostic (scripts/diagnose-changed.mjs) wired into the release workflow that runs `lerna changed` and emits a warning explaining the "No changed packages to version" situation, instead of a silent no-op that reads like a broken release.
Add an informational, non-blocking CI job (scripts/check-provenance.mjs) that inspects each published package's latest version and warns when it lacks a provenance attestation — the symptom of a manual publish instead of the CD OIDC Trusted Publisher, which broke @faststore/diagnostics in the v4 launch.
Add a workflow_run-triggered workflow that opens a PR back-merging main into dev after every release (push cannot be used because the release commit is `[no ci] Release: x.y.z`). Deterministic conflicts (version fields and CHANGELOGs) are resolved by scripts/back-merge-resolve.mjs and generated files/lockfile are regenerated; anything else is auto-resolved to the dev side and the PR opens as a draft flagged for manual review.
|
Important Review skippedReview was skipped due to path filters ⛔ Files ignored due to path filters (8)
CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. |
|
renatomaurovtex
left a comment
There was a problem hiding this comment.
Reviewed the full diff (release-workflow automation, SFS-3247). Clean hygiene overall: no runtime deps added (pure node builtins + git/npm/gh CLIs), no lockfile or generated files in the diff, and both new CI checks are non-blocking by design. All checks green (SonarQube, codesandbox, node-ci-v2). Notes below.
🟠 [governance] CI/CD + release-versioning change — needs release-owner sign-off
This touches the release/CD pipeline (release.yml, back-merge.yml) and versioning semantics (package.json scripts), which is a maintainer-domain change. Flagging for an explicit release-owner review (@lemagnetic) before merge — not a code defect, just the approval gate for this class of change.
🟠 [bug] release:v3 now force-publishes every package
release gaining --force-conventional-graduate is well-justified (plain --force-publish is ignored next to --conventional-graduate, and release:dev already force-publishes), so fixed-mode graduation is consistent. But release:v3 previously versioned only changed packages; adding --force-publish makes it bump/publish all 8 on every v3 release even when untouched.
- "release:v3": "lerna version --conventional-commits --yes && pnpm -r publish --access public --tag v3-latest --no-git-checks",
+ "release:v3": "lerna version --conventional-commits --force-publish --yes && pnpm -r publish --access public --tag v3-latest --no-git-checks",Is the fixed-mode "everything moves together" behavior intended for the v3 line too, or only for main? If v3 should keep versioning real changes, drop --force-publish here. Worth a one-line note in the PR body either way.
🟡 [ci] back-merge.yml regresses the action pins #3391 just bumped
Base dev is on @v6 for all three actions (checkout / pnpm-action-setup / setup-node) after #3391, and this PR's own new provenance job in ci.yml correctly uses @v6. The new back-merge.yml, though, pins pnpm/action-setup@v4 and actions/setup-node@v4 — inconsistent within the same PR and a regression of the node-deprecation cleanup.
- name: Setup pnpm
- uses: pnpm/action-setup@v4
+ uses: pnpm/action-setup@v6
with:
version: 10.28.0
- name: Setup Node.js environment
- uses: actions/setup-node@v4
+ uses: actions/setup-node@v6
with:
node-version: 24.13.0
cache: "pnpm"💬 [behavior] Non-deterministic conflicts auto-resolved to the dev side
The resolve step does git checkout --ours on every leftover conflict (incl. source files), so a main hotfix landing in a file the resolver doesn't understand is silently dropped to the dev version. The draft + flagged-file list mitigates this, but the safety net relies entirely on a human actually inspecting the flagged files before merging the draft. Given that's the exact failure mode this RFC is trying to prevent, consider making the flagged case louder (e.g. request-review / assignee) rather than just a draft. Working as designed — just confirming the intent.
💬 [edge] CHANGELOG union dedupes by trimmed line content
unionResolveContent skips any theirs line whose trimmed text already appears on the ours side. For version-scoped CHANGELOG entries this is safe, but a legitimately repeated line (identical bullet text across two entries) would be dropped from the main side. Low risk; noting for completeness.
💬 [ci] provenance heuristic depends on dist.attestations being in the packument
check-provenance.mjs infers provenance from npm view <pkg>@<v> dist.attestations. Please confirm the registry actually surfaces attestations under dist for your published packages — if not, this will false-positive "NO prov" for everything. It's continue-on-error/exit-0 so it can't break CI, but a permanently-noisy warning loses its value.
Nice touches: the verify-publish-manifests repository.url/directory guard reads EXPECTED_REPO_URL from the root manifest and no-ops when absent, so it stays fork/mirror-safe; and the back-merge workflow_run trigger correctly sidesteps the [no ci] release-commit skip.
Verdict: Approved with comments
Blocking (🟠):
- Release-owner sign-off for the CI/CD + versioning change (governance gate).
- Confirm
release:v3 --force-publishis intended (v3 previously versioned only changed packages).
Non-blocking (🟡/💬):
- Align
back-merge.ymltopnpm/action-setup@v6+actions/setup-node@v6(matches dev + this PR's ownci.yml). - Make the flagged-conflict draft louder than a passive draft.
- CHANGELOG union dedupe edge case; provenance
dist.attestationsassumption.
Checks to confirm before merge: pnpm lint · build · pnpm release:verify (new repository.url guard) · dry-run the back-merge resolver on a simulated version+CHANGELOG conflict. No pnpm size needed (no runtime/bundle surface).

0 New Issues
0 Fixed Issues
0 Accepted Issues
No data about coverage (22.60% Estimated after merge)
What's the purpose of this pull request?
Implements the automation roadmap from our release-workflow RFC, turning
several manual/error-prone release steps into CI guards and automation.
The goal is to prevent the classes of failures we hit during the v4 launch
(partial publishes, missing
repository.url/provenance, silent "no changedpackages", and forgotten
main→devback-merges) without changing theday-to-day flow.
How it works?
Each commit is a self-contained piece, ordered from smallest guard to the
larger automation:
ci: validate repository.url in release:verify—release:verifynow also fails when a publishable package is missing/mismatched on
repository.urlor has a wrongrepository.directory. This is thecause of the v4
E422on@faststore/diagnostics.ci: force all packages on graduation and v3 release—releaseuses
--force-conventional-graduate(plain--force-publishis ignoredalongside
--conventional-graduate) andrelease:v3uses--force-publish, so all 8 packages always graduate/publish together infixed mode.
ci: warn when no packages would be versioned— non-blocking stepthat runs
lerna changedand explains the "No changed packages toversion" situation instead of a confusing silent no-op.
ci: flag packages missing npm provenance— informational,non-blocking CI job that warns when a package's latest version has no
provenance attestation (symptom of a manual publish rather than the CD
OIDC Trusted Publisher).
ci: automate main to dev back-merge after release— aworkflow_run-triggered workflow that, after CD onmain, opens achore: update dev with mainPR. Deterministic conflicts (version fieldsand CHANGELOGs) are resolved by a script; generated files and the lockfile
are regenerated; any other conflict is auto-resolved to the
devside andthe PR opens as a draft flagged for manual review.
Both new CI checks (3 and 4) are non-blocking by design — they only emit
warnings.
How to test it?
pnpm release:verifypasses for the current 8 packages and fails if youtemporarily blank a package's
repository.url.node ./scripts/diagnose-changed.mjsprints the warning on analready-released HEAD and a "changed packages detected" message otherwise.
node ./scripts/check-provenance.mjslists each package's latest versionand flags any without provenance.
main;the resolver (
scripts/back-merge-resolve.mjs) was validated on a simulatedversion + CHANGELOG conflict.
References
--conventional-graduate/--force-conventional-graduate.Checklist
Made with Cursor