Skip to content

Commit d163843

Browse files
JOYclaude
andcommitted
fix(ci): force version files to match upstream after merge
Git auto-merge can silently pick the wrong side for version/dep files when both sides modified them. After merge (clean or conflict-resolved), explicitly checkout version files from upstream tag and create a fixup commit if any differ. Prevents version string and dependency mismatches. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 4e6b43c commit d163843

1 file changed

Lines changed: 52 additions & 36 deletions

File tree

.github/workflows/sync-upstream.yml

Lines changed: 52 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,7 @@ jobs:
6262
git config user.name "github-actions[bot]"
6363
git config user.email "github-actions[bot]@users.noreply.github.com"
6464
65-
# Try clean merge first
66-
if git merge "$TAG" --no-edit -m "Merge upstream $TAG"; then
67-
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
65+
# Files that MUST match upstream exactly (versions, deps, build config)
7666
VERSION_FILES=(
7767
mix.exs
7868
rel/config.exs
@@ -86,37 +76,63 @@ jobs:
8676
apps/utils/mix.exs
8777
)
8878
79+
# Try clean merge first
80+
if git merge "$TAG" --no-edit -m "Merge upstream $TAG"; then
81+
echo "Clean merge succeeded"
82+
else
83+
# Merge failed — auto-resolve conflicts
84+
echo "::notice::Merge conflict detected, attempting auto-resolve..."
85+
86+
for f in "${VERSION_FILES[@]}"; do
87+
if git diff --name-only --diff-filter=U | grep -qx "$f"; then
88+
echo " Auto-resolve (theirs): $f"
89+
git checkout --theirs "$f"
90+
git add "$f"
91+
fi
92+
done
93+
94+
# Accept upstream for ALL upstream workflow files (version bumps)
95+
# Our custom workflows (docker-publish, deploy-config, sync-upstream) won't conflict
96+
CONFLICT_WORKFLOWS=$(git diff --name-only --diff-filter=U | grep '^\.github/workflows/' || true)
97+
if [ -n "$CONFLICT_WORKFLOWS" ]; then
98+
echo " Auto-resolve (theirs): workflow files"
99+
echo "$CONFLICT_WORKFLOWS" | xargs git checkout --theirs
100+
echo "$CONFLICT_WORKFLOWS" | xargs git add
101+
fi
102+
103+
# Check if any conflicts remain
104+
REMAINING=$(git diff --name-only --diff-filter=U || true)
105+
if [ -n "$REMAINING" ]; then
106+
echo "::warning::Unresolvable conflicts in: $REMAINING"
107+
git merge --abort
108+
echo "result=conflict" >> $GITHUB_OUTPUT
109+
echo "conflict_files<<EOF" >> $GITHUB_OUTPUT
110+
echo "$REMAINING" >> $GITHUB_OUTPUT
111+
echo "EOF" >> $GITHUB_OUTPUT
112+
exit 0
113+
fi
114+
115+
git commit --no-edit -m "Merge upstream $TAG (auto-resolved conflicts)"
116+
fi
117+
118+
# Post-merge: ensure version files match upstream EXACTLY
119+
# Git auto-merge can silently pick the wrong side for these files
120+
FIXUP_NEEDED=false
89121
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"
122+
if [ -f "$f" ] && ! diff -q <(git show "$TAG":"$f" 2>/dev/null) "$f" >/dev/null 2>&1; then
123+
echo " Fixup (upstream): $f"
124+
git checkout "$TAG" -- "$f"
125+
FIXUP_NEEDED=true
94126
fi
95127
done
96128
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
129+
if [ "$FIXUP_NEEDED" = true ]; then
130+
git add -A
131+
git commit -m "fixup: restore upstream version files from $TAG"
132+
echo "::notice::Version files fixed up to match upstream $TAG"
104133
fi
105134
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
112-
else
113-
echo "::warning::Unresolvable conflicts in: $REMAINING"
114-
git merge --abort
115-
echo "result=conflict" >> $GITHUB_OUTPUT
116-
echo "conflict_files<<EOF" >> $GITHUB_OUTPUT
117-
echo "$REMAINING" >> $GITHUB_OUTPUT
118-
echo "EOF" >> $GITHUB_OUTPUT
119-
fi
135+
echo "result=success" >> $GITHUB_OUTPUT
120136
121137
- name: Push and tag
122138
if: steps.target.outputs.skip == 'false' && steps.merge.outputs.result == 'success'

0 commit comments

Comments
 (0)