Skip to content

Commit 4431deb

Browse files
pepicrftclaude
andcommitted
fix(release): write release body to file and include GHCR package link
Two issues with the 0.1.0 GitHub Releases that just shipped: 1. The cliff-generated release notes never made it into the release body. The notes were captured via a heredoc into $GITHUB_OUTPUT and then passed through `needs.release-*.outputs`, but the multi-line interpolation came out empty (probably the rerun-after-failed-job dance lost the upstream job's outputs). 2. The release body just printed the image/registry tag as text. Now that the package is linked to the repo, we should link to the GHCR package page so readers can browse versions. Switch to file-based bodies: - `release-server` writes `release-body.md` (heading + clickable GHCR package link + cliff notes) and uploads it as part of `server-artifacts`. - `release-helm` does the same to `infra/helm/hive/release-body.md`, also including a `helm install` snippet. - `commit-and-release` downloads the artifacts and points `softprops/action-gh-release@v2` at the files via `body_path:` instead of the multi-line `body:` template. File-based bodies don't suffer from output-interpolation losses. Drop the now-unused `outputs.release-notes` from `release-server` and `release-helm` since the data flows via artifacts. Also tighten AGENTS.md: PR titles and commits use Conventional Commits *with an explicit scope naming the domain* — `feat(auth):`, `refactor(helm):`, etc. The scope is what cliff reads to bucket commits into the right release notes, so omitting it undermines the per-component changelog. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 76cdebf commit 4431deb

2 files changed

Lines changed: 51 additions & 36 deletions

File tree

.github/workflows/release.yml

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,6 @@ jobs:
150150
if: needs.check-releases.outputs.server-should-release == 'true'
151151
runs-on: ubuntu-latest
152152
timeout-minutes: 30
153-
outputs:
154-
release-notes: ${{ steps.notes.outputs.release-notes }}
155153
steps:
156154
- uses: actions/checkout@v4
157155
with:
@@ -161,22 +159,30 @@ jobs:
161159
install_args: git-cliff
162160
cache: "false"
163161

164-
- name: Get release notes
165-
id: notes
162+
- name: Build release body
166163
env:
167164
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
165+
VERSION: ${{ needs.check-releases.outputs.server-next-version-number }}
168166
run: |
169167
LATEST_VERSION=$(git tag -l | grep -E '^server@[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n1)
170168
171-
{
172-
echo "release-notes<<EOF"
173-
if [ -n "$LATEST_VERSION" ]; then
174-
git cliff --config cliff.toml --repository "." 2>/dev/null -- ${LATEST_VERSION}..HEAD | sed -n '/<!-- RELEASE NOTES START -->/,$p' | tail -n +2
175-
else
176-
git cliff --config cliff.toml --repository "." 2>/dev/null | sed -n '/<!-- RELEASE NOTES START -->/,$p' | tail -n +2
177-
fi
178-
echo "EOF"
179-
} >> "$GITHUB_OUTPUT"
169+
if [ -n "$LATEST_VERSION" ]; then
170+
NOTES=$(git cliff --config cliff.toml --repository "." 2>/dev/null -- ${LATEST_VERSION}..HEAD | sed -n '/<!-- RELEASE NOTES START -->/,$p' | tail -n +2)
171+
else
172+
NOTES=$(git cliff --config cliff.toml --repository "." 2>/dev/null | sed -n '/<!-- RELEASE NOTES START -->/,$p' | tail -n +2)
173+
fi
174+
175+
cat > release-body.md <<EOF
176+
## Docker image
177+
178+
\`ghcr.io/tuist/hive:${VERSION}\` — [view in GitHub Container Registry](https://github.com/${{ github.repository }}/pkgs/container/hive)
179+
180+
$NOTES
181+
EOF
182+
183+
echo "::group::release-body.md"
184+
cat release-body.md
185+
echo "::endgroup::"
180186
181187
- name: Update CHANGELOG.md
182188
env:
@@ -211,7 +217,9 @@ jobs:
211217
- uses: actions/upload-artifact@v4
212218
with:
213219
name: server-artifacts
214-
path: CHANGELOG.md
220+
path: |
221+
CHANGELOG.md
222+
release-body.md
215223
retention-days: 1
216224

217225
release-helm:
@@ -220,8 +228,6 @@ jobs:
220228
if: needs.check-releases.outputs.helm-should-release == 'true'
221229
runs-on: ubuntu-latest
222230
timeout-minutes: 15
223-
outputs:
224-
release-notes: ${{ steps.notes.outputs.release-notes }}
225231
steps:
226232
- uses: actions/checkout@v4
227233
with:
@@ -231,22 +237,36 @@ jobs:
231237
install_args: "git-cliff helm"
232238
cache: "false"
233239

234-
- name: Get release notes
235-
id: notes
240+
- name: Build release body
236241
env:
237242
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
243+
VERSION: ${{ needs.check-releases.outputs.helm-next-version-number }}
238244
run: |
239245
LATEST_VERSION=$(git tag -l | grep -E '^helm@[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n1)
240246
241-
{
242-
echo "release-notes<<EOF"
243-
if [ -n "$LATEST_VERSION" ]; then
244-
git cliff --include-path "infra/helm/**/*" --config infra/helm/hive/cliff.toml --repository "." 2>/dev/null -- ${LATEST_VERSION}..HEAD | sed -n '/<!-- RELEASE NOTES START -->/,$p' | tail -n +2
245-
else
246-
git cliff --include-path "infra/helm/**/*" --config infra/helm/hive/cliff.toml --repository "." 2>/dev/null | sed -n '/<!-- RELEASE NOTES START -->/,$p' | tail -n +2
247-
fi
248-
echo "EOF"
249-
} >> "$GITHUB_OUTPUT"
247+
if [ -n "$LATEST_VERSION" ]; then
248+
NOTES=$(git cliff --include-path "infra/helm/**/*" --config infra/helm/hive/cliff.toml --repository "." 2>/dev/null -- ${LATEST_VERSION}..HEAD | sed -n '/<!-- RELEASE NOTES START -->/,$p' | tail -n +2)
249+
else
250+
NOTES=$(git cliff --include-path "infra/helm/**/*" --config infra/helm/hive/cliff.toml --repository "." 2>/dev/null | sed -n '/<!-- RELEASE NOTES START -->/,$p' | tail -n +2)
251+
fi
252+
253+
cat > infra/helm/hive/release-body.md <<EOF
254+
## Helm chart (OCI artifact)
255+
256+
\`oci://ghcr.io/tuist/charts/hive:${VERSION}\` — [view in GitHub Container Registry](https://github.com/orgs/tuist/packages/container/charts%2Fhive)
257+
258+
Install with:
259+
260+
\`\`\`bash
261+
helm install hive oci://ghcr.io/tuist/charts/hive --version ${VERSION}
262+
\`\`\`
263+
264+
$NOTES
265+
EOF
266+
267+
echo "::group::release-body.md"
268+
cat infra/helm/hive/release-body.md
269+
echo "::endgroup::"
250270
251271
- name: Update Chart.yaml
252272
run: |
@@ -281,6 +301,7 @@ jobs:
281301
path: |
282302
infra/helm/hive/Chart.yaml
283303
infra/helm/hive/CHANGELOG.md
304+
infra/helm/hive/release-body.md
284305
retention-days: 1
285306

286307
commit-and-release:
@@ -330,10 +351,7 @@ jobs:
330351
draft: false
331352
name: Server ${{ needs.check-releases.outputs.server-next-version-number }}
332353
tag_name: ${{ needs.check-releases.outputs.server-next-version }}
333-
body: |
334-
Docker image: `ghcr.io/tuist/hive:${{ needs.check-releases.outputs.server-next-version-number }}`
335-
336-
${{ needs.release-server.outputs.release-notes }}
354+
body_path: release-body.md
337355

338356
- name: Create Helm GitHub Release
339357
if: needs.check-releases.outputs.helm-should-release == 'true' && needs.release-helm.result == 'success'
@@ -342,10 +360,7 @@ jobs:
342360
draft: false
343361
name: Helm Chart ${{ needs.check-releases.outputs.helm-next-version-number }}
344362
tag_name: ${{ needs.check-releases.outputs.helm-next-version }}
345-
body: |
346-
OCI registry: `oci://ghcr.io/tuist/charts/hive:${{ needs.check-releases.outputs.helm-next-version-number }}`
347-
348-
${{ needs.release-helm.outputs.release-notes }}
363+
body_path: infra/helm/hive/release-body.md
349364

350365
- name: Commit CHANGELOG / Chart bumps
351366
run: |

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ YAML
124124

125125
## Conventions
126126

127-
- Conventional Commits for PR titles and commit messages (`feat:`, `refactor(helm):`, `docs:`).
127+
- **PR titles and commit messages use Conventional Commits with an explicit scope naming the domain.** Examples: `feat(auth): support Apple sign-in`, `refactor(helm): genericize the chart`, `style(web): adopt tuist-style login`, `test(auth): use Mimic instead of put_env`, `ci(release): pin action SHAs`, `docs(deploy): document Tuist's overlay`. The scope drives `git-cliff`'s changelog grouping: `(helm)` commits feed the chart's release notes; every other scope feeds the app's. Don't omit the scope (`feat:` alone is acceptable in cliff but undermines reviewer/release-note clarity).
128128
- Prefer editing existing files over creating new ones; keep modules small and domain-focused.
129129
- No comments unless the *why* is non-obvious. Don't restate what well-named code does.
130130
- For UI work, the reference design system is Noora (already in `deps/`). Reference layouts and patterns from `../tuist/server` and `../atlas` when in doubt.

0 commit comments

Comments
 (0)