mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-11 21:57:14 +03:00
Retry the generated-output push when main advances mid-sync
The sync workflow built once from the checked-out main and aborted when a human commit landed during the ~30s build window (about 10% of runs per the evidence in issue #388), leaving generated provider output stale until the next unrelated push re-triggered it. The commit step now loops up to five times: on a lost race it resets hard to the fresh origin/main (source included), re-installs and rebuilds, and pushes again with linear backoff. Every attempt therefore builds from the main it will land on, which is the invariant the old abort guard protected; the merge-base check stays inside the loop as the pre-push verification. When the rebuilt output shows no drift (the racing commit was another sync, or the new source produces identical output) the step exits cleanly instead of committing an empty sync. Validated by yaml-lint, bash -n, and a local three-repo simulation (bare origin + worker + racer) confirming the lost race rebuilds against the racer's source and lands matching output on attempt two. Retry design proposed by @mktdgtbrz in #388; implemented from the description with the no-drift early exit added. Prepared with AI assistance (Claude Code), directed by @pbakaus. Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Code
parent
af78b1e512
commit
dfd7f9636d
@@ -80,18 +80,42 @@ jobs:
|
||||
- name: Commit generated output
|
||||
if: steps.drift.outputs.changed == 'true'
|
||||
run: |
|
||||
set -euo pipefail
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git add $GENERATED_PATHS
|
||||
git commit -m "Sync generated provider output"
|
||||
|
||||
git fetch origin main
|
||||
if ! git merge-base --is-ancestor origin/main HEAD; then
|
||||
echo "::error::main advanced while generated output was building; rerun this workflow on the latest main."
|
||||
exit 1
|
||||
fi
|
||||
# A push can lose the race against a human commit landing on main
|
||||
# during the ~30s build window (issue #388: ~10% of runs). Instead
|
||||
# of aborting and waiting for an unrelated push to re-trigger the
|
||||
# sync, re-sync to the latest main, rebuild against the current
|
||||
# source, and push again, with backoff. Every attempt builds from
|
||||
# a fresh origin/main, so pushed output always matches the source
|
||||
# state it lands on.
|
||||
for attempt in 1 2 3 4 5; do
|
||||
git add $GENERATED_PATHS
|
||||
if git diff --cached --quiet; then
|
||||
# The race that beat us was another sync (or the rebuilt output
|
||||
# matches the new main); nothing left to push.
|
||||
echo "No generated output drift after rebuild (attempt $attempt); nothing to push."
|
||||
exit 0
|
||||
fi
|
||||
git commit -m "Sync generated provider output"
|
||||
|
||||
git push origin HEAD:main
|
||||
git fetch origin main
|
||||
if git merge-base --is-ancestor origin/main HEAD && git push origin HEAD:main; then
|
||||
echo "Pushed generated output on attempt $attempt."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "main advanced during attempt $attempt; re-syncing and rebuilding."
|
||||
git reset --hard origin/main
|
||||
bun install --frozen-lockfile
|
||||
bun run build:release
|
||||
sleep $((attempt * 5))
|
||||
done
|
||||
|
||||
echo "::error::main kept advancing through 5 sync attempts; rerun this workflow on the latest main."
|
||||
exit 1
|
||||
|
||||
- name: Summarize generated output commit
|
||||
if: steps.drift.outputs.changed == 'true'
|
||||
|
||||
Reference in New Issue
Block a user