Skip to content

Harden release script so failed builds cannot continue to publish steps #90

@JoshSEdwards

Description

@JoshSEdwards

Problem

The current release script can continue after a failed artifact build. During the v0.9.10 release, python3 setup.py sdist bdist_wheel failed because the active Python environment was missing release/build tooling, but the script continued into signing, upload, and Git push steps.

That left the release in a partial state:

  • The version bump commit and tag were created.
  • No dist/ directory or artifacts were produced.
  • The script attempted to cd dist, failed, then signed files in the repo root instead.
  • twine upload dist/* failed because no artifacts existed.
  • The version commit and tag were pushed even though PyPI upload failed.

Proposed fix

Harden release.sh so failures stop the release before any later side effects happen.

Suggested changes:

  • Add strict shell behavior near the top of the script:
set -euo pipefail
  • Run preflight checks before bumpversion creates a commit/tag:
    • clean working tree
    • required Python version is available
    • setuptools, wheel, twine, and bumpversion are available
    • requested GPG key exists locally
  • Use module-based Python commands to avoid PATH mismatches:
python -m twine check dist/*
python -m twine upload dist/*
  • Add twine check dist/* before upload.
  • Ensure signing only happens inside an existing dist/ directory and only for regular files.
  • Push Git commit/tag only after artifact build, signing, metadata validation, and PyPI upload all succeed.
  • Consider pushing upstream explicitly instead of relying on the local branch tracking remote.

Optional improvement

Split the release into separate prepare and publish phases:

  • prepare: bump version, build artifacts, sign artifacts, run twine check
  • publish: upload to PyPI, then push Git commit/tag

This would provide an inspection point before irreversible publishing steps.

Acceptance criteria

  • A missing dependency or failed build exits before signing, uploading, or pushing Git changes.
  • A missing dist/ directory cannot cause repo-root files to be signed.
  • The script validates artifacts with twine check before upload.
  • The script uses a single known Python environment for build and upload commands.
  • Documentation lists all local release tooling needed for a successful release.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/enhancementA modification or enhancement to existing functionality

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions