mirror of
https://github.com/github/spec-kit.git
synced 2026-03-18 03:13:07 +00:00
* 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>
142 lines
5.1 KiB
YAML
142 lines
5.1 KiB
YAML
name: Release Trigger
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
version:
|
|
description: 'Version to release (e.g., 0.1.11). Leave empty to auto-increment patch version.'
|
|
required: false
|
|
type: string
|
|
|
|
jobs:
|
|
bump-version:
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v6
|
|
with:
|
|
fetch-depth: 0
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Configure Git
|
|
run: |
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
|
|
- name: Determine version
|
|
id: version
|
|
env:
|
|
INPUT_VERSION: ${{ github.event.inputs.version }}
|
|
run: |
|
|
if [[ -n "$INPUT_VERSION" ]]; then
|
|
# Manual version specified - strip optional v prefix
|
|
VERSION="${INPUT_VERSION#v}"
|
|
# Validate strict semver format to prevent injection
|
|
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
echo "Error: Invalid version format '$VERSION'. Must be X.Y.Z (e.g. 1.2.3 or v1.2.3)"
|
|
exit 1
|
|
fi
|
|
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
echo "tag=v$VERSION" >> $GITHUB_OUTPUT
|
|
echo "Using manual version: $VERSION"
|
|
else
|
|
# Auto-increment patch version
|
|
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
|
|
echo "Latest tag: $LATEST_TAG"
|
|
|
|
# Extract version number and increment
|
|
VERSION=$(echo $LATEST_TAG | sed 's/v//')
|
|
IFS='.' read -ra VERSION_PARTS <<< "$VERSION"
|
|
MAJOR=${VERSION_PARTS[0]:-0}
|
|
MINOR=${VERSION_PARTS[1]:-0}
|
|
PATCH=${VERSION_PARTS[2]:-0}
|
|
|
|
# Increment patch version
|
|
PATCH=$((PATCH + 1))
|
|
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
|
|
|
|
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
|
|
echo "tag=v$NEW_VERSION" >> $GITHUB_OUTPUT
|
|
echo "Auto-incremented version: $NEW_VERSION"
|
|
fi
|
|
|
|
- name: Check if tag already exists
|
|
run: |
|
|
if git rev-parse "${{ steps.version.outputs.tag }}" >/dev/null 2>&1; then
|
|
echo "Error: Tag ${{ steps.version.outputs.tag }} already exists!"
|
|
exit 1
|
|
fi
|
|
|
|
- name: Update pyproject.toml
|
|
run: |
|
|
sed -i "s/version = \".*\"/version = \"${{ steps.version.outputs.version }}\"/" pyproject.toml
|
|
echo "Updated pyproject.toml to version ${{ steps.version.outputs.version }}"
|
|
|
|
- name: Update CHANGELOG.md
|
|
run: |
|
|
if [ -f "CHANGELOG.md" ]; then
|
|
DATE=$(date +%Y-%m-%d)
|
|
|
|
# Get the previous tag to compare commits
|
|
PREVIOUS_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
|
|
|
|
echo "Generating changelog from commits..."
|
|
if [[ -n "$PREVIOUS_TAG" ]]; then
|
|
echo "Changes since $PREVIOUS_TAG"
|
|
|
|
# Get commits since last tag, format as bullet points
|
|
# Extract PR numbers and format nicely
|
|
COMMITS=$(git log --oneline "$PREVIOUS_TAG"..HEAD --no-merges --pretty=format:"- %s" 2>/dev/null || echo "- Initial release")
|
|
else
|
|
echo "No previous tag found - this is the first release"
|
|
COMMITS="- Initial release"
|
|
fi
|
|
|
|
# Create new changelog entry
|
|
{
|
|
head -n 8 CHANGELOG.md
|
|
echo ""
|
|
echo "## [${{ steps.version.outputs.version }}] - $DATE"
|
|
echo ""
|
|
echo "### Changed"
|
|
echo ""
|
|
echo "$COMMITS"
|
|
echo ""
|
|
tail -n +9 CHANGELOG.md
|
|
} > CHANGELOG.md.tmp
|
|
mv CHANGELOG.md.tmp CHANGELOG.md
|
|
|
|
echo "✅ Updated CHANGELOG.md with commits since $PREVIOUS_TAG"
|
|
else
|
|
echo "No CHANGELOG.md found"
|
|
fi
|
|
|
|
- name: Commit version bump
|
|
run: |
|
|
if [ -f "CHANGELOG.md" ]; then
|
|
git add pyproject.toml CHANGELOG.md
|
|
else
|
|
git add pyproject.toml
|
|
fi
|
|
|
|
if git diff --cached --quiet; then
|
|
echo "No changes to commit"
|
|
else
|
|
git commit -m "chore: bump version to ${{ steps.version.outputs.version }}"
|
|
echo "Changes committed"
|
|
fi
|
|
- name: Create and push tag
|
|
run: |
|
|
git tag -a "${{ steps.version.outputs.tag }}" -m "Release ${{ steps.version.outputs.tag }}"
|
|
git push origin main
|
|
git push origin "${{ steps.version.outputs.tag }}"
|
|
echo "Tag ${{ steps.version.outputs.tag }} created and pushed"
|
|
|
|
- name: Summary
|
|
run: |
|
|
echo "✅ Version bumped to ${{ steps.version.outputs.version }}"
|
|
echo "✅ Tag ${{ steps.version.outputs.tag }} created and pushed"
|
|
echo "🚀 Release workflow will now build artifacts automatically"
|