Skip to content

Commit f3ecfc3

Browse files
yepzdkclaude
andcommitted
feat: add manual release workflow
- Add manual-release.yml for creating releases via GitHub Actions UI - Supports patch, minor, and major version bumps - Automatically updates CHANGELOG.md and plugin.json - Creates git tag and GitHub release with notes from changelog - Update README with new workflow documentation - Update skills directory structure documentation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 2a60092 commit f3ecfc3

3 files changed

Lines changed: 199 additions & 10 deletions

File tree

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
name: Manual Release
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version_bump:
7+
description: 'Version bump type'
8+
required: true
9+
type: choice
10+
options:
11+
- patch
12+
- minor
13+
- major
14+
15+
jobs:
16+
release:
17+
runs-on: ubuntu-latest
18+
permissions:
19+
contents: write
20+
steps:
21+
- uses: actions/checkout@v4
22+
with:
23+
fetch-depth: 0
24+
25+
- name: Configure Git
26+
run: |
27+
git config user.name "github-actions[bot]"
28+
git config user.email "github-actions[bot]@users.noreply.github.com"
29+
30+
- name: Validate changelog has unreleased content
31+
run: |
32+
# Extract content between [Unreleased] and next ## [
33+
UNRELEASED_CONTENT=$(sed -n '/^## \[Unreleased\]/,/^## \[/p' CHANGELOG.md | sed '1d;$d' | sed '/^$/d')
34+
35+
if [ -z "$UNRELEASED_CONTENT" ]; then
36+
echo "Error: No content in [Unreleased] section. Nothing to release."
37+
exit 1
38+
fi
39+
40+
echo "Found unreleased content:"
41+
echo "$UNRELEASED_CONTENT"
42+
43+
- name: Calculate new version
44+
id: version
45+
env:
46+
VERSION_BUMP: ${{ inputs.version_bump }}
47+
run: |
48+
PLUGIN_JSON=".claude-plugin/plugin.json"
49+
CURRENT_VERSION=$(jq -r '.version' "$PLUGIN_JSON")
50+
51+
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"
52+
53+
case "$VERSION_BUMP" in
54+
major)
55+
NEW_VERSION="$((MAJOR + 1)).0.0"
56+
;;
57+
minor)
58+
NEW_VERSION="$MAJOR.$((MINOR + 1)).0"
59+
;;
60+
patch)
61+
NEW_VERSION="$MAJOR.$MINOR.$((PATCH + 1))"
62+
;;
63+
esac
64+
65+
echo "Current version: $CURRENT_VERSION"
66+
echo "New version: $NEW_VERSION"
67+
echo "current=$CURRENT_VERSION" >> $GITHUB_OUTPUT
68+
echo "new=$NEW_VERSION" >> $GITHUB_OUTPUT
69+
70+
- name: Extract release notes from changelog
71+
run: |
72+
# Extract content between [Unreleased] and next ## [ heading
73+
# Remove the first line ([Unreleased]) and last line (next version header)
74+
RELEASE_NOTES=$(sed -n '/^## \[Unreleased\]/,/^## \[/p' CHANGELOG.md | sed '1d;$d')
75+
76+
# Write to file for use in release (handles multiline properly)
77+
echo "$RELEASE_NOTES" > release_notes.md
78+
79+
echo "Release notes extracted:"
80+
cat release_notes.md
81+
82+
- name: Update CHANGELOG.md
83+
env:
84+
NEW_VERSION: ${{ steps.version.outputs.new }}
85+
CURRENT_VERSION: ${{ steps.version.outputs.current }}
86+
run: |
87+
TODAY=$(date +%Y-%m-%d)
88+
89+
# Replace [Unreleased] with new version, and add new [Unreleased] section
90+
sed -i "s/^## \[Unreleased\]$/## [Unreleased]\n\n## [$NEW_VERSION] - $TODAY/" CHANGELOG.md
91+
92+
# Update the comparison links at the bottom
93+
# Change: [Unreleased]: .../compare/vX.Y.Z...HEAD
94+
# To: [Unreleased]: .../compare/vNEW...HEAD
95+
sed -i "s|\[Unreleased\]: \(.*\)/compare/v${CURRENT_VERSION}\.\.\.HEAD|[Unreleased]: \1/compare/v${NEW_VERSION}...HEAD|" CHANGELOG.md
96+
97+
# Add new version link after [Unreleased] link
98+
# Find the [Unreleased] link line and add new version link after it
99+
sed -i "/^\[Unreleased\]:.*HEAD$/a [$NEW_VERSION]: https://github.com/itk-dev/itkdev-claude-plugins/compare/v${CURRENT_VERSION}...v${NEW_VERSION}" CHANGELOG.md
100+
101+
echo "Updated CHANGELOG.md:"
102+
head -30 CHANGELOG.md
103+
echo "..."
104+
tail -10 CHANGELOG.md
105+
106+
- name: Update plugin.json
107+
env:
108+
NEW_VERSION: ${{ steps.version.outputs.new }}
109+
run: |
110+
PLUGIN_JSON=".claude-plugin/plugin.json"
111+
jq --arg v "$NEW_VERSION" '.version = $v' "$PLUGIN_JSON" > tmp.json && mv tmp.json "$PLUGIN_JSON"
112+
113+
echo "Updated plugin.json:"
114+
cat "$PLUGIN_JSON"
115+
116+
- name: Commit changes
117+
env:
118+
NEW_VERSION: ${{ steps.version.outputs.new }}
119+
run: |
120+
git add CHANGELOG.md .claude-plugin/plugin.json
121+
git commit -m "chore: prepare release v${NEW_VERSION}"
122+
123+
- name: Create and push tag
124+
env:
125+
NEW_VERSION: ${{ steps.version.outputs.new }}
126+
run: |
127+
TAG="v${NEW_VERSION}"
128+
git tag -a "$TAG" -m "Release $TAG"
129+
git push origin main
130+
git push origin "$TAG"
131+
132+
- name: Create GitHub Release
133+
env:
134+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
135+
NEW_VERSION: ${{ steps.version.outputs.new }}
136+
CURRENT_VERSION: ${{ steps.version.outputs.current }}
137+
run: |
138+
TAG="v${NEW_VERSION}"
139+
140+
# Build release notes with header and footer
141+
{
142+
echo "## What's Changed"
143+
echo ""
144+
cat release_notes.md
145+
echo ""
146+
echo "## Full Changelog"
147+
echo "https://github.com/itk-dev/itkdev-claude-plugins/compare/v${CURRENT_VERSION}...v${NEW_VERSION}"
148+
} > full_release_notes.md
149+
150+
gh release create "$TAG" \
151+
--title "Release $TAG" \
152+
--notes-file full_release_notes.md
153+
154+
echo "Created release: $TAG"

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Manual release workflow for creating releases via GitHub Actions UI
13+
- Supports patch, minor, and major version bumps
14+
- Automatically updates CHANGELOG.md and plugin.json
15+
- Creates git tag and GitHub release with notes from changelog
16+
1017
## [0.3.1] - 2026-01-27
1118

