ci(sync-upstream): guard merge/push on existing remote branch - #14
Merged
Merged
Conversation
The sync branch name is derived from the upstream commit date, so every run computes the same name while upstream sits on one release. The only idempotency guard checked for an *open* PR; a branch pushed by a prior run that never landed a PR (or whose PR was closed) slipped through. The job then re-created the branch from origin/main and force-free-pushed a diverged history, which git rejects as non-fast-forward — wedging the workflow on every 2-hour cron tick. Detect the existing remote branch and skip the merge/push when present, while still letting the Create PR step (re)open a PR against it. This both fixes the non-fast-forward failure and recovers orphaned branches.
The fork removed .github/workflows/zizmor.yml and .github/CODEOWNERS, both of which still exist upstream. An upstream edit to either surfaces as a modify/delete conflict (same as release.yml), which previously fell through to the manual-review path and aborted the merge. Resolve them back to 'deleted' automatically so the fork's removals are preserved.
dogmar
force-pushed
the
claude/peaceful-euler-eEY69
branch
from
May 28, 2026 23:30
c7e17b4 to
43d9ec3
Compare
A closed (not merged) sync PR means the version was deliberately rejected. The prior open-only check let it through, but gh pr create refuses a second PR for a head that already has one, so the recovery path still wedged. Match PRs in any state so a closed PR skips the sync.
dogmar
marked this pull request as ready for review
May 28, 2026 23:40
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 to the Sync Upstream workflow (
.github/workflows/sync-upstream.yml). Rebased on latestmain.1. Guard merge/push on an existing remote branch
Fixes the recurring non-fast-forward push failure:
Root cause: the sync branch name is derived from the upstream commit date, so every run computes the same name while upstream sits on one release. The only idempotency guard matched open PRs only — a branch pushed by a prior run that never landed a PR (or whose PR was closed) slipped through, got re-created from
origin/main, and the plain (non-force) push was rejected as diverged, wedging the workflow every 2 hours.Change: the check step now also detects an existing remote branch (
git ls-remote --exit-code --heads) and exposesbranch_exists. The Setup/Merge steps gain&& branch_exists == 'false'so an existing branch is never re-created or re-pushed, while Create PR still runs to (re)open a PR against it — recovering orphaned branches instead of stranding them.2. Keep fork-removed files deleted on sync
The fork removed
.github/workflows/zizmor.ymland.github/CODEOWNERS, both of which still exist upstream and at the merge-base. An upstream edit to either surfaces as a modify/delete conflict (same shape asrelease.yml), which previously fell through to the manual-review path and aborted the merge.Change: the conflict resolver now keeps
release.yml,zizmor.yml, andCODEOWNERSdeleted automatically, preserving the fork's removals.Test plan
Sync Upstreamwhen async/...branch exists with no open PR → merge/push skipped, PR opened against the existing branch (no non-fast-forward error).zizmor.ymlorCODEOWNERS→ both auto-resolved to deleted, merge completes.Notes
GITHUB_TOKENworkflows-permission push error).