PluginBench
Skill
Pass
Audit score 90

tag-release

jssblck/agents

Tag and cut patch, minor, or major releases with verified commit, convention-matching tags, and green CI.

What is tag-release?

Automates semantic versioning and release tagging by syncing to the remote default branch, reading the repository's established tag convention, computing the next version, creating and pushing the tag, and verifying CI passes. Use this when asked to cut a release and you need to ensure the tag points to the correct commit, matches the repo's format, and the release pipeline succeeds.

  • Syncs to the remote default branch and fetches tags to ensure the tag points to the actual remote HEAD
  • Inspects prior releases to determine version format (leading v, package prefix, pre-release suffix) and tag kind (lightweight, annotated, or signed)
  • Computes the next semantic version (patch, minor, or major) preserving the repository's established conventions
  • Verifies CI checks are green on the target commit before creating the tag
  • Creates and pushes the tag matching the repository's tag kind, then watches the release pipeline to completion
  • Reports the version, commit SHA, tag type, and release outcome

How to install tag-release

npx skills add https://github.com/jssblck/agents --skill tag-release
Prerequisites
  • Git repository with a configured origin remote
  • GitHub CLI (gh) installed and authenticated
  • Access to push tags and create releases on the repository
Claude Code
Cursor
Windsurf
Cline

How to use tag-release

  1. 1.Fetch the remote default branch and tags to ensure local state matches origin
  2. 2.Inspect prior releases using gh release list or git ls-remote to identify the version format and tag convention
  3. 3.Compute the next semantic version by reading the latest tag and applying the requested bump (patch, minor, or major)
  4. 4.Re-fetch and verify the default branch SHA, latest tag, and CI status have not changed since step 1
  5. 5.Create the tag using git tag, matching the repository's tag kind (lightweight, annotated, or signed)
  6. 6.Push the tag with git push origin <version>
  7. 7.If the repository uses forge releases, create a GitHub release with gh release create
  8. 8.Verify the remote tag resolves to the correct commit and watch the release pipeline until it passes

Use cases

Good for
  • Cut a patch release after bug fixes are merged to the default branch
  • Bump a minor version when new features are ready for release
  • Create a major version release with breaking changes
  • Tag a release in a monorepo with package-specific version namespaces
  • Automate release tagging as part of a release workflow while ensuring CI is green
Who it's for
  • Release engineers and maintainers cutting releases
  • CI/CD automation systems triggering releases on merge or schedule
  • Development teams using semantic versioning with automated release pipelines

tag-release FAQ

What if the repository has no prior releases?

Use the repository's documented starting version (often v0.1.0 or v1.0.0), or ask the user which version to use as the first release.

How do I handle pre-release versions?

Read the repository's history to determine whether to advance, retain, or drop the pre-release suffix. If the pattern is unclear, ask the user before computing the next version.

What if CI checks are failing on the target commit?

Do not tag while required checks are unresolved. Diagnose the failure and repair it if within your authorized scope, or report it as a blocker if new authorization or access is needed.

Should I create a GitHub release or just push the tag?

Inspect prior releases to determine the repository's convention. If prior releases are forge Release objects, create one with gh release create after pushing the tag. If releases are just pushed tags, stop after pushing.

What if the default branch moved between my checks?

Recompute the release and re-verify the checks. Do not tag if the default branch SHA or latest tag changed; repeat the verification steps to ensure consistency.

Full instructions (SKILL.md)

Source of truth, from jssblck/agents.


name: tag-release description: "Use when asked to tag or cut a patch, minor, or major release." user-invocable: true

Tag a release

Tag the current origin default-branch HEAD in the repository's established version format and tag kind. Inspect the release convention, compute the next version, verify the exact target, push the tag, and watch the release to green.

The request authorizes creating and pushing the tag and running the repository's established release workflow. Ask only when a required value cannot be derived or the repository state makes the release ambiguous.

1. Sync to the origin default branch first

The tag must point at what is actually on the remote, not whatever your local checkout happens to be at.