1219
### Fixed

README.md

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ itkdev-claude-plugins/
1111
│ ├── marketplace.json # Marketplace catalog
1212
│ └── mcp-versions.json # Tracked MCP dependency versions
1313
├── .github/workflows/ # GitHub Actions workflows
14-
│ ├── check-mcp-updates.yml # Weekly MCP update checker
15-
│ └── release.yml # Automated release workflow
14+
│ ├── check-mcp-updates.yml # Daily MCP update checker
15+
│ ├── manual-release.yml # Manual release workflow
16+
│ └── release.yml # MCP dependency release workflow
1617
├── .mcp.json # MCP server configurations
1718
├── commands/ # Slash commands (Markdown files)
1819
│ └── example.md
19-
├── skills/ # Skills (Markdown files with frontmatter)
20-
│ └── itkdev-github-guidelines.md
20+
├── skills/ # Skills (subdirectories with SKILL.md)
21+
│ └── itkdev-github-guidelines/
22+
│ └── SKILL.md
2123
└── README.md
2224
```
2325

@@ -49,24 +51,44 @@ GitHub workflow guidelines for the ITK Dev team. Automatically activates when wo
4951
- Changelog updates (Keep a Changelog format)
5052
- PR requirements and templates
5153

52-
## Auto-Release Workflow
54+
## Release Workflows
55+
56+
### Manual Release
57+
58+
Create a new release manually via GitHub Actions:
59+
60+
1. Go to **Actions** > **Manual Release**
61+
2. Click **Run workflow**
62+
3. Select version bump type:
63+
- `patch` - Bug fixes (0.3.1 → 0.3.2)
64+
- `minor` - New features (0.3.1 → 0.4.0)
65+
- `major` - Breaking changes (0.3.1 → 1.0.0)
66+
67+
The workflow will:
68+
- Validate that `[Unreleased]` section has content
69+
- Update `CHANGELOG.md` with version and date
70+
- Update `plugin.json` version
71+
- Create git tag and push
72+
- Create GitHub release with changelog notes
73+
74+
### MCP Dependency Auto-Release
5375

5476
This plugin automatically releases new versions when MCP server dependencies publish updates.
5577

56-
### How it works
78+
#### How it works
5779

5880
1. **Daily Check**: A GitHub Actions workflow runs every day at 8:30 UTC
5981
2. **Version Comparison**: Compares latest MCP releases with tracked versions in `.claude-plugin/mcp-versions.json`
6082
3. **Automated Release**: If updates are detected, a new patch version is released automatically
6183

62-
### Tracked Dependencies
84+
#### Tracked Dependencies
6385

6486
| MCP Server | Repository |
6587
|------------|------------|
6688
| browser-feedback | [mcp-claude-code-browser-feedback](https://github.com/itk-dev/mcp-claude-code-browser-feedback) |
6789
| docker | [mcp-itkdev-docker](https://github.com/itk-dev/mcp-itkdev-docker) |
6890

69-
### Manual Trigger
91+
#### Manual MCP Check
7092

7193
You can manually trigger a dependency check via the GitHub Actions UI:
7294
1. Go to **Actions** > **Check MCP Updates**
@@ -95,11 +117,17 @@ Create new Markdown files in the `commands/` directory. Each file becomes a slas
95117

96118
### Adding Skills
97119

98-
Create new Markdown files in the `skills/` directory with YAML frontmatter:
120+
Create a subdirectory in `skills/` with a `SKILL.md` file containing YAML frontmatter:
121+
122+
```
123+
skills/
124+
└── your-skill-name/
125+
└── SKILL.md
126+
```
99127

100128
```markdown
101129
---
102-
name: skill-name
130+
name: your-skill-name
103131
description: When this skill should be activated automatically.
104132
---
105133

0 commit comments

Comments
 (0)