Skip to content

Commit 266077e

Browse files
MoonBoi9001claude
andcommitted
fix(ci): improve sync-manifest to handle branch protection
- Only sync manifest when tag > manifest (forward-only, never downgrade) - Create PR instead of pushing directly to main (respects branch protection) - Check for existing sync PR to avoid duplicates - Skip release-please while sync PR is open to prevent incorrect release PRs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 966dd53 commit 266077e

File tree

2 files changed

+60
-12
lines changed

2 files changed

+60
-12
lines changed

.github/actions/sync-manifest/action.yml

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ runs:
2828
id: check
2929
shell: bash
3030
run: |
31+
# Compare semver versions: returns 0 if $1 > $2
32+
version_gt() {
33+
test "$(printf '%s\n' "$1" "$2" | sort -V | head -n1)" != "$1"
34+
}
35+
3136
# Get latest tag (with fallback if no tags exist)
3237
LATEST_TAG=$(git tag --sort=-version:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -1 || echo "v0.0.0")
3338
LATEST_VERSION="${LATEST_TAG#v}"
@@ -38,27 +43,43 @@ runs:
3843
echo "Latest tag: $LATEST_TAG ($LATEST_VERSION)"
3944
echo "Manifest version: $MANIFEST_VERSION"
4045
41-
# Check if they match
42-
if [ "$LATEST_VERSION" != "$MANIFEST_VERSION" ]; then
46+
echo "latest_version=$LATEST_VERSION" >> $GITHUB_OUTPUT
47+
echo "manifest_version=$MANIFEST_VERSION" >> $GITHUB_OUTPUT
48+
49+
# Only sync if tag is AHEAD of manifest (never downgrade)
50+
# This prevents reverting manifest during release PR merges while still
51+
# catching drift from manual deploys (tag created before PR merge)
52+
if [ "$LATEST_VERSION" != "$MANIFEST_VERSION" ] && version_gt "$LATEST_VERSION" "$MANIFEST_VERSION"; then
4353
echo "drift=true" >> $GITHUB_OUTPUT
44-
echo "latest_version=$LATEST_VERSION" >> $GITHUB_OUTPUT
45-
echo "manifest_version=$MANIFEST_VERSION" >> $GITHUB_OUTPUT
46-
echo "Drift detected - manifest needs update"
54+
echo "Drift detected - manifest ($MANIFEST_VERSION) is behind tag ($LATEST_VERSION)"
55+
elif [ "$LATEST_VERSION" != "$MANIFEST_VERSION" ]; then
56+
echo "drift=false" >> $GITHUB_OUTPUT
57+
echo "Manifest ($MANIFEST_VERSION) is ahead of tag ($LATEST_VERSION) - release in progress, skipping"
4758
else
4859
echo "drift=false" >> $GITHUB_OUTPUT
49-
echo "latest_version=$LATEST_VERSION" >> $GITHUB_OUTPUT
50-
echo "manifest_version=$MANIFEST_VERSION" >> $GITHUB_OUTPUT
5160
echo "Manifest is in sync with tags"
5261
fi
5362
5463
- name: Update manifest if drifted
5564
id: update
5665
if: steps.check.outputs.drift == 'true' && inputs.auto-commit == 'true'
5766
shell: bash
67+
env:
68+
GH_TOKEN: ${{ github.token }}
5869
run: |
5970
VERSION="${{ steps.check.outputs.latest_version }}"
71+
OLD_VERSION="${{ steps.check.outputs.manifest_version }}"
72+
BRANCH="chore/sync-manifest-to-${VERSION}"
73+
74+
# Check if PR already exists for this sync
75+
EXISTING_PR=$(gh pr list --head "$BRANCH" --json number --jq '.[0].number' 2>/dev/null || echo "")
76+
if [ -n "$EXISTING_PR" ]; then
77+
echo "PR #$EXISTING_PR already exists for this manifest sync"
78+
echo "synced=false" >> $GITHUB_OUTPUT
79+
exit 0
80+
fi
6081
61-
# Update manifest (with error handling for missing/invalid file)
82+
# Update manifest
6283
if ! jq --arg version "$VERSION" '.["."] = $version' .release-please-manifest.json > manifest.tmp 2>/dev/null; then
6384
echo "Warning: Could not update manifest, creating new one"
6485
echo "{\".\": \"$VERSION\"}" > manifest.tmp
@@ -69,10 +90,23 @@ runs:
6990
git config user.name "github-actions[bot]"
7091
git config user.email "github-actions[bot]@users.noreply.github.com"
7192
72-
# Commit and push
93+
# Create branch and commit
94+
git checkout -b "$BRANCH"
7395
git add .release-please-manifest.json
74-
git commit -m "chore: auto-sync manifest to $VERSION (was ${{ steps.check.outputs.manifest_version }}) [skip ci]"
75-
git push origin main
96+
git commit -m "chore: sync manifest to $VERSION (was $OLD_VERSION)"
97+
git push -u origin "$BRANCH"
98+
99+
# Create PR
100+
gh pr create \
101+
--title "chore: sync release-please manifest to $VERSION" \
102+
--body "Auto-generated PR to sync release-please manifest with git tags.
103+
104+
- **Previous version:** $OLD_VERSION
105+
- **Target version:** $VERSION
106+
107+
This PR was created because the manifest version fell behind the latest git tag, likely due to a manual release." \
108+
--base main \
109+
--head "$BRANCH"
76110

77111
echo "synced=true" >> $GITHUB_OUTPUT
78-
echo "Manifest synced: ${{ steps.check.outputs.manifest_version }} -> $VERSION"
112+
echo "Created PR to sync manifest: $OLD_VERSION -> $VERSION"

.github/workflows/release-please.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,18 @@ jobs:
3535
# Run even if sync-manifest was skipped (bot commits)
3636
if: always() && (needs.sync-manifest.result == 'success' || needs.sync-manifest.result == 'skipped')
3737
steps:
38+
- name: Check for open sync PRs
39+
id: check-sync
40+
env:
41+
GH_TOKEN: ${{ github.token }}
42+
run: |
43+
SYNC_PR=$(gh pr list --repo ${{ github.repository }} --search "sync release-please manifest in:title" --state open --json number --jq '.[0].number' 2>/dev/null || echo "")
44+
if [ -n "$SYNC_PR" ]; then
45+
echo "skip=true" >> $GITHUB_OUTPUT
46+
echo "::warning::Skipping release-please - manifest sync PR #$SYNC_PR is open. Merge it first."
47+
else
48+
echo "skip=false" >> $GITHUB_OUTPUT
49+
fi
50+
3851
- uses: google-github-actions/release-please-action@v4
52+
if: steps.check-sync.outputs.skip != 'true'

0 commit comments

Comments
 (0)