Skip to content

Manual Release

Manual Release #1

name: Manual Release
on:
workflow_dispatch:
inputs:
version_bump:
description: 'Version bump type'
required: true
type: choice
options:
- patch
- minor
- major
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Validate changelog has unreleased content
run: |
# Extract content between [Unreleased] and next ## [
UNRELEASED_CONTENT=$(sed -n '/^## \[Unreleased\]/,/^## \[/p' CHANGELOG.md | sed '1d;$d' | sed '/^$/d')
if [ -z "$UNRELEASED_CONTENT" ]; then
echo "Error: No content in [Unreleased] section. Nothing to release."
exit 1
fi
echo "Found unreleased content:"
echo "$UNRELEASED_CONTENT"
- name: Calculate new version
id: version
env:
VERSION_BUMP: ${{ inputs.version_bump }}
run: |
PLUGIN_JSON=".claude-plugin/plugin.json"
CURRENT_VERSION=$(jq -r '.version' "$PLUGIN_JSON")
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"
case "$VERSION_BUMP" in
major)
NEW_VERSION="$((MAJOR + 1)).0.0"
;;
minor)
NEW_VERSION="$MAJOR.$((MINOR + 1)).0"
;;
patch)
NEW_VERSION="$MAJOR.$MINOR.$((PATCH + 1))"
;;
esac
echo "Current version: $CURRENT_VERSION"
echo "New version: $NEW_VERSION"
echo "current=$CURRENT_VERSION" >> $GITHUB_OUTPUT
echo "new=$NEW_VERSION" >> $GITHUB_OUTPUT
- name: Extract release notes from changelog
run: |
# Extract content between [Unreleased] and next ## [ heading
# Remove the first line ([Unreleased]) and last line (next version header)
RELEASE_NOTES=$(sed -n '/^## \[Unreleased\]/,/^## \[/p' CHANGELOG.md | sed '1d;$d')
# Write to file for use in release (handles multiline properly)
echo "$RELEASE_NOTES" > release_notes.md
echo "Release notes extracted:"
cat release_notes.md
- name: Update CHANGELOG.md
env:
NEW_VERSION: ${{ steps.version.outputs.new }}
CURRENT_VERSION: ${{ steps.version.outputs.current }}
run: |
TODAY=$(date +%Y-%m-%d)
# Replace [Unreleased] with new version, and add new [Unreleased] section
sed -i "s/^## \[Unreleased\]$/## [Unreleased]\n\n## [$NEW_VERSION] - $TODAY/" CHANGELOG.md
# Update the comparison links at the bottom
# Change: [Unreleased]: .../compare/vX.Y.Z...HEAD
# To: [Unreleased]: .../compare/vNEW...HEAD
sed -i "s|\[Unreleased\]: \(.*\)/compare/v${CURRENT_VERSION}\.\.\.HEAD|[Unreleased]: \1/compare/v${NEW_VERSION}...HEAD|" CHANGELOG.md
# Add new version link after [Unreleased] link
# Find the [Unreleased] link line and add new version link after it
sed -i "/^\[Unreleased\]:.*HEAD$/a [$NEW_VERSION]: https://github.com/itk-dev/itkdev-claude-plugins/compare/v${CURRENT_VERSION}...v${NEW_VERSION}" CHANGELOG.md
echo "Updated CHANGELOG.md:"
head -30 CHANGELOG.md
echo "..."
tail -10 CHANGELOG.md
- name: Update plugin.json
env:
NEW_VERSION: ${{ steps.version.outputs.new }}
run: |
PLUGIN_JSON=".claude-plugin/plugin.json"
jq --arg v "$NEW_VERSION" '.version = $v' "$PLUGIN_JSON" > tmp.json && mv tmp.json "$PLUGIN_JSON"
echo "Updated plugin.json:"
cat "$PLUGIN_JSON"
- name: Commit changes
env:
NEW_VERSION: ${{ steps.version.outputs.new }}
run: |
git add CHANGELOG.md .claude-plugin/plugin.json
git commit -m "chore: prepare release v${NEW_VERSION}"
- name: Create and push tag
env:
NEW_VERSION: ${{ steps.version.outputs.new }}
run: |
TAG="v${NEW_VERSION}"
git tag -a "$TAG" -m "Release $TAG"
git push origin main
git push origin "$TAG"
- name: Create GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NEW_VERSION: ${{ steps.version.outputs.new }}
CURRENT_VERSION: ${{ steps.version.outputs.current }}
run: |
TAG="v${NEW_VERSION}"
# Build release notes with header and footer
{
echo "## What's Changed"
echo ""
cat release_notes.md
echo ""
echo "## Full Changelog"
echo "https://github.com/itk-dev/itkdev-claude-plugins/compare/v${CURRENT_VERSION}...v${NEW_VERSION}"
} > full_release_notes.md
gh release create "$TAG" \
--title "Release $TAG" \
--notes-file full_release_notes.md
echo "Created release: $TAG"