ci: publish npm copies from main through the npm environment #5

Merged
jercik merged 1 commit from ci/npm-environment into main 2026-10-21 19:41:17 +00:00
Owner

Re-aligns the repository with @j4k/align 7.0.1. The rendered npm mirror workflow (.github/workflows/release-npm.yml) now publishes from main through the GitHub environment npm. The Forge release.yml and release.config.mjs change with it.

This is a ci: change, so it releases nothing. Do not merge before the npm environment exists on Jercik/fta-check and the Forge protects tags matching /^[^v]/.

Review items 174499 to 174503 on #2 were comment wording in align's templates. Align 6.7.3 and 6.7.4 already fixed them, so nothing is hand-edited here.

🤖 Generated with Claude Code

Re-aligns the repository with `@j4k/align` 7.0.1. The rendered npm mirror workflow (`.github/workflows/release-npm.yml`) now publishes from `main` through the GitHub environment `npm`. The Forge `release.yml` and `release.config.mjs` change with it. This is a `ci:` change, so it releases nothing. Do not merge before the `npm` environment exists on `Jercik/fta-check` and the Forge protects tags matching `/^[^v]/`. Review items 174499 to 174503 on #2 were comment wording in align's templates. Align 6.7.3 and 6.7.4 already fixed them, so nothing is hand-edited here. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
ci: publish npm copies from main through the npm environment
All checks were successful
Checks / pr-flow-canary (pull_request) Has been skipped
Checks / reuse (pull_request) Successful in 4s
commit-msg / commitlint (pull_request) Successful in 10s
Checks / quality-checks (26.5.0) (pull_request) Successful in 50s
Checks / quality-checks (24.15.0) (pull_request) Successful in 53s
Review / Review (pull_request_target) Successful in 3m38s
c04aa6d0f3
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Review 01M5FZ9TSSVKHWKEB9TK5WRQ2K — head c04aa6d0f355a73948d8516d727d21b995e8dbe1

Review — j4k-oss/fta-check @ a67f855405

Scope: diff against base tree 20f9fee31b1e
Status: dispatched — coverage complete (5/5 slots terminal)
Facts: current review-wide projection

Computed under:

{
  "abandonment": "abandonment-v1",
  "anchor_recipe": 1,
  "batch_policy": "batch-v1",
  "coverage": "coverage-v3",
  "dispatch_policy": "dispatch-v2",
  "grounder_version": 1,
  "grounding_read_rule": "grounding-read-v1",
  "promotion_policy": "promotion-v1",
  "report": "report-v4",
  "tally": "tally-v1",
  "triage_settle": "triage-settle-v2"
}

Findings (3)

high — Step name lists four checks, but the step now also verifies the GitHub environment policy and Forge tag names

  • claim: 01M5FZC88KMJZPYR9K9VPYC7TV
  • anchor: .forgejo/workflows/release.yml (snippet)
Check the npm account, publisher, provenance and dist-tag
  • lens: restated-sets · arm: default
  • verdicts: 1 valid / 0 invalid / 0 uncertain
    • pass 01M5FZE4GF7DKJ1S9YR9MVMAHR · valid: Grounded (exact) step name lists four categories as what the step checks, which the restated-sets guideline treats as a copy of the set the step's inline script defines. The body names the source (the same step's node script in .forgejo/workflows/release.yml) and lists its checks: npm collaborators/maintainers, _npmUser and trusted-publisher id, provenance fields plus SLSA attestation, dist-tag, GITHUB_VISIBILITY, the GitHub environment 'npm' deployment branch policy/rules, and the Forge non-v tag check. Name-only members: none. Script-only members: visibility, environment deployment-branch policy, Forge foreign-tag check. One could argue the environment policy belongs under 'publisher', but the Forge tag-name check falls under none of the four labels, so at least one member is missing and the copy already disagrees with its source (high). No exception applies: a step label is not a table of contents, a pointer, or a dated record, and a reader of the run UI does not need the inventory to use the job. The proposed fix (a purpose-only name such as 'Verify the npm copy against its publisher and the Forge release') removes the copy without losing a constraint.
  • disposition: none

