Live PyPI + CI badges; token-based release workflow with skip-existing #5
Workflow file for this run
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
| name: CI & Publish | |
| # Runs tests on every push/PR. Publishes to PyPI when a version tag | |
| # (v1.0.1, v1.0.2, ...) is pushed, using the PYPI_API_TOKEN repo | |
| # secret. `skip-existing` makes re-runs safe (an already-published | |
| # version is skipped, not failed). | |
| # | |
| # To cut a release: bump the version in pyproject.toml, then | |
| # git tag v1.0.1 && git push origin v1.0.1 | |
| # | |
| # (Prefer PyPI Trusted Publishing instead of a stored token? Configure | |
| # a publisher on pypi.org for workflow.yml + environment "pypi", then | |
| # swap the publish step's `password` for `id-token: write` permissions.) | |
| on: | |
| push: | |
| branches: [main, master] | |
| tags: ["v*"] | |
| pull_request: | |
| branches: [main, master] | |
| jobs: | |
| test: | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, windows-latest, macos-latest] | |
| python-version: ["3.11", "3.12"] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Install (core + dev) | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev]" | |
| - name: Run tests | |
| run: pytest -q | |
| build: | |
| needs: test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Build sdist + wheel | |
| run: | | |
| python -m pip install --upgrade pip build | |
| python -m build | |
| - name: Check metadata | |
| run: | | |
| pip install twine | |
| twine check dist/* | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: dist | |
| path: dist/ | |
| publish: | |
| # Only on a version tag, only after tests + build pass. | |
| needs: build | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| runs-on: ubuntu-latest | |
| environment: pypi | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: dist | |
| path: dist/ | |
| - name: Publish to PyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| password: ${{ secrets.PYPI_API_TOKEN }} | |
| skip-existing: true |