ci: arm auto-merge on Fern regeneration PRs - #3
Draft
antonwhop wants to merge 1 commit into
Draft
Conversation
Adds a pull_request_target workflow that enables squash auto-merge for pull requests opened by fern-api[bot] from an in-repo fern-bot/* branch, and lists it in .fernignore so a regeneration cannot prune it.
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.
Why / Prompt
Fern opens an SDK regeneration PR in each of these repos and it then sits there until a human clicks merge. Three of the four things needed for those PRs to merge themselves are already configured:
allow_auto_merge, amainruleset with required status checks, and the Fern API app as apull_requestbypass actor so its PRs do not need the approval. The missing piece is the thing that arms each PR. This adds it.Merging is not publishing — a version bump through
publish-main.ymlis still a separate deliberate act — so what lands onmainunreviewed is generated code that the required checks have passed.What changed?
.github/workflows/auto-merge.yml. Onpull_request_target(opened,reopened,synchronize) it runsgh pr merge --auto --squashfor a PR opened byfern-api[bot](user id115122769) from an in-repofern-bot/*branch targeting the default branch. No actions are used, so there is nothing to pin; no PR code is checked out..fernignore..fernignoreis read from the PR's base branch, so the entry only protects the file once this PR is merged — the file is unprotected against a regeneration that opens before this lands.Choices, all four verified by running them against
whopsdk-ruby#56:pull_request_target, notpull_request.pull_request_targetruns the workflow file from the base branch, so a PR cannot edit the logic that arms it;pull_requestruns the head copy and, for an in-repo branch, hands it a write-capable token. The job checks out nothing, so the usualpull_request_targethazard of executing untrusted code does not apply.fern-bot/*branch, so the load-bearing condition isuser.id == 115122769, which cannot be renamed into. The branch prefix and an in-repo head-repo check are kept as secondary conditions.synchronizeas well asopened.openedalone misses a PR Fern force-pushes to. Re-arming is safe: a secondgh pr merge --autoon an already-armed PR exits 0.contents: write. Measured, not copied: withcontents: readandpull-requests: write,enablePullRequestAutoMergefails withResource not accessible by integration.This does not fully work yet, and the reason is not fixable from a workflow
Run on
whopsdk-ruby#56withGITHUB_TOKEN,gh pr merge --auto --squashsucceeds and GitHub records:GitHub attributes the eventual merge to whoever enabled auto-merge, not to the PR author.
github-actionsis app id15368; the Integration bypass actor configured in all seven rulesets isfern-api, app id244756. So the armed PR will still be held for the one required approval.I did not observe the blocked merge itself — every open Fern PR in all seven repos is currently conflicted, so none can reach the merge point, and merging one was out of scope. The attribution and the permission requirement are measured; the block that follows from them is read off the ruleset configuration.
Closing that gap means making the arming identity one the ruleset already trusts. The narrow version is a dedicated GitHub App used only for this, added as an
Integrationbypass actor. Deliberately not done here: no ruleset was changed and no bypass actor was added, and bypassing blanketgithub-actionsis the wrong answer because it would let any workflow in the repo merge anything.Java-specific: two required contexts cannot report today
The ruleset requires
compile,test,build, anddecide. Onlycompileandtestexist onmain, from Fern'sci.yml;buildanddecidecome frompublish-main.yml, still unmerged in #2. Until that lands, an armed Fern PR waits indefinitely on two contexts that never arrive.