git remote get-url origin
git ls-remote --symref origin HEAD
git fetch origin --tags --prune
  • Resolve the GitHub owner/repository from the origin URL. Pass that value explicitly with --repo or -R to every gh command so GH_REPO, another remote, or a configured default cannot redirect release operations.
  • Resolve the default branch from the remote's symbolic HEAD, not from a local branch or a potentially stale origin/HEAD. Record its full ref name.
  • Leave the working tree and local branches untouched. A dirty or diverged checkout does not affect a tag created directly from the fetched remote-tracking ref.
  • Record git rev-parse origin/<default-branch> as the candidate release commit. Do not cut a release from a red default branch. If the repository gates releases on CI, verify the checks are green on that exact commit.

2. Read the prior release and the repo's convention

Never invent a format. Look at what the repo already does:

gh release list -R <owner/repository>    # if releases are forge Release objects
git ls-remote --tags --refs origin 'refs/tags/<relevant-prefix>*'

Choose the relevant package or release namespace before selecting the latest version. A repository may contain unrelated product tags, package tags, or legacy formats that sort ahead of the series being released. Treat the remote tag refs as authoritative. Local tags may be stale or local-only even after git fetch --tags --prune. Fetch and inspect matching tag objects only after identifying the relevant remote series.

From the latest release, read:

  • Version format: a leading v or not, any component or package prefix (a monorepo may tag pkg-name/v1.2.3), and any pre-release or build suffix.
  • Tag kind: lightweight, annotated, or signed. Check with git cat-file -t <tag> (a tag object means annotated/signed, a commit means lightweight) and git verify-tag <tag> for signing.
  • Release mechanism: whether a release is just a pushed tag (a pipeline picks it up), or an explicit forge Release created with gh release create.

If there is no prior release, there is nothing to bump from: use the repo's documented starting version, or ask which to use.

3. Compute the next version

Compute a semantic bump from the latest tag in the relevant series, preserving its leading v and any package prefix:

  • patch: x.y.(z+1)
  • minor: x.(y+1).0
  • major: (x+1).0.0

Follow the repository's established transition from prerelease to stable tags. If history does not establish whether to advance, retain, or drop a prerelease suffix, ask the user.

Record the computed tag, candidate commit SHA, tag kind, and release mechanism.

4. Create the tag, matching convention

Immediately before tagging, re-fetch and confirm nothing moved:

git ls-remote --symref origin HEAD
git fetch origin --tags --prune
git rev-parse origin/<default-branch>
git ls-remote --tags --refs origin 'refs/tags/<relevant-prefix>*'
gh api 'repos/<owner>/<repository>/commits/<release-sha>/check-runs'
gh api 'repos/<owner>/<repository>/commits/<release-sha>/status'

The default branch, its SHA, and the latest relevant tag must be unchanged, the proposed tag must not exist, and required checks on the release SHA must be green. If anything moved, recompute the release and repeat this check. Wait for pending checks with the existing CI watcher, then recheck the target. For a failed check, diagnose it and repair only within the authorized scope. Do not tag while a required check is unresolved; continue independent preparation and report a blocker if repair needs new authorization or unavailable access.

Then tag the fetched remote HEAD explicitly, matching the kind of the prior tags:

# lightweight (prior tags are lightweight):
git tag <version> origin/<default-branch>

# annotated (prior tags are annotated):
git tag -a <version> origin/<default-branch> -m "<version>"

A global tag.gpgsign = true silently turns even a lightweight or annotated tag into a signed one. If the repo's existing tags are unsigned, pass --no-sign so the new tag matches. If they are signed, sign it.

5. Push, then watch the release to green

git push origin <version>

If the convention includes a forge release, create it only after pushing the verified local tag. Use gh release create <version> --verify-tag ..., matching how prior releases set their title, notes, and assets, and pass --repo <owner/repository>. Then verify the outcome:

git ls-remote origin 'refs/tags/<version>' 'refs/tags/<version>^{}'
gh run watch <run-id> -R <owner/repository> --exit-status --interval 20
gh release view <version> -R <owner/repository>

For an annotated or signed tag, compare the peeled ^{} result with the release commit SHA. For a lightweight tag, compare the direct tag result. Do not call it done until the remote tag resolves to the release commit, the release pipeline is green, and the expected release artifacts exist.

6. Report

State the version you cut, the commit SHA it points at, how it was tagged (lightweight / annotated / signed), and the release or pipeline result.