The step name 'Check the npm account, publisher, provenance and dist-tag' presents four items as what the step checks. The step's script, the only source of what it checks, now checks more, so a reader scanning the workflow run UI to learn what the 'Verify npm mirror' job guarantees will believe the GitHub environment and Forge tag protections are not verified there.

Members the script defines (same step in .forgejo/workflows/release.yml, the inline node script): npmjs collaborators and maintainers (account); _npmUser and trusted publisher id/oidcConfigId (publisher); provenance repository/workflow/ref/trigger/commit-on-Forge-main plus SLSA attestation presence (provenance); dist-tags.<expected tag> (dist-tag); the GITHUB_VISIBILITY check; and, added by this diff, the GitHub environment 'npm' deployment branch policy and branch rules (expect("deployment branch policy of environment ..."), expect("deployment branch rules of environment ...")) and expect("Forge tags that do not start with v", foreignTags, []). Members in the name only: none. Members in the script but missing from the name: environment deployment-branch policy, Forge foreign-tag check (and visibility, which predates the diff). The copy already disagrees with its source.

No exception applies: a step name is not a table of contents whose entries say what an item covers, and no reader task needs a local inventory of checks in the title; the script is where the checks are defined.

Correction: name the purpose and let the script be the list, e.g. 'Verify the npm copy against its publisher and the Forge release' (no member list), so adding a check does not require editing the name.

Examined: the full diff and .forgejo/workflows/release.yml lines ~320-560, including every expect()/failures.push call in the step. Static reading only; nothing was run.

medium — Install-step comment says semantic-release publishes the package, but this change moves the publish to a later step

  • claim: 01M5FZCFDDJTMNJ977S1MXM3ER
  • anchor: .forgejo/workflows/release.yml (snippet)
the package's own prepack, if it defines one, still runs when semantic-release publishes it.
  • lens: writing-quality · arm: default
  • verdicts: 1 valid / 0 invalid / 0 uncertain
    • pass 01M5FZE4GF7DKJ1S9YR9MVMAHR · valid: The grounded comment says the package's prepack 'still runs when semantic-release publishes it'. The reviewer's trace says release.config.mjs now sets @semantic-release/npm to npmPublish: false with tarballDir, and a later step runs 'npm publish "$tarball" --ignore-scripts'. The other grounded release.config.mjs comment in this batch backs that up: 'The release job publishes the tarball this plugin packs'. So semantic-release no longer publishes to npm, and prepack runs at pack time. The clause now gives a wrong account of where scripts run, in a comment whose job is to justify skipping install scripts while a token is present. A maintainer could reason wrongly about publish-time script exposure. The diff made this stale even though the line itself is unchanged, and a stale description is a documentation defect. Medium is reasonable. The proposed rewrite is longer than it needs to be. The smallest correct fix is to change 'publishes' to 'packs', e.g. 'still runs when semantic-release packs it', which keeps the security rationale.
  • disposition: none

The comment above pnpm install --frozen-lockfile --ignore-scripts justifies skipping dependency scripts by saying the package's own prepack "still runs when semantic-release publishes it". After this change that is false. release.config.mjs sets @semantic-release/npm to npmPublish: false, tarballDir: "release-tarball", so semantic-release only packs. The new step "Publish the release tarball and record it" runs npm publish "$tarball" --ignore-scripts ... on that packed file. The comment on that publish says "Publishing a packed file skips the scripts only a folder publish runs". package.json defines "prepack": "pnpm run clean && pnpm run build", and it runs at pack time, either in semantic-release's prepare step or in the rerun branch's npm pack, not at publish. A maintainer who trusts the install-step comment could conclude that publish-time scripts run while the npm token is in ~/.npmrc. That is the exposure the comment exists to warn about, and it contradicts the new step.

Correction: replace the clause with the current fact, for example "; the package's own prepack, if it defines one, runs when semantic-release or the publish step packs the tarball, and npm publish of that file runs no scripts." This keeps the security rationale and states where scripts run.

Examined: the full diff of .forgejo/workflows/release.yml, release.config.mjs, package.json scripts, and the comments in the Release and Publish steps. I did not run the workflow. This line is unchanged context in the diff, and the behavior change elsewhere in the same diff made it stale. Refuting evidence would be a path where semantic-release still publishes, for example npmPublish overridden elsewhere. I found none.

