Claude-skill-registry-data make-release
Use when ready to publish a new version. Triggers on "release", "publish", "ship it", or version bump requests. Runs quality checks, bumps version, tags, and creates GitHub release.
git clone https://github.com/majiayu000/claude-skill-registry-data
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry-data "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/make-release" ~/.claude/skills/majiayu000-claude-skill-registry-data-make-release && rm -rf "$T"
data/make-release/SKILL.mdRelease
Release workflow for publishing a new version to PyPI via GitHub Actions.
When to Use
- After feature work is complete and committed
- When asked to release, publish, or ship a new version
- When bumping to a new version number
Prerequisites
Before releasing:
- All work committed (clean working tree)
- On
branchmain
passed/code-review
completed (CHANGELOG updated)/commit-work
Workflow
┌─────────────────────────┐ │ 1. Ask for version │ │ Patch/Minor/Major? │ └───────────┬─────────────┘ │ ▼ ┌─────────────────────────┐ │ 2. Verify clean state │ │ git status │ └───────────┬─────────────┘ │ ▼ ┌───────────┐ │ Clean? │───No──→ STOP. Commit or stash first. └─────┬─────┘ │Yes ▼ ┌─────────────────────────┐ │ 3. Run quality checks │ │ ruff → pytest │ └───────────┬─────────────┘ │ ▼ ┌───────────┐ │ All pass? │───No──→ STOP. Fix issues first. └─────┬─────┘ │Yes ▼ ┌─────────────────────────┐ │ 4. Bump version │ │ __init__.py + │ │ pyproject.toml │ └───────────┬─────────────┘ │ ▼ ┌─────────────────────────┐ │ 5. Update CHANGELOG │ │ [Unreleased] → [X.Y.Z] └───────────┬─────────────┘ │ ▼ ┌─────────────────────────┐ │ 6. Commit + Tag + Push │ │ (triggers workflow) │ └───────────┬─────────────┘ │ ▼ ┌─────────────────────────┐ │ 7. Verify release │ │ PyPI + GitHub release│ └─────────────────────────┘
Step 1: Ask for Version Number
Before doing anything else, ask the user which version number to release:
Use
AskUserQuestion with options:
- Patch (X.Y.Z+1): Bug fixes only
- Minor (X.Y+1.0): New features, backward compatible
- Major (X+1.0.0): Breaking changes
Or let them specify a custom version.
Step 2: Verify Clean State
scripts/verify_release_state.sh
Requirements:
- Working tree must be clean (no uncommitted changes)
- Must be on
branchmain
If not clean: Run
/commit first or stash changes.
Step 3: Run Quality Checks
scripts/run_release_checks.sh
All must pass. No exceptions - releases with failing tests are forbidden.
Step 4: Bump Version
Update version in both files:
uv run python scripts/bump_version.py X.Y.Z
Important: Both files must have the same version number.
Version format: Follow SemVer
- MAJOR: Breaking changes
- MINOR: New features (backward compatible)
- PATCH: Bug fixes
Step 5: Update CHANGELOG
In
CHANGELOG.md, convert the Unreleased section to a versioned release:
Before:
## [Unreleased] ### Added - New feature
After:
## [Unreleased] ## [X.Y.Z] - YYYY-MM-DD ### Added - New feature
Keep an empty
[Unreleased] section at the top for future changes.
Use the deterministic script to promote the changelog:
uv run python scripts/promote_changelog.py X.Y.Z
Step 6: Commit, Tag, and Push
git add agr/__init__.py pyproject.toml CHANGELOG.md git commit -m "$(cat <<'EOF' Release vX.Y.Z Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> EOF )" scripts/tag_and_push.sh X.Y.Z
Order matters: Push commit first, then tag. This ensures the commit exists on remote before the tag references it.
Important: The tag push triggers the publish workflow which:
- Runs quality checks
- Builds and publishes to PyPI
- Extracts release notes from CHANGELOG.md
- Creates GitHub release
Step 7: Verify Release
Watch the Workflow
The tag push triggers
.github/workflows/publish.yml which:
- Quality checks: Runs ruff + pytest
- Build: Creates wheel and sdist
- Publish: Uploads to PyPI via trusted publishing (OIDC)
- Release: Creates GitHub release from CHANGELOG.md
# Watch the workflow run to completion gh run watch --workflow=publish.yml
Verify Everything Succeeded
# Verify GitHub release was created gh release view vX.Y.Z # Verify PyPI publication (may take a few minutes) pip index versions agr
If Workflow Fails
| Failure Point | Result | Action |
|---|---|---|
| Quality checks | No PyPI, no release | Delete tag (), fix issue, re-release |
| PyPI publish | No release created | Fix PyPI config, delete tag (), re-release |
| Release creation | PyPI has package, no release | Create release manually (see below) |
Manual release creation (if only the release step failed):
VERSION="X.Y.Z" gh release create "v$VERSION" --title "v$VERSION" --notes-file <( echo "## What's New in v$VERSION" echo "" awk -v ver="$VERSION" '/^## \[/ { if (found) exit; if ($0 ~ "\\[" ver "\\]") found=1; next } found { print }' CHANGELOG.md echo "" echo "---" echo "" echo "**Full changelog**: https://github.com/kasperjunge/agent-resources/blob/main/CHANGELOG.md" ) ## Red Flags - STOP - Uncommitted changes → Commit first - Tests failing → Fix before release - Not on main branch → Switch to main - CHANGELOG not updated → Update it - Skipping quality checks → Never skip ## Common Mistakes | Mistake | Fix | |---------|-----| | Releasing with dirty working tree | Commit or stash first | | Skipping tests "we tested earlier" | Run tests immediately before release | | Forgetting to push the tag | Push tag separately after commit | | Not watching the workflow | Use `gh run watch` to verify full pipeline | | CHANGELOG not updated for version | Add version section before tagging | | Only updating `__init__.py` version | Update both `__init__.py` and `pyproject.toml` | ## No Exceptions - "We already tested it" → Run tests again now - "It's just a patch" → Full quality checks required - "Nobody reads release notes" → CHANGELOG is documentation. Use it. - "We're in a hurry" → Rushed releases cause incidents