One command, like npm version. Bumps every version field, commits, and tags.
scripts/release.py patch # 1.1.0 -> 1.1.1
scripts/release.py minor # 1.1.0 -> 1.2.0
scripts/release.py major # 1.1.0 -> 2.0.0
scripts/release.py 2.0.0 # explicit version
git push --follow-tags # ship itThat's the whole repo-side flow. The push triggers .github/workflows/release.yml, which builds the .tar.gz + .zip artifacts and publishes a GitHub Release with auto-generated notes.
- Refuses to run if the working tree is dirty or you're not on
main(override with--allow-dirty/--allow-any-branch). - Reads current version from
.claude-plugin/marketplace.json(canonical). - Bumps it according to
major | minor | patch | X.Y.Z. - Updates the version in:
b2-cloud-storage/SKILL.md— frontmattermetadata.version.claude-plugin/marketplace.json—metadata.versionAND everyplugins[].version
git addthose two files.git commit -m "chore: release vX.Y.Z".git tag -a vX.Y.Z -m "Release vX.Y.Z".
It does not push. You push.
| Flag | Effect |
|---|---|
--dry-run |
Print the bump; do not modify files or git. |
--no-tag |
Bump + commit, but skip the tag. |
--no-commit |
Update files only; do git add / commit / tag yourself. |
--no-changelog |
Bump + commit + tag, but skip CHANGELOG rotation. |
--allow-dirty |
Skip the clean-tree check. |
--allow-any-branch |
Skip the main/master branch check. |
pre-commit run --all-files # all hooks green
python -m pytest tests/ -v # 9/9 pass
# Optionally, full Python matrix:
for v in 3.10 3.11 3.12 3.13 3.14; do
uv run --python $v --no-project --with pytest --with pyyaml pytest tests/ -v
doneCHANGELOG.md follows Keep a Changelog. The release script rotates it for you: the body of ## [Unreleased] is moved into a new ## [X.Y.Z] - YYYY-MM-DD section, the [Unreleased] heading is reset to empty, and the link references at the bottom are repointed ([Unreleased]: ...compare/vX.Y.Z...HEAD) with a new [X.Y.Z]: ...compare/v<previous>...vX.Y.Z line inserted.
Your job: keep ## [Unreleased] populated as you merge PRs. The release script bundles whatever's there into the version section.
Skip rotation: pass --no-changelog (e.g. for a hotfix where the changelog entry was prepared manually).
The GitHub Release body is built by release.yml from auto-generated PR titles; the curated CHANGELOG.md entries are the canonical record in-repo.
-
GitHub Release fires automatically from the tag (see
.github/workflows/release.yml).- Artifacts:
b2-cloud-storage-vX.Y.Z.tar.gz,b2-cloud-storage-vX.Y.Z.zip - Release notes: auto-generated from merged-PR titles since the previous tag.
- Artifacts:
-
Directories that auto-update from GitHub (no action needed; sync within ~24h):
- SkillsMP
- Claude Marketplaces
- SkillsLLM
- ClaudeSkills.info
- LobeHub Skills
- Pawgrammer Claude Skills Market
- Agent Skills Market
-
One directory needs a manual re-publish — SkillHub uses CLI-uploaded snapshots, not GitHub:
cd b2-cloud-storage npx @skill-hub/cli publish -
Awesome Claude Skills — no version field in the awesome list. No re-PR needed unless the description changes meaningfully.
| Where | What to check |
|---|---|
https://github.com/backblaze-labs/claude-skill-b2-cloud-storage/releases/tag/vX.Y.Z |
Release exists, artifacts attached, notes populated |
skillsmp.com search "b2 cloud storage" |
Listing reflects new description / version |
claudemarketplaces.com search "backblaze" |
Plugin entry version matches |
| SkillHub CLI output | publish printed the new live URL |
| LobeHub / Pawgrammer / Agent Skills Market listing pages | Version (from SKILL.md frontmatter) matches |
git tag -d vX.Y.Z # delete locally
git push origin :refs/tags/vX.Y.Z # delete on remote
gh release delete vX.Y.Z --yes # delete the GitHub Release
git revert HEAD # revert the bump commitIf a directory has already pulled the bad version, ship vX.Y.Z+1 immediately rather than trying to retract — most crawlers cache and a yanked version is harder to undo than overwrite.
| Field | Who reads it |
|---|---|
SKILL.md metadata.version |
Some directory crawlers (LobeHub, Agent Skills Market) and Claude Code's skill loader. |
marketplace.json metadata.version |
claudemarketplaces.com (the marketplace as a whole). |
marketplace.json plugins[].version |
Claude Code's /plugin marketplace add and any tooling that consumes the per-plugin spec. |
The script keeps them in lock-step so you never have to think about which one a given consumer reads.