github-release

Guides IA through releasing a new version of a GitHub library end-to-end. Handles SemVer versioning and Keep a Changelog formatting automatically.

By github · 551 installs

npx skills add github/awesome-copilot --skill github-release

Source repository · Upstream listing

GitHub Release Skill This skill automates the full release workflow for a single package GitHub repository, from analysis through changelog authoring and PR creation. It relies exclusively on gh (GitHub CLI) and git no other tools needed. Steps 1 4 are read only reconnaissance nothing is written to the repo until Step 5, once the version number is confirmed. When to Use This Skill Use this skill whenever the user wants to cut a new release, publish a new version, bump a version, create a release branch, generate a changelog, or open a release PR on a GitHub repository. Trigger even if the user says something casual like "let's ship a new version" or "time to release". Prerequisites Examples below include both Bash and PowerShell variants; Windows users should prefer the PowerShell blocks. Before starting, verify the environment: If any check fails, stop and tell the user what to fix before continuing. Then ask the user one question: "Which directory contains your library's public facing source code? (e.g. src/ , lib/ , pkg/ used to focus the diff on what consumers actually see. Press Enter to scan the whole repo.)" Store the answer as PUBLIC PATH . If empty, PUBLIC PATH is . (repo root). Exclude these paths from all diffs regardless: tests/ , test/ , spec/ , tests / , docs/ , .lock , lock.json , .sum , generated files (files with a "do not edit" header comment), and build artefacts. The 9 Step Release Workflow Work through every step in order. Show the user what command you're about to run and its output. Pause and ask for confirmation only when explicitly noted. Step 1 Ensure main is up to date Stay on main for now. The release branch is created in Step 5, after the version is confirmed. Step 2 Grab the latest version tag Why not gh release list ? GitHub Releases are an optional layer on top of Git tags. Many repos tag releases with git tag without ever creating a GitHub Release, so gh release list can return empty even when version tags exist. Reading tags directly from git is the reliable source of truth. Then verify the tag exists on the remote (not just locally): If the remote check returns nothing, warn the user that the tag appears to be local only and hasn't been pushed they may want to push it before continuing. PREV TAG is the tag name exactly as found (e.g. v1.4.2 ). Strip any leading v when doing arithmetic; preserve it when naming things. If no tags exist at all , treat PREV TAG as (none) , set PREV SHA to the first commit, and default the new version to 1.0.0 (skip Step 4 versioning logic; go straight to Step 5). If the tag does not point to a real commit (orphaned tag), fall back to git rev list max parents=0 HEAD and warn the user. Step 3 Analyse what changed since the last release This step uses two complementary signals . The code diff is the primary source of truth; commit messages provide supporting context about intent. 3a Code diff (primary signal) Read the full diff output. For each changed file, identify: 1. Removed symbols functions, classes, methods, constants, exported names that existed before and are now gone. ? Strong signal for MAJOR. 2. Changed signatures functions that exist in both versions but with different parameters, return types, or thrown errors. ? Strong signal for MAJOR. 3. New exported symbols public functions, classes, constants that didn't exist before. ? Signal for MINOR. 4. Internal only changes modifications that don't touch any public interface (private helpers, unexported functions, algorithm internals). ? PATCH. 5. Bug fixes corrections to logic that was provably wrong (e.g. off by one, null check, wrong condition), without changing the public API. ? PATCH. If the diff is very large (thousands of lines), first run the stat summary to prioritise which files to read in full: Focus your detailed reading on files with the most changes and files whose names suggest they define public interfaces (e.g. index. , api. , exports. , public. , mod. , init . ). 3b Commit log (secondary signal) Use this to: Understand the intent behind code changes that aren't self explanatory from the diff alone (e.g. a one line security fix labelled as such). Catch changes that may be in paths outside PUBLIC PATH but are still user visible (e.g. a CLI flag change in a cmd/ directory). Fill in context for changelog entries where the code alone doesn't tell the whole story. See references/commit classification.md for mapping message patterns to change types. 3c Reconcile the two signals When signals agree ? use that classification with confidence. When signals conflict ? prefer the code diff . Examples: Commit says fix: typo but the diff shows a removed public method ? treat as MAJOR. Commit says feat: new API but the diff only touches private internals ? treat as PATCH. Commit says chore: refactor but the diff adds new exported symbols ? treat as MINOR. Document any conflicts you notice flag them to the user during the changelog review in Step 6. Step 4 Determine the next SemVer version Apply these rules to your analysis from Step 3 (full rules in references/semver rules.md ): Condition Bump Any breaking change to public API (removal, signature change, behaviour change) MAJOR New exported symbol or feature, no breaking changes MINOR Bug fix, perf improvement, security fix, docs, chore only PATCH When a release contains a mix, the highest precedence wins : MAJOR MINOR PATCH . Compute NEXT VERSION : Split PREV TAG into MAJOR.MINOR.PATCH integers. Apply the appropriate bump. Format as vMAJOR.MINOR.PATCH . Present the proposed version to the user with a brief rationale that cites specific code findings, not just commit messages. Example: "I'm proposing v2.1.0. The diff shows two new exported functions ( NewClient and WithTimeout ) in src/client.go , and no existing public symbols were removed or changed. Commit messages corroborate this as feature additions." Ask: "Does this version look right, or would you like to adjust it?" Wait for confirmation before proceeding. Step 5 Create the release branch Now that the version is confirmed, create the branch with the correct name from the start: Step 6 Update CHANGELOG.md Read the existing CHANGELOG.md (or create it if absent). Follow the [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format strictly. Structure to insert at the top (just below the Changelog header): Rules: Use today's date in YYYY MM DD format. Omit sections that have no entries don't leave empty headings. Write entries in plain English from a user's perspective , derived primarily from what the code diff shows, supplemented by commit message context. Good: "Added WithTimeout option to HTTP client constructor." Bad: "feat: add timeout cfg param" Map findings to sections: New exported symbol ? Added Breaking removal ? Removed Breaking change to existing API ? Changed (flag it as breaking) Bug/logic fix, perf ? Fixed Security fix ? Security Internal refactor, docs, chore, test ? omit unless user visible If a commit message revealed intent that the code diff alone wouldn't convey (e.g. a security fix disguised as a one line change), include that context in the changelog entry. Also update the diff link at the bottom of the file: Show the user the proposed changelog section before writing it to disk. If any signal conflicts were found in Step 3c, flag them here so the user can verify. Ask: "Does this changelog look accurate? Any entries to add, remove, or reword?" Incorporate feedback, then write to disk. Step 7 Commit and push Confirm the push succeeded before moving on. Step 8 Open a Pull Request ?? IMPORTANT: Always use body file to pass PR body text, never body with inline text. Inline escape sequences like \n are not interpreted as newlines by PowerShell and will appear as literal text in the PR. Using a file ensures proper markdown formatting. git tag vX.Y.Z <merge commit sha git push origin vX.Y.Z Paste the changelog section into the PR body's "What's included" block (or leave placeholder for manual review). Step 9 Hand off to the user Tell the user: Release PR is open! ?? New version: vX.Y.Z Once the PR is reviewed and merged, you'll need to create the tag yourself on the merge commit: Then go to GitHub Releases and publish the release from that tag. You can copy the changelog section directly into the release notes. Error handling Situation What to do gh auth status fails Stop; tell user to run gh auth login Not inside a git repo Stop; tell user to cd into their repo Working tree is dirty Warn; ask if they want to stash or abort No commits since last tag Tell user there's nothing to release Tag exists but points to no commit Use first commit as diff base; warn user Latest tag exists locally but not on remote Warn user; ask if they want to push the tag first or continue anyway Diff is empty for PUBLIC PATH but commits exist Warn; all changes may be internal; ask if they still want to proceed git push fails (e.g. protected branch rules) Report the error verbatim; suggest they check branch protection settings Troubleshooting in PowerShell If a command that works locally prints gh usage or treats a subcommand as separate token, ensure you're invoking the gh.exe on PATH (Get Command gh) and avoid passing unexpanded nested substitutions; use the PowerShell patterns above. Recommend tests: gh version; git fetch tags; run the PowerShell snippet to set $prevTag and run git diff name only $prevSha..HEAD src/ Limitations Requires the gh CLI to be installed and authenticated. Requires git tags to determine current version. Reference files references/semver rules.md Extended SemVer decision rules and edge cases references/commit classification.md Heuristics for classifying commit messages into change types