low — release.config.mjs comment's "before the tag is pushed" can be read as the publish happening before the tag

  • claim: 01M5FZCKM4TZHGR2PXTKFDFP4M
  • anchor: release.config.mjs (snippet)
// The release job publishes the tarball this plugin packs before the tag is pushed,
    // so the integrity it records is of bytes it built, not of what the registry serves.
  • lens: writing-quality · arm: default
  • verdicts: 1 valid / 0 invalid / 0 uncertain
    • pass 01M5FZE4GF7DKJ1S9YR9MVMAHR · valid: The grounded comment reads 'The release job publishes the tarball this plugin packs before the tag is pushed'. The phrase 'before the tag is pushed' can attach to 'publishes' as well as 'packs'. The workflow order the reviewer cites (semantic-release packs, then tags, then a later step publishes) makes only the 'packs' reading true. The publish-before-tag reading is the wrong order, and it bears on the tag/artifact ordering the workflow cares about. The second line uses 'it' for both the job and the plugin, and 'the integrity it records' never names who records it. These are real clarity defects under the writing skill's precision guidance, not just a style preference. Low severity fits: the facts are right and the Release step comment states the order. One remedy caveat: the suggested '(before it pushes the tag)' makes the plugin the actor, but semantic-release pushes the tag. Better: 'This plugin only packs the tarball; semantic-release then pushes the tag, and the release job publishes that file and records its integrity, so the integrity covers bytes the job built, not what the registry serves.'
  • disposition: none

The comment says "The release job publishes the tarball this plugin packs before the tag is pushed". Grammatically, "before the tag is pushed" can modify "publishes" or "packs". In the workflow it modifies only "packs". .forgejo/workflows/release.yml runs pnpm exec semantic-release first, which packs in its prepare step and then pushes the tag. The later "Publish the release tarball and record it" step publishes the tarball, and that step comes after the tag exists. The Release step's own comment says "semantic-release tags the released commit before it publishes". A reader of the config who takes the first reading will think publish precedes tagging, which is the ordering the repo's "Never cancel: ... can leave a tag without its published artifacts" concurrency comment treats as the failure case.

The second line also uses "it" for both the job and the plugin, and "the integrity it records" does not say who records it. Suggested wording, which keeps the same meaning: "This plugin only packs the tarball (before it pushes the tag). The release job later publishes that exact file and records its integrity, so the recorded integrity covers bytes the job built, not whatever the registry serves."

Examined: release.config.mjs, the Release and Publish steps in .forgejo/workflows/release.yml. The impact is low: it is a readability ambiguity, not an error in the facts.

Other claims

  • grounding-pending (0)
  • ungrounded (0)
  • rejected (0)
  • duplicate-of (0)
  • unadjudicated (0)

Coverage

Coverage pass: 01M5FZAAV98TRJEBGE7JRD9ZQA
Accounting: complete
Slot health: healthy

lens part arm unit status runs loss
restated-sets whole default claims-emitted 1 no
general-bug whole default no-claims 1 no
writing-quality whole default claims-emitted 1 no
project-docs whole default no-claims 1 no
unix-cli whole default no-claims 1 no
  • test-trimming — skipped-by-dispatch: no test files changed; only workflows and release config
  • use-effect — skipped-by-dispatch: no React code changed; only CI workflows and release config
  • react — skipped-by-dispatch: no React components changed; only CI workflows and release config
<!-- review:summary --> **Review** `01M5FZ9TSSVKHWKEB9TK5WRQ2K` — head `c04aa6d0f355a73948d8516d727d21b995e8dbe1` # Review — j4k-oss/fta-check @ a67f85540504 Scope: diff against base tree `20f9fee31b1e` Status: dispatched — coverage complete (5/5 slots terminal) Facts: current review-wide projection Computed under: ```json { "abandonment": "abandonment-v1", "anchor_recipe": 1, "batch_policy": "batch-v1", "coverage": "coverage-v3", "dispatch_policy": "dispatch-v2", "grounder_version": 1, "grounding_read_rule": "grounding-read-v1", "promotion_policy": "promotion-v1", "report": "report-v4", "tally": "tally-v1", "triage_settle": "triage-settle-v2" } ``` ## Findings (3) ### high — Step name lists four checks, but the step now also verifies the GitHub environment policy and Forge tag names - claim: `01M5FZC88KMJZPYR9K9VPYC7TV` - anchor: `.forgejo/workflows/release.yml` (snippet) ``` Check the npm account, publisher, provenance and dist-tag ``` - lens: restated-sets · arm: default - verdicts: 1 valid / 0 invalid / 0 uncertain - pass `01M5FZE4GF7DKJ1S9YR9MVMAHR` · valid: Grounded (exact) step name lists four categories as what the step checks, which the restated-sets guideline treats as a copy of the set the step's inline script defines. The body names the source (the same step's node script in .forgejo/workflows/release.yml) and lists its checks: npm collaborators/maintainers, _npmUser and trusted-publisher id, provenance fields plus SLSA attestation, dist-tag, GITHUB_VISIBILITY, the GitHub environment 'npm' deployment branch policy/rules, and the Forge non-v tag check. Name-only members: none. Script-only members: visibility, environment deployment-branch policy, Forge foreign-tag check. One could argue the environment policy belongs under 'publisher', but the Forge tag-name check falls under none of the four labels, so at least one member is missing and the copy already disagrees with its source (high). No exception applies: a step label is not a table of contents, a pointer, or a dated record, and a reader of the run UI does not need the inventory to use the job. The proposed fix (a purpose-only name such as 'Verify the npm copy against its publisher and the Forge release') removes the copy without losing a constraint. - disposition: none > The step name 'Check the npm account, publisher, provenance and dist-tag' presents four items as what the step checks. The step's script, the only source of what it checks, now checks more, so a reader scanning the workflow run UI to learn what the 'Verify npm mirror' job guarantees will believe the GitHub environment and Forge tag protections are not verified there. > > Members the script defines (same step in .forgejo/workflows/release.yml, the inline node script): npmjs collaborators and maintainers (account); _npmUser and trusted publisher id/oidcConfigId (publisher); provenance repository/workflow/ref/trigger/commit-on-Forge-main plus SLSA attestation presence (provenance); dist-tags.&lt;expected tag> (dist-tag); the GITHUB_VISIBILITY check; and, added by this diff, the GitHub environment 'npm' deployment branch policy and branch rules (expect("deployment branch policy of environment ..."), expect("deployment branch rules of environment ...")) and expect("Forge tags that do not start with v", foreignTags, []). Members in the name only: none. Members in the script but missing from the name: environment deployment-branch policy, Forge foreign-tag check (and visibility, which predates the diff). The copy already disagrees with its source. > > No exception applies: a step name is not a table of contents whose entries say what an item covers, and no reader task needs a local inventory of checks in the title; the script is where the checks are defined. > > Correction: name the purpose and let the script be the list, e.g. 'Verify the npm copy against its publisher and the Forge release' (no member list), so adding a check does not require editing the name. > > Examined: the full diff and .forgejo/workflows/release.yml lines ~320-560, including every expect()/failures.push call in the step. Static reading only; nothing was run. ### medium — Install-step comment says semantic-release publishes the package, but this change moves the publish to a later step - claim: `01M5FZCFDDJTMNJ977S1MXM3ER` - anchor: `.forgejo/workflows/release.yml` (snippet) ``` the package's own prepack, if it defines one, still runs when semantic-release publishes it. ``` - lens: writing-quality · arm: default - verdicts: 1 valid / 0 invalid / 0 uncertain - pass `01M5FZE4GF7DKJ1S9YR9MVMAHR` · valid: The grounded comment says the package's prepack 'still runs when semantic-release publishes it'. The reviewer's trace says release.config.mjs now sets @semantic-release/npm to npmPublish: false with tarballDir, and a later step runs 'npm publish "$tarball" --ignore-scripts'. The other grounded release.config.mjs comment in this batch backs that up: 'The release job publishes the tarball this plugin packs'. So semantic-release no longer publishes to npm, and prepack runs at pack time. The clause now gives a wrong account of where scripts run, in a comment whose job is to justify skipping install scripts while a token is present. A maintainer could reason wrongly about publish-time script exposure. The diff made this stale even though the line itself is unchanged, and a stale description is a documentation defect. Medium is reasonable. The proposed rewrite is longer than it needs to be. The smallest correct fix is to change 'publishes' to 'packs', e.g. 'still runs when semantic-release packs it', which keeps the security rationale. - disposition: none > The comment above `pnpm install --frozen-lockfile --ignore-scripts` justifies skipping dependency scripts by saying the package's own `prepack` "still runs when semantic-release publishes it". After this change that is false. `release.config.mjs` sets `@semantic-release/npm` to `npmPublish: false, tarballDir: "release-tarball"`, so semantic-release only packs. The new step "Publish the release tarball and record it" runs `npm publish "$tarball" --ignore-scripts ...` on that packed file. The comment on that publish says "Publishing a packed file skips the scripts only a folder publish runs". `package.json` defines `"prepack": "pnpm run clean && pnpm run build"`, and it runs at pack time, either in semantic-release's prepare step or in the rerun branch's `npm pack`, not at publish. A maintainer who trusts the install-step comment could conclude that publish-time scripts run while the npm token is in `~/.npmrc`. That is the exposure the comment exists to warn about, and it contradicts the new step. > > Correction: replace the clause with the current fact, for example "; the package's own `prepack`, if it defines one, runs when semantic-release or the publish step packs the tarball, and `npm publish` of that file runs no scripts." This keeps the security rationale and states where scripts run. > > Examined: the full diff of `.forgejo/workflows/release.yml`, `release.config.mjs`, `package.json` scripts, and the comments in the Release and Publish steps. I did not run the workflow. This line is unchanged context in the diff, and the behavior change elsewhere in the same diff made it stale. Refuting evidence would be a path where semantic-release still publishes, for example `npmPublish` overridden elsewhere. I found none. ### low — `release.config.mjs` comment's "before the tag is pushed" can be read as the publish happening before the tag - claim: `01M5FZCKM4TZHGR2PXTKFDFP4M` - anchor: `release.config.mjs` (snippet) ``` // The release job publishes the tarball this plugin packs before the tag is pushed, // so the integrity it records is of bytes it built, not of what the registry serves. ``` - lens: writing-quality · arm: default - verdicts: 1 valid / 0 invalid / 0 uncertain - pass `01M5FZE4GF7DKJ1S9YR9MVMAHR` · valid: The grounded comment reads 'The release job publishes the tarball this plugin packs before the tag is pushed'. The phrase 'before the tag is pushed' can attach to 'publishes' as well as 'packs'. The workflow order the reviewer cites (semantic-release packs, then tags, then a later step publishes) makes only the 'packs' reading true. The publish-before-tag reading is the wrong order, and it bears on the tag/artifact ordering the workflow cares about. The second line uses 'it' for both the job and the plugin, and 'the integrity it records' never names who records it. These are real clarity defects under the writing skill's precision guidance, not just a style preference. Low severity fits: the facts are right and the Release step comment states the order. One remedy caveat: the suggested '(before it pushes the tag)' makes the plugin the actor, but semantic-release pushes the tag. Better: 'This plugin only packs the tarball; semantic-release then pushes the tag, and the release job publishes that file and records its integrity, so the integrity covers bytes the job built, not what the registry serves.' - disposition: none > The comment says "The release job publishes the tarball this plugin packs before the tag is pushed". Grammatically, "before the tag is pushed" can modify "publishes" or "packs". In the workflow it modifies only "packs". `.forgejo/workflows/release.yml` runs `pnpm exec semantic-release` first, which packs in its prepare step and then pushes the tag. The later "Publish the release tarball and record it" step publishes the tarball, and that step comes after the tag exists. The Release step's own comment says "semantic-release tags the released commit before it publishes". A reader of the config who takes the first reading will think publish precedes tagging, which is the ordering the repo's "Never cancel: ... can leave a tag without its published artifacts" concurrency comment treats as the failure case. > > The second line also uses "it" for both the job and the plugin, and "the integrity it records" does not say who records it. Suggested wording, which keeps the same meaning: "This plugin only packs the tarball (before it pushes the tag). The release job later publishes that exact file and records its integrity, so the recorded integrity covers bytes the job built, not whatever the registry serves." > > Examined: `release.config.mjs`, the Release and Publish steps in `.forgejo/workflows/release.yml`. The impact is low: it is a readability ambiguity, not an error in the facts. ## Other claims - grounding-pending (0) - ungrounded (0) - rejected (0) - duplicate-of (0) - unadjudicated (0) ## Coverage Coverage pass: 01M5FZAAV98TRJEBGE7JRD9ZQA Accounting: complete Slot health: healthy | lens | part | arm | unit status | runs | loss | | --- | --- | --- | --- | --- | --- | | restated-sets | whole | default | claims-emitted | 1 | no | | general-bug | whole | default | no-claims | 1 | no | | writing-quality | whole | default | claims-emitted | 1 | no | | project-docs | whole | default | no-claims | 1 | no | | unix-cli | whole | default | no-claims | 1 | no | - test-trimming — skipped-by-dispatch: no test files changed; only workflows and release config - use-effect — skipped-by-dispatch: no React code changed; only CI workflows and release config - react — skipped-by-dispatch: no React components changed; only CI workflows and release config
@ -314,4 +362,4 @@
sleep 30
done
- name: Check the npm account, publisher, provenance and dist-tag

