Automates releases on GitHub, GitLab, or Gitea: detects platform, computes semver bump, generates notes from PRs/commits, previews before tagging/publishing.
From release-toolsnpx claudepluginhub umputun/cc-thingz --plugin release-toolsThis skill is limited to using the following tools:
scripts/calc-version.shscripts/detect-platform.shscripts/get-notes.shDispatches code-reviewer subagent to evaluate code changes via git SHAs after tasks, major features, or before merging, with focused context on implementation and requirements.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Processes code review feedback technically: verify suggestions against codebase, clarify unclear items, push back if questionable, implement after evaluation—not blind agreement.
Creates GitHub, GitLab, or Gitea releases with auto-versioning and release notes generation.
Helper scripts in skill's scripts/ directory (use ${CLAUDE_PLUGIN_ROOT} for path resolution):
detect-platform.sh - outputs github, gitlab, or giteacalc-version.sh <type> - outputs new version (e.g., v1.2.3)get-notes.sh <platform> - outputs release notes (PRs/MRs or commits)Use AskUserQuestion tool to get release type:
{
"questions": [{
"question": "What type of release is this?",
"header": "Version",
"options": [
{"label": "Hotfix", "description": "Bug fixes (1.2.3 → 1.2.4)"},
{"label": "Minor", "description": "New features (1.2.3 → 1.3.0)"},
{"label": "Major", "description": "Breaking changes (1.2.3 → 2.0.0)"}
],
"multiSelect": false
}]
}
platform=$(sh ${CLAUDE_PLUGIN_ROOT}/skills/release/scripts/detect-platform.sh)
# working tree must be clean
if [ -n "$(git status --porcelain)" ]; then
echo "error: uncommitted changes - commit or stash first"
fi
# sync with remote (--tags ensures all remote tags are fetched)
git fetch origin --tags
last_tag=$(git describe --tags --abbrev=0 --match "v*" 2>/dev/null || echo "none")
new_version=$(sh ${CLAUDE_PLUGIN_ROOT}/skills/release/scripts/calc-version.sh <release_type>)
Verify tag doesn't already exist:
if git rev-parse "$new_version" &>/dev/null; then
echo "error: tag $new_version already exists"
fi
notes=$(sh ${CLAUDE_PLUGIN_ROOT}/skills/release/scripts/get-notes.sh "$platform")
Script logic:
Post-processing (Claude must do this before presenting):
Output format:
**New Features**
- add user authentication #45 @username
- implement caching d41d3ad
**Improvements**
- refactor auth module abc1234
- update dependencies #47 @contributor
**Bug Fixes**
- resolve login timeout #46 @username
- handle nil pointer def5678
# detect actual changelog filename (case-sensitive filesystem!)
changelog=""
for f in CHANGELOG.md changelog.md CHANGELOG; do
[ -f "$f" ] && changelog="$f" && break
done
If changelog exists:
$changelog) for all operations - do not hardcode "CHANGELOG.md"git add "$changelog"
git commit -m "docs: update changelog for $new_version"
Common formats to detect:
## [Unreleased] section, versions as ## [X.Y.Z] - YYYY-MM-DD## X.Y.Z or # X.Y.ZShow the release preview to user:
=== Release Preview ===
Platform: GitHub/GitLab
Current version: v1.2.3
New version: v1.3.0
Title: Version 1.3.0
CHANGELOG: <detected filename> will be updated (or "none found")
Release Notes:
--------------
**New Features**
- add user authentication #45 @username
**Improvements**
- refactor auth module abc1234
**Bug Fixes**
- resolve login timeout #46 @contributor
--------------
Use AskUserQuestion tool to confirm:
{
"questions": [{
"question": "Proceed with creating this release?",
"header": "Release",
"options": [
{"label": "Yes, publish", "description": "Create tag and publish release"},
{"label": "Cancel", "description": "Abort release"}
],
"multiSelect": false
}]
}
Wait for user confirmation before creating release.
Only after user confirms:
GitHub:
gh release create "$new_version" \
--title "Version ${new_version#v}" \
--notes "$notes"
GitLab:
glab release create "$new_version" \
--name "Version ${new_version#v}" \
--notes "$notes"
Gitea:
tea release create \
--tag "$new_version" \
--title "Version ${new_version#v}" \
--note "$notes"
After successful creation:
| Case | Handling |
|---|---|
| No previous tags | Default version based on type |
| Pre-release tag (v1.2.3-rc1) | Strip suffix, use base version |
| No PRs/MRs found | Show commits only (still with hashes) |
| Tag already exists | Error and abort |
| No CHANGELOG file | Skip changelog update |
| Unknown CHANGELOG format | Ask user or use simple ## vX.Y.Z format |
vX.Y.ZVersion X.Y.Z- description #123 @author (PRs) or - description abc1234 (commits)#123 (GitHub/Gitea) or !123 (GitLab)