Skip to content
Back to skills

Publish Github Release

ASecurity

Use this whenever the user asks to ship, publish, release, tag, or cut a new version of the project — OR when CHANGELOG.md has an "Unreleased" / in-progress section ready to be shipped. The skill bumps the version across all version-bearing files, regenerates the CHANGELOG entry from git log since the last tag, commits, pushes, waits for green CI, and creates a GitHub release with auto-generated notes.

  • 8 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added May 27, 2026
data-aipythongoshellbashgitdevops

Works with

  • cli

Security analysis

A100/100

Pro scans all 7 files and shows the line behind each finding

Scanned May 27, 2026

npx -y skills add iampantherr/SecureContext --skill publish-github-release --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Publish Github Release?

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

Security grade badge for Publish Github Release
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/iampantherr-publish-github-release/badge)](https://www.skillsdirectory.com/skills/iampantherr-publish-github-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: publish-github-release
description: |
  Use this whenever the user asks to ship, publish, release, tag, or cut a
  new version of the project — OR when CHANGELOG.md has an "Unreleased" /
  in-progress section ready to be shipped. The skill bumps the version
  across all version-bearing files, regenerates the CHANGELOG entry from
  git log since the last tag, commits, pushes, waits for green CI, and
  creates a GitHub release with auto-generated notes.
version: 1.0.0
scope: global
intended_roles: [developer, devops, orchestrator]
tags: [release, git, github, ci, automation]
allowed_tools: [Bash, Read, Edit]
user_invocable: true
disable_model_invocation: false
shell_exec_ok: false
unsupported_scripts_ok: true
---

# Publish a GitHub release

Generic procedure for shipping a new version of a project. Reads
project-specific config from `<project>/.publish-github-release-config.json`
if present (see `references/config-schema.md`).

## When to use

Trigger phrases (literal words the user might type):

- "ship v1.2.3"
- "release"
- "tag a new version"
- "publish"
- "cut a release"
- "make a new release"
- "bump version and release"
- "deploy this release to github"

Auto-detect trigger: if `CHANGELOG.md` has a `## [Unreleased]` heading with
entries underneath, and the agent has just finished a coherent unit of work,
suggest invoking this skill.

DO NOT use this for:

- Patch increments without code changes (use `npm version patch` directly).
- Pre-release / RC builds (use the `prerelease-tag` skill instead — coming
  in a later release).
- Repos with no GitHub remote (the skill assumes `gh` CLI auth and a remote
  named `origin` pointing at GitHub).

## Procedure

### Step 1 — Preflight gates

Run `scripts/preflight.py`. Reads project config; fails fast on:

- Working tree dirty (uncommitted changes)
- Branch is not on `main` (or whatever `config.main_branch` says)
- Local is behind remote on main (would force-push)
- CI is currently red on the head commit
- `package.json` version doesn't match the previous CHANGELOG entry header

Exits 0 = ready to release. Non-zero = stop and surface the failure to the
operator.

### Step 2 — Bump version everywhere

Run `python scripts/bump-version.py --kind {major|minor|patch}` (or
`--version 1.2.3` for an explicit version). Reads
`config.version_files` and atomically rewrites the version string in
each. Default version-bearing files:

- `package.json` (`.version`)
- Plus anything listed in `<project>/.publish-github-release-config.json`'s
  `version_files`. SecureContext for example lists
  `[package.json, src/config.ts, .claude-plugin/plugin.json]`.

Refuses to bump if the new version is already a tag.

### Step 3 — Regenerate the CHANGELOG entry

Run `python scripts/regenerate-changelog.py --version X.Y.Z`. Walks
`git log` from the last tag → HEAD, groups commits by type (feat / fix /
docs / refactor / chore), produces a new section formatted to Keep-a-Changelog
spec, and inserts it under the `## [Unreleased]` heading (creating one if
needed). The operator reviews + edits before commit.

### Step 4 — Commit + push

```bash
git add -A
git commit -m "vX.Y.Z — <one-line title>"
git push origin main
```

The commit message follows project convention (controlled by
`config.commit_template` if set; default is `"vX.Y.Z — {title}"`).

### Step 5 — Wait for green CI

Run `bash scripts/wait-for-ci.sh`. Polls `gh run watch --exit-status` on
the just-pushed commit for up to 10 minutes (configurable via
`config.ci_timeout_seconds`). Exits non-zero if CI goes red — operator
fixes forward, never deletes the commit.

### Step 6 — Tag + create GitHub release

Run `bash scripts/create-release.sh vX.Y.Z`. Calls `gh release create
vX.Y.Z` with `--target <pushed-commit-sha>` and release notes pulled from
the CHANGELOG entry created in step 3. If `config.release_notes_extra`
is set in the project config, appends those bullets to the body.

### Step 7 — Verify the release is live

```bash
gh release view vX.Y.Z --json url,name,createdAt
```

Output the URL to stdout so the operator (or another agent) can confirm.

## Bundled scripts

- `scripts/preflight.py` — gate checks (working tree, branch, CI status)
- `scripts/bump-version.py` — atomic multi-file version bump
- `scripts/regenerate-changelog.py` — git log → Keep-a-Changelog section
- `scripts/wait-for-ci.sh` — `gh run watch --exit-status` polling wrapper
- `scripts/create-release.sh` — `gh release create` wrapper

## Reference materials

- `references/config-schema.md` — the `.publish-github-release-config.json` schema
- `references/conventional-commits.md` — commit-type → CHANGELOG-section mapping
- `references/semver-rules.md` — when to bump major/minor/patch

## Failure modes + recovery

| Symptom | Cause | Fix |
|---|---|---|
| Preflight reports working tree dirty | Uncommitted changes | `git stash` or commit them; re-run |
| Preflight reports behind remote | Someone else pushed to main | `git pull --rebase`; re-run |
| Preflight reports CI red | Existing red CI on main | Fix the CI failure first; do not release on red |
| bump-version says "version X.Y.Z already a tag" | You're trying to re-release | Increment further (e.g. patch) |
| regenerate-changelog produces empty section | No commits since last tag | Nothing to release; abort |
| wait-for-ci times out | CI is slow on this commit | Extend `config.ci_timeout_seconds` or wait manually |
| wait-for-ci goes red | A test failed | Fix forward in a new commit; re-run from step 3 |
| create-release.sh "tag already exists" | Previous attempt got partway | Delete local tag (`git tag -d vX.Y.Z`); re-run create-release.sh |

## Notes on safety

- The skill **never** rewrites git history. No `--force`, no `--amend`, no
  `git reset --hard` on remote.
- The skill **never** deletes tags or releases from GitHub.
- If anything goes wrong after step 4 (commit pushed), the standard
  recovery is "fix forward in a new commit." Do not try to undo the push.
- Pre-existing tags are sacrosanct. The release-tag is computed from the
  newly-bumped version, which the bump step refused to set to anything that
  already exists.

## Composition with other skills

After this skill runs successfully, consider invoking:

- `~/.claude/skills/readme-author/` to update README badges with the new version.
- `~/.claude/skills/architecture-doc-author/` to add a section reflecting any
  structural changes in this release.
- Project-specific post-release skills (e.g. `cleancheck-deploy-to-vercel`).

Each of those is a separate skill the orchestrator can ASSIGN after seeing
this skill's COMPLETE broadcast.

Files in this skill

  • SKILL.md6.5 KB
  • references/config-schema.md2.3 KB
  • scripts/bump-version.py6.9 KB
  • scripts/create-release.sh2.3 KB
  • scripts/preflight.py7.8 KB
  • scripts/regenerate-changelog.py7.5 KB
  • scripts/wait-for-ci.sh1.8 KB

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…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.