Skip to content
Back to skills

Release

ASecurity

Create a GitHub release with auto-generated changelog. Use this skill whenever the user wants to create a release, tag a release, publish a release, cut a release, or ship a version. Triggers on phrases like \"release 1.2.3\", \"create a release\", \"tag a new version\", \"ship it\", \"cut a release\", or any mention of creating GitHub releases.

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 29, 2026
developmentgobashgitapifullstack

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 29, 2026

npx -y skills add abnegate/claudes --skill release --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Release?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Release
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/abnegate-release/badge)](https://www.skillsdirectory.com/skills/abnegate-release)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: release
description: "Create a GitHub release with auto-generated changelog. Use this skill whenever the user wants to create a release, tag a release, publish a release, cut a release, or ship a version. Triggers on phrases like \"release 1.2.3\", \"create a release\", \"tag a new version\", \"ship it\", \"cut a release\", or any mention of creating GitHub releases."
argument-hint: "[[version]=auto|1.2.3|major|minor|patch, [branch]=main, [pre-release]=false]"
---

# GitHub Release

Create a GitHub release using the `gh` CLI with auto-generated changelog from all changes since the last release.

## Arguments

The user provides these in natural language — extract them from the prompt:

- **version** (optional): An explicit semver tag without `v` prefix (e.g. `1.2.3`, `2.0.0-beta.1`), a semver bump keyword (`major`, `minor`, `patch`), or omitted entirely to auto-detect the bump type from the changelog.
- **branch** (optional): Branch to create the tag/release on. Defaults to `main`.
- **pre-release** (optional): Explicitly mark as pre-release. Auto-detected if the version contains `alpha`, `beta`, or `rc` (e.g. `1.0.0-rc.1`).

## Commit subjects

Commits use scoped conventional subjects, `type(scope): subject`:

- **type**: `feat`, `fix`, `refactor`, `chore`, `docs`, `test`, `style` or `perf`; `ci`, `build` and `revert` are accepted too.
- **scope** (optional): the area touched, e.g. `fix(auth): handle expired sessions`. Omit it for repo-wide changes.
- **`!`** right before the colon marks a breaking change: `feat(api)!: remove v1 routes`. So does a `BREAKING CHANGE:` or `BREAKING-CHANGE:` footer at the start of a body line.
- Legacy subjects in the old `(type): subject` form, e.g. `(feat): add planner agent`, classify the same way: the word in parentheses is the type, and there is no scope.
- Any other subject (e.g. `Update README`) has no type.

## Workflow

### 1. Resolve the version

**If no version was provided** (auto-detect from changelog):

1. Fetch the latest release tag:
   ```bash
   gh release list --limit 1 --json tagName --jq '.[0].tagName'
   ```
2. Strip any `v` prefix from the tag to get the current version. If no previous release exists, use `0.0.0` as the base.
3. List the commits since the last release. The second command, the footer command, lists the commits whose body carries a `BREAKING CHANGE:` or `BREAKING-CHANGE:` footer, which the subjects alone do not show:
   ```bash
   git log <latest-tag>..HEAD --no-merges --format='%h %s'
   ```
   ```bash
   git log <latest-tag>..HEAD --no-merges -E --grep='^BREAKING[ -]CHANGE:' --format='%h %s'
   ```
   If there is no previous release, drop `<latest-tag>..HEAD` from both commands.
4. Parse each subject as described in Commit subjects above and pick the bump:
   - **major** — any subject has `!` right before the colon (`feat!:`, `fix(api)!:`), or the footer command printed any commit
   - **minor** — any commit has type `feat`
   - **patch** — everything else, including subjects without a type

   The highest-priority classification wins: major > minor > patch. If a subject without a type looks like a new feature or a breaking change, point it out in the summary so the user can choose a higher bump.
5. **Present a confirmation summary to the user and wait for approval before proceeding.** The summary must include:
   - **Previous version**: the current latest release tag
   - **Changes**: a categorised list of commits since that tag (grouped as in the changelog: breaking, features, fixes, other)
   - **Detected bump**: the bump type and the commit that decided it (e.g. "major — `feat(api)!: remove v1 routes`")
   - **Proposed version**: the computed next version

   Do NOT proceed to create the release until the user explicitly confirms.

**If the user provided a bump keyword** (`major`, `minor`, or `patch`):

1. Fetch the latest release tag:
   ```bash
   gh release list --limit 1 --json tagName --jq '.[0].tagName'
   ```
2. Strip any `v` prefix from the tag to get the current version. If no previous release exists, use `0.0.0` as the base.
3. Bump the appropriate component:
   - `major`: increment MAJOR, reset MINOR and PATCH to 0 (e.g. `1.2.3` → `2.0.0`)
   - `minor`: increment MINOR, reset PATCH to 0 (e.g. `1.2.3` → `1.3.0`)
   - `patch`: increment PATCH (e.g. `1.2.3` → `1.2.4`)
4. Show the user the resolved version and confirm before proceeding.

**If the user provided an explicit version string:**

Confirm the version string is valid semver. It should match the pattern `MAJOR.MINOR.PATCH` with an optional pre-release suffix like `-alpha.1`, `-beta.2`, or `-rc.1`. Reject anything with a `v` prefix — strip it and inform the user if they include one.

### 2. Determine pre-release status

A release is pre-release if:
- The version contains `-alpha`, `-beta`, or `-rc` (e.g. `1.0.0-beta.1`)
- The user explicitly says it's a pre-release

### 3. Build the changelog

Reuse the two commit lists from auto-detection. If the version was given explicitly or as a bump keyword, fetch the latest release tag and run both `git log` commands from step 1 now.

Group the commits into these sections, in this order. Each commit goes in the first section it matches:

- **Breaking Changes** — `!` before the colon, or listed by the footer command
- **New Features** — type `feat`
- **Bug Fixes** — type `fix`
- **Other Changes** — every other type (`refactor`, `perf`, `chore`, `docs`, `test`, `style`, `build`, `ci`, `revert`) and subjects without a type

Write each commit as one bullet:

- Strip the `type(scope)!: ` prefix (the scope and `!` are optional), or the legacy `(type): ` prefix.
- If the subject has a scope, start the bullet with `**scope:** `.
- Capitalise the first letter of the description and keep it concise.
- For a commit listed by the footer command, append the footer's explanation (`git show -s --format='%b' <hash>` prints the body).

For example, `feat(api)!: remove v1 routes` becomes `**api:** Remove v1 routes` under Breaking Changes, and the legacy `(fix): handle empty input` becomes `Handle empty input` under Bug Fixes.

Omit empty sections. If a section has no commits, don't include it.

Format the body as:

```markdown
## Breaking Changes

- **api:** Remove v1 routes

## New Features

- **agents:** Add planner agent for task decomposition
- **agents:** Add verifier agent for plan validation

## Bug Fixes

- **swoole-expert:** Restore API surfaces stripped during compression
- **consolidation:** Remove arbitrary subtask limit

## Other Changes

- **android-expert:** Remove training-redundant content
- Rename elite-fullstack-architect -> architect, code-griller -> reviewer
- Update commands to use consolidation pattern for parallel work
```

### 4. Create the release

```bash
gh release create <version> --title '<version>' --target <branch> [--prerelease] --notes-file - <<'EOF'
[changelog body from step 3]
EOF
```

Use `--notes-file -` with the hand-crafted changelog, NOT `--generate-notes`.

### 5. Confirm

After creation, display the release URL:

```bash
gh release view <version> --json url,tagName,isPrerelease,createdAt
```

## Examples

**Explicit version:**
Prompt: `release 1.2.3`
1. Build changelog from commits since last tag
2. Create the release:

```bash
gh release create 1.2.3 --title '1.2.3' --target main --notes-file - <<'EOF'
[changelog body from step 3]
EOF
```

**Auto-detect:**
Prompt: `create a release`
1. Fetch last tag (`1.2.3`); the commits since are `feat(auth): add passkey login` and `fix(api): accept empty filters`, and the footer command prints nothing
2. Detect bump: minor — `feat(auth): add passkey login`
3. Show confirmation with changelog preview and proposed version (`1.3.0`)
4. After user confirms:

```bash
gh release create 1.3.0 --title '1.3.0' --target main --notes-file - <<'EOF'
[changelog body from step 3]
EOF
```

**Breaking change:**
Prompt: `ship it`
1. Fetch last tag (`1.3.0`); `feat(api)!: remove v1 routes` has `!` before the colon (a `BREAKING CHANGE:` footer on any commit counts the same)
2. Detect bump: major; the changelog opens with Breaking Changes: `- **api:** Remove v1 routes`
3. Show confirmation with changelog preview and proposed version (`2.0.0`)
4. After user confirms:

```bash
gh release create 2.0.0 --title '2.0.0' --target main --notes-file - <<'EOF'
[changelog body from step 3]
EOF
```

**Pre-release:**
Prompt: `cut a release 2.0.0-beta.1 on develop`
1. Create the pre-release:

```bash
gh release create 2.0.0-beta.1 --title '2.0.0-beta.1' --target develop --prerelease --notes-file - <<'EOF'
[changelog body from step 3]
EOF
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…