Publishing PyMixEF

PyMixEF releases are designed to use PyPI Trusted Publishing from GitHub Actions. The workflow exchanges a short-lived OpenID Connect identity for publish permission; it does not use a stored PyPI password or API token.

Publishing a filename and version to PyPI is irreversible. Complete every prerequisite and obtain the intended maintainer approval before running the publishing workflow.

Repository configuration

The canonical source repository is kkusima/PyMixEF, the package is published as pymixef, and the public documentation is hosted on Read the Docs.

Before publishing a release, confirm that the project retains:

  1. Maintainer recovery and security-contact arrangements.

  2. A GitHub environment named pypi, configured with required reviewers. Apply branch or tag protection appropriate to the repository’s governance.

  3. A PyPI Trusted Publisher whose values exactly match:

    • PyPI project: pymixef

    • GitHub owner: kkusima

    • GitHub repository: PyMixEF

    • Workflow filename: publish.yml

    • Environment: pypi

The workflow grants id-token: write only to the publish job. It derives the release tag from the version in pyproject.toml, verifies every synchronized version field, builds the distributions, runs strict Twine metadata checks, creates or reuses the matching GitHub release, and transfers only verified artifacts to the OIDC-backed PyPI upload.

Official setup references:

Prepare a release

Start from a reviewed, clean checkout and an isolated Python environment.

  1. Update the version consistently in pyproject.toml, src/pymixef/_version.py, CITATION.cff, CHANGELOG.md, the native ABI, and the R package metadata. tests/test_release_consistency.py enforces the current set.

  2. Give the changelog an accurate release date and user-visible changes.

  3. If any tutorial cell source changed, run make notebooks-refresh, review all stored results in the notebook diff, and commit only intentional changes. Committed notebooks must have sequential execution counts, no error outputs, and a current source fingerprint.

  4. Run the full local checks:

    python -m pip install -e ".[dev,notebooks]"
    make test
    make lint
    make format-check
    make typecheck
    make notebooks
    make release-check
    

    make release-check executes the tutorial notebooks, python -m build, and python -m twine check --strict dist/*. Notebook validation first checks the committed results and then independently replays every tutorial in a clean Jupyter kernel without rewriting it. Inspect dist/ and confirm that the intended version has exactly one wheel and one source archive.

  5. Check the planned tag explicitly:

    python scripts/check_release_tag.py v0.1.1
    

    Replace v0.1.1 with v followed by the version in pyproject.toml.

  6. Review the wheel and source archive contents, install the wheel in a fresh environment, and run an import/CLI smoke test.

  7. Commit and push the release changes to main, then let required CI complete. Do not create a vX.Y.Z tag or GitHub release by hand; the publishing workflow owns both operations.

Publish

Open Actions → Publish to PyPI → Run workflow in GitHub and run .github/workflows/publish.yml from main. The workflow reads the package version from pyproject.toml, derives the corresponding vX.Y.Z tag, verifies that all release metadata agrees, and creates or reuses the matching GitHub release before publishing through PyPI Trusted Publishing.

Do not create the tag or GitHub release manually. A hand-created reference can point at code whose package metadata still names another version and will cause the release guard to fail. The manual action run from reviewed main is the single supported publishing entry point; there is no token-based fallback.

The pypi environment approval is the final human authorization boundary. Review the tag, version, changelog, and build-job output before approving it. Approving the environment allows the verified wheel and source archive to be uploaded to PyPI.

Verify a release

After the workflow succeeds:

  1. Confirm the PyPI release shows both expected distribution files and provenance attestations.

  2. In a fresh environment, run:

    python -m pip install --no-cache-dir "pymixef==X.Y.Z"
    python -c "import pymixef; print(pymixef.__version__)"
    pymixef --help
    
  3. Confirm the installed version matches the release and retain the workflow, artifact, and validation references required by the project governance.

If any check fails before upload, fix the release commit on main, let CI pass, and run the publishing workflow again. Do not repair the release by creating or moving tags manually. Never reuse an already-published version or overwrite a published distribution filename.