Skip to content

Releasing

magmacrunchmedia edited this page Aug 24, 2026 · 4 revisions

Releasing

texastoast publishes to PyPI from GitHub Actions using PyPI Trusted Publishing. There is no API token and no repository secret to rotate: GitHub mints a short-lived identity token for the workflow run, and PyPI verifies it came from this repository.

Cutting a release

  1. Update CHANGELOG.md — move the unreleased entries under the new version with today's date.

  2. Bump __version__ in texastoast/__init__.py. That is the single source of truth; pyproject.toml reads it via [tool.hatch.version], so there is nothing else to keep in sync.

  3. Commit, then tag and push:

    git tag v0.4.0
    git push origin main --tags

release.yml then verifies the tag matches __version__, builds the sdist and wheel, checks them with twine, publishes with skip-existing, and opens a GitHub Release with generated notes. A mismatched tag fails the run before anything is published.

Let CI go green on main before tagging. The release workflow does not run the test suite — it only checks that the artifacts build.

Checking locally first

python -m build
twine check dist/*

How Trusted Publishing is wired

Two things have to line up, and both are easy to get subtly wrong.

1. The workflow must request the OIDC token.

jobs:
  publish:
    permissions:
      contents: write
      id-token: write        # ← required; without it TP cannot work

This is the trap. Once a job declares a permissions: block, every permission not listed is set to none — so a block containing only contents: write silently leaves id-token at none, and the publish fails with no obvious explanation.

2. There must be no password: input.

- uses: pypa/gh-action-pypi-publish@release/v1
  with:
    skip-existing: true      # ← no password:

Passing password: at all disables Trusted Publishing — even if the secret it references does not exist, in which case the step falls back to an empty credential and fails. The action says so in the log:

The workflow was run with the 'attestations: true' input, but an explicit
password was also set, disabling Trusted Publishing.

texastoast shipped 0.1.0–0.3.0 on an API token and moved to Trusted Publishing in 0.4.0. The repository now holds no Actions secrets at all.

Verifying a release really used TP

Check the "Publish to PyPI" step's log for:

Generating and uploading digital attestations
Found and verified trusted root

and .publish.attestation files written next to the artifacts. Attestations are only produced under Trusted Publishing, so their presence is proof.

Do not read INFO username: __token__ as evidence of an API token — that line appears under Trusted Publishing too, where the "token" is the short-lived OIDC credential.

PyPI-side setup (one time)

A maintainer adds a GitHub publisher at https://pypi.org/manage/project/texastoast/settings/publishing/:

Field Value
Owner magmacrunchmedia
Repository texastoast
Workflow release.yml
Environment (leave blank)

The workflow name must match exactly. If it does not, the build succeeds and the publish step fails.

Versioning

texastoast follows semantic versioning. While it is 0.x, a minor bump may carry breaking changes — 0.2.0 changed the signature of Entity.move(), and 0.3.0 made DialogueBox and Menu frame-driven. Breaking changes get a migration page; see Migrating to 0.2.0.

0.4.0 was additive, deprecating Camera.follow() without dt; 0.5.0 turned that deprecation into an error — the one-release warning window is the pattern for future breaks.

Clone this wiki locally