Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 93 additions & 4 deletions .changeset/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,95 @@
This directory is managed by Changesets.
# Changesets

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

## Quick Start

```bash
pnpm changeset
```

Follow the prompts to select version bump type and describe your changes.

## Workflow

1. **Add a changeset** — Run `pnpm changeset` locally before or after your PR
2. **Version PR** — CI opens/updates a "Version Packages" PR when changesets merge to main
3. **Release** — Merging the Version PR triggers npm publish and GitHub Release

> **Note:** Contributors only need to run `pnpm changeset`. Versioning (`changeset version`) and publishing happen automatically in CI.

## Template

Use this structure for your changeset content:

```markdown
---
"@fission-ai/openspec": patch
---

### New Features

- **Feature name** — What users can now do

### Bug Fixes

- Fixed issue where X happened when Y

### Breaking Changes

- `oldMethod()` has been removed, use `newMethod()` instead

### Deprecations

- `legacyOption` is deprecated and will be removed in v2.0

### Other

- Internal refactoring of X for better performance
```

Include only the sections relevant to your change.

## Version Bump Guide

| Type | When to use | Example |
|------|-------------|---------|
| `patch` | Bug fixes, small improvements | Fixed crash when config missing |
| `minor` | New features, non-breaking additions | Added `--verbose` flag |
| `major` | Breaking changes, removed features | Renamed `init` to `setup` |

## When to Create a Changeset

**Create one for:**
- New features or commands
- Bug fixes that affect users
- Breaking changes or deprecations
- Performance improvements users would notice

**Skip for:**
- Documentation-only changes
- Test additions/fixes
- Internal refactoring with no user impact
- CI/tooling changes

## Writing Good Descriptions

**Do:** Write for users, not developers
```markdown
- **Shell completions** — Tab completion now available for Bash, Fish, and PowerShell
```

**Don't:** Write implementation details
```markdown
- Added ShellCompletionGenerator class with Bash/Fish/PowerShell subclasses
```

**Do:** Explain the impact
```markdown
- Fixed config loading to respect `XDG_CONFIG_HOME` on Linux
```

**Don't:** Just reference the fix
```markdown
- Fixed #123
```
5 changes: 4 additions & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"$schema": "https://unpkg.com/@changesets/config/schema.json",
"changelog": "@changesets/cli/changelog",
"changelog": [
"@changesets/changelog-github",
{ "repo": "Fission-AI/OpenSpec" }
],
"commit": false,
"fixed": [],
"linked": [],
Expand Down
137 changes: 137 additions & 0 deletions .github/workflows/polish-release-notes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
name: Polish Release Notes

# Triggers when changesets creates a release
on:
release:
types: [published]

permissions:
contents: write

jobs:
polish:
# Only run on the main repo, not forks
if: github.repository == 'Fission-AI/OpenSpec'
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Get current release body
id: get-release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release view "${{ github.event.release.tag_name }}" --json body -q '.body' > current-notes.md
echo "Fetched release notes for ${{ github.event.release.tag_name }}"

- name: Transform release notes with Claude
uses: anthropics/claude-code-action@v1
id: claude
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, let's look at the workflow file to understand the context
echo "=== Examining the workflow file ==="
cat .github/workflows/polish-release-notes.yml

Repository: Fission-AI/OpenSpec

Length of output: 4518


🏁 Script executed:

#!/bin/bash
# Search for documentation about CLAUDE_CODE_OAUTH_TOKEN
echo "=== Searching for CLAUDE_CODE_OAUTH_TOKEN documentation ==="
rg -i "CLAUDE_CODE_OAUTH_TOKEN" -C 3

echo -e "\n=== Searching for setup instructions ==="
find . -type f \( -name "README*" -o -name "CONTRIBUTING*" -o -name "SETUP*" -o -name "*.md" \) | head -20 | xargs rg -i "secret" --type md -C 2 2>/dev/null || echo "No matches found"

Repository: Fission-AI/OpenSpec

Length of output: 352


🏁 Script executed:

#!/bin/bash
# Check if there's any CI configuration or environment setup documentation
echo "=== Looking for CI/setup documentation ==="
git ls-files | grep -E "(\.github|setup|config|README|CONTRIBUTING)" | head -30

