GitHub Version Release
Use this skill to publish the current local changes from dev as a new semantic version on GitHub and promote them to prod.
Principles
- Work conservatively and inspect state before every operation that changes branch, history, remote state, tags, or releases.
- Never use
git push --force,git push --force-with-lease, history rewrites, destructive cleanup, or broad file deletion unless the user explicitly asks for it and the risk is explained first. - Stop and report a concrete recommendation when a required branch, remote, permission, version decision, test command, merge, tag, or release step is unclear or fails.
- Preserve user changes. Do not revert unrelated work unless the user explicitly requests it.
- Prefer existing repository conventions over generic assumptions, especially for changelog format, release notes, version files, test commands, and branch names.
Required Starting State
Before making changes, verify all of the following:
- Run
git status --short --branch. - Confirm the current branch is exactly
dev. If not, stop and tell the user the current branch and that the release workflow must start fromdev. - Confirm the working tree contains the local changes that should be released. If there are no changes and no new commits on
devrelative toprod, stop and ask whether an empty release is intended. - Run
git remote -vand confirm a GitHub remote exists, normallyorigin. - Run
git branch --list dev prodand confirm localdevandprodbranches exist. Ifprodis missing, check whetherorigin/prodexists before recommending how to create it. - Run
git fetch --prune --tags originwhen network access and permissions are available. If fetching fails, stop with the exact failure and a recommendation.
Analyze Changes
Build a release summary before editing documentation:
Compare
devagainstprod:git log --oneline --decorate prod..dev git diff --stat prod...dev git diff --name-status prod...devAlso inspect unstaged, staged, and untracked local changes:
git diff --stat git diff --cached --stat git status --shortRead changed files selectively to understand user-facing behavior, configuration, installation, APIs, CLI commands, migrations, dependency changes, tests, and bug fixes.
If the change set mixes unrelated work or includes secrets, generated junk, credentials, build artifacts, or files that appear accidental, stop and ask the user how to proceed.
Update CHANGELOG
Find the changelog using this preference order:
- Existing
CHANGELOG.md,Changelog.md, or equivalent repository changelog. - Existing release notes file named by repository convention.
- If no changelog exists, create
CHANGELOG.mdonly if the repository appears to maintain release documentation or the user asked for a release record. Otherwise stop and recommend creating one.
Update the changelog using the existing style. If no style exists, use this structure:
## vX.Y.Z - YYYY-MM-DD
### Added
- ...
### Changed
- ...
### Fixed
- ...
Include only meaningful release notes:
- New features and user-visible behavior changes.
- Bug fixes.
- Breaking changes, migrations, or compatibility notes.
- Installation, configuration, dependency, or operational changes.
- Security fixes, if any.
Do not paste raw commit logs. Convert the analyzed changes into concise release notes.
Update README
Inspect README.md or the repository's primary documentation when changes affect:
- Installation or setup.
- Configuration or environment variables.
- Commands, usage, CLI options, API behavior, UI behavior, or screenshots.
- Supported platforms, dependencies, deployment, or troubleshooting.
- New features that users need to discover.
Keep README edits minimal and consistent with the existing voice. If no README change is needed, note why in the final summary.
Determine Tests And Checks
Discover available verification commands from repository conventions before running them:
package.json:npm test,npm run lint,npm run typecheck,npm run build, or equivalent package-manager commands.composer.json:composer test,composer lint,vendor/bin/phpunit, or project scripts.pyproject.toml,setup.cfg,tox.ini,pytest.ini:pytest,ruff,mypy,tox, or project scripts.Makefile: relevantmake test,make lint,make check, ormake buildtargets.- CI configuration: mirror required checks when practical.
Run the smallest reliable set that covers the release risk. If dependencies are missing, commands are ambiguous, or tests require unavailable services, stop or report the limitation clearly with a recommendation. Do not invent destructive or production-touching checks.
Commit On Dev
After changelog, README, and verification are complete:
Re-run
git status --short --branch.Confirm still on
dev.Review the final diff:
git diff git diff --cachedStage all intended release changes:
git add -ARe-check staged content:
git status --short git diff --cached --statCommit with a concise, meaningful message, for example:
git commit -m "Release vX.Y.Z"
Use a more specific message if the release is not yet versioned, such as Prepare release vX.Y.Z. If there is nothing to commit because all changes were already committed, continue only after confirming the existing dev commits are the intended release content.
Push Dev
Push dev without force:
git push origin dev
If push is rejected because the remote has new commits, stop. Recommend fetching and rebasing or merging only after inspecting the remote changes; do not auto-rewrite history.
Promote To Prod
Before changing branches:
Ensure
devis clean:git status --short --branchSwitch to
prod:git switch prodUpdate
prodfrom the remote:git pull --ff-only origin prod
If fast-forward pull fails, stop and report the reason. Do not merge remote changes blindly.
Merge dev into prod:
git merge --no-ff dev
If merge conflicts occur:
- Stop immediately after reporting conflicted files from
git status --short. - Do not resolve conflicts unless the user asks.
- Recommend a conflict-resolution path, usually resolving on
prod, rerunning checks, committing the merge, then continuing the release.
After a clean merge, run the relevant tests/checks again when the merge changed code or when branch differences make verification meaningful.
Choose Semantic Version
Determine the next version from the latest semantic tag and the release scope.
Find the latest tag:
git tag --list 'v[0-9]*' --sort=-v:refnameInspect recent tags if needed:
git describe --tags --abbrev=0 git log --oneline --decorate --tags --max-count=20Choose the version:
- Major (
vX.0.0) for breaking changes or incompatible migrations. - Minor (
vX.Y.0) for backward-compatible features or notable enhancements. - Patch (
vX.Y.Z) for backward-compatible fixes, documentation-only release notes, or small maintenance changes.
- Major (
If there are no existing tags, use v0.1.0 for an initial pre-1.0 release unless the repository clearly states another version. If package metadata already declares a version, keep tag, changelog, release notes, and package version consistent.
Stop if:
- The latest version cannot be determined safely.
- A chosen tag already exists locally or remotely.
- Multiple version sources disagree and there is no clear repository convention.
Create And Push Tag
Create an annotated tag on prod after the merge commit and successful checks:
git tag -a vX.Y.Z -m "Release vX.Y.Z"
Verify the tag points to the intended prod commit:
git show --stat vX.Y.Z
git status --short --branch
Push prod and the tag without force:
git push origin prod
git push origin vX.Y.Z
If either push fails, stop and report the exact failure with a recommended next step.
Create GitHub Release
Create the GitHub Release from the new tag using the changelog entry as release notes.
Preferred command when GitHub CLI is available and authenticated:
gh release create vX.Y.Z --title "vX.Y.Z" --notes-file /tmp/release-notes-vX.Y.Z.md
Before running it:
- Write a temporary notes file containing only the changelog points for
vX.Y.Z. - Confirm
gh auth statussucceeds for the target GitHub host. - Confirm the repository remote points to the intended GitHub repository.
If gh is unavailable, use the GitHub app/API if available. If no authenticated GitHub release mechanism is available, stop after pushing the tag and tell the user exactly what release title and notes to create manually.
Do not create duplicate releases. Check existing releases or tags first when there is any uncertainty.
Return To Dev
After all release steps have completed successfully, including the GitHub Release creation, switch the local checkout back to dev:
git status --short --branch
git switch dev
git status --short --branch
Only do this when the workflow has fully succeeded. If the workflow stopped early or needs manual follow-up, leave the checkout on the branch where the issue occurred and report that branch in the final response.
Final Report
Report concisely:
- Branches updated.
- Final local branch after the release.
- Commit hash and commit message.
- Version tag created.
- GitHub Release URL or the reason it could not be created.
- Tests/checks run and their result.
- README status: updated or not needed.
- Any warnings, skipped checks, or follow-up recommendations.
If the workflow stopped early, report:
- The last completed safe step.
- The blocking condition.
- The exact command or state that revealed it.
- A concrete recommended next action.