@@ -14,35 +14,48 @@ permissions:
1414 pull-requests : write
1515
1616jobs :
17+ # release-please owns tag + GitHub Release creation (no
18+ # skip-github-release). Because it tags every release inside its own run
19+ # — before it computes the next release PR — it always knows the previous
20+ # release boundary, so it never regenerates the changelog from the start
21+ # of history or proposes a spurious major bump. This job is kept minimal
22+ # so nothing downstream (changelog enrichment, release notes) can fail it.
1723 release-please :
18- needs : publish-release
19- if : needs.publish-release.outputs.is-release != 'true'
2024 runs-on : ubuntu-latest
2125 outputs :
2226 pr : ${{ steps.release.outputs.pr }}
27+ release_created : ${{ steps.release.outputs.release_created }}
28+ tag_name : ${{ steps.release.outputs.tag_name }}
2329 steps :
2430 - uses : actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # 3.2.0
2531 id : app-token
2632 with :
2733 app-id : ${{ vars.SDK_BOT_APP_ID }}
2834 private-key : ${{ secrets.SDK_BOT_PRIVATE_KEY }}
2935
30- # skip-github-release means release-please opens/updates release
31- # PRs and updates CHANGELOG.md as usual, but does NOT tag or create
32- # the GitHub Release on merge. Those are owned by publish-release
33- # below so we can set the Release body from the rich CHANGELOG.md
34- # section instead of release-please's terse default rendering.
3536 - uses : googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0
3637 id : release
3738 with :
3839 token : ${{ steps.app-token.outputs.token }}
39- skip-github-release : true
40+
41+ # While the release PR is open, enrich it before it merges. Runs as its
42+ # own job (gated on the PR existing) so a failure here can never block the
43+ # release or any publish that depends on release-please.
44+ enrich-release-pr :
45+ needs : release-please
46+ if : needs.release-please.outputs.pr
47+ runs-on : ubuntu-latest
48+ steps :
49+ - uses : actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # 3.2.0
50+ id : app-token
51+ with :
52+ app-id : ${{ vars.SDK_BOT_APP_ID }}
53+ private-key : ${{ secrets.SDK_BOT_PRIVATE_KEY }}
4054
4155 - name : Checkout release PR branch
42- if : steps.release.outputs.pr
4356 uses : actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # 6.0.3
4457 with :
45- ref : ${{ fromJSON(steps .release.outputs.pr).headBranchName }}
58+ ref : ${{ fromJSON(needs .release-please .outputs.pr).headBranchName }}
4659 token : ${{ steps.app-token.outputs.token }}
4760
4861 # Inline pending changelog fragments under the version heading
5366 # release-please wrote. Fragments are deleted in the same commit.
5467 # Idempotent: if no fragments exist, skip silently.
5568 - name : Inline rich changelog fragments
56- if : steps.release.outputs.pr
5769 env :
58- PR_JSON : ${{ steps .release.outputs.pr }}
70+ PR_JSON : ${{ needs .release-please .outputs.pr }}
5971 run : |
6072 set -euo pipefail
6173 shopt -s nullglob
@@ -134,94 +146,39 @@ jobs:
134146 git commit -m "chore: inline release notes from .changelog-pending"
135147 git push
136148
137- # Detect when a release-please release PR has merged, then tag and
138- # create the GitHub Release whose body is extracted from CHANGELOG.md
139- # (now rich, after the inline step above). Runs on every push to main;
140- # the detect step gates everything else.
141- publish-release :
149+ # After release-please tags the release and creates the GitHub Release,
150+ # replace its body with the rich section from CHANGELOG.md (release-please
151+ # writes only its terse default rendering). Cosmetic-only: never fails the
152+ # release if the section can't be found.
153+ update-release-notes :
154+ needs : release-please
155+ if : needs.release-please.outputs.release_created == 'true'
142156 runs-on : ubuntu-latest
143- permissions :
144- contents : write
145- pull-requests : write
146- outputs :
147- is-release : ${{ steps.detect.outputs.is-release }}
148- version : ${{ steps.detect.outputs.version }}
149157 steps :
150- - name : Generate token
151- id : generate-token
152- uses : actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # 3.2.0
158+ - uses : actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # 3.2.0
159+ id : app-token
153160 with :
154161 app-id : ${{ vars.SDK_BOT_APP_ID }}
155162 private-key : ${{ secrets.SDK_BOT_PRIVATE_KEY }}
156163
157164 - uses : actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # 6.0.3
158165 with :
159- fetch-depth : 0
160- token : ${{ steps.generate-token.outputs.token }}
161-
162- - name : Detect release PR merge
163- id : detect
164- run : |
165- set -euo pipefail
166- SUBJECT=$(git log -1 --format=%s)
167- # release-please's default release PR title:
168- # chore(main): release X.Y.Z
169- if [[ "$SUBJECT" =~ ^chore\(.*\):[[:space:]]release[[:space:]]([0-9]+\.[0-9]+\.[0-9]+) ]]; then
170- VERSION="${BASH_REMATCH[1]}"
171- echo "is-release=true" >> "$GITHUB_OUTPUT"
172- echo "version=$VERSION" >> "$GITHUB_OUTPUT"
173- if [[ "$SUBJECT" =~ \#([0-9]+) ]]; then
174- echo "pr-number=${BASH_REMATCH[1]}" >> "$GITHUB_OUTPUT"
175- fi
176- echo "Detected release PR merge for v$VERSION"
177- else
178- echo "Not a release PR merge: $SUBJECT"
179- echo "is-release=false" >> "$GITHUB_OUTPUT"
180- fi
166+ token : ${{ steps.app-token.outputs.token }}
181167
182- - name : Extract release notes from CHANGELOG.md
183- if : steps.detect.outputs.is-release == 'true'
168+ - name : Set rich release notes from CHANGELOG.md
184169 env :
185- VERSION : ${{ steps.detect.outputs.version }}
170+ GH_TOKEN : ${{ steps.app-token.outputs.token }}
171+ TAG : ${{ needs.release-please.outputs.tag_name }}
186172 run : |
187173 set -euo pipefail
174+ VERSION="${TAG#v}"
188175 awk -v v="$VERSION" '
189176 $0 ~ ("^## \\[" v "\\]") { found=1; next }
190177 found && /^## \[/ { exit }
191178 found
192179 ' CHANGELOG.md > /tmp/release-notes.md
193- if [ ! -s /tmp/release-notes.md ]; then
194- echo "::error::CHANGELOG.md has no body for v$VERSION"
195- exit 1
196- fi
197-
198- - name : Tag and create GitHub Release
199- if : steps.detect.outputs.is-release == 'true'
200- env :
201- GH_TOKEN : ${{ steps.generate-token.outputs.token }}
202- VERSION : ${{ steps.detect.outputs.version }}
203- run : |
204- set -euo pipefail
205- TAG="v$VERSION"
206- if gh release view "$TAG" >/dev/null 2>&1; then
207- echo "Release $TAG already exists; skipping."
208- exit 0
180+ if [ -s /tmp/release-notes.md ]; then
181+ gh release edit "$TAG" --notes-file /tmp/release-notes.md
182+ else
183+ echo "No CHANGELOG.md body for $TAG; keeping release-please default notes."
209184 fi
210- git config user.name "workos-sdk-automation[bot]"
211- git config user.email "255426317+workos-sdk-automation[bot]@users.noreply.github.com"
212- git tag -a "$TAG" -m "Release $TAG"
213- git push origin "$TAG"
214- gh release create "$TAG" \
215- --title "$TAG" \
216- --notes-file /tmp/release-notes.md
217-
218- - name : Mark release PR as tagged
219- if : steps.detect.outputs.is-release == 'true' && steps.detect.outputs['pr-number']
220- env :
221- GH_TOKEN : ${{ steps.generate-token.outputs.token }}
222- PR_NUMBER : ${{ steps.detect.outputs['pr-number'] }}
223- run : |
224- set -euo pipefail
225- gh pr edit "$PR_NUMBER" \
226- --remove-label "autorelease: pending" \
227- --add-label "autorelease: tagged"
0 commit comments