Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions .claude/commands/release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
name: "Release"
description: Run the full release workflow — changelog, version bump, tag, GitHub release
allowed-tools: Bash, Read, Edit
category: Workflow
tags: [release, workflow]
---

Execute the full release workflow. Follow every step in order; always confirm with the user before any irreversible action (tag push, GitHub release, PyPI publish).

---

## Step 1 — Pre-flight checks

Run all three checks before proceeding. If any fails, stop and tell the user what to fix.

```bash
git branch --show-current # must be "main"
git status --porcelain # must be empty (clean tree)
gh auth status # must show BastiTee as the active account
```

## Step 2 — Determine next version

```bash
grep '^version' pyproject.toml | head -1 # current version
git log $(git describe --tags --abbrev=0)..HEAD --oneline # commits since last tag
```

Show the user the current version and the commit list, then ask: **"What should the new version number be?"**

## Step 3 — Draft and confirm changelog entry

Extract PR numbers from merge commits and build a draft `## X.Y.Z` section:

```bash
git log $(git describe --tags --abbrev=0)..HEAD --oneline | grep "Merge pull request"
```

For each user-facing change, include a linked PR reference in the format `([#N](https://github.com/BastiTee/python-boilerplate/pull/N))`. Skip Dependabot and pure CI commits. Show the draft to the user and ask them to confirm or edit before writing anything.

## Step 4 — Update files

1. Prepend the confirmed changelog section to `CHANGELOG.md` — insert it right after the `# Changelog` title line, above all existing version sections.
2. Update `version = "..."` in `pyproject.toml` to the new version.
3. Show `git diff` and ask for confirmation before continuing.

## Step 5 — Build the release artifact

```bash
make release
```

This runs a clean build (tests, mypy, lint, format, package) and lists the built artifacts. It must succeed before committing. Fix any failures before continuing.

## Step 6 — Commit

```bash
git add CHANGELOG.md pyproject.toml uv.lock
git commit -m "Release X.Y.Z"
```

## Step 7 — Tag and push _(confirm before running — irreversible)_

```bash
git tag -a X.Y.Z -m "Version X.Y.Z"
git push && git push --tags
```

## Step 8 — Create GitHub release _(confirm before running — irreversible)_

The release title is `vX.Y.Z` (v-prefixed). The notes are a bare URL to the changelog section — the anchor is the version with dots stripped (e.g. `0.1.2` → `#012`).

```bash
gh release create X.Y.Z \
--title "vX.Y.Z" \
--notes "https://github.com/BastiTee/python-boilerplate/blob/main/CHANGELOG.md#XYZ"
```

Report the release as complete once Step 8 succeeds.
18 changes: 0 additions & 18 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,21 +175,3 @@ First release. Contains support for:
- vscode editor configuration including debugging support, unit test discovery and on-save formatting
- Dockerized builds and run with nginx/uwsgi
- Publishing to PyPi.org at <https://pypi.org/project/python3-boilerplate/>

## How to release a new version

- Implement all desired changes on branch
- Update this changelog
- Bump version number in `pyproject.toml`
- Finish development on branch and merge to main
- Run

```shell
VERSION=$( python -m uv version --short --color never ) &&\
echo "Release: ${VERSION}" &&\
git tag -a ${VERSION} -m "Version ${VERSION}" &&\
git push --tags
git push
```

- Create a new release under <https://github.com/BastiTee/python-boilerplate/releases>
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export LC_ALL = C
export LANG = C.UTF-8
PY_FILES := src tests

.PHONY: help all clean clear-cache venv build test mypy lint lint-fix format format-check outdated update run-venv install-run audit pre-commit
.PHONY: help all clean clear-cache venv build release test mypy lint lint-fix format format-check outdated update run-venv install-run audit pre-commit
.DEFAULT_GOAL := all

help: ## Show this help message
Expand Down Expand Up @@ -49,6 +49,9 @@ venv: clean ## Clean and recreate virtual environment
build: test mypy lint format ## Run the entire build chain
uv build

release: clean build ## Prepare release
ls -la dist

test: ## Run pytest test suite
uv run py.test tests

Expand Down
2 changes: 1 addition & 1 deletion rename_template.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@ EOF

# Clean up
find . -type f -iname "*.rename-bak" -exec rm -f {} \;
rm -rf $( basename $0 ) CHANGELOG.md CLAUDE.md .claude .github/workflows/main-build.yml
rm -rf $( basename $0 ) CHANGELOG.md CLAUDE.md .claude .github/CODEOWNERS .github/workflows/main-build.yml
Loading