high — Step name lists four checks, but the step now also verifies the GitHub environment policy and Forge tag names

The step name 'Check the npm account, publisher, provenance and dist-tag' presents four items as what the step checks. The step's script, the only source of what it checks, now checks more, so a reader scanning the workflow run UI to learn what the 'Verify npm mirror' job guarantees will believe the GitHub environment and Forge tag protections are not verified there.

Members the script defines (same step in .forgejo/workflows/release.yml, the inline node script): npmjs collaborators and maintainers (account); _npmUser and trusted publisher id/oidcConfigId (publisher); provenance repository/workflow/ref/trigger/commit-on-Forge-main plus SLSA attestation presence (provenance); dist-tags.<expected tag> (dist-tag); the GITHUB_VISIBILITY check; and, added by this diff, the GitHub environment 'npm' deployment branch policy and branch rules (expect("deployment branch policy of environment ..."), expect("deployment branch rules of environment ...")) and expect("Forge tags that do not start with v", foreignTags, []). Members in the name only: none. Members in the script but missing from the name: environment deployment-branch policy, Forge foreign-tag check (and visibility, which predates the diff). The copy already disagrees with its source.

No exception applies: a step name is not a table of contents whose entries say what an item covers, and no reader task needs a local inventory of checks in the title; the script is where the checks are defined.

