Manual Release #2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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" |