# Git Release

> Publish the current local dev branch changes as a new semantic version on GitHub. Use when Codex is asked to release local changes by inspecting git status, updating CHANGELOG and README, running available tests/checks, committing to dev, pushing dev, merging dev into prod, creating and pushing a semantic version tag, creating a GitHub Release, and returning the local checkout to dev after success. Includes careful stop conditions for merge conflicts, missing remotes, missing permissions, unclear version numbers, and destructive operations.

- Skill: `mdeuerlein/git-release` (Agent Skill)
- Install (CLI): `npx skillmds@latest add mdeuerlein/git-release`
- Raw SKILL.md: https://api.skillmd.com/api/skills/mdeuerlein/git-release/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: mdeuerlein (https://skillmd.com/u/mdeuerlein)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/mdeuerlein/git-release

---


# 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:

1. Run `git status --short --branch`.
2. Confirm the current branch is exactly `dev`. If not, stop and tell the user the current branch and that the release workflow must start from `dev`.
3. Confirm the working tree contains the local changes that should be released. If there are no changes and no new commits on `dev` relative to `prod`, stop and ask whether an empty release is intended.
4. Run `git remote -v` and confirm a GitHub remote exists, normally `origin`.
5. Run `git branch --list dev prod` and confirm local `dev` and `prod` branches exist. If `prod` is missing, check whether `origin/prod` exists before recommending how to create it.
6. Run `git fetch --prune --tags origin` when 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:

1. Compare `dev` against `prod`:

   ```bash
   git log --oneline --decorate prod..dev
   git diff --stat prod...dev
   git diff --name-status prod...dev
   ```

2. Also inspect unstaged, staged, and untracked local changes:

   ```bash
   git diff --stat
   git diff --cached --stat
   git status --short
   ```

3. Read changed files selectively to understand user-facing behavior, configuration, installation, APIs, CLI commands, migrations, dependency changes, tests, and bug fixes.
4. 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:

1. Existing `CHANGELOG.md`, `Changelog.md`, or equivalent repository changelog.
2. Existing release notes file named by repository convention.
3. If no changelog exists, create `CHANGELOG.md` only 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:

```markdown
## 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`: relevant `make test`, `make lint`, `make check`, or `make build` targets.
- 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:

1. Re-run `git status --short --branch`.
2. Confirm still on `dev`.
3. Review the final diff:

   ```bash
   git diff
   git diff --cached
   ```

4. Stage all intended release changes:

   ```bash
   git add -A
   ```

5. Re-check staged content:

   ```bash
   git status --short
   git diff --cached --stat
   ```

6. Commit with a concise, meaningful message, for example:

   ```bash
   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:

```bash
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:

1. Ensure `dev` is clean:

   ```bash
   git status --short --branch
   ```

2. Switch to `prod`:

   ```bash
   git switch prod
   ```

3. Update `prod` from the remote:

   ```bash
   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`:

```bash
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.

1. Find the latest tag:

   ```bash
   git tag --list 'v[0-9]*' --sort=-v:refname
   ```

2. Inspect recent tags if needed:

   ```bash
   git describe --tags --abbrev=0
   git log --oneline --decorate --tags --max-count=20
   ```

3. Choose 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.

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:

```bash
git tag -a vX.Y.Z -m "Release vX.Y.Z"
```

Verify the tag points to the intended `prod` commit:

```bash
git show --stat vX.Y.Z
git status --short --branch
```

Push `prod` and the tag without force:

```bash
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:

```bash
gh release create vX.Y.Z --title "vX.Y.Z" --notes-file /tmp/release-notes-vX.Y.Z.md
```

Before running it:

1. Write a temporary notes file containing only the changelog points for `vX.Y.Z`.
2. Confirm `gh auth status` succeeds for the target GitHub host.
3. 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`:

```bash
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.

