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"
0 commit comments