release.sh: batch preflight, defer push-after-publish, modern build#322
Merged
release.sh: batch preflight, defer push-after-publish, modern build#322
Conversation
fa79141 to
d3416d6
Compare
Restructure release.sh into a preflight phase that collects all
environment, credential and repo-state problems and reports them
together, plus a release phase that publishes to PyPI and Docker Hub
before pushing the commit and signed tag to GitHub.
New preflight checks:
- Required binaries: docker, pass, gpg, python3
- Docker daemon reachable + docker buildx available
- GPG secret key present (required for git tag -s)
- pass entries 'community-tc/secret-values.yml' (with the
'tc-admin-release-pypi-password' line) and
'hub.docker.com/taskclusterbot' both exist
- Branch is explicitly 'main' (the prior SHA-only check passed on a
feature branch sitting at the same commit as main)
Reorder so 'git push' happens AFTER the PyPI upload and Docker Hub
push succeed. A publish failure now leaves the remote untouched,
making recovery a matter of 'git reset --hard HEAD~1 && git tag -d
v<version>' rather than chasing a half-released tag.
Switch the build from the deprecated 'setup.py sdist / bdist_wheel'
to the PEP-517 frontend ('python -m build'), and run 'twine check'
on the built distributions before uploading so common metadata
problems (bad README rendering, invalid classifiers, ...) are caught
locally.
Drop the '--real' / '-r' flag. It only redirected PyPI between the
test and real indexes; Docker Hub and GitHub were always published
to the real registries, so the flag did not provide a true dry-run
mode and was misleading. End-to-end test-PyPI verification can be
done with a manual one-liner outside the release script (documented
in RELEASING.md).
Add RELEASING.md documenting prerequisites, the workflow each phase
executes, how to verify a release before publishing, and how to
recover from a failed run.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
d3416d6 to
bc68c4c
Compare
matt-boris
approved these changes
Apr 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Restructures
release.shso that:git pushhappens AFTER PyPI and Docker Hub publishes succeed. A publish failure now leaves the remote untouched, making recovery a matter ofgit reset --hard HEAD~1 && git tag -d v<version>instead of having a half-released tag on GitHub.python -m build(PEP-517 frontend) instead of the deprecatedsetup.py sdist / bdist_wheel, withtwine checkrun on the built dists before upload to catch metadata problems (bad README rendering, invalid classifiers, etc.) locally.--realflag. It only redirected PyPI between test and real; Docker Hub and GitHub were always published to the real registries, so it wasn't a true dry-run. Documented an end-to-end test-PyPI one-liner inRELEASING.mdfor the rare case it's wanted.Companion
RELEASING.mddocuments prerequisites, the workflow, pre-publish verification, and the recovery procedure.New preflight checks
docker,pass,gpg,python3onPATHdocker buildxavailablegit tag -swould otherwise fail mid-scriptpassentries exist (community-tc/secret-values.ymlwithtc-admin-release-pypi-password:line, plushub.docker.com/taskclusterbot)mainmainExisting checks (working tree clean, local HEAD == remote main HEAD, version regex on both old and new, tag-doesn't-exist locally + remotely, not in a virtualenv, signed tag) all preserved.
Comparison and out-of-scope items
This came out of a comparison with json-e/release.sh. Items deliberately not included in this PR:
pass+ GPG key into a container, anddocker buildx --pushfrom inside Docker is awkward.Test plan
release.shandRELEASING.mdfor sanity🤖 Generated with Claude Code