Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions .github/workflows/back-merge.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
name: Back-merge

# After a release on main, sync main back into next so its changelog, manifest,
# and version bumps do not drift. No conflict -> push next directly (the App is
# an "always" bypass actor on next). Conflict -> open a PR for a human.
# Any other failure -> open a tracking issue so the drift is never silent.
# and version bumps do not drift. When next holds no unreleased work, realign it
# onto main's hashes (force-push, the App is an "always" bypass actor on next)
# so the rebase-promote hash drift cannot accumulate. When next has real work,
# keep the merge. Conflict -> open a PR for a human. Any other failure -> open a
# tracking issue so the drift is never silent.

on:
release:
Expand Down Expand Up @@ -40,7 +42,17 @@ jobs:
git config user.email "aidd-bot[bot]@users.noreply.github.com"
git fetch origin main
if git merge --no-edit origin/main; then
git push origin next
# Promotes to main are rebase-merged, so main carries new commit
# hashes and next drifts even though the content matches. When the
# merge result is content-identical to main (next held no unreleased
# work), realign next onto main's clean hashes so the drift cannot
# accumulate into a giant conflicting promote later. Otherwise next
# has real unreleased work, so keep the merge and push normally.
if git diff --quiet origin/main HEAD; then
git push --force origin "origin/main:refs/heads/next"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve concurrent updates when force-realigning next

In this release workflow, actions/checkout snapshots next before the merge; if any PR or Dependabot merge lands on next while the job is running, this new unconditional --force can still reset refs/heads/next to the previously fetched origin/main, discarding those newer commits. I checked git push -h: --force is only “force updates”, while --force-with-lease requires the old ref value, so using a lease or refetching/rechecking would turn this race into a failed back-merge issue instead of history loss.

Useful? React with 👍 / 👎.

else
git push origin next
fi
else
git merge --abort
BRANCH="back-merge/main-to-next-${{ github.run_id }}"
Expand Down
14 changes: 8 additions & 6 deletions docs/RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@ To force a package to a chosen version on the next cut, set `release-as` for it
in `release-please-config.json` (deterministic, overrides any `Release-As:`
commit footer). Remove the pin afterwards so automatic bumps resume.

## Back-merge failures

If the back-merge cannot push `next`, it opens an issue labelled
`back-merge-failed`. Resync by opening a `main -> next` PR. The root cause is the
bot app needing an `always` bypass on the `next` ruleset; align that and the
back-merge runs unattended.
## Back-merge and drift

The back-merge runs unattended (the bot app has an `always` bypass on the `next`
ruleset). After each release it either realigns `next` onto `main` (when `next`
holds no unreleased work, the normal case) or keeps a merge (when it does), so
the rebase-promote hash drift never accumulates. If it ever cannot push, it
opens an issue labelled `back-merge-failed`; resync by opening a `main -> next`
PR.