Skip to content

Commit be62cae

Browse files
authored
Merge pull request #9 from runloopai/ci/stlc-fork-heal-hint
ci(stlc): explain the trunk-fork heal when back-sync or promote blocks
2 parents a4eecec + 3cb7e2b commit be62cae

3 files changed

Lines changed: 56 additions & 2 deletions

File tree

‎.github/scripts/stlc-fork-hint.sh‎

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env bash
2+
# Explains a staging/production trunk fork and prints the heal command.
3+
# Expects origin/main = staging main and production/main = production main,
4+
# plus GITHUB_REPOSITORY (staging) and PRODUCTION_REPO (production).
5+
set -uo pipefail
6+
7+
STAGING_REPO="$GITHUB_REPOSITORY"
8+
MERGE_MSG="chore: merge staging main into production to heal trunk fork"
9+
# A squash PR cannot heal the fork: only a real merge commit makes staging an
10+
# ancestor of production again, so this pushes past production's PR rule.
11+
HEAL="git clone -q https://github.com/${STAGING_REPO}.git heal-fork && cd heal-fork && git remote add production https://github.com/${PRODUCTION_REPO}.git && git fetch -q production main && git checkout -B heal-fork production/main && git merge --no-ff origin/main -m \"${MERGE_MSG}\" && git push production heal-fork:main"
12+
RESYNC="gh workflow run stlc-sync.yml -R ${STAGING_REPO}"
13+
14+
if git merge-tree --write-tree origin/main production/main >/dev/null 2>&1; then
15+
CLEAN=true
16+
else
17+
CLEAN=false
18+
fi
19+
20+
{
21+
echo "### Staging and production main have forked"
22+
echo
23+
echo "Each trunk has commits the other lacks, so neither back-sync nor promote can fast-forward. Every run of both fails until the fork is healed."
24+
echo
25+
echo "**Only on staging** (\`${STAGING_REPO}\`):"
26+
echo '```'
27+
git log --format='%h %an %s' production/main..origin/main
28+
echo '```'
29+
echo "**Only on production** (\`${PRODUCTION_REPO}\`):"
30+
echo '```'
31+
git log --format='%h %an %s' origin/main..production/main
32+
echo '```'
33+
if [ "$CLEAN" = true ]; then
34+
echo "They merge cleanly. Heal by pushing a merge commit to production main, with an identity that can bypass its pull-request rule (a squash-merged PR does not restore ancestry):"
35+
echo '```'
36+
echo "$HEAL"
37+
echo '```'
38+
echo "Then back-sync fast-forwards staging onto it:"
39+
echo '```'
40+
echo "$RESYNC"
41+
echo '```'
42+
else
43+
echo "They **conflict**, so the heal needs a hand-resolved merge: run the command below without the final \`git push\`, resolve and commit, then push \`heal-fork\` to production main and run \`${RESYNC}\`."
44+
echo '```'
45+
echo "$HEAL"
46+
echo '```'
47+
fi
48+
} >> "${GITHUB_STEP_SUMMARY:-/dev/stdout}"
49+
50+
if [ "$CLEAN" = true ]; then
51+
echo "::error title=Trunks forked (clean merge)::staging and production main have diverged. Heal: push a merge commit to production main, then re-run back-sync. See the job summary for the commits involved.%0A%0A${HEAL}%0A%0A${RESYNC}"
52+
else
53+
echo "::error title=Trunks forked (conflicting)::staging and production main have diverged and do not merge cleanly. Hand-resolve a merge of staging main into production main, push it, then run: ${RESYNC}. See the job summary."
54+
fi

‎.github/workflows/stlc-promote.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ jobs:
6565
# Refuse unless production is an ancestor of staging: otherwise the trunks
6666
# have forked (production advanced without a back-sync) and FF is unsafe.
6767
if ! git merge-base --is-ancestor production/main origin/main; then
68-
echo "::error title=Promote blocked::production/main is not an ancestor of staging main. Back-sync production into staging first."
68+
bash .github/scripts/stlc-fork-hint.sh
6969
exit 1
7070
fi
7171
git push production origin/main:refs/heads/main

‎.github/workflows/stlc-sync.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ jobs:
7777
# Refuse unless staging is an ancestor of production: otherwise the
7878
# trunks have forked and a fast-forward would be unsafe.
7979
if ! git merge-base --is-ancestor origin/main production/main; then
80-
echo "::error title=Back-sync blocked::staging main is not an ancestor of production/main."
80+
bash .github/scripts/stlc-fork-hint.sh
8181
exit 1
8282
fi
8383
if [ -z "${PRODUCTION_REPO_TOKEN:-}" ]; then

0 commit comments

Comments
 (0)