1+ ` ` ` yaml
12name: Publish Python Package
23
3- # 1. Trigger the workflow when a new GitHub Release is published
4+ # Trigger on:
5+ # - pushes to any branch (we'll publish to TestPyPI for non-main branches and to PyPI for main)
6+ # - published GitHub Releases (keep existing behavior for canonical releases)
47on:
8+ push:
9+ branches: ["**"]
510 release:
611 types: [published]
712
13+ permissions:
14+ contents: read
15+ id-token: write
16+
817jobs:
918 build_sdist_and_wheel:
1019 name: Build distribution 📦
1120 runs-on: ubuntu-latest
21+ outputs:
22+ dist-path: ${{ steps.upload.outputs.artifact-path }}
1223 steps:
1324 - name: Checkout repository
1425 uses: actions/checkout@v4
@@ -18,70 +29,70 @@ jobs:
1829 with:
1930 python-version: "3.x"
2031
21- # Install the 'build' tool, which creates the distribution files
22- - name : Install build dependencies
23- run : python -m pip install build
32+ - name: Install build tooling
33+ run: python -m pip install --upgrade pip build
2434
25- # Create source and wheel distribution archives in the 'dist/' directory
2635 - name: Build distributions
27- run : python -m build
36+ run: python -m build --sdist --wheel
2837
29- # Store the built artifacts for the next jobs to download
3038 - name: Upload distribution artifacts
39+ id: upload
3140 uses: actions/upload-artifact@v4
3241 with:
3342 name: python-package-distributions
3443 path: dist/
3544
36- # --- PyPI Release Job (Secure, using OIDC) ---
37- pypi_publish :
38- name : Publish to PyPI
39- needs : [build_sdist_and_wheel] # Ensure the build job succeeds first
45+ # Publish from pushes to non-main branches -> TestPyPI
46+ publish_testpypi:
47+ name: Publish to TestPyPI (branches except main)
4048 runs-on: ubuntu-latest
41- # Only publish to PyPI for full releases (not pre-releases)
42- if : github.event.release.prerelease == false
43-
44- # 2. Use the environment name you configured in PyPI (Optional, but recommended)
45- environment : pypi
46-
47- # 3. CRITICAL: This is the mandatory permission for Trusted Publishers (OIDC)
49+ needs: build_sdist_and_wheel
50+ # Only run for pushes (not releases) and only for branches that are NOT main
51+ if: |
52+ github.event_name == 'push' &&
53+ startsWith(github.ref, 'refs/heads/') &&
54+ github.ref != 'refs/heads/main'
55+ environment: testpypi
4856 permissions:
49- id-token : write
50- contents : read # Required to read the repository contents
57+ id-token: write
58+ contents: read
5159
5260 steps:
53- - name : Download all the dists
61+ - name: Download dists
5462 uses: actions/download-artifact@v4
5563 with:
5664 name: python-package-distributions
5765 path: dist/
5866
59- # 4. The PyPA action handles the OIDC token exchange and Twine upload securely
60- - name : Publish package distributions to PyPI
67+ - name: Publish package distributions to TestPyPI
6168 uses: pypa/gh-action-pypi-publish@release/v1
62-
63- # --- TestPyPI Release Job (Optional, for pre-release testing) ---
64- testpypi_publish :
65- name : Publish to TestPyPI
66- needs : [build_sdist_and_wheel]
67- runs-on : ubuntu-latest
68-
69- # Use the environment name you configured in TestPyPI
70- environment : testpypi
69+ with:
70+ # repository-url directs upload to TestPyPI
71+ repository-url: https://test.pypi.org/legacy/
7172
73+ # Publish from pushes to main OR when a Release is published -> Production PyPI
74+ publish_pypi:
75+ name: Publish to PyPI (main branch or GitHub Release)
76+ runs-on: ubuntu-latest
77+ needs: build_sdist_and_wheel
78+ # Run when:
79+ # - push to main branch, or
80+ # - release published event (keeps existing release-based behavior)
81+ if: |
82+ (github.event_name == 'push' && github.ref == 'refs/heads/main') ||
83+ (github.event_name == 'release' && github.event.action == 'published')
84+ environment: pypi
7285 permissions:
7386 id-token: write
7487 contents: read
7588
7689 steps:
77- - name : Download all the dists
90+ - name: Download dists
7891 uses: actions/download-artifact@v4
7992 with:
8093 name: python-package-distributions
8194 path: dist/
82-
83- # The 'repository-url' is what makes this target TestPyPI
84- - name : Publish package distributions to TestPyPI
95+
96+ - name: Publish package distributions to PyPI
8597 uses: pypa/gh-action-pypi-publish@release/v1
86- with :
87- repository-url : https://test.pypi.org/legacy/
98+ ` ` `
0 commit comments