Skip to content

Commit 984cc95

Browse files
JOYclaude
andcommitted
ci: Fix sync-upstream workflow — auto-resolve version conflicts
- Add auto-resolve strategy: accept upstream (theirs) for version files (mix.exs, Makefile, config.exs, CHANGELOG) and workflow files - Only create PR for actual code conflicts that need manual resolution - Use GH_PAT secret (fallback GITHUB_TOKEN) for pushing workflow files - Fix PR base branch: master → main Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent eaecba5 commit 984cc95

1 file changed

Lines changed: 72 additions & 9 deletions

File tree

.github/workflows/sync-upstream.yml

Lines changed: 72 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ jobs:
2323
uses: actions/checkout@v4
2424
with:
2525
fetch-depth: 0
26-
token: ${{ secrets.GITHUB_TOKEN }}
26+
# PAT required to push .github/workflows/ changes
27+
# GITHUB_TOKEN cannot modify workflow files
28+
token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }}
2729

2830
- name: Add upstream remote
2931
run: |
@@ -60,13 +62,60 @@ jobs:
6062
git config user.name "github-actions[bot]"
6163
git config user.email "github-actions[bot]@users.noreply.github.com"
6264
63-
# Merge upstream tag into current branch
65+
# Try clean merge first
6466
if git merge "$TAG" --no-edit -m "Merge upstream $TAG"; then
6567
echo "result=success" >> $GITHUB_OUTPUT
68+
exit 0
69+
fi
70+
71+
# Merge failed — auto-resolve conflicts
72+
echo "::notice::Merge conflict detected, attempting auto-resolve..."
73+
74+
# Strategy: accept upstream (theirs) for version/build files
75+
# These are the files that ALWAYS conflict because fork tracks upstream version
76+
VERSION_FILES=(
77+
mix.exs
78+
rel/config.exs
79+
docker/Makefile
80+
CHANGELOG.md
81+
apps/block_scout_web/mix.exs
82+
apps/ethereum_jsonrpc/mix.exs
83+
apps/explorer/mix.exs
84+
apps/indexer/mix.exs
85+
apps/nft_media_handler/mix.exs
86+
apps/utils/mix.exs
87+
)
88+
89+
for f in "${VERSION_FILES[@]}"; do
90+
if git diff --name-only --diff-filter=U | grep -qx "$f"; then
91+
echo " Auto-resolve (theirs): $f"
92+
git checkout --theirs "$f"
93+
git add "$f"
94+
fi
95+
done
96+
97+
# Accept upstream for ALL upstream workflow files (version bumps)
98+
# Our custom workflows (docker-publish, deploy-config, sync-upstream) won't conflict
99+
CONFLICT_WORKFLOWS=$(git diff --name-only --diff-filter=U | grep '^\.github/workflows/' || true)
100+
if [ -n "$CONFLICT_WORKFLOWS" ]; then
101+
echo " Auto-resolve (theirs): workflow files"
102+
echo "$CONFLICT_WORKFLOWS" | xargs git checkout --theirs
103+
echo "$CONFLICT_WORKFLOWS" | xargs git add
104+
fi
105+
106+
# Check if any conflicts remain
107+
REMAINING=$(git diff --name-only --diff-filter=U || true)
108+
if [ -z "$REMAINING" ]; then
109+
echo "All conflicts auto-resolved!"
110+
git commit --no-edit -m "Merge upstream $TAG (auto-resolved version conflicts)"
111+
echo "result=success" >> $GITHUB_OUTPUT
66112
else
67-
echo "::warning::Merge conflict detected. Creating PR instead."
113+
echo "::warning::Unresolvable conflicts in: $REMAINING"
68114
git merge --abort
69115
echo "result=conflict" >> $GITHUB_OUTPUT
116+
echo "conflict_files<<EOF" >> $GITHUB_OUTPUT
117+
echo "$REMAINING" >> $GITHUB_OUTPUT
118+
echo "EOF" >> $GITHUB_OUTPUT
70119
fi
71120
72121
- name: Push and tag
@@ -86,7 +135,7 @@ jobs:
86135
- name: Create release
87136
if: steps.target.outputs.skip == 'false' && steps.merge.outputs.result == 'success'
88137
env:
89-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
138+
GH_TOKEN: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }}
90139
run: |
91140
TAG="${{ steps.target.outputs.tag }}"
92141
# Delete existing release if any (from upstream fork sync)
@@ -99,34 +148,48 @@ jobs:
99148
- name: Create PR on conflict
100149
if: steps.target.outputs.skip == 'false' && steps.merge.outputs.result == 'conflict'
101150
env:
102-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
151+
GH_TOKEN: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }}
103152
run: |
104153
TAG="${{ steps.target.outputs.tag }}"
105154
BRANCH="sync-upstream-${TAG}"
106155
107156
git checkout -b "$BRANCH"
108157
git merge "$TAG" --no-edit || true
109158
110-
# Stage everything including conflict markers
159+
# Auto-resolve what we can (same strategy as above)
160+
for f in mix.exs rel/config.exs docker/Makefile CHANGELOG.md apps/*/mix.exs; do
161+
if git diff --name-only --diff-filter=U | grep -qx "$f" 2>/dev/null; then
162+
git checkout --theirs "$f" && git add "$f"
163+
fi
164+
done
165+
CONFLICT_WF=$(git diff --name-only --diff-filter=U | grep '^\.github/workflows/' || true)
166+
[ -n "$CONFLICT_WF" ] && echo "$CONFLICT_WF" | xargs git checkout --theirs && echo "$CONFLICT_WF" | xargs git add
167+
111168
git add -A
112169
git commit -m "WIP: Merge upstream $TAG (has conflicts)" --no-verify || true
113170
git push origin "$BRANCH"
114171
172+
REMAINING=$(echo "${{ steps.merge.outputs.conflict_files }}" | head -20)
115173
gh pr create \
116174
--title "Sync upstream $TAG (merge conflicts)" \
117175
--body "$(cat <<EOF
118176
## Upstream Sync - $TAG
119177
120-
Auto-merge with upstream \`$TAG\` failed due to conflicts.
178+
Auto-merge with upstream \`$TAG\` failed. Version/workflow conflicts were auto-resolved,
179+
but the following files have code conflicts that need manual resolution:
180+
181+
\`\`\`
182+
$REMAINING
183+
\`\`\`
121184
122185
**To resolve:**
123186
1. Check out this branch locally
124-
2. Resolve conflicts
187+
2. Resolve remaining conflicts
125188
3. Push and merge this PR
126189
4. Then create tag \`$TAG\` to trigger Docker build
127190
128191
[Upstream release notes](https://github.com/blockscout/blockscout/releases/tag/$TAG)
129192
EOF
130193
)" \
131194
--head "$BRANCH" \
132-
--base master
195+
--base main

0 commit comments

Comments
 (0)