Skip to content

Commit 89f034e

Browse files
authored
Add automated release notes generation (#846)
1 parent 4b9e0a4 commit 89f034e

File tree

2 files changed

+155
-33
lines changed

2 files changed

+155
-33
lines changed

.github/workflows/release.yml

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@ permissions:
99
contents: write
1010

1111
jobs:
12-
release:
13-
name: Build and Release XCFrameworks
12+
release-notes:
13+
uses: ./.github/workflows/release_notes.yml
14+
with:
15+
tag-name: ${{ github.ref_name }}
16+
secrets: inherit
17+
18+
build-xcframeworks:
19+
name: Build and Upload XCFrameworks
20+
needs: release-notes
1421
runs-on: macos-15
1522
outputs:
1623
checksum_OpenSwiftUI: ${{ steps.build.outputs.checksum_OpenSwiftUI }}
@@ -33,41 +40,35 @@ jobs:
3340
tag-name: ${{ github.ref_name }}
3441
signing-certificate-base64: ${{ secrets.SIGNING_CERTIFICATE_BASE_64 }}
3542
signing-certificate-password: ${{ secrets.SIGNING_CERTIFICATE_PASSWORD }}
36-
- name: Create Release
37-
uses: ncipollo/release-action@v1
38-
with:
39-
body: |
40-
```swift
41-
${{ steps.build.outputs.body }}
42-
```
43-
allowUpdates: true
44-
artifacts: "build/*.xcframework.zip"
45-
token: ${{ secrets.GITHUB_TOKEN }}
43+
- name: Upload assets to release
44+
run: gh release upload "${{ github.ref_name }}" build/*.xcframework.zip --clobber
4645

4746
update-binary-repo:
4847
name: Update OpenSwiftUI-spm
49-
needs: release
48+
needs: build-xcframeworks
5049
runs-on: ubuntu-latest
51-
if: ${{ secrets.BINARY_REPO_PAT != '' }}
50+
env:
51+
BINARY_REPO_PAT: ${{ secrets.BINARY_REPO_PAT }}
5252
steps:
53-
- name: Clone binary repo
54-
run: |
55-
git clone https://x-access-token:${{ secrets.BINARY_REPO_PAT }}@github.com/OpenSwiftUIProject/OpenSwiftUI-spm.git
56-
cd OpenSwiftUI-spm
57-
git config user.name "github-actions[bot]"
58-
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
59-
- name: Generate Package.swift from template
53+
- name: Update binary repo
6054
env:
6155
VERSION: ${{ github.ref_name }}
62-
CHECKSUM_OpenSwiftUI: ${{ needs.release.outputs.checksum_OpenSwiftUI }}
63-
CHECKSUM_OpenSwiftUICore: ${{ needs.release.outputs.checksum_OpenSwiftUICore }}
64-
CHECKSUM_OpenAttributeGraphShims: ${{ needs.release.outputs.checksum_OpenAttributeGraphShims }}
65-
CHECKSUM_OpenCoreGraphicsShims: ${{ needs.release.outputs.checksum_OpenCoreGraphicsShims }}
66-
CHECKSUM_OpenObservation: ${{ needs.release.outputs.checksum_OpenObservation }}
67-
CHECKSUM_OpenQuartzCoreShims: ${{ needs.release.outputs.checksum_OpenQuartzCoreShims }}
68-
CHECKSUM_OpenRenderBoxShims: ${{ needs.release.outputs.checksum_OpenRenderBoxShims }}
56+
CHECKSUM_OpenSwiftUI: ${{ needs.build-xcframeworks.outputs.checksum_OpenSwiftUI }}
57+
CHECKSUM_OpenSwiftUICore: ${{ needs.build-xcframeworks.outputs.checksum_OpenSwiftUICore }}
58+
CHECKSUM_OpenAttributeGraphShims: ${{ needs.build-xcframeworks.outputs.checksum_OpenAttributeGraphShims }}
59+
CHECKSUM_OpenCoreGraphicsShims: ${{ needs.build-xcframeworks.outputs.checksum_OpenCoreGraphicsShims }}
60+
CHECKSUM_OpenObservation: ${{ needs.build-xcframeworks.outputs.checksum_OpenObservation }}
61+
CHECKSUM_OpenQuartzCoreShims: ${{ needs.build-xcframeworks.outputs.checksum_OpenQuartzCoreShims }}
62+
CHECKSUM_OpenRenderBoxShims: ${{ needs.build-xcframeworks.outputs.checksum_OpenRenderBoxShims }}
6963
run: |
64+
if [ -z "$BINARY_REPO_PAT" ]; then
65+
echo "::notice::BINARY_REPO_PAT not set, skipping binary repo update"
66+
exit 0
67+
fi
68+
git clone https://x-access-token:${BINARY_REPO_PAT}@github.com/OpenSwiftUIProject/OpenSwiftUI-spm.git
7069
cd OpenSwiftUI-spm
70+
git config user.name "github-actions[bot]"
71+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
7172
sed \
7273
-e "s|{{VERSION}}|${VERSION}|g" \
7374
-e "s|{{CHECKSUM_OpenSwiftUI}}|${CHECKSUM_OpenSwiftUI}|g" \
@@ -80,11 +81,6 @@ jobs:
8081
Package.swift.template > Package.swift
8182
echo "Generated Package.swift:"
8283
head -50 Package.swift
83-
- name: Commit, push, and tag
84-
env:
85-
VERSION: ${{ github.ref_name }}
86-
run: |
87-
cd OpenSwiftUI-spm
8884
git add Package.swift
8985
git diff --cached --quiet && echo "No changes" && exit 0
9086
git commit -m "Update to ${VERSION} with code-signed XCFrameworks"
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
name: Release Notes
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
tag-name:
7+
description: 'Tag name (e.g. 0.17.1)'
8+
required: true
9+
workflow_call:
10+
inputs:
11+
tag-name:
12+
description: 'Tag name for the release'
13+
required: true
14+
type: string
15+
secrets:
16+
CLAUDE_CODE_OAUTH_TOKEN:
17+
required: false
18+
19+
permissions:
20+
contents: write
21+
22+
jobs:
23+
release-notes:
24+
name: Generate Release Notes
25+
runs-on: ubuntu-latest
26+
env:
27+
GH_TOKEN: ${{ github.token }}
28+
steps:
29+
- uses: actions/checkout@v4
30+
with:
31+
fetch-depth: 0
32+
33+
- name: Generate changelog from GitHub
34+
env:
35+
TAG_NAME: ${{ inputs.tag-name }}
36+
run: |
37+
gh api repos/${{ github.repository }}/releases/generate-notes \
38+
-f tag_name="${TAG_NAME}" \
39+
--jq '.body' > /tmp/changelog.md
40+
echo "Generated changelog:"
41+
cat /tmp/changelog.md
42+
43+
- name: Generate highlights with Claude Code
44+
env:
45+
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
46+
TAG_NAME: ${{ inputs.tag-name }}
47+
run: |
48+
if [ -z "$CLAUDE_CODE_OAUTH_TOKEN" ]; then
49+
echo "::warning::CLAUDE_CODE_OAUTH_TOKEN not set, using placeholder highlights"
50+
printf '## Highlights\n\n_To be written._\n' > /tmp/highlights.md
51+
exit 0
52+
fi
53+
54+
{
55+
cat <<'STATIC_EOF'
56+
You are generating the Highlights section for an OpenSwiftUI release.
57+
OpenSwiftUI is an open source reimplementation of Apple's SwiftUI framework.
58+
59+
Below is the auto-generated changelog:
60+
61+
STATIC_EOF
62+
cat /tmp/changelog.md
63+
cat <<'STATIC_EOF'
64+
65+
Write ONLY a ## Highlights section with concise bullet points of key user-facing changes.
66+
Rules:
67+
- Skip [NFC], [CI], refactoring, docs, and internal-only changes
68+
- Each bullet starts with a verb: Add, Fix, Improve, Update
69+
- Keep 1-5 bullets, be concise
70+
- Output ONLY the ## Highlights header followed by bullet points, nothing else
71+
72+
Examples from past releases:
73+
74+
## Highlights
75+
76+
- Add Xcode Preview support
77+
- Add initial Text support
78+
- Add OpenSwiftUI xcframework release support
79+
80+
## Highlights
81+
82+
- Add NS/UIApplicationDelegateAdapter support
83+
- Add Compute backend support as an alternative to AttributeGraph
84+
- Add NamedImage support for bundle image and system image
85+
STATIC_EOF
86+
} > /tmp/prompt.txt
87+
88+
npx -y @anthropic-ai/claude-code@latest \
89+
--model claude-opus-4-6 \
90+
-p "$(cat /tmp/prompt.txt)" \
91+
--output-format text > /tmp/highlights.md
92+
93+
echo "Generated highlights:"
94+
cat /tmp/highlights.md
95+
96+
- name: Create release
97+
env:
98+
TAG_NAME: ${{ inputs.tag-name }}
99+
run: |
100+
{
101+
cat /tmp/highlights.md
102+
echo ""
103+
cat /tmp/changelog.md
104+
cat <<INTEGRATION_EOF
105+
106+
## Binary Integration
107+
108+
\`\`\`swift
109+
.package(url: "https://github.com/OpenSwiftUIProject/OpenSwiftUI-spm.git", from: "${TAG_NAME}")
110+
\`\`\`
111+
112+
See [INTEGRATION.md](https://github.com/OpenSwiftUIProject/OpenSwiftUI/blob/main/INTEGRATION.md#binary-integration-recommended) for more details.
113+
INTEGRATION_EOF
114+
} > /tmp/release_notes.md
115+
116+
echo "=== Full release notes ==="
117+
cat /tmp/release_notes.md
118+
echo "=========================="
119+
120+
if gh release view "${TAG_NAME}" > /dev/null 2>&1; then
121+
gh release edit "${TAG_NAME}" --notes-file /tmp/release_notes.md
122+
else
123+
gh release create "${TAG_NAME}" \
124+
--title "${TAG_NAME}" \
125+
--notes-file /tmp/release_notes.md
126+
fi

0 commit comments

Comments
 (0)