Skip to content

ci(publish): inline publish steps into publish.yml - #372

Merged
codewizdave merged 1 commit into
mainfrom
refactor/inline-publish-steps
Aug 3, 2026
Merged

ci(publish): inline publish steps into publish.yml#372
codewizdave merged 1 commit into
mainfrom
refactor/inline-publish-steps

Conversation

@martyy-code

Copy link
Copy Markdown
Contributor

Summary

Inlines every publish step into publish.yml itself, removing the reusable workflow pattern. Required so npm Trusted Publishing's workflow filename check matches the file that contains the pnpm changeset publish step.

Why

npm Trusted Publishing validates the workflow file that literally contains the publish step. With the reusable-workflow pattern (introduced in PR #367), the publish step ran inside the called reusable file (_publish-release.yml, _publish-hotfix.yml, _publish-canary.yml). The OIDC token's workflow_ref claim pointed to that reusable file, not to publish.yml.

The Trusted Publisher entry on npmjs.com was registered with workflow filename release.yml (the original name before PR #367). After PR #367 renamed release.yml_publish-release.yml, the registered filename no longer matched any workflow file. PR #371 then added id-token: write to the reusable workflows, which made OIDC proceed far enough to generate the provenance attestation — but the final PUT to npm failed with E404 Not Found because the OIDC workflow_ref claim (_publish-canary.yml) did not match the registered filename (release.yml). This is documented behavior in npm/cli#9088 — a misleading 404 instead of a clear diagnostic.

Root cause: the OIDC workflow_ref claim must match the filename registered on npmjs.com.

Fix: inline every publish step into publish.yml so the workflow file containing the publish step IS the file registered on npmjs.com.

Changes

  • .github/workflows/publish.yml: full rewrite. Three jobs (release, hotfix, canary) now contain their step lists inline. The check-release gating job from PR ci(publish): skip publish paths when no changeset pending #369 is preserved.
  • .github/workflows/_publish-release.yml: deleted.
  • .github/workflows/_publish-hotfix.yml: deleted.
  • .github/workflows/_publish-canary.yml: deleted.

4 files changed, +194 / -316.

Required follow-up

After merging this PR, the Trusted Publisher entry on https://www.npmjs.com/package/@deessejs/fp/access must be updated to Workflow filename = publish.yml (currently set to release.yml). Once updated, the dummy e2e test (PR #370) can be retried and should succeed end-to-end.

Senior rationale

The reusable-workflow pattern is elegant for sharing logic across many workflows, but it's a poor fit for npm Trusted Publishing because npm's check is filename-based and the OIDC workflow_ref claim is the file that runs the publish step. Trying to make the entrypoint + reusable pattern work requires either:

  • Registering each reusable file on npm — blocked by the one-Trusted-Publisher-per-package limit.
  • npm evolving to support caller validation — not currently the case.

Inlining is the pragmatic senior choice. The trade-off (a longer single workflow file) is acceptable: the workflow is still under 250 lines and remains readable.

Test plan

  • pnpm turbo type-check passes.
  • pnpm turbo lint passes.
  • Post-merge + Trusted Publisher updated to publish.yml: dummy e2e test (PR docs(fp): dummy e2e release test (1.0.1 -> 1.0.2) #370) re-triggered → canary snapshot publishes on @canary dist-tag with provenance.
  • Subsequent: Version Packages PR auto-opens, publishes @latest with provenance.

Risk

Low. No code change. The workflow structure is reorganized but functionally equivalent. The Trusted Publisher filename must be updated; if forgotten, OIDC will continue to fail with E404 (same as before, no regression).

Rollback

Revert the merge commit. Re-add the three _publish-*.yml files from git history. Update the Trusted Publisher back to the previous filename (if changed).

🤖 Generated with Claude Code

npm Trusted Publishing validates the workflow file that contains
the literal 'pnpm changeset publish' step. With the previous
reusable-workflow pattern, the publish step ran inside the
called reusable workflow (_publish-release.yml, _publish-hotfix.yml,
_publish-canary.yml), and the OIDC token's workflow_ref claim
pointed to that reusable file. The Trusted Publisher entry on
npmjs.com was registered with workflow filename 'publish.yml',
so the OIDC claims did not match — npm rejected the publish
with a misleading E404 (documented npm/cli #9088).

The fix is to inline every publish step into publish.yml
itself, so the workflow file containing the publish step IS
the file registered on npmjs.com.

Three jobs (release, hotfix, canary) are now defined directly
in publish.yml with their full step lists. The check-release
job (added in PR #369) remains as the gating job.

Removed:
- .github/workflows/_publish-release.yml
- .github/workflows/_publish-hotfix.yml
- .github/workflows/_publish-canary.yml

No code change. No publish triggered by this PR.

Post-merge action required:
- Update the Trusted Publisher entry on
  https://www.npmjs.com/package/@deessejs/fp/access to
  Workflow filename = 'publish.yml' (if it was set to a
  different value).
@codewizdave
codewizdave merged commit e66cba1 into main Aug 3, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants