* fix: split release process to sync pyproject.toml version with git tags (#1721) - Split release workflow into two: release-trigger.yml and release.yml - release-trigger.yml: Updates pyproject.toml, generates changelog from commits, creates tag - release.yml: Triggered by tag push, builds artifacts, creates GitHub release - Ensures git tags point to commits with correct version in pyproject.toml - Auto-generates changelog from commit messages since last tag - Supports manual version input or auto-increment patch version - Added simulate-release.sh for local testing without pushing - Added comprehensive RELEASE-PROCESS.md documentation - Updated pyproject.toml to v0.1.10 to sync with latest release This fixes the version mismatch issue where tags pointed to commits with outdated pyproject.toml versions, preventing confusion when installing from source. * Update .github/workflows/RELEASE-PROCESS.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update .github/workflows/scripts/simulate-release.sh Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update .github/workflows/release.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update .github/workflows/release-trigger.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: harden release-trigger against shell injection and fix stale docs - Pass workflow_dispatch version input via env: instead of direct interpolation into shell script, preventing potential injection attacks - Validate version input against strict semver regex before use - Fix RELEASE-PROCESS.md Option 2 still referencing [Unreleased] section handling that no longer exists in the workflow --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
5.7 KiB
Release Process
This document describes the automated release process for Spec Kit.
Overview
The release process is split into two workflows to ensure version consistency:
- Release Trigger Workflow (
release-trigger.yml) - Manages versioning and triggers release - Release Workflow (
release.yml) - Builds and publishes artifacts
This separation ensures that git tags always point to commits with the correct version in pyproject.toml.
Before Creating a Release
Important: Write clear, descriptive commit messages!
How CHANGELOG.md Works
The CHANGELOG is automatically generated from your git commit messages:
-
During Development: Write clear, descriptive commit messages:
git commit -m "feat: Add new authentication feature" git commit -m "fix: Resolve timeout issue in API client (#123)" git commit -m "docs: Update installation instructions" -
When Releasing: The release trigger workflow automatically:
- Finds all commits since the last release tag
- Formats them as changelog entries
- Inserts them into CHANGELOG.md
- Commits the updated changelog before creating the new tag
Commit Message Best Practices
Good commit messages make good changelogs:
- Be descriptive: "Add user authentication" not "Update files"
- Reference issues/PRs: Include
(#123)for automated linking - Use conventional commits (optional):
feat:,fix:,docs:,chore: - Keep it concise: One line is ideal, details go in commit body
Example commits that become good changelog entries:
fix: prepend YAML frontmatter to Cursor .mdc files (#1699)
feat: add generic agent support with customizable command directories (#1639)
docs: document dual-catalog system for extensions (#1689)
Creating a Release
Option 1: Auto-Increment (Recommended for patches)
- Go to Actions → Release Trigger
- Click Run workflow
- Leave the version field empty
- Click Run workflow
The workflow will:
- Auto-increment the patch version (e.g.,
0.1.10→0.1.11) - Update
pyproject.toml - Update
CHANGELOG.mdby adding a new section for the release based on commits since the last tag - Commit changes
- Create and push git tag
- Trigger the release workflow automatically
Option 2: Manual Version (For major/minor bumps)
- Go to Actions → Release Trigger
- Click Run workflow
- Enter the desired version (e.g.,
0.2.0orv0.2.0) - Click Run workflow
The workflow will:
- Use your specified version
- Update
pyproject.toml - Update
CHANGELOG.mdby adding a new section for the release based on commits since the last tag - Commit changes
- Create and push git tag
- Trigger the release workflow automatically
What Happens Next
Once the release trigger workflow completes:
- The git tag is pushed to GitHub
- The Release Workflow is automatically triggered
- Release artifacts are built for all supported agents
- A GitHub Release is created with all assets
- Release notes are generated from PR titles
Workflow Details
Release Trigger Workflow
File: .github/workflows/release-trigger.yml
Trigger: Manual (workflow_dispatch)
Permissions Required: contents: write
Steps:
- Checkout repository
- Determine version (manual or auto-increment)
- Check if tag already exists (prevents duplicates)
- Update
pyproject.toml - Update
CHANGELOG.md - Commit changes
- Create and push tag
Release Workflow
File: .github/workflows/release.yml
Trigger: Tag push (v*)
Permissions Required: contents: write
Steps:
- Checkout repository at tag
- Extract version from tag name
- Check if release already exists
- Build release package variants (all agents × shell/powershell)
- Generate release notes from commits
- Create GitHub Release with all assets
Version Constraints
- Tags must follow format:
v{MAJOR}.{MINOR}.{PATCH} - Example valid versions:
v0.1.11,v0.2.0,v1.0.0 - Auto-increment only bumps patch version
- Cannot create duplicate tags (workflow will fail)
Benefits of This Approach
✅ Version Consistency: Git tags point to commits with matching pyproject.toml version
✅ Single Source of Truth: Version set once, used everywhere
✅ Prevents Drift: No more manual version synchronization needed
✅ Clean Separation: Versioning logic separate from artifact building
✅ Flexibility: Supports both auto-increment and manual versioning
Troubleshooting
No Commits Since Last Release
If you run the release trigger workflow when there are no new commits since the last tag:
- The workflow will still succeed
- The CHANGELOG will show "- Initial release" if it's the first release
- Or it will be empty if there are no commits
- Consider adding meaningful commits before releasing
Best Practice: Use descriptive commit messages - they become your changelog!
Tag Already Exists
If you see "Error: Tag vX.Y.Z already exists!", you need to:
- Choose a different version number, or
- Delete the existing tag if it was created in error
Release Workflow Didn't Trigger
Check that:
- The release trigger workflow completed successfully
- The tag was pushed (check repository tags)
- The release workflow is enabled in Actions settings
Version Mismatch
If pyproject.toml doesn't match the latest tag:
- Run the release trigger workflow to sync versions
- Or manually update
pyproject.tomland push changes before running the release trigger
Legacy Behavior (Pre-v0.1.10)
Before this change, the release workflow:
- Created tags automatically on main branch pushes
- Updated
pyproject.tomlAFTER creating the tag - Resulted in tags pointing to commits with outdated versions
This has been fixed in v0.1.10+.