一键导入
release
Use when preparing or publishing a new release of phx-filters — covers release notes, version bump, build, PyPI upload, and GitHub release creation
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when preparing or publishing a new release of phx-filters — covers release notes, version bump, build, PyPI upload, and GitHub release creation
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | release |
| description | Use when preparing or publishing a new release of phx-filters — covers release notes, version bump, build, PyPI upload, and GitHub release creation |
gh release list --limit 1 --json tagName --jq '.[0].tagName' # find last release tag
git log <last-tag>..HEAD --oneline # all commits since
For every merge commit, extract the PR number and fetch its description:
git log <last-tag>..HEAD --oneline --merges
gh pr view <number> --json title,body,labels
For every #<number> reference in commit messages, fetch the issue:
gh issue view <number> --json title,body,labels
Using the commit list, PR descriptions, and issue context, draft the release notes following the Writing Release Notes guide below. When a bullet relates to a GitHub issue, prefix it with [#number]. Run the nz-english skill on the draft, then present it to the developer for review and incorporate feedback before proceeding.
Based on the changes, recommend a semver bump:
Stop here. Get explicit confirmation of the release notes and version number before continuing.
developuv version <version>
This updates pyproject.toml and re-locks uv.lock in one step. Commit both files and push to develop.
gh pr create --base main --title "Release v<version>" --body-file release-<version>.md
Stop here. Wait for the user to confirm the PR is merged before continuing.
maingit checkout main && git pull
uv sync --group=dev
rm -f dist/*
uv build
Sync first — pulling main may have brought in dependency changes. Artefacts land in dist/.
git tag -a <version> -m "Release <version>"
git push origin <version>
<version> must match pyproject.toml.
a. Append checksums to the release notes file:
echo -e "\n# SHA256 Checksums" >> release-<version>.md
sha256sum dist/phx_filters-* >> release-<version>.md
b. GPG-sign the document and each build artefact:
GPG_KEY=$(git config user.email)
gpg --local-user "$GPG_KEY" --clearsign release-<version>.md # → release-<version>.md.asc
for f in dist/phx_filters-*; do gpg --local-user "$GPG_KEY" --detach-sign "$f"; done
# Creates dist/phx_filters-*.sig alongside each artefact
d. Build the release body — concatenate the notes and the signed copy:
<contents of release-<version>.md>
---
<contents of release-.md.asc>
```
Write this to `release-<version>-body.md`.
**e. Create the release and upload all artefacts:**
```bash
gh release create <version> dist/* \
--title "Filters v<version>" \
--notes-file release-<version>-body.md
```
`dist/*` picks up the `.whl`, `.tar.gz`, and `.sig` files.
### 11. Upload to PyPI
```bash
uv publish --username __token__
```
### 12. Clean up
```bash
rm release-<version>.md release-<version>.md.asc release-<version>-body.md
git checkout develop && git pull
```
### 13. Close related GitHub issues
For every issue referenced in the release notes, close it with a comment:
```bash
gh issue close <number> --comment "Implemented in [v<version>](https://github.com/todofixthis/filters/releases/tag/<version>)."
```
### 14. Rebase `develop` onto `main`
```bash
git rebase origin/main
git push
```
Because `develop` now contains all of `main`'s commits, the histories no longer diverge and a regular (non-force) push succeeds.
---
## Writing Release Notes
### Structure
```markdown
# Filters v<version>
<one-sentence summary of the release character>
> [!WARNING]
> **Breaking changes**
> - {what changed}
> - {migration instructions}
> - {error you'll see if you don't migrate}
## New features
## Enhancements
## Bug fixes
> [!NOTE]
> **Verifying release artefacts**
> 1. Import the signing key: `curl https://github.com/todofixthis.gpg | gpg --import`
> 2. Download the `.whl` or `.tar.gz` and its matching `.sig` file from the release assets
> 3. Verify: `gpg --verify phx_filters-<version>-py3-none-any.whl.sig phx_filters-<version>-py3-none-any.whl`
>
> Key fingerprint: `457997A2A506270F918D7BD1925CC6E316680401`
# SHA256 Checksums
```
Only include the `[!WARNING]` block if there are breaking changes. Omit any section that has no entries.
### Grouping related items
- **2–4 related bullets:** nest as a hierarchical sublist under the parent bullet
- **5+ related bullets:** promote to a `###` subheading within the section
### Content filter
**Always include**
- New capabilities developers can use
- Architectural decisions
- Behaviour changes
- Breaking changes
**Usually omit**
- Technical details of how something works internally
- Configuration consolidation (unless it changes developer-facing behaviour)
- Code organisation changes
- Dependency updates (include only if resolving a critical or high-severity vulnerability)
- Improvements to coding agent instructions
**Always omit**
- Formatting, linting, minor refactoring
- Test coverage updates
### Breaking changes alert
```markdown
> [!WARNING]
> **Breaking changes**
> - `SomeClass.old_method()` removed
> - Replace with `SomeClass.new_method()`
> - You'll know you need to migrate if you see: `AttributeError: 'SomeClass' object has no attribute 'old_method'`
```