Launch and monitor a SuperMarioBros-Nes-turbo PyPI release. Use when the user says /build-release, asks to cut a release, asks to tag/publish a version, asks whether a release made it to PyPI, or asks for macOS and Linux supermariobrosnes-turbo wheels.
Install
mkdir -p .claude/skills/build-release-tsilva && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/15456" && unzip -o skill.zip -d .claude/skills/build-release-tsilva && rm skill.zipInstalls to .claude/skills/build-release-tsilva
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Launch and monitor a SuperMarioBros-Nes-turbo PyPI release. Use when the user says /build-release, asks to cut a release, asks to tag/publish a version, asks whether a release made it to PyPI, or asks for macOS and Linux supermariobrosnes-turbo wheels.About this skill
Build Release
Use this skill to launch the repo-owned supermariobrosnes-turbo release flow
and monitor it until the package is visible on PyPI. The release implementation
lives in scripts/release.py and the Makefile release target. Prefer that
path over manually replaying version bumps, tags, wheel builds, validation, or
uploads.
This repo is not a fork, so versioning is owned here: use normal project
versions from pyproject.toml and Cargo.toml, not upstream-aligned .postN
versions unless the user explicitly asks for one.
make release runs uv sync --extra dev --group dev and then
scripts/release.py. The script enforces a clean tree, configured upstream,
synced remote state, unused PyPI version, version consistency, lock refresh,
local checks, release commit, tag creation, and atomic push. The pushed tag
triggers .github/workflows/release.yml, which builds/audits the macOS and
Linux wheels and publishes via PyPI trusted publishing.
Do not upload to PyPI manually unless the user explicitly asks for a manual recovery path after the GitHub Actions publish path fails. Never print or commit PyPI tokens. Do not create or switch branches unless the user explicitly asks.
Flow
- Launch the release command from the repo root:
make release
If the user explicitly requested a non-default bump or exact version, run the
script directly because the Make target does not pass arguments through. Choose
exactly one scripts/release.py invocation:
UV_CACHE_DIR=.uv-cache uv sync --extra dev --group dev
scripts/release.py --to <version>
UV_CACHE_DIR=.uv-cache uv sync --extra dev --group dev
scripts/release.py --part minor
UV_CACHE_DIR=.uv-cache uv sync --extra dev --group dev
scripts/release.py --part major
For "next version" or no version preference, use make release; it defaults to
the next patch version. If the user typed make releaes, treat it as a typo and
use the actual release target.
- Let the release script own the release gates.
Do not manually duplicate the old local wheel-building checklist. If
make release fails, report the failing stage and exact relevant error, then
stop. Common failures include a dirty worktree, unsynced upstream, an existing
PyPI version, formatting/test failures, tag collisions, or push failures.
- Capture the released tag and version.
The command should end with output like:
Released v<version>: pushed <branch> and tag to <remote>.
GitHub Actions will build and validate the release wheels from the pushed tag.
If needed, confirm the tag after the command succeeds:
git describe --tags --exact-match HEAD
- Monitor the GitHub Actions release workflow for the pushed tag.
Use gh if it is available:
release_sha="$(git rev-list -n 1 v<version>)"
gh run list --workflow release.yml --commit "$release_sha" --limit 5 \
--json databaseId,status,conclusion,event,headBranch,headSha,displayTitle,url
gh run watch <run-id> --exit-status
If the commit-filtered query does not find the run, list recent release runs and pick the run whose event/ref corresponds to the pushed tag:
gh run list --workflow release.yml --limit 10 \
--json databaseId,status,conclusion,event,headBranch,headSha,displayTitle,url
The workflow publishes only for tag-push events. workflow_dispatch builds are
validation builds and do not publish.
- After the workflow succeeds, poll PyPI until the released version appears.
python - <<'PY'
import json
import time
import urllib.request
package = "supermariobrosnes-turbo"
version = "<version>"
url = f"https://pypi.org/pypi/{package}/json"
for attempt in range(30):
with urllib.request.urlopen(url, timeout=20) as response:
data = json.load(response)
files = data.get("releases", {}).get(version, [])
if files:
print(f"https://pypi.org/project/{package}/{version}/")
print(f"https://pypi.org/project/{package}/")
for file in files:
print(file["filename"])
break
print(f"waiting for PyPI to show {package} {version} ({attempt + 1}/30)")
time.sleep(20)
else:
raise SystemExit(f"{package} {version} did not appear on PyPI yet")
PY
- If PyPI still does not show the version after a successful workflow, wait a little longer and retry before declaring failure. PyPI indexing can lag briefly. If the publish job failed, report the job URL and the failing step; do not try a manual Twine upload unless the user explicitly asks.
Useful Inspection Commands
gh run view <run-id> --web
gh run view <run-id> --log-failed
gh run view <run-id> --json url,status,conclusion,event,headBranch,headSha,displayTitle
The final PyPI package URLs are:
https://pypi.org/project/supermariobrosnes-turbo/<version>/
https://pypi.org/project/supermariobrosnes-turbo/
The GitHub Actions workflow environment URL is:
https://pypi.org/p/supermariobrosnes-turbo
Keep .codex/skills/build-release/scripts/release_build.py as the workflow's
release helper and for narrow diagnostics. Use it directly only when inspecting
versions, PyPI presence, or workflow build failures; do not re-create the
release locally unless the user asks for manual recovery.
Final Response
When the release reaches PyPI, lead with the PyPI version URL. Also report the tag, GitHub Actions run URL, workflow conclusion, and published wheel filenames. If the release did not reach PyPI, report the exact failed command/job/step and the next recovery action.