Skip to content

Add the PyPI release workflow (M-PYPI PYPI.6) - #35

Merged
NCCU-Schultz-Lab merged 1 commit into
mainfrom
pypi-release-workflow
Jul 31, 2026
Merged

Add the PyPI release workflow (M-PYPI PYPI.6)#35
NCCU-Schultz-Lab merged 1 commit into
mainfrom
pypi-release-workflow

Conversation

@NCCU-Schultz-Lab

Copy link
Copy Markdown
Collaborator

M-PYPI PYPI.6 — the workflow that will actually publish to PyPI.

Design

Three jobs, pypa/gh-action-pypi-publish + Trusted Publishing throughout (OIDC
— no PyPI/TestPyPI token stored anywhere in this repo):

  • build — builds the sdist + wheel once and shares them via
    upload-artifact, so TestPyPI and PyPI always publish the exact same
    bytes
    rather than two separate builds that could theoretically differ.
    twine check, then — the part worth reading closely — installs only the
    built wheel
    into a throwaway venv and imports it. That catches a packaging
    mistake (missing bundled data file, wrong package discovery, etc.) that an
    editable install (pip install -e .) would never surface, because editable
    installs bypass most of what actually goes into a wheel.
  • publish-testpypi — runs on every trigger, immediately before any
    production publish, so a broken build is caught on the sandbox index first.
    skip-existing: true because TestPyPI rejects re-uploading a version and a
    rehearsal run will often repeat one.
  • publish-pypi — gated if: github.event_name == 'release'. A manual
    rehearsal run has no code path to this job at all — that's a structural
    safeguard, not just the pypi environment's required-reviewer gate. No
    skip-existing here: PyPI's own rejection of a duplicate version should fail
    the job loudly, not be silently skipped.

Triggers

  • release: [published] — the real path (PYPI.7).
  • workflow_dispatch — run manually from the Actions tab to rehearse
    build + TestPyPI publish without touching PyPI or needing a throwaway tag.
    Replaces the roadmap's originally-sketched -rc tag convention; this is
    simpler and can't accidentally leak toward production because of the if
    above.

Already done (not in this diff — GitHub/PyPI web UI only)

  • Trusted Publishing registered on both indexes: a pending publisher on
    pypi.org (project doesn't exist there yet) and a normal publisher on
    test.pypi.org (it does — from the manual PYPI.4 TestPyPI upload). Both point
    at release.yml and their respective pypi / testpypi environment names.
  • Both GitHub Environments created; pypi has a required reviewer, so a tag
    push builds the release but a human approves the actual production publish.
  • The manual PYPI.4 upload token has been revoked — no PyPI credential exists
    outside PyPI/GitHub OIDC now.

Before the first real release

Rehearse via Actions → Release → Run workflow and confirm the TestPyPI job
goes green end to end. Only after that should PYPI.7 (cutting the actual
v0.5.0 GitHub Release) happen.

Testing

YAML validated (yaml.safe_load); pre-commit run clean. The workflow itself
can only be meaningfully tested by running it — see the rehearsal step above,
which should happen after merge, before tagging a release.

🤖 Generated with Claude Code

Three jobs, gh-action-pypi-publish + Trusted Publishing throughout (OIDC,
no stored PyPI token):

  - build: sdist + wheel, twine check, then installs ONLY the built wheel
    into a fresh venv and imports it — catches a packaging mistake that an
    editable install would hide. Built once and shared via upload-artifact
    so TestPyPI and PyPI publish the exact same bytes.
  - publish-testpypi: runs on every trigger, right before any production
    publish, so a bad build surfaces on the sandbox index first.
  - publish-pypi: gated with `if: github.event_name == 'release'`. A
    workflow_dispatch rehearsal run has no code path to this job at all —
    that's a structural safeguard, not just the `pypi` environment's
    required-reviewer gate.

workflow_dispatch replaces the originally-sketched `-rc` tag convention for
rehearsing against TestPyPI: trigger it manually from the Actions tab to
exercise build + TestPyPI publish without touching production PyPI or
needing a throwaway tag.

Trusted Publishing already registered on both indexes (PYPI.5): pending
publisher on pypi.org (project doesn't exist there yet), normal publisher
on test.pypi.org (it does, from the manual PYPI.4 upload). Both point at
this workflow file and their respective `pypi` / `testpypi` GitHub
Environments.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@NCCU-Schultz-Lab
NCCU-Schultz-Lab merged commit c294c90 into main Jul 31, 2026
5 checks passed
@NCCU-Schultz-Lab
NCCU-Schultz-Lab deleted the pypi-release-workflow branch July 31, 2026 18:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant