Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when user asks to create a release, cut a release, or publish a version. Auto-detects GitHub vs GitLab vs Gitea, calculates semantic version, generates release notes from PRs/MRs or commits, shows preview for confirmation before publishing.
.claude/skills/umputun-new/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-08 | ✗→✓ | ▲ Improved | 420% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 3% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 48% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 67% | 0% |
| case-22 | ✗→✓ | ▲ Improved | -63% | 0% |
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:
json{ "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 }] }
bashplatform=$(sh ${CLAUDE_PLUGIN_ROOT}/skills/release/scripts/detect-platform.sh)
bash# 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
bashlast_tag=$(git describe --tags --abbrev=0 --match "v*" 2>/dev/null || echo "none")
bashnew_version=$(sh ${CLAUDE_PLUGIN_ROOT}/skills/release/scripts/calc-version.sh <release_type>)
Verify tag doesn't already exist:
bashif git rev-parse "$new_version" &>/dev/null; then echo "error: tag $new_version already exists" fi
bashnotes=$(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 def5678bash# 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"bashgit 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:
json{ "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:
bashgh release create "$new_version" \ --title "Version ${new_version#v}" \ --notes "$notes"
GitLab:
bashglab release create "$new_version" \ --name "Version ${new_version#v}" \ --notes "$notes"
Gitea:
bashtea 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)| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-16 | pass→pass | 10,001 | 1,987 | -80% | 1 | 1 | 0% | 1,442 | 2,013 | +40% | 0 | 0 | — |
case-15 | pass→pass | 7,440 | 1,851 | -75% | 1 | 1 | 0% | 1,301 | 2,063 | +59% | 0 | 0 | — |
case-01 | fail→fail | 8,130 | 6,671 | -18% | 1 | 1 | 0% | 1,357 | 2,165 | +60% | 0 | 0 | — |
case-02 | fail→fail | 15,131 | 6,630 | -56% | 1 | 1 | 0% | 2,789 | 2,090 | -25% | 0 | 0 | — |
case-03 | fail→fail | 5,698 | 6,204 | +9% | 1 | 1 | 0% | 917 | 2,124 | +132% | 0 | 0 | — |
case-04 | fail→fail | 11,538 | 8,034 | -30% | 1 | 1 | 0% | 1,996 | 3,151 | +58% | 0 | 0 | — |
case-05 | pass→pass | 3,958 | 3,251 | -18% | 1 | 1 | 0% | 622 | 2,350 | +278% | 0 | 0 | — |
case-06 | pass→pass | 2,915 | 2,636 | -10% | 1 | 1 | 0% | 472 | 2,188 | +364% | 0 | 0 | — |
case-07 | pass→pass | 3,591 | 1,569 | -56% | 1 | 1 | 0% | 567 | 1,980 | +249% | 0 | 0 | — |
case-08 | fail→pass | 3,015 | 1,549 | -49% | 1 | 1 | 0% | 384 | 1,996 | +420% | 0 | 0 | — |
case-09 | pass→pass | 6,586 | 3,495 | -47% | 1 | 1 | 0% | 1,103 | 2,337 | +112% | 0 | 0 | — |
case-10 | pass→pass | 7,299 | 3,148 | -57% | 1 | 1 | 0% | 1,275 | 2,280 | +79% | 0 | 0 | — |
case-11 | fail→pass | 11,059 | 1,752 | -84% | 1 | 1 | 0% | 2,001 | 2,057 | +3% | 0 | 0 | — |
case-12 | fail→pass | 8,269 | 1,706 | -79% | 1 | 1 | 0% | 1,379 | 2,035 | +48% | 0 | 0 | — |
case-13 | pass→pass | 3,154 | 2,729 | -13% | 1 | 1 | 0% | 628 | 2,221 | +254% | 0 | 0 | — |
case-14 | pass→pass | 6,406 | 1,791 | -72% | 1 | 1 | 0% | 1,140 | 2,037 | +79% | 0 | 0 | — |
case-17 | pass→pass | 7,687 | 3,220 | -58% | 1 | 1 | 0% | 1,236 | 2,223 | +80% | 0 | 0 | — |
case-18 | fail→pass | 7,868 | 2,697 | -66% | 1 | 1 | 0% | 1,267 | 2,110 | +67% | 0 | 0 | — |
case-19 | pass→pass | 12,742 | 2,164 | -83% | 1 | 1 | 0% | 2,141 | 2,094 | -2% | 0 | 0 | — |
case-20 | pass→pass | 16,785 | 6,375 | -62% | 1 | 1 | 0% | 2,883 | 2,819 | -2% | 0 | 0 | — |
case-21 | pass→pass | 6,851 | 2,238 | -67% | 1 | 1 | 0% | 1,126 | 2,140 | +90% | 0 | 0 | — |
case-22 | fail→pass | 34,311 | 1,924 | -94% | 1 | 1 | 0% | 5,523 | 2,053 | -63% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 19 counted toward the lift figure. The other 3 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +23 percentage points is the difference between those two pass rates over the 19 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.