Repository: Fission-AI/OpenSpec

Length of output: 1570


Ensure the CLAUDE_CODE_OAUTH_TOKEN secret is configured in repository settings.

This workflow requires a repository secret named CLAUDE_CODE_OAUTH_TOKEN to authenticate with Claude via the Anthropic Claude Code Action. This token must be set up in the repository's secrets before the workflow can execute on release publication.

🤖 Prompt for AI Agents
In @.github/workflows/polish-release-notes.yml at line 32, Add the repository
secret named CLAUDE_CODE_OAUTH_TOKEN (exactly that name) in GitHub > Settings >
Secrets and variables > Actions so the workflow can access it; create a new
repository secret, paste the Anthropic/Claude Code OAuth token as the value,
save it, and ensure any CI users who need to update it have the token source and
rotation policy (do not hardcode the token into the repo).

github_token: ${{ secrets.GITHUB_TOKEN }}
direct_prompt: |
Transform the changelog in `current-notes.md` into release notes for OpenSpec ${{ github.event.release.tag_name }}.

## Voice

OpenSpec is a developer tool. Write like you're talking to a peer:
- Direct and practical, not marketing copy
- Focus on what changed and why it matters
- Skip the hype, keep it real

## Output

Create two files:

### 1. `release-title.txt`

A short title in this format:
```
${{ github.event.release.tag_name }} - [1-4 words describing the release]
```

Examples:
- `v0.18.0 - OPSX Experimental Workflow`
- `v0.16.0 - Antigravity, iFlow Support`
- `v0.15.0 - Gemini CLI, RooCode`

Rules for title:
- Lead with the most notable addition
- 1-4 words after the dash, no fluff
- If multiple features, comma-separate the top 2
- For bugfix-only releases, use something like `v0.17.2 - Pre-commit Hook Fix`

### 2. `polished-notes.md`

```markdown
## What's New in ${{ github.event.release.tag_name }}

[One sentence: what's the theme of this release?]

### New

- **Feature name** - What it does and why you'd use it

### Improved

- **Area** - What got better

### Fixed

- What was broken, now works
```

Omit empty sections.

## Rules

1. Write for developers using OpenSpec with AI coding assistants
2. Remove commit hashes (like `eb152eb:`), PR numbers, and changesets wrappers (`### Minor Changes`)
3. Lead with what users can do, not implementation details
4. One to two sentences per item, max
5. Use **bold** for feature/area names
6. Skip internal changes (CI, refactors, tests) unless they affect users
7. If the input is already well-formatted, just clean up structure and remove noise

## Example

Before:
```
### Minor Changes
- 8dfd824: Add OPSX experimental workflow commands and enhanced artifact system
**New Commands:**
- `/opsx:ff` - Fast-forward through artifact creation
```

After (polished-notes.md):
```
### New

- **Fast-forward mode** - Generate all planning artifacts at once with `/opsx:ff`. Useful when you already know what you're building.
```

After (release-title.txt):
```
v0.18.0 - OPSX Experimental Workflow
```

Write both files. No other output.

- name: Update release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="${{ github.event.release.tag_name }}"

if [ -f "polished-notes.md" ] && [ -f "release-title.txt" ]; then
TITLE=$(cat release-title.txt)
gh release edit "$TAG" --title "$TITLE" --notes-file polished-notes.md
echo "Updated: $TITLE"
elif [ -f "polished-notes.md" ]; then
gh release edit "$TAG" --notes-file polished-notes.md
echo "Updated notes (title unchanged)"
else
echo "No changes generated, keeping original"
fi
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@
"check:pack-version": "node scripts/pack-version-check.mjs",
"release": "pnpm run release:ci",
"release:ci": "pnpm run check:pack-version && pnpm exec changeset publish",
"release:local": "pnpm exec changeset version && pnpm run check:pack-version && pnpm exec changeset publish",
"changeset": "changeset"
},
"engines": {
"node": ">=20.19.0"
},
"devDependencies": {
"@changesets/changelog-github": "^0.5.2",
"@changesets/cli": "^2.27.7",
"@types/node": "^24.2.0",
"@vitest/ui": "^3.2.4",
Expand Down
Loading
Loading