Skip to content

Commit 36078b1

Browse files
authored
chore: improve release notes pipeline (Fission-AI#481)
* chore: improve changelog generation with GitHub integration - Switch to @changesets/changelog-github for PR/author links in CHANGELOG.md - Add comprehensive changeset README with template and contributor guidance - Remove release:local script (CI-only releases) * ci: add AI-powered release notes polishing Transforms raw changelog into user-friendly release notes when a GitHub Release is published. Uses Claude Code Action to: - Generate concise release title (e.g., "v0.18.0 - OPSX Workflow") - Rewrite changelog as developer-friendly release notes - Remove noise (commit hashes, PR numbers, internal changes) Requires CLAUDE_CODE_OAUTH_TOKEN secret (from claude setup-token).
1 parent d0e1b07 commit 36078b1

5 files changed

Lines changed: 301 additions & 6 deletions

File tree

.changeset/README.md

Lines changed: 93 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,95 @@
1-
This directory is managed by Changesets.
1+
# Changesets
22

3-
- Add a changeset locally with `pnpm changeset`.
4-
- The CI "Release (prepare)" workflow opens/updates a Version Packages PR.
5-
- Publishing happens from a GitHub Release via the "Publish to npm" workflow.
3+
This directory is managed by [Changesets](https://github.com/changesets/changesets).
64

5+
## Quick Start
6+
7+
```bash
8+
pnpm changeset
9+
```
10+
11+
Follow the prompts to select version bump type and describe your changes.
12+
13+
## Workflow
14+
15+
1. **Add a changeset** — Run `pnpm changeset` locally before or after your PR
16+
2. **Version PR** — CI opens/updates a "Version Packages" PR when changesets merge to main
17+
3. **Release** — Merging the Version PR triggers npm publish and GitHub Release
18+
19+
> **Note:** Contributors only need to run `pnpm changeset`. Versioning (`changeset version`) and publishing happen automatically in CI.
20+
21+
## Template
22+
23+
Use this structure for your changeset content:
24+
25+
```markdown
26+
---
27+
"@fission-ai/openspec": patch
28+
---
29+
30+
### New Features
31+
32+
- **Feature name** — What users can now do
33+
34+
### Bug Fixes
35+
36+
- Fixed issue where X happened when Y
37+
38+
### Breaking Changes
39+
40+
- `oldMethod()` has been removed, use `newMethod()` instead
41+
42+
### Deprecations
43+
44+
- `legacyOption` is deprecated and will be removed in v2.0
45+
46+
### Other
47+
48+
- Internal refactoring of X for better performance
49+
```
50+
51+
Include only the sections relevant to your change.
52+
53+
## Version Bump Guide
54+
55+
| Type | When to use | Example |
56+
|------|-------------|---------|
57+
| `patch` | Bug fixes, small improvements | Fixed crash when config missing |
58+
| `minor` | New features, non-breaking additions | Added `--verbose` flag |
59+
| `major` | Breaking changes, removed features | Renamed `init` to `setup` |
60+
61+
## When to Create a Changeset
62+
63+
**Create one for:**
64+
- New features or commands
65+
- Bug fixes that affect users
66+
- Breaking changes or deprecations
67+
- Performance improvements users would notice
68+
69+
**Skip for:**
70+
- Documentation-only changes
71+
- Test additions/fixes
72+
- Internal refactoring with no user impact
73+
- CI/tooling changes
74+
75+
## Writing Good Descriptions
76+
77+
**Do:** Write for users, not developers
78+
```markdown
79+
- **Shell completions** — Tab completion now available for Bash, Fish, and PowerShell
80+
```
81+
82+
**Don't:** Write implementation details
83+
```markdown
84+
- Added ShellCompletionGenerator class with Bash/Fish/PowerShell subclasses
85+
```
86+
87+
**Do:** Explain the impact
88+
```markdown
89+
- Fixed config loading to respect `XDG_CONFIG_HOME` on Linux
90+
```
91+
92+
**Don't:** Just reference the fix
93+
```markdown
94+
- Fixed #123
95+
```

.changeset/config.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
{
22
"$schema": "https://unpkg.com/@changesets/config/schema.json",
3-
"changelog": "@changesets/cli/changelog",
3+
"changelog": [
4+
"@changesets/changelog-github",
5+
{ "repo": "Fission-AI/OpenSpec" }
6+
],
47
"commit": false,
58
"fixed": [],
69
"linked": [],
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
name: Polish Release Notes
2+
3+
# Triggers when changesets creates a release
4+
on:
5+
release:
6+
types: [published]
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
polish:
13+
# Only run on the main repo, not forks
14+
if: github.repository == 'Fission-AI/OpenSpec'
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Get current release body
21+
id: get-release
22+
env:
23+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
24+
run: |
25+
gh release view "${{ github.event.release.tag_name }}" --json body -q '.body' > current-notes.md
26+
echo "Fetched release notes for ${{ github.event.release.tag_name }}"
27+
28+
- name: Transform release notes with Claude
29+
uses: anthropics/claude-code-action@v1
30+
id: claude
31+
with:
32+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
33+
github_token: ${{ secrets.GITHUB_TOKEN }}
34+
direct_prompt: |
35+
Transform the changelog in `current-notes.md` into release notes for OpenSpec ${{ github.event.release.tag_name }}.
36+
37+
## Voice
38+
39+
OpenSpec is a developer tool. Write like you're talking to a peer:
40+
- Direct and practical, not marketing copy
41+
- Focus on what changed and why it matters
42+
- Skip the hype, keep it real
43+
44+
## Output
45+
46+
Create two files:
47+
48+
### 1. `release-title.txt`
49+
50+
A short title in this format:
51+
```
52+
${{ github.event.release.tag_name }} - [1-4 words describing the release]
53+
```
54+
55+
Examples:
56+
- `v0.18.0 - OPSX Experimental Workflow`
57+
- `v0.16.0 - Antigravity, iFlow Support`
58+
- `v0.15.0 - Gemini CLI, RooCode`
59+
60+
Rules for title:
61+
- Lead with the most notable addition
62+
- 1-4 words after the dash, no fluff
63+
- If multiple features, comma-separate the top 2
64+
- For bugfix-only releases, use something like `v0.17.2 - Pre-commit Hook Fix`
65+
66+
### 2. `polished-notes.md`
67+
68+
```markdown
69+
## What's New in ${{ github.event.release.tag_name }}
70+
71+
[One sentence: what's the theme of this release?]
72+
73+
### New
74+
75+
- **Feature name** - What it does and why you'd use it
76+
77+
### Improved
78+
79+
- **Area** - What got better
80+
81+
### Fixed
82+
83+
- What was broken, now works
84+
```
85+
86+
Omit empty sections.
87+
88+
## Rules
89+
90+
1. Write for developers using OpenSpec with AI coding assistants
91+
2. Remove commit hashes (like `eb152eb:`), PR numbers, and changesets wrappers (`### Minor Changes`)
92+
3. Lead with what users can do, not implementation details
93+
4. One to two sentences per item, max
94+
5. Use **bold** for feature/area names
95+
6. Skip internal changes (CI, refactors, tests) unless they affect users
96+
7. If the input is already well-formatted, just clean up structure and remove noise
97+
98+
## Example
99+
100+
Before:
101+
```
102+
### Minor Changes
103+
- 8dfd824: Add OPSX experimental workflow commands and enhanced artifact system
104+
**New Commands:**
105+
- `/opsx:ff` - Fast-forward through artifact creation
106+
```
107+
108+
After (polished-notes.md):
109+
```
110+
### New
111+
112+
- **Fast-forward mode** - Generate all planning artifacts at once with `/opsx:ff`. Useful when you already know what you're building.
113+
```
114+
115+
After (release-title.txt):
116+
```
117+
v0.18.0 - OPSX Experimental Workflow
118+
```
119+
120+
Write both files. No other output.
121+
122+
- name: Update release
123+
env:
124+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
125+
run: |
126+
TAG="${{ github.event.release.tag_name }}"
127+
128+
if [ -f "polished-notes.md" ] && [ -f "release-title.txt" ]; then
129+
TITLE=$(cat release-title.txt)
130+
gh release edit "$TAG" --title "$TITLE" --notes-file polished-notes.md
131+
echo "Updated: $TITLE"
132+
elif [ -f "polished-notes.md" ]; then
133+
gh release edit "$TAG" --notes-file polished-notes.md
134+
echo "Updated notes (title unchanged)"
135+
else
136+
echo "No changes generated, keeping original"
137+
fi

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@
5454
"check:pack-version": "node scripts/pack-version-check.mjs",
5555
"release": "pnpm run release:ci",
5656
"release:ci": "pnpm run check:pack-version && pnpm exec changeset publish",
57-
"release:local": "pnpm exec changeset version && pnpm run check:pack-version && pnpm exec changeset publish",
5857
"changeset": "changeset"
5958
},
6059
"engines": {
6160
"node": ">=20.19.0"
6261
},
6362
"devDependencies": {
63+
"@changesets/changelog-github": "^0.5.2",
6464
"@changesets/cli": "^2.27.7",
6565
"@types/node": "^24.2.0",
6666
"@vitest/ui": "^3.2.4",

0 commit comments

Comments
 (0)