Correction: name the purpose and let the script be the list, e.g. 'Verify the npm copy against its publisher and the Forge release' (no member list), so adding a check does not require editing the name.

Examined: the full diff and .forgejo/workflows/release.yml lines ~320-560, including every expect()/failures.push call in the step. Static reading only; nothing was run.

lens restated-sets · arm default · tally 1 valid / 0 invalid / 0 uncertain
claim 01M5FZC88KMJZPYR9K9VPYC7TV of review 01M5FZ9TSSVKHWKEB9TK5WRQ2K

<!-- review:claim:01M5FZC88KMJZPYR9K9VPYC7TV --> **high** — Step name lists four checks, but the step now also verifies the GitHub environment policy and Forge tag names > The step name 'Check the npm account, publisher, provenance and dist-tag' presents four items as what the step checks. The step's script, the only source of what it checks, now checks more, so a reader scanning the workflow run UI to learn what the 'Verify npm mirror' job guarantees will believe the GitHub environment and Forge tag protections are not verified there. > > Members the script defines (same step in .forgejo/workflows/release.yml, the inline node script): npmjs collaborators and maintainers (account); _npmUser and trusted publisher id/oidcConfigId (publisher); provenance repository/workflow/ref/trigger/commit-on-Forge-main plus SLSA attestation presence (provenance); dist-tags.&lt;expected tag> (dist-tag); the GITHUB_VISIBILITY check; and, added by this diff, the GitHub environment 'npm' deployment branch policy and branch rules (expect("deployment branch policy of environment ..."), expect("deployment branch rules of environment ...")) and expect("Forge tags that do not start with v", foreignTags, []). Members in the name only: none. Members in the script but missing from the name: environment deployment-branch policy, Forge foreign-tag check (and visibility, which predates the diff). The copy already disagrees with its source. > > No exception applies: a step name is not a table of contents whose entries say what an item covers, and no reader task needs a local inventory of checks in the title; the script is where the checks are defined. > > Correction: name the purpose and let the script be the list, e.g. 'Verify the npm copy against its publisher and the Forge release' (no member list), so adding a check does not require editing the name. > > Examined: the full diff and .forgejo/workflows/release.yml lines ~320-560, including every expect()/failures.push call in the step. Static reading only; nothing was run. lens `restated-sets` · arm `default` · tally 1 valid / 0 invalid / 0 uncertain claim `01M5FZC88KMJZPYR9K9VPYC7TV` of review `01M5FZ9TSSVKHWKEB9TK5WRQ2K`
jercik marked this conversation as resolved
Lines 7-8
@ -5,3 +5,4 @@
["@semantic-release/commit-analyzer", { preset: "conventionalcommits" }],
["@semantic-release/release-notes-generator", { preset: "conventionalcommits" }],
"@semantic-release/npm",
// The release job publishes the tarball this plugin packs before the tag is pushed,
// so the integrity it records is of bytes it built, not of what the registry serves.

