1717 pull-requests : write
1818 outputs :
1919 pr : ${{ steps.release.outputs.pr }}
20+ release_created : ${{ steps.release.outputs.release_created }}
21+ tag_name : ${{ steps.release.outputs.tag_name }}
2022 steps :
2123 - name : Generate token
2224 id : generate-token
@@ -25,17 +27,17 @@ jobs:
2527 app-id : ${{ vars.SDK_BOT_APP_ID }}
2628 private-key : ${{ secrets.SDK_BOT_PRIVATE_KEY }}
2729
28- # skip-github-release means release-please opens/updates release
29- # PRs and updates CHANGELOG.md as usual, but does NOT tag or create
30- # the GitHub Release on merge. Those are owned by publish-release
31- # below so we can set the Release body from the rich CHANGELOG.md
32- # section instead of release-please's terse default rendering.
30+ # release-please owns tag + GitHub Release creation (no
31+ # skip-github-release). This keeps its release-state tracking intact:
32+ # because it tags every release itself, it always knows the previous
33+ # release boundary, so it never regenerates the changelog from the
34+ # start of history or proposes a spurious major bump. The rich release
35+ # body is applied afterward by the update-release-notes job below.
3336 - name : Run release-please
3437 id : release
3538 uses : googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0
3639 with :
3740 token : ${{ steps.generate-token.outputs.token }}
38- skip-github-release : true
3941
4042 - name : Checkout release PR branch
4143 if : steps.release.outputs.pr
@@ -147,18 +149,16 @@ jobs:
147149 git commit -m "chore: inline release notes from .changelog-pending"
148150 git push
149151
150- # Detect when a release-please release PR has merged, then tag and
151- # create the GitHub Release whose body is extracted from CHANGELOG.md
152- # (now rich, after the inline step above). Runs on every push to main;
153- # the detect step gates everything else.
154- publish-release :
152+ # After release-please tags the release and creates the GitHub Release,
153+ # replace its body with the rich section from CHANGELOG.md (release-please
154+ # writes only its terse default rendering). Cosmetic-only: never fails the
155+ # release if the section can't be found.
156+ update-release-notes :
157+ needs : release-please
158+ if : needs.release-please.outputs.release_created == 'true'
155159 runs-on : ubuntu-latest
156160 permissions :
157161 contents : write
158- pull-requests : write
159- outputs :
160- is-release : ${{ steps.detect.outputs.is-release }}
161- version : ${{ steps.detect.outputs.version }}
162162 steps :
163163 - name : Generate token
164164 id : generate-token
@@ -169,79 +169,29 @@ jobs:
169169
170170 - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
171171 with :
172- fetch-depth : 0
173172 token : ${{ steps.generate-token.outputs.token }}
174173
175- - name : Detect release PR merge
176- id : detect
177- run : |
178- set -euo pipefail
179- SUBJECT=$(git log -1 --format=%s)
180- # release-please's default release PR title:
181- # chore(main): release X.Y.Z
182- if [[ "$SUBJECT" =~ ^chore\(.*\):[[:space:]]release[[:space:]]([0-9]+\.[0-9]+\.[0-9]+) ]]; then
183- VERSION="${BASH_REMATCH[1]}"
184- echo "is-release=true" >> "$GITHUB_OUTPUT"
185- echo "version=$VERSION" >> "$GITHUB_OUTPUT"
186- if [[ "$SUBJECT" =~ \#([0-9]+) ]]; then
187- echo "pr-number=${BASH_REMATCH[1]}" >> "$GITHUB_OUTPUT"
188- fi
189- echo "Detected release PR merge for v$VERSION"
190- else
191- echo "Not a release PR merge: $SUBJECT"
192- echo "is-release=false" >> "$GITHUB_OUTPUT"
193- fi
194-
195- - name : Extract release notes from CHANGELOG.md
196- if : steps.detect.outputs.is-release == 'true'
174+ - name : Set rich release notes from CHANGELOG.md
197175 env :
198- VERSION : ${{ steps.detect.outputs.version }}
176+ GH_TOKEN : ${{ steps.generate-token.outputs.token }}
177+ TAG : ${{ needs.release-please.outputs.tag_name }}
199178 run : |
200179 set -euo pipefail
180+ VERSION="${TAG#v}"
201181 awk -v v="$VERSION" '
202182 $0 ~ ("^## \\[" v "\\]") { found=1; next }
203183 found && /^## \[/ { exit }
204184 found
205185 ' CHANGELOG.md > /tmp/release-notes.md
206- if [ ! -s /tmp/release-notes.md ]; then
207- echo "::error::CHANGELOG.md has no body for v$VERSION"
208- exit 1
209- fi
210-
211- - name : Tag and create GitHub Release
212- if : steps.detect.outputs.is-release == 'true'
213- env :
214- GH_TOKEN : ${{ steps.generate-token.outputs.token }}
215- VERSION : ${{ steps.detect.outputs.version }}
216- run : |
217- set -euo pipefail
218- TAG="v$VERSION"
219- if gh release view "$TAG" >/dev/null 2>&1; then
220- echo "Release $TAG already exists; skipping."
221- exit 0
186+ if [ -s /tmp/release-notes.md ]; then
187+ gh release edit "$TAG" --notes-file /tmp/release-notes.md
188+ else
189+ echo "No CHANGELOG.md body for $TAG; keeping release-please default notes."
222190 fi
223- git config user.name "workos-sdk-automation[bot]"
224- git config user.email "255426317+workos-sdk-automation[bot]@users.noreply.github.com"
225- git tag -a "$TAG" -m "Release $TAG"
226- git push origin "$TAG"
227- gh release create "$TAG" \
228- --title "$TAG" \
229- --notes-file /tmp/release-notes.md
230-
231- - name : Mark release PR as tagged
232- if : steps.detect.outputs.is-release == 'true' && steps.detect.outputs['pr-number']
233- env :
234- GH_TOKEN : ${{ steps.generate-token.outputs.token }}
235- PR_NUMBER : ${{ steps.detect.outputs['pr-number'] }}
236- run : |
237- set -euo pipefail
238- gh pr edit "$PR_NUMBER" \
239- --remove-label "autorelease: pending" \
240- --add-label "autorelease: tagged"
241191
242192 publish :
243- needs : publish- release
244- if : needs.publish- release.outputs.is-release == 'true'
193+ needs : release-please
194+ if : needs.release-please .outputs.release_created == 'true'
245195 runs-on : ubuntu-latest
246196 permissions :
247197 id-token : write
0 commit comments