name: kon-release-publish description: Tag, publish to PyPI, and create GitHub release for Kon with validation and rollback-safe steps
Kon Release + PyPI Publish
Use this skill when the user asks to cut a new Kon version, tag it, publish to PyPI, and/or create a GitHub release.
Inputs to confirm
- Target version (example:
0.2.1) - Base range for notes (usually previous tag, example:
v0.2.0..HEAD) - Whether to push
main - Whether to publish to PyPI now
- Whether to create GitHub release now
Versioning requirement
- Kon's update check only supports strict numeric
MAJOR.MINOR.PATCHversions such as0.2.7and0.3.0. - Do not cut releases with PyPI/PEP 440 prerelease or suffix forms like
0.3.0rc1,0.3.0b1,0.3.0.post1, or0.3.0.dev1unless the update-check logic is updated first. - Even though PyPI commonly allows those formats, Kon releases should continue following plain
X.Y.Zso update detection stays correct.
Files to bump
pyproject.toml→[project].versionsrc/kon/version.py→ fallbackVERSION = "..."uv.lock→ local package version block
Release workflow
Preflight
git status --short --branchmust be clean (or confirm with user)git tag --listandgit log --oneline <prev_tag>..HEADto summarize changes
Update CHANGELOG.md
- Replace the
## [Unreleased]section's- No changes yet.with a new versioned heading:## <version> - YYYY-MM-DD - Use
git log --oneline <prev_tag>..HEADto categorize changes into### Added,### Changed,### Fixedsections - Credit external contributors with
- @username - Commit message:
docs: update changelog for <version>
- Replace the
Version bump
- Update version in all 3 files above
Quality gates
uv run ruff format .uv run ruff check .uv run pyright .uv run pytest
Commit
- Commit message:
build: bump version to <version>
- Commit message:
Tag
- Annotated tag:
git tag -a v<version> -m "v<version> ..." - Include concise "changes since previous tag" bullets
- Annotated tag:
Push
git push origin maingit push origin v<version>
Build + verify artifacts
rm -rf dist && uv builduv run python -m twine check dist/*
Publish to PyPI
- Prefer token file if present (example
~/.pypi-token): TWINE_USERNAME=__token__ TWINE_PASSWORD="$(< ~/.pypi-token)" uv run python -m twine upload dist/*- Verify:
https://pypi.org/project/kon-coding-agent/<version>/https://pypi.org/pypi/kon-coding-agent/jsonreports latest version
- Prefer token file if present (example
Create GitHub release
- If token exists at
~/.github-token, call Releases API: POST /repos/<owner>/<repo>/releaseswith:tag_name: v<version>target_commitish: mainname: v<version>generate_release_notes: true
- If 403 occurs, report missing token scopes/permissions (
contents:writerequired)
Important notes
- Tagging and GitHub release are separate:
- Tag = git ref in repository
- Release = GitHub object attached to a tag (notes/assets)
- You can do either independently, but most projects do both together for user-facing releases.
- If PyPI publish succeeds but GitHub release fails, do not retag/re-publish. Just fix auth and create the release for the existing tag.
Output checklist to report
- Changelog updated for
<version> - Version bumped in all files
- Checks passed
- Commit hash
- Tag created and pushed
- PyPI upload URL
- GitHub release URL (or exact error + remediation)