fix(ci): use ACTIONS_PAT for main-release-marker push#18
Merged
Conversation
Swimburger
approved these changes
May 20, 2026
6 tasks
The main-release-marker job's `git push origin main` is rejected by
branch protection (GH006: protected branch update failed, "Changes
must be made through a pull request"). This means the per-action
`<action>/RELEASES.md` ledger entries never land on main, and the
`chore(release): <action>@<version>` markers we designed for searchable
release history on main are silently dropped each release.
Fix mirrors fern's release-software.yml pattern: pass an `ACTIONS_PAT`
to actions/checkout so subsequent git operations authenticate as a
user/app that's been added to main's branch-protection bypass
allowlist. Falls back to GITHUB_TOKEN when ACTIONS_PAT isn't set, so
the existing "best-effort with warning" behavior is preserved for
anyone running the workflow without the PAT configured.
Operator action required to make this actually work:
1. Generate a fine-grained PAT (Contents: read and write on this repo)
under a user account that has bypass access for main's protection
rule. Same setup fern already uses.
2. Add it as `ACTIONS_PAT` repo secret in fern-api/actions.
The release workflow itself is unchanged in behavior when ACTIONS_PAT
is missing — it still releases successfully and logs the marker-push
warning.
Documents ACTIONS_PAT in CONTRIBUTING.md alongside the other required
secrets.
sentry-cli 2.x uploads as an artifact bundle, which Sentry matches via debug IDs — not filename + release-files fallback. Bundle had no debug ID, so the matcher had nothing to match on and stack frames stayed minified. Inject in the build job upstream of upload-artifact: both sentry-release (uploads to Sentry) and publish-dist (commits to dist/<action>) consume the same artifact, so the bundle Sentry knows about and the one consumers actually execute share the same debug ID. Sets inject: false on the sentry-release action so it doesn't re-inject with fresh UUIDs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
bf55466 to
66ff598
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two fixes coupled into one PR to release ASAP. Both unblock the observability rollout end-to-end.
1. Use
ACTIONS_PATfor themain-release-markerpushThe release workflow's
main-release-markerstep triesgit push origin mainto land thechore(release): <action>/<version>ledger commit. That push is rejected by main's branch protection:Confirmed in run 25934187071. The release itself succeeded — only the ledger commit was dropped, exactly as designed for the "best-effort marker" semantics. But that means
<action>/RELEASES.mdnever gets populated on main, defeating the whole point of having the ledger.Mirror fern's release-software.yml pattern: pass an
ACTIONS_PATsecret toactions/checkoutso subsequentgit pushcalls authenticate as a user/app with branch-protection bypass.Falls back to
GITHUB_TOKENifACTIONS_PATisn't configured — preserves the current "best-effort with warning" behavior for anyone running the workflow without the PAT.2. Inject Sentry debug IDs before
upload-artifactStack frames in Sentry stayed minified despite source-map upload succeeding. The Sentry CLI log from the failing release confirms what's happening:
sentry-cli2.x uploads as an artifact bundle, which Sentry matches against runtime stack frames via debug IDs — UUIDs embedded in both the JS (//# debugId=…) and the sourcemap ("debugId": …). The legacy filename + release-files fallback doesn't kick in for artifact bundles. Verified the publisheddist/verify-tokenbundle had//# sourceMappingURL=…but nodebugId=pragma, and the sourcemap hadsourcesContent+ 942 source entries butdebugId: <unset>.Fix: run
sentry-cli sourcemaps injectin thebuildjob beforeupload-artifact. Both downstream jobs (sentry-release,publish-dist) download the same artifact, so:sentry-releaseuploads the injected bundle to Sentry — debug ID embedded;publish-distcommits the injected JS todist/<action>— so the bundle consumers actually execute carries the same debug ID, and the Sentry SDK reports it in stack frames.Doing inject only in sentry-release (
inject: trueongetsentry/action-release@v1) wouldn't fix this — that injects in its own workspace, butpublish-distdownloads its own un-injected copy and pushes that to the dist branch.inject: falseis set explicitly on sentry-release so it doesn't re-inject with fresh UUIDs.Verified locally —
sentry-cli sourcemaps injectadds matching0e2441e4-9669-58ae-aaa8-bc853561d4c0to both files on a fresh build.Operator action required (unchanged from before)
To make the marker step actually push successfully:
fern-api/actions, on an account that's allowed to bypass branch protection onmain.ACTIONS_PATonfern-api/actions.Without this, the marker step continues to log a warning and skip — release still completes, ledger entry just doesn't land (same as today).
Test plan
pnpm typecheckclean,actionlintcleansentry-cli sourcemaps injectagainst a freshpnpm buildof verify-token — JS gets a//# debugId=…pragma, .map gets a matching"debugId"field with the same UUIDrelease.ymlforverify-tokenwithv0.0.2-test,prerelease=true. Verify:Inject Sentry debug IDsstep succeedsCreate Sentry release + upload sourcemapsstill logsUpload type: artifact bundlegit show verify-token/v0.0.2-test:dist/index.js | tail -2 | grep debugIdverify-token/RELEASES.mdnow actually appears on main with the new entry (ACTIONS_PAT fix)federico-automations-testsin failure mode, confirm the resulting Sentry event has TypeScript-source stack frames, not minified JS.Out of scope
The existing
verify-token/v0.0.1-testrelease will keep showing minified frames — it was published without a debug ID. Cut a new prerelease (v0.0.2-test) to validate end-to-end. The old release can't be retroactively deobfuscated unless its bundle is re-uploaded with debug IDs, which isn't worth the effort for a smoke-test release.