Skip to content

docs(fp): dummy e2e release test (1.0.1 -> 1.0.2) - #370

Merged
codewizdave merged 10 commits into
stagingfrom
feat/dummy-release-test
Aug 3, 2026
Merged

docs(fp): dummy e2e release test (1.0.1 -> 1.0.2)#370
codewizdave merged 10 commits into
stagingfrom
feat/dummy-release-test

Conversation

@martyy-code

Copy link
Copy Markdown
Contributor

Summary

End-to-end test of the release pipeline.

Adds a documentation marker and a patch changeset. No code or API change. The purpose is to validate Trusted Publishing end-to-end:

  1. Canary: this PR → snapshot published on npm dist-tag canary.
  2. Version Packages PR: changeset-version.yml opens a PR staging → main with version bump 1.0.1 → 1.0.2.
  3. Release: merge the Version Packages PR into main → _publish-release.yml publishes via OIDC on dist-tag latest, with Sigstore provenance.

After the test completes successfully, this changeset can be reverted (the bump is reverted by re-running changeset version on a follow-up).

Test plan

  • pnpm turbo type-check passes.
  • pnpm turbo lint passes.
  • Canary snapshot appears on https://www.npmjs.com/package/@deessejs/fp?activeTab=versions under the canary dist-tag.
  • PR comment with install instructions is posted on this PR.
  • After merge: a "Version Packages" PR auto-opens targeting main.
  • After merging the Version Packages PR: publish on @latest succeeds with provenance.

Risk

Very low. Documentation-only change. No runtime impact. Any artifact published under canary or latest will be functionally identical to 1.0.1.

Rollback

Revert this PR's merge commit. The changeset file can be deleted; pnpm changeset version on a follow-up release will then produce no version bump.

🤖 Generated with Claude Code

codewizdave and others added 4 commits August 3, 2026 13:36
ci(release): activate release pipeline on main
When the publish.yml entrypoint is triggered by a push to main
that does not contain a pending changeset (e.g. infra-only
changes, doc edits, or back-merges), the workflow currently
proceeds to the reusable workflow, which then fails the
anti-republish guard when the local version is already on npm.
This produces a red CI run for what is essentially a no-op.

Add a check-release job at the top of publish.yml that detects
pending changesets and exposes a 'has_changeset' output. The
three downstream jobs (release, hotfix, canary) are gated on
this output:

- release:  runs only when has_changeset=true AND push to main
  (not a tag).
- hotfix:   runs only when push tag v*. Always publishes
  regardless of has_changeset (a tag is an explicit signal).
- canary:   runs only when has_changeset=true AND pull_request.

When the workflow is triggered with no pending changesets, only
the check-release job runs and exits 0 with a 'nothing to
publish' log. The downstream jobs are skipped and the overall
workflow run reports green. This keeps the CI history clean
without losing the audit trail.

The anti-republish guard in _publish-release.yml is preserved
as defense in depth — it should never fire under normal
operation, but it catches any edge case where the changeset
detection lies (e.g. a malformed changeset that is still
consumed by the snapshot).

Tag push handling:
- check-release always emits has_changeset=true for tag pushes
  (tags are explicit publish signals, not derived from
  changesets).
- hotfix job's 'if' uses ref matching, not the has_changeset
  output, since tag push semantics are independent.

Concurrency:
- The check-release job runs first; release/hotfix/canary run
  after it (needs: check-release). Sequential, but the cost is
  a few seconds — negligible compared to npm publish latency.

All third-party actions remain SHA-pinned.
…sets

ci(publish): skip publish paths when no changeset pending
Adds a marker comment to docs/internal/product/README.md and a
patch changeset. This is a controlled end-to-end test of the
release pipeline:

1. Merge this PR into staging.
2. observe the canary snapshot published on the @canary dist-tag.
3. changesets/action auto-opens a Version Packages PR targeting
   main with version bump 1.0.1 -> 1.0.2.
4. Merge the Version Packages PR into main.
5. publish.yml dispatches to _publish-release.yml; OIDC publish
   happens on the @latest dist-tag with a Sigstore-signed
   provenance attestation.

No code change. No API change. The changeset entry can be
reverted after the test completes.
GitHub Actions does not propagate permissions from a calling
workflow to a called reusable workflow. 'permissions can only
be maintained or reduced — not elevated — throughout the chain'
(GitHub docs).

The publish.yml entrypoint declares 'id-token: write' on each
caller job, but the OIDC token is minted in the context of the
called workflow's job — which did not declare id-token: write.
This caused npm to fail with:

  EUSAGE Provenance generation in GitHub Actions requires
  "write" access to the "id-token" permission

Observed on the dummy e2e test (PR #370): _publish-canary.yml
reached the 'Publish snapshot to canary tag' step, npm
authenticated via OIDC successfully, then npm refused to
generate the provenance attestation because the OIDC context did
not carry the id-token write scope.

Fix: declare 'id-token: write' explicitly in the permissions
block of the single job inside each reusable workflow:
- _publish-release.yml
- _publish-hotfix.yml
- _publish-canary.yml

This is the senior pattern: every reusable workflow declares
its own dependencies. The entrypoint's id-token: write stays
as documentation but is not relied upon for propagation.
ci(publish): add id-token: write to reusable workflow jobs
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).
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

✅ Canary snapshot published: @deessejs/fp@0.0.0-canary-20260803121141

Install with:

pnpm add @deessejs/fp@canary

This is a snapshot build. Do not depend on it in production.

@codewizdave
codewizdave merged commit 7b4200a into staging Aug 3, 2026
8 checks passed
martyy-code added a commit that referenced this pull request Aug 3, 2026
The changesets/action v1.9.0 input for the version commit
message is named 'commit', not 'commit-message'. The latter is a
v2 input.

Observed on the e2e test run (PR #370 merge to staging):
  Unexpected input(s) 'commit-message', valid inputs are
  ['github-token', 'publish', 'version', 'cwd', 'commit',
   'title', 'setupGitUser', 'createGithubReleases', 'commitMode',
   'branch', 'prDraft']

This commit also requires the org-level setting 'Allow GitHub
Actions to create and approve pull requests' to be enabled in
Settings → Actions → General. See
docs/engineering/plans/release-pipeline-github-ui-setup.md §6.
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