Skip to content

Commit c00b69e

Browse files
author
FirstUnicorn
committed
feat: migrate PyPI publishing to GitHub Actions with trusted publishing
Replace manual PowerShell scripts with automated GitHub Actions workflows using OpenID Connect trusted publishing. Changes: - Add .github/workflows/publish-testpypi.yml for TestPyPI publishing - Add .github/workflows/publish-pypi.yml for production PyPI publishing - Remove scripts/publish-test.ps1 (outdated manual approach) - Remove scripts/publish-prod.ps1 (outdated manual approach) - Update README.md with new publishing workflow instructions - Use choice input type for manual confirmation (best practice) Benefits: - No API tokens required (OIDC trusted publishing) - Automated on release creation - Better security and audit trail - Dropdown confirmation prevents typos Made-with: Cursor
1 parent 02b6632 commit c00b69e

6 files changed

Lines changed: 1982 additions & 820 deletions

File tree

.github/workflows/publish-pypi.yml

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
name: Publish to PyPI
2+
3+
on:
4+
release:
5+
types: [published]
6+
workflow_dispatch:
7+
inputs:
8+
confirm:
9+
description: 'Confirm production PyPI publishing'
10+
required: true
11+
type: choice
12+
options:
13+
- 'No'
14+
- 'Yes'
15+
default: 'No'
16+
17+
jobs:
18+
build:
19+
name: Build distributions
20+
runs-on: ubuntu-latest
21+
if: github.event_name == 'release' || github.event.inputs.confirm == 'Yes'
22+
steps:
23+
- uses: actions/checkout@v4
24+
25+
- name: Set up Python
26+
uses: actions/setup-python@v5
27+
with:
28+
python-version: '3.10'
29+
30+
- name: Install build tools
31+
run: pip install --upgrade build
32+
33+
- name: Build all packages
34+
run: |
35+
for pkg_dir in packages/*/; do
36+
echo "Building $(basename $pkg_dir)..."
37+
cd "$pkg_dir"
38+
python -m build --wheel --sdist
39+
cd ../..
40+
done
41+
42+
- name: Collect distributions
43+
run: |
44+
mkdir -p dist-all
45+
find packages -name '*.whl' -o -name '*.tar.gz' | while read file; do
46+
cp "$file" dist-all/
47+
done
48+
49+
- name: Upload distributions
50+
uses: actions/upload-artifact@v4
51+
with:
52+
name: distributions
53+
path: dist-all/
54+
55+
publish-pypi:
56+
name: Publish to PyPI
57+
needs: build
58+
runs-on: ubuntu-latest
59+
environment: pypi
60+
permissions:
61+
id-token: write
62+
steps:
63+
- name: Download distributions
64+
uses: actions/download-artifact@v4
65+
with:
66+
name: distributions
67+
path: dist/
68+
69+
- name: Publish to PyPI
70+
uses: pypa/gh-action-pypi-publish@release/v1
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: Publish to TestPyPI
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
tags:
7+
- 'v*'
8+
9+
jobs:
10+
build:
11+
name: Build distributions
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Set up Python
17+
uses: actions/setup-python@v5
18+
with:
19+
python-version: '3.10'
20+
21+
- name: Install build tools
22+
run: pip install --upgrade build
23+
24+
- name: Build all packages
25+
run: |
26+
for pkg_dir in packages/*/; do
27+
echo "Building $(basename $pkg_dir)..."
28+
cd "$pkg_dir"
29+
python -m build --wheel --sdist
30+
cd ../..
31+
done
32+
33+
- name: Collect distributions
34+
run: |
35+
mkdir -p dist-all
36+
find packages -name '*.whl' -o -name '*.tar.gz' | while read file; do
37+
cp "$file" dist-all/
38+
done
39+
40+
- name: Upload distributions
41+
uses: actions/upload-artifact@v4
42+
with:
43+
name: distributions
44+
path: dist-all/
45+
46+
publish-testpypi:
47+
name: Publish to TestPyPI
48+
needs: build
49+
runs-on: ubuntu-latest
50+
environment: testpypi
51+
permissions:
52+
id-token: write
53+
steps:
54+
- name: Download distributions
55+
uses: actions/download-artifact@v4
56+
with:
57+
name: distributions
58+
path: dist/
59+
60+
- name: Publish to TestPyPI
61+
uses: pypa/gh-action-pypi-publish@release/v1
62+
with:
63+
repository-url: https://test.pypi.org/legacy/

0 commit comments

Comments
 (0)