low — release.config.mjs comment's "before the tag is pushed" can be read as the publish happening before the tag

The comment says "The release job publishes the tarball this plugin packs before the tag is pushed". Grammatically, "before the tag is pushed" can modify "publishes" or "packs". In the workflow it modifies only "packs". .forgejo/workflows/release.yml runs pnpm exec semantic-release first, which packs in its prepare step and then pushes the tag. The later "Publish the release tarball and record it" step publishes the tarball, and that step comes after the tag exists. The Release step's own comment says "semantic-release tags the released commit before it publishes". A reader of the config who takes the first reading will think publish precedes tagging, which is the ordering the repo's "Never cancel: ... can leave a tag without its published artifacts" concurrency comment treats as the failure case.

The second line also uses "it" for both the job and the plugin, and "the integrity it records" does not say who records it. Suggested wording, which keeps the same meaning: "This plugin only packs the tarball (before it pushes the tag). The release job later publishes that exact file and records its integrity, so the recorded integrity covers bytes the job built, not whatever the registry serves."

Examined: release.config.mjs, the Release and Publish steps in .forgejo/workflows/release.yml. The impact is low: it is a readability ambiguity, not an error in the facts.

lens writing-quality · arm default · tally 1 valid / 0 invalid / 0 uncertain
claim 01M5FZCKM4TZHGR2PXTKFDFP4M of review 01M5FZ9TSSVKHWKEB9TK5WRQ2K

<!-- review:claim:01M5FZCKM4TZHGR2PXTKFDFP4M --> **low** — `release.config.mjs` comment's "before the tag is pushed" can be read as the publish happening before the tag > The comment says "The release job publishes the tarball this plugin packs before the tag is pushed". Grammatically, "before the tag is pushed" can modify "publishes" or "packs". In the workflow it modifies only "packs". `.forgejo/workflows/release.yml` runs `pnpm exec semantic-release` first, which packs in its prepare step and then pushes the tag. The later "Publish the release tarball and record it" step publishes the tarball, and that step comes after the tag exists. The Release step's own comment says "semantic-release tags the released commit before it publishes". A reader of the config who takes the first reading will think publish precedes tagging, which is the ordering the repo's "Never cancel: ... can leave a tag without its published artifacts" concurrency comment treats as the failure case. > > The second line also uses "it" for both the job and the plugin, and "the integrity it records" does not say who records it. Suggested wording, which keeps the same meaning: "This plugin only packs the tarball (before it pushes the tag). The release job later publishes that exact file and records its integrity, so the recorded integrity covers bytes the job built, not whatever the registry serves." > > Examined: `release.config.mjs`, the Release and Publish steps in `.forgejo/workflows/release.yml`. The impact is low: it is a readability ambiguity, not an error in the facts. lens `writing-quality` · arm `default` · tally 1 valid / 0 invalid / 0 uncertain claim `01M5FZCKM4TZHGR2PXTKFDFP4M` of review `01M5FZ9TSSVKHWKEB9TK5WRQ2K`
jercik marked this conversation as resolved
Author
Owner

