Skip to content

ci: fail when an upstream sync loses its merge parent - #403

Merged
omegent-app[bot] merged 4 commits into
fork/devfrom
ci/upstream-lineage-guard
Aug 15, 2026
Merged

ci: fail when an upstream sync loses its merge parent#403
omegent-app[bot] merged 4 commits into
fork/devfrom
ci/upstream-lineage-guard

Conversation

@omegent-app

@omegent-app omegent-app Bot commented Aug 14, 2026

Copy link
Copy Markdown

#401 was squash-merged. That kept the code and threw the lineage away: the 23 upstream commits stopped being ancestors, so fork/dev read as 29 commits behind upstream when only 6 were genuinely outstanding, and the next sync would have re-merged and re-resolved all 23 — on the same mobile files that took sixteen conflicts to land the first time.

Nobody noticed for two merges. It surfaced in a deploy alert that said "Commits (2)" for a range that had carried 23.

What this adds

A push-triggered check on fork/dev that fails when a commit which carried a sync has fewer than two parents, and prints the -s ours repair in the log.

Sync commits are identified by the head branch of the PR they came from, not by their subject, because subjects vary by merge method:

Merge pull request #400 from patroza/sync/upstream-2026-08-12b
Merge upstream/main into fork/dev (23 commits) (#401)
merge: sync upstream through b73232bdd

A merge-button commit names the branch inline, so no API call is needed; squash and rebase commits are resolved through the API, with the subject line as a fallback when that is unavailable. Ordinary fork PRs are untouched — they are expected to squash, and are never checked.

Verified against the real commits

commit what it is result
5e63531b1 #401, squash-merged sync fails, exit 1
0bf7835cc #400, sync merged properly recognised as a sync, passes (2 parents)
a76069bd9 #402, an ordinary squashed PR not flagged

The third row is the one that matters most: the guard has to stay silent on your normal workflow.

This detects, it does not prevent

Worth being explicit, since it was the first question asked: clicking merge does not fail. The check runs after the merge lands, because GitHub has no per-PR merge-method control, and a repository-wide setting cannot allow squash for ordinary fork PRs while requiring a merge commit for syncs. Squash merges do fire push5e63531b1 triggered Fork CI at 08:08 — so this turns a silent, weeks-later discovery into a red check within a minute.

Actual prevention is gh pr merge <n> --merge, which is how #398, #399 and #400 all landed correctly. That is now written into the sync runbook in AGENTS.md.

If you would rather it be enforced at the button, the next step is a sync:upstream label workflow that merges the PR through the API once checks pass — say the word and I will add it.

Co-authored-by: Patrick Roza 42661+patroza@users.noreply.github.com

🤖 Generated with Claude Code via T3 Chat on Discord

Squash- and rebase-merging a sync PR keeps the code and discards the lineage:
the upstream commits stop being ancestors, so `fork/dev..upstream/main` reports
already-merged work as missing and the next sync re-merges and re-resolves all
of it. #401 landed that way — 23 upstream commits collapsed into one
single-parent commit — and it surfaced two merges later in a deploy alert that
said "Commits (2)" for a range that had carried 23. fork/dev read as 29 commits
behind upstream when only 6 were genuinely outstanding.

The guard runs on every push to fork/dev and fails when a commit that carried a
sync has fewer than two parents, printing the -s ours repair.

Sync commits are identified by the head branch of the PR they came from, not by
their subject, because subjects vary across merge methods:

  Merge pull request #400 from patroza/sync/upstream-2026-08-12b
  Merge upstream/main into fork/dev (23 commits) (#401)
  merge: sync upstream through b73232b

A merge-button commit names the branch inline; squash and rebase commits are
resolved through the API, falling back to the subject when that is unavailable.
Ordinary fork PRs are untouched — they are expected to squash.

This detects rather than prevents: GitHub has no per-PR merge-method control,
and a repository-wide setting cannot allow squash for fork PRs while requiring a
merge commit for syncs. Prevention is `gh pr merge <n> --merge`, now written
into the sync runbook.

Verified against the real commits: #401's squash fails, #400's merge commit
passes as a recognised sync, and #402 — an ordinary squashed PR — is not
flagged.

Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
omegent-app Bot and others added 3 commits August 15, 2026 14:33
`PreviewFaviconIcon.test.tsx` mocks `~/browserFaviconStore`, but the web
`unit` project runs with `isolate: false` and shares one module registry per
worker. When an earlier file in the same worker binds the real module first,
the mock never applies: `useFaviconForThreadUrl` returns null, the icon falls
back to the browser mockup, and only the second assertion — the one that needs
the mock to return a value — fails. That is what #403's CI hit. It reproduces
only under CI's worker sharding, not locally, which is exactly why the file
belongs on the isolated list next to its siblings ProjectFavicon.test.tsx and
PreviewView.test.tsx.

Also removes upstream-pr-body.md, a scratch PR description that a `git add -A`
swept into the #411 sync merge by mistake.

Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
…ge-guard

#410 dropped the obsolete fork stack workflow section this branch had edited.
Kept its simplification and folded the sync-merge rule into the existing
"Updating from upstream" bullet instead of resurrecting the old section.

Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
@omegent-app
omegent-app Bot merged commit a19e4ec into fork/dev Aug 15, 2026
5 checks passed
@omegent-app
omegent-app Bot deleted the ci/upstream-lineage-guard branch August 15, 2026 15:12
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.

0 participants