From 4baba2d8d067ece56377221bcebca196091d5ea7 Mon Sep 17 00:00:00 2001 From: BastiTee Date: Mon, 5 Oct 2026 08:53:56 +0200 Subject: [PATCH 1/6] feat: add release skill Adapts the knbn release workflow skill for this repo. The skill walks through changelog, version bump, build, tag, GitHub release, and PyPI publish in order, with confirmation gates before irreversible steps. Uses `make build` instead of `make release` (no release target exists here). Co-Authored-By: Claude Code --- .claude/commands/release.md | 88 +++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 .claude/commands/release.md diff --git a/.claude/commands/release.md b/.claude/commands/release.md new file mode 100644 index 0000000..0d74bfd --- /dev/null +++ b/.claude/commands/release.md @@ -0,0 +1,88 @@ +--- +name: "Release" +description: Run the full release workflow — changelog, version bump, tag, GitHub release, PyPI publish +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 build +``` + +This runs the full build chain (tests, mypy, lint, format, package) and 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 the version number. The notes are a single link 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 "X.Y.Z" \ + --notes "See [CHANGELOG](https://github.com/BastiTee/python-boilerplate/blob/main/CHANGELOG.md#XYZ)" +``` + +## Step 9 — Publish to PyPI _(manual — requires your credentials)_ + +Tell the user to run this themselves in the terminal: + +```bash +uv publish +``` + +Do not run this command yourself. Report the release as complete once the user confirms it succeeded. From 1a89201538e9ee0fa247faee1adf37e5ee1ec1ec Mon Sep 17 00:00:00 2001 From: BastiTee Date: Mon, 5 Oct 2026 08:55:13 +0200 Subject: [PATCH 2/6] chore: remove manual release instructions from CHANGELOG Superseded by the /release skill. Co-Authored-By: Claude Code --- CHANGELOG.md | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index deb2d57..ac68aab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 - -## 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 From f8484e482e14333d9e36509fef60d0d81d5602a3 Mon Sep 17 00:00:00 2001 From: BastiTee Date: Mon, 5 Oct 2026 08:56:28 +0200 Subject: [PATCH 3/6] fix: correct GitHub release format in release skill Title uses v-prefix (vX.Y.Z), notes are a bare URL to the CHANGELOG anchor (dots stripped), matching actual release history. Co-Authored-By: Claude Code --- .claude/commands/release.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.claude/commands/release.md b/.claude/commands/release.md index 0d74bfd..87c740a 100644 --- a/.claude/commands/release.md +++ b/.claude/commands/release.md @@ -69,12 +69,12 @@ git push && git push --tags ## Step 8 — Create GitHub release _(confirm before running — irreversible)_ -The release title is the version number. The notes are a single link to the changelog section — the anchor is the version with dots stripped (e.g. `0.1.2` → `#012`). +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 "X.Y.Z" \ - --notes "See [CHANGELOG](https://github.com/BastiTee/python-boilerplate/blob/main/CHANGELOG.md#XYZ)" + --title "vX.Y.Z" \ + --notes "https://github.com/BastiTee/python-boilerplate/blob/main/CHANGELOG.md#XYZ" ``` ## Step 9 — Publish to PyPI _(manual — requires your credentials)_ From 63208e9ea330107978eed5e3ab60dda22b17b33a Mon Sep 17 00:00:00 2001 From: BastiTee Date: Mon, 5 Oct 2026 08:57:36 +0200 Subject: [PATCH 4/6] feat: add make release target and update skill to use it Mirrors the knbn Makefile pattern: `release` depends on `clean build` and lists dist artifacts on success. Co-Authored-By: Claude Code --- .claude/commands/release.md | 4 ++-- Makefile | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.claude/commands/release.md b/.claude/commands/release.md index 87c740a..53253dc 100644 --- a/.claude/commands/release.md +++ b/.claude/commands/release.md @@ -48,10 +48,10 @@ For each user-facing change, include a linked PR reference in the format `([#N]( ## Step 5 — Build the release artifact ```bash -make build +make release ``` -This runs the full build chain (tests, mypy, lint, format, package) and must succeed before committing. Fix any failures before continuing. +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 diff --git a/Makefile b/Makefile index 66d651d..efdc5dd 100644 --- a/Makefile +++ b/Makefile @@ -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 @@ -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 From 3bb1e5e9e26064495bb86d25ceb6b00e8f144e28 Mon Sep 17 00:00:00 2001 From: BastiTee Date: Mon, 5 Oct 2026 08:58:20 +0200 Subject: [PATCH 5/6] chore: remove PyPI publish step from release skill This is a GitHub template repo, not a PyPI package. Co-Authored-By: Claude Code --- .claude/commands/release.md | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/.claude/commands/release.md b/.claude/commands/release.md index 53253dc..65f9c5f 100644 --- a/.claude/commands/release.md +++ b/.claude/commands/release.md @@ -1,6 +1,6 @@ --- name: "Release" -description: Run the full release workflow — changelog, version bump, tag, GitHub release, PyPI publish +description: Run the full release workflow — changelog, version bump, tag, GitHub release allowed-tools: Bash, Read, Edit category: Workflow tags: [release, workflow] @@ -77,12 +77,4 @@ gh release create X.Y.Z \ --notes "https://github.com/BastiTee/python-boilerplate/blob/main/CHANGELOG.md#XYZ" ``` -## Step 9 — Publish to PyPI _(manual — requires your credentials)_ - -Tell the user to run this themselves in the terminal: - -```bash -uv publish -``` - -Do not run this command yourself. Report the release as complete once the user confirms it succeeded. +Report the release as complete once Step 8 succeeds. From 50e01e83f5bc4f1a67da2360b42e7255c57ee789 Mon Sep 17 00:00:00 2001 From: BastiTee Date: Mon, 5 Oct 2026 09:00:06 +0200 Subject: [PATCH 6/6] chore: remove CODEOWNERS when running rename_template.sh Co-Authored-By: Claude Code --- rename_template.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rename_template.sh b/rename_template.sh index 0f607b5..b6818a3 100755 --- a/rename_template.sh +++ b/rename_template.sh @@ -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