ワンクリックで
releaserator
Generate semantic versioned releases with changelog and GitHub releases
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Generate semantic versioned releases with changelog and GitHub releases
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Set up macOS launchd service for auto-starting Python applications
Initialize complete Python project with comprehensive documentation, development environment, and tooling. Use when creating a new Python project from scratch.
Add FastAPI server capabilities to an existing Python project with uvicorn, OpenAPI docs, and configuration management
Install git hooks to prevent common workflow mistakes
| name | releaserator |
| description | Generate semantic versioned releases with changelog and GitHub releases |
| allowed-tools | Read, Write, Edit, Bash(git:*), Bash(gh:*), Bash(command:*), Bash(test:*), Grep, Glob, AskUserQuestion |
Automate the release process with semantic versioning, Keep A Changelog format, and GitHub release creation.
Task: Verify repository state is clean and ready for release
Run these checks:
# Check git status (must be clean)
git status --porcelain
# Check current branch
git branch --show-current
# Detect version file (check in priority order)
for f in .claude-plugin/plugin.json package.json pyproject.toml Cargo.toml; do
test -f "$f" && echo "VERSION_FILE=$f" && break
done
# Check for gh CLI
command -v gh >/dev/null 2>&1 && echo "INSTALLED" || echo "NOT_FOUND"
Validation:
.claude-plugin/plugin.json — Claude Code pluginpackage.json — Node.js projectpyproject.toml — Python project (version in [project] or [tool.poetry])Cargo.toml — Rust project (version in [package])Store:
VERSION_FILE = path to the detected version fileOptional check: Verify docs/CONTEXT.md is recent (< 24 hours old)
/session-wrapup firstTask: Read current version and find last release tag
# Read current version from VERSION_FILE (use Read tool)
# Parse the version field based on file type (see below)
# Find last tag (if any)
git describe --tags --abbrev=0 2>/dev/null || echo "NO_TAGS"
# List all tags for reference
git tag --list --sort=-version:refname
Version parsing by file type:
| Version File | How to read version |
|---|---|
.claude-plugin/plugin.json | JSON field "version" |
package.json | JSON field "version" |
pyproject.toml | [project] version = "X.Y.Z" or [tool.poetry] version = "X.Y.Z" |
Cargo.toml | [package] version = "X.Y.Z" |
Logic:
Store:
CURRENT_VERSION = version from VERSION_FILELAST_TAG = latest git tag (or "NO_TAGS")IS_FIRST_RELEASE = true if no tags existTask: Get all commits since last release for changelog generation
# If tags exist: commits since last tag
git log LAST_TAG..HEAD --oneline --no-merges
# If no tags: all commits (first release)
git log --oneline --no-merges
Parse each commit:
For each commit line, extract:
Example parsing:
abc1234 feat(auth): add OAuth support (#42)
→ hash: abc1234
→ type: feat
→ scope: auth
→ breaking: false
→ description: add OAuth support
→ pr: 42
Check commit body for BREAKING CHANGE:
For commits that might have breaking changes, also check the full commit message:
git log LAST_TAG..HEAD --format="%H %s%n%b%n---" --no-merges
Look for BREAKING CHANGE: in commit body.
Store parsed commits in a data structure:
commits = [
{hash, type, scope, breaking, description, pr},
...
]
Task: Analyze commits to determine MAJOR.MINOR.PATCH bump
Rules (Conventional Commits):
MAJOR bump if ANY commit has:
MINOR bump if (and no MAJOR):
feat: commits existPATCH bump if (and no MAJOR/MINOR):
fix: or perf: commits existNo bump if only:
docs:, refactor:, chore:, test:, ci:, build:, style:Calculate new version:
# Pseudocode for version bump
def bump_version(current, bump_type):
major, minor, patch = map(int, current.split('.'))
if bump_type == 'MAJOR':
return f"{major + 1}.0.0"
elif bump_type == 'MINOR':
return f"{major}.{minor + 1}.0"
elif bump_type == 'PATCH':
return f"{major}.{minor}.{patch + 1}"
else:
return current # No bump
Edge case: If no version bump needed (only docs/chore commits), ask user:
⚠️ No version bump needed (only documentation/chore commits).
Do you want to create a release anyway? (y/N)
Store:
BUMP_TYPE = "MAJOR" | "MINOR" | "PATCH" | "NONE"NEW_VERSION = calculated new versionTask: Create Keep A Changelog formatted entry for this release
Group commits by section:
| Commit Type | Changelog Section | Variable |
|---|---|---|
feat: | Added | ADDED |
refactor: (behavior change) | Changed | CHANGED |
| Mentions "deprecat" | Deprecated | DEPRECATED |
| Mentions "remov" | Removed | REMOVED |
fix: | Fixed | FIXED |
| Mentions "security" or "CVE" | Security | SECURITY |
Format each commit line:
- Description ([#PR](https://github.com/OWNER/REPO/pull/PR)) ([hash](https://github.com/OWNER/REPO/commit/hash))
If no PR reference, omit PR link. Always include commit hash link.
Breaking changes:
Collect all breaking changes (commits with exclamation mark or BREAKING CHANGE) and add to the top of the relevant section with ⚠️:
- ⚠️ **BREAKING**: Description of breaking change
Extract repo info:
# Get remote URL and parse owner/repo
git remote get-url origin
# Parse: git@github.com:owner/repo.git → owner/repo
# Or: https://github.com/owner/repo.git → owner/repo
Load template: Read skills/releaserator/templates/changelog-entry.md
Substitute variables:
{{VERSION}} → NEW_VERSION{{DATE}} → today's date (ISO format: YYYY-MM-DD){{ADDED}} → formatted commit lines (or empty if none){{CHANGED}} → formatted commit lines (or empty if none){{DEPRECATED}} → formatted commit lines (or empty if none){{REMOVED}} → formatted commit lines (or empty if none){{FIXED}} → formatted commit lines (or empty if none){{SECURITY}} → formatted commit lines (or empty if none){{BREAKING}} → breaking changes summary (or omit section if none)Remove empty sections: If a section has no commits, remove the entire section heading and content.
Store: CHANGELOG_ENTRY = generated markdown
Task: Prepend new version entry to CHANGELOG.md
Check if CHANGELOG.md exists:
test -f CHANGELOG.md && echo "EXISTS" || echo "MISSING"
If CHANGELOG.md exists:
## [Unreleased] exists, insert after it[VERSION]: https://github.com/OWNER/REPO/releases/tag/vVERSION[Unreleased]: https://github.com/OWNER/REPO/compare/vVERSION...HEADIf CHANGELOG.md doesn't exist:
skills/releaserator/templates/CHANGELOG.md{{VERSION}} → NEW_VERSION{{DATE}} → today's date{{REPO}} → owner/repo from git remote{{ADDED}}, {{CHANGED}}, etc. → from CHANGELOG_ENTRYUse Write tool to create/update CHANGELOG.md
Task: Write new version to VERSION_FILE
By file type:
| Version File | How to update |
|---|---|
.claude-plugin/plugin.json | Update JSON "version" field. Use 2-space indentation, trailing newline. |
package.json | Update JSON "version" field. Preserve existing indentation and trailing newline. |
pyproject.toml | Replace version = "OLD" with version = "NEW" in the correct section. |
Cargo.toml | Replace version = "OLD" with version = "NEW" in the [package] section. |
Use Read and Edit tools for precise replacement.
Task: Create commit for version and changelog changes
# Stage files (VERSION_FILE is the detected version file from Step 1)
git add VERSION_FILE CHANGELOG.md
# Create commit
git commit -m "chore: bump version to NEW_VERSION"
Commit message format: chore: bump version to X.Y.Z
This follows conventional commits (type: chore, as it's a release task).
Store commit hash for later reference:
git rev-parse HEAD
Task: Create annotated git tag for release
# Create annotated tag (not lightweight)
git tag -a vNEW_VERSION -m "Release vNEW_VERSION"
Tag format: v prefix + semantic version (e.g., v1.2.3)
Annotated tags are used (not lightweight) so they contain:
Task: Push commit and tag to remote
Ask user for confirmation:
Ready to push release v1.2.3 to remote?
- Commit: abc1234 "chore: bump version to 1.2.3"
- Tag: v1.2.3
This will:
1. Push commit to main branch
2. Push tag v1.2.3
3. Trigger any CI/CD workflows
Continue? (y/N)
If confirmed:
# Push commit to current branch
git push origin $(git branch --show-current)
# Push tag
git push origin vNEW_VERSION
If not confirmed: Stop here and report that release is ready locally but not pushed.
Task: Create GitHub release using gh CLI
Prepare release notes file (temporary file):
skills/releaserator/templates/release-notes.md{{VERSION}} → NEW_VERSION{{CHANGELOG_ENTRY}} → the changelog entry content{{REPO}} → owner/repoCreate GitHub release:
gh release create vNEW_VERSION --title "vNEW_VERSION" --notes-file /tmp/release-notes-NEW_VERSION.md
Flags explained:
vNEW_VERSION: Tag name (must already exist from step 9)--title: Release title shown on GitHub--notes-file: Release body (our changelog entry + links)Capture release URL:
# Get release URL
gh release view vNEW_VERSION --json url --jq .url
Store: RELEASE_URL = GitHub release URL
Task: Display release information to user
Output a summary:
✅ Release vNEW_VERSION created successfully!
**Changes**:
- Updated VERSION_FILE (OLD_VERSION → NEW_VERSION)
- Created/updated CHANGELOG.md with entry for vNEW_VERSION
- Committed changes (abc1234: "chore: bump version to NEW_VERSION")
- Created git tag vNEW_VERSION
- Pushed commit and tag to remote
- Created GitHub release: RELEASE_URL
**Release includes**:
- X features added
- Y bugs fixed
- Z changes made
**Next steps**:
- Announce release to users
- Update plugin registry (if applicable)
- Monitor for issues in new release
- Continue development
View release: RELEASE_URL
View changelog: https://github.com/OWNER/REPO/blob/main/CHANGELOG.md
Templates use {{VARIABLE}} substitution syntax:
| Variable | Description | Example |
|---|---|---|
{{VERSION}} | New version number | "1.2.3" |
{{VERSION_TAG}} | Version with v prefix | "v1.2.3" |
{{OLD_VERSION}} | Previous version | "1.2.2" |
{{DATE}} | Release date (ISO) | "2026-01-11" |
{{REPO}} | GitHub owner/repo | "owner/repo" |
{{ADDED}} | Added section content | "- New feature\n- Another feature" |
{{CHANGED}} | Changed section content | "- Updated behavior" |
{{DEPRECATED}} | Deprecated section | "- Old API deprecated" |
{{REMOVED}} | Removed section | "- Dropped support for X" |
{{FIXED}} | Fixed section | "- Bug fix" |
{{SECURITY}} | Security section | "- CVE fix" |
{{BREAKING}} | Breaking changes summary | "⚠️ BREAKING: API changed" |
{{CHANGELOG_ENTRY}} | Full changelog entry | (entire entry content) |
Error: Git status shows uncommitted changes
Message:
❌ Working directory has uncommitted changes.
Please commit or stash changes before creating a release.
Run: git status
Action: Exit without making any changes
Error: gh command not found
Message:
❌ GitHub CLI (gh) not found.
Install with: brew install gh
After installing, run: gh auth login
Action: Exit without making any changes
Error: Tag vX.Y.Z already exists
Message:
❌ Version X.Y.Z already exists as git tag.
Current version in VERSION_FILE: X.Y.Z
Existing tag: vX.Y.Z
Please update the version manually in VERSION_FILE,
or delete the tag if it was created in error:
git tag -d vX.Y.Z
git push origin :refs/tags/vX.Y.Z
Action: Exit without making any changes
Error: No new commits found
Message:
⚠️ No commits found since last release vX.Y.Z
Current HEAD: abc1234
Last release tag: vX.Y.Z (abc1234)
These are the same commit. Nothing to release.
Action: Exit without making any changes
Warning: Only docs/chore commits
Message:
⚠️ No version bump needed (only documentation/chore commits).
Commits since v1.2.3:
- docs: update README
- chore: fix typo in comment
Do you want to create a release anyway? This will keep version at 1.2.3. (y/N)
Action: Ask user to confirm, proceed if yes
Error: Remote URL is not GitHub
Message:
❌ This plugin is not hosted on GitHub.
Remote URL: https://gitlab.com/owner/repo.git
The releaserator currently only supports GitHub.
GitLab and Gitea support coming soon!
Action: Exit without making any changes
Current implementation: GitHub-only
GitHub-specific code is isolated in:
skills/releaserator/platforms/github.mdPlatform interface (for future expansion):
Platform detection logic:
REMOTE_URL=$(git remote get-url origin 2>/dev/null)
if echo "$REMOTE_URL" | grep -q "github.com"; then
PLATFORM="github"
elif echo "$REMOTE_URL" | grep -q "gitlab.com"; then
PLATFORM="gitlab"
elif echo "$REMOTE_URL" | grep -qE "gitea|codeberg"; then
PLATFORM="gitea"
else
PLATFORM="unknown"
fi
To add GitLab support:
skills/releaserator/platforms/gitlab.mdBenefits:
Cause: Version bump calculation matched an existing tag
Solution: This shouldn't happen if logic is correct. If it does:
Cause: Commit messages don't follow Conventional Commits format
Solution:
Cause: User doesn't have push access to remote
Solution:
gh auth login or setting up SSH keysCause: gh CLI not authenticated
Solution:
❌ GitHub CLI authentication failed.
Run: gh auth login
Then try creating the release again.
Cause: Git remote URL in unexpected format
Solution:
git@github.com:owner/repo.githttps://github.com/owner/repo.githttps://github.com/owner/repoAfter running releaserator, verify: