Install
$ agentstack add skill-mgiovani-cc-arsenal-git-release ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Release Manager
Create semantic version releases with automated changelog generation from conventional commits, version file updates, and GitHub release publishing.
Quality Guidelines
Release operations are high-consequence and irreversible once pushed:
- Verify every change — analyze actual commits, not assumptions
- Confirm version bump — the detected semver bump must match the change scope
- Validate changelog — every entry must correspond to a real commit
- User approval required — confirm before executing anything in Phase 5
Workflow
Phase 1: Collect Commits Since Last Tag
- Find the latest tag:
``bash git describe --tags --abbrev=0 2>/dev/null || echo "none" ``
- If no tags exist, collect all commits on the current branch
- If a tag exists, collect commits since that tag
- Collect commits:
```bash # With existing tag git log ..HEAD --format="%H %s" --no-merges
# Without existing tag (first release) git log --format="%H %s" --no-merges ```
- Validate preconditions:
- Working tree is clean:
git status --porcelain - On the expected branch (main/master or release branch)
- Remote is up to date:
git fetch origin && git log HEAD..origin/$(git branch --show-current) --oneline - If there are no commits since the last tag, abort with a clear message
Phase 2: Auto-Detect Version Bump
- Parse each commit using conventional commit format:
- Extract type:
feat,fix,docs,style,refactor,perf,test,build,ci,chore,revert - Extract scope (optional): text in parentheses after type
- Detect breaking changes:
!after type/scope ORBREAKING CHANGE:in commit body - For non-conventional commits, classify as
other
This is plain regex/string parsing over commit subjects — do it inline regardless of commit count, no agent needed.
- Determine version bump: load
references/semver-guide.mdfor the full commit-type → bump mapping and pre-1.0 rules. The highest-priority bump wins (major > minor > patch).
- Calculate new version:
- Parse last tag as semver (strip leading
vif present) - If no previous tag, start from
0.1.0(first feature release) or1.0.0if user specifies - Apply the detected bump
- Respect
--major,--minor, or--patchoverride from arguments
- Display version summary — the counts must reflect commits you actually parsed in step 1, never estimated:
``` Current version: v1.2.3 Detected bump: minor (2 features, 5 fixes, 3 chores) New version: v1.3.0
Breaking changes: none ```
Phase 3: Build the CHANGELOG Entry
- Read existing CHANGELOG.md (if it exists) to understand the current format and preserve it
- Group commits by type using this order and heading format:
```markdown ## 1.3.0 (YYYY-MM-DD)
### Breaking Changes
- scope: description ([hash](url))
### Features
- scope: description ([hash](url))
### Bug Fixes
- scope: description ([hash](url))
### Performance
- scope: description ([hash](url))
### Documentation
- scope: description ([hash](url))
### Other Changes
- scope: description ([hash](url))
```
Type-to-heading mapping:
- Breaking changes (any type with
!orBREAKING CHANGE:) → Breaking Changes feat→ Featuresfix→ Bug Fixesperf→ Performancedocs→ Documentationrefactor,style,test,build,ci,chore,revert,other→ Other Changes
Only include sections that have entries. Omit empty sections.
- Generate comparison URL:
``bash gh repo view --json url -q .url 2>/dev/null || git remote get-url origin ``
- Construct the changelog entry:
- Use short commit hashes (7 chars) linked to the full commit URL
- If scope exists, bold it:
**scope:** description - If no scope: just the description
- Date format:
YYYY-MM-DD
- Insertion logic (defines the mechanics only — nothing is written to disk yet, so the Phase 4 preview and a later abort both stay side-effect-free):
- If CHANGELOG.md exists, insert the entry after the
# Changelogheader, preserving existing entries below it - If CHANGELOG.md does not exist, this entry becomes the file's first entry under a new
# Changelogheader - Maintain a blank line between the header and first entry, and between entries
- The actual file write happens in Phase 5 step 2, or Phase 3b step 2 for changelog-only mode — both reuse this same logic
- Verify the write (same call sites as step 5): after writing the file, re-read it and confirm the new version heading (
## []) is present and that at least one section under it has a real bullet line, not just an empty### Headingwith nothing below. A narrated changelog is not evidence the write succeeded — check the file on disk, e.g.:
``bash grep -A2 "## \[\]" CHANGELOG.md `` If the heading is missing, or every section under it is empty, abort before creating the release commit: "CHANGELOG.md write produced empty sections — release aborted, no commit created." Do not proceed to Phase 5 step 3 (or, in changelog-only mode, report success) on a failed verification.
Phase 3b: Changelog-Only Mode (if --changelog-only)
When --changelog-only is passed, skip Phases 4-6 entirely:
- Run Phases 1-3 normally (collect commits, detect version bump, build the changelog entry)
- Write CHANGELOG.md using the Phase 3 step 5 insertion logic, including its step 6 verification — abort here on a failed verification, do not report success
- Display the updated changelog entry to the user
- Stop here — no tag, version bump, commit, or GitHub release
Use case: draft a changelog before deciding on a release, or maintain a running changelog during development.
# Example output for --changelog-only
git-release --changelog-only
# → Scans commits since v1.2.3
# → Writes changelog entry to CHANGELOG.md
# → Reports: "CHANGELOG.md updated with 8 commits. No tag or release created."
Phase 4: User Approval
- Display release summary:
``` === Release Summary ===
Version: v1.2.3 → v1.3.0 (minor) Tag: v1.3.0 Commits: 12 commits since v1.2.3 Branch: main
Changelog preview: ───────────────────── ## [1.3.0](...) (2025-01-15)
### Features
- auth: add OAuth2 login support (abc1234)
- api: add rate limiting endpoint (def5678)
### Bug Fixes
- api: resolve null pointer in user endpoint (ghi9012)
─────────────────────
Version files to update:
- package.json (1.2.3 → 1.3.0)
- pyproject.toml (1.2.3 → 1.3.0)
Actions:
- Update version files
- Update CHANGELOG.md
- Create git commit: "chore(release): v1.3.0"
- Create git tag: v1.3.0
- Push commit and tag to origin
- Create GitHub release with changelog
```
- If
--dry-run(or-n) was passed: stop here. The summary above already shows everything that would happen — this flag is the only dry-run entry point, so no separate "preview" option is offered below.
- Otherwise, ask for confirmation:
- "Proceed with release" — continue to Phase 5
- "Change version" — ask for the desired version, recalculate, re-display the summary
- "Abort" — exit cleanly with "Release cancelled."
Phase 5: Execute Release
Execute all release actions in strict order. Stop immediately if any step fails and report which step failed and what manual cleanup may be needed.
- Update version files (detect and update all that exist):
package.json: Update"version": "x.y.z"fieldpackage-lock.json: Update"version": "x.y.z"at root levelpyproject.toml: Updateversion = "x.y.z"under[project]or[tool.poetry]Cargo.toml: Updateversion = "x.y.z"under[package]VERSIONorVERSION.txt: Replace entire file contentsetup.cfg: Updateversion = x.y.zunder[metadata]build.gradle/build.gradle.kts: Updateversion = "x.y.z"- Other version files: Skip unknown formats, notify user
- Write CHANGELOG.md using the Phase 3 step 5 insertion logic, including its step 6 verification — abort before step 3 below if verification fails.
- Create release commit:
``bash git add -A git commit -m "chore(release): v" ``
- Create annotated tag:
``bash git tag -a v -m "Release v" ``
- Push commit and tag:
``bash git push origin $(git branch --show-current) git push origin v ``
- Create GitHub release (unless
--no-githubflag is set):
``bash notes_file=$(mktemp -t release-notes) # write the changelog entry (without the "## [version]" header) to $notes_file gh release create v \ --title "v" \ --notes-file "$notes_file" \ --latest rm -f "$notes_file" ` A fixed path (e.g. /tmp/release-notes.md) can collide across concurrent or repeated runs — mktemp` guarantees a unique file.
- Display completion summary:
``` Release v1.3.0 completed successfully!
- Commit: abc1234 chore(release): v1.3.0
- Tag: v1.3.0
- GitHub: https://github.com/owner/repo/releases/tag/v1.3.0
- Changelog: Updated CHANGELOG.md
```
Argument Parsing
Parse optional arguments from command arguments:
--major: Force a major version bump (overrides auto-detection)--minor: Force a minor version bump (overrides auto-detection)--patch: Force a patch version bump (overrides auto-detection)--dry-runor-n: Show what would happen without making changes (see Phase 4 step 2 — the single dry-run entry point)--no-github: Skip GitHub release creation (only local tag + changelog)--changelog-only: Generate/update CHANGELOG.md only — skip tagging, version bumps, and GitHub release
When force flags conflict (e.g., --major --minor), use the highest: major > minor > patch.
Edge Cases
- No conventional commits: If commits don't follow conventional format, default to
patchbump and list all commits under Other Changes - Pre-release versions (e.g.,
0.x.y): Follow semver pre-1.0 rules — breaking changes bump minor, features bump minor, fixes bump patch - Monorepo: If multiple
package.jsonfiles exist, only update the root one. Warn the user about other version files found - Dirty working tree: Abort with a clear message asking the user to commit or stash changes first
- No remote: If
git pushfails due to no remote, skip push and GitHub release, warn the user - Tag already exists: If the computed tag already exists, abort and suggest a force flag or a different version
- CHANGELOG write verification fails: If the re-read in Phase 3 step 6 shows a missing heading or empty sections, abort before the release commit — never commit a changelog write you haven't confirmed on disk
Important Notes
- Conventional Commits: Works best with conventional commits (see the git-commit skill)
- Tag Format: Always uses
vprefix (e.g.,v1.3.0) unless existing tags use a different convention - CHANGELOG Format: Follows Keep a Changelog conventions
- Semver: Follows Semantic Versioning 2.0.0
- Never skip hooks: Never pass
--no-verifyon the release commit - No inline execution: Nothing in Phase 1-4 writes to the working tree — the first mutation is Phase 5 step 1, after approval
Examples
# Auto-detect version bump from commits
git-release
# Force a major version bump
git-release --major
# Preview without making changes
git-release --dry-run
# Release without creating a GitHub release
git-release --no-github
# Force minor bump, dry run
git-release --minor --dry-run
# Update CHANGELOG.md only (no tag or release)
git-release --changelog-only
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: mgiovani
- Source: mgiovani/cc-arsenal
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.