Review 01M5FZ9TSSVKHWKEB9TK5WRQ2K on head c04aa6d: three prose findings, all confirmed against the current files, none introduced by hand here. Each sits in a file @j4k/align renders (.forgejo/workflows/release.yml, release.config.mjs), so the fix belongs in the align templates and a hand edit would be overwritten on the next align run. None makes this PR harmful to merge: the comments and step name are wrong or ambiguous, the behavior is right.

  • high, step name Check the npm account, publisher, provenance and dist-tag (release.yml:365): confirmed, it omits the environment policy and Forge tag checks. Align template change: name the purpose, not the list of checks.
  • medium, install-step comment (release.yml:190): confirmed, release.config.mjs sets npmPublish: false, so semantic-release packs and the later npm publish "$tarball" step publishes. Align template change: say "packs" and that publishing the tarball runs no scripts.
  • low, release.config.mjs:7 "before the tag is pushed": confirmed, ambiguous between packing and publishing. Align template change: reword so only packing precedes the tag.

Other claims: none. No follow-up PR opens in this repository; the align changes are reported to the maintainer.

Review `01M5FZ9TSSVKHWKEB9TK5WRQ2K` on head `c04aa6d`: three prose findings, all confirmed against the current files, none introduced by hand here. Each sits in a file `@j4k/align` renders (`.forgejo/workflows/release.yml`, `release.config.mjs`), so the fix belongs in the align templates and a hand edit would be overwritten on the next align run. None makes this PR harmful to merge: the comments and step name are wrong or ambiguous, the behavior is right. - high, step name `Check the npm account, publisher, provenance and dist-tag` (release.yml:365): confirmed, it omits the environment policy and Forge tag checks. Align template change: name the purpose, not the list of checks. - medium, install-step comment (release.yml:190): confirmed, `release.config.mjs` sets `npmPublish: false`, so semantic-release packs and the later `npm publish "$tarball"` step publishes. Align template change: say "packs" and that publishing the tarball runs no scripts. - low, `release.config.mjs:7` "before the tag is pushed": confirmed, ambiguous between packing and publishing. Align template change: reword so only packing precedes the tag. Other claims: none. No follow-up PR opens in this repository; the align changes are reported to the maintainer.
jercik merged commit 197c53b22f into main 2026-10-21 19:41:17 +00:00
jercik deleted branch ci/npm-environment 2026-10-21 19:41:17 +00:00
Author
Owner

Fixed in align and released as @j4k/align 7.0.3: j4k/align#754

  • Item 175089 (step name): the verify step is now named "Verify the npm copy against its publisher and the Forge release".
  • Item 175090 (release.config.mjs comment): it now says the plugin only packs the tarball, and that the release job publishes that file and records its integrity.
  • Medium item in summary comment 175088 (install-step comment): in npm-mirror renders it says prepack runs when semantic-release or the publish step packs the tarball, and that npm publish of the packed file runs no scripts. Other renders keep the old wording, because they have no separate publish step.

The next align run in this repository picks these up.

Fixed in align and released as `@j4k/align` 7.0.3: https://code.j4k.dev/j4k/align/pulls/754 - Item 175089 (step name): the verify step is now named "Verify the npm copy against its publisher and the Forge release". - Item 175090 (`release.config.mjs` comment): it now says the plugin only packs the tarball, and that the release job publishes that file and records its integrity. - Medium item in summary comment 175088 (install-step comment): in npm-mirror renders it says `prepack` runs when semantic-release or the publish step packs the tarball, and that `npm publish` of the packed file runs no scripts. Other renders keep the old wording, because they have no separate publish step. The next align run in this repository picks these up.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
j4k-oss/fta-check!5
No description provided.