Skip to content

Commit b2f7c9f

Browse files
committed
chore(ci): fix race condition in steps that auto-push changes to main
1 parent 62ad6d1 commit b2f7c9f

2 files changed

Lines changed: 58 additions & 8 deletions

File tree

.github/workflows/ci.yml

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,9 @@ jobs:
110110
- name: Commit bundle size history
111111
if: success() && github.ref == 'refs/heads/main'
112112
run: |
113-
git config user.name "github-actions[bot]"
114-
git config user.email "github-actions[bot]@users.noreply.github.com"
115-
git add components/secutils-webui/.bundlesize/history.jsonl
116-
git diff --cached --quiet || git commit -m "chore: update bundle size history [skip ci]" && git push
113+
./dev/scripts/commit-ci-history.sh \
114+
components/secutils-webui/.bundlesize/history.jsonl \
115+
"chore: update bundle size history [skip ci]"
117116
118117
ci-perf:
119118
name: JS Runtime Perf Harness (Linux)
@@ -178,10 +177,9 @@ jobs:
178177
- name: Commit perf history
179178
if: success() && github.ref == 'refs/heads/main'
180179
run: |
181-
git config user.name "github-actions[bot]"
182-
git config user.email "github-actions[bot]@users.noreply.github.com"
183-
git add .perf/history.jsonl
184-
git diff --cached --quiet || git commit -m "chore: update JS runtime perf history [skip ci]" && git push
180+
./dev/scripts/commit-ci-history.sh \
181+
.perf/history.jsonl \
182+
"chore: update JS runtime perf history [skip ci]"
185183
186184
ci-docs:
187185
name: Build Docs (Linux)

dev/scripts/commit-ci-history.sh

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Commit a single auto-generated history file and push it to the current branch.
4+
#
5+
# Multiple CI jobs (the webui bundle-size job and the JS runtime perf job) run in
6+
# parallel on every push to `main` and each commit a different history file back
7+
# to the branch. They all check out the same triggering SHA, so the first one to
8+
# push advances `origin/main` and the others become non-fast-forward and get
9+
# rejected. Because every job touches a distinct, append-only history file, we can
10+
# safely fetch + rebase our single commit onto the latest branch tip and retry the
11+
# push until it lands.
12+
#
13+
# Usage: commit-ci-history.sh <file> <commit-message>
14+
15+
set -euo pipefail
16+
17+
if [[ $# -ne 2 ]]; then
18+
echo "Usage: $0 <file> <commit-message>" >&2
19+
exit 2
20+
fi
21+
22+
FILE="$1"
23+
MESSAGE="$2"
24+
BRANCH="${GITHUB_REF_NAME:-$(git rev-parse --abbrev-ref HEAD)}"
25+
MAX_ATTEMPTS="${PUSH_MAX_ATTEMPTS:-5}"
26+
27+
git config user.name "github-actions[bot]"
28+
git config user.email "github-actions[bot]@users.noreply.github.com"
29+
30+
git add "$FILE"
31+
if git diff --cached --quiet; then
32+
echo "No changes to ${FILE}; nothing to commit."
33+
exit 0
34+
fi
35+
36+
git commit -m "$MESSAGE"
37+
38+
for attempt in $(seq 1 "$MAX_ATTEMPTS"); do
39+
if git push origin "HEAD:${BRANCH}"; then
40+
echo "Pushed ${FILE} on attempt ${attempt}/${MAX_ATTEMPTS}."
41+
exit 0
42+
fi
43+
44+
echo "Push rejected (attempt ${attempt}/${MAX_ATTEMPTS}); rebasing onto origin/${BRANCH} and retrying..."
45+
git fetch origin "$BRANCH"
46+
# The racing job only ever touches a different history file, so replaying our
47+
# single commit onto the new tip never conflicts.
48+
git rebase "origin/${BRANCH}"
49+
done
50+
51+
echo "Failed to push ${FILE} after ${MAX_ATTEMPTS} attempts." >&2
52+
exit 1

0 commit comments

Comments
 (0)