1+ name : publish
2+
3+ on :
4+ push :
5+ tags :
6+ - ' v*'
7+ workflow_dispatch :
8+ inputs :
9+ os :
10+ description : " Limit to one OS (ubuntu-latest|macos-13|macos-15|windows-latest)"
11+ required : false
12+ default : " "
13+ arch :
14+ description : " Limit to one arch (x86_64|aarch64|arm64|x64)"
15+ required : false
16+ default : " "
17+ py :
18+ description : " Limit to one Python (e.g. 3.12 or 3.13t)"
19+ required : false
20+ default : " "
21+
22+ permissions :
23+ contents : read
24+ id-token : write
25+
26+ env :
27+ CARGO_INCREMENTAL : 0
28+ CARGO_NET_RETRY : 10
29+ RUSTUP_MAX_RETRIES : 10
30+
31+ jobs :
32+ sdist :
33+ runs-on : ubuntu-latest
34+ steps :
35+ - uses : actions/checkout@v4
36+ - uses : actions/setup-python@v5
37+ with : { python-version: '3.12' }
38+ - uses : astral-sh/setup-uv@v6
39+ - name : Build sdist
40+ run : |
41+ cd py-radiate
42+ uvx maturin sdist -o target-sdist
43+ - uses : actions/upload-artifact@v4
44+ with :
45+ name : sdist
46+ path : py-radiate/target-sdist/*.tar.gz
47+
48+ wheels :
49+ continue-on-error : true
50+ name : >-
51+ ${{ matrix.os }} • ${{ matrix.arch }} •
52+ ${{ contains(matrix.py, 't') && 'nogil' || 'gil' }}
53+ runs-on : ${{ matrix.os }}
54+ strategy :
55+ fail-fast : false
56+ matrix :
57+ include :
58+ # Linux
59+ - { os: ubuntu-latest, arch: x86_64, py: '3.12' }
60+ - { os: ubuntu-latest, arch: aarch64, py: '3.12', target: aarch64-unknown-linux-gnu }
61+ - { os: ubuntu-latest, arch: x86_64, py: '3.13t' }
62+ - { os: ubuntu-latest, arch: aarch64, py: '3.13t', target: aarch64-unknown-linux-gnu }
63+
64+ # macOS
65+ - { os: macos-13, arch: x86_64, py: '3.12' }
66+ - { os: macos-15, arch: arm64, py: '3.12' }
67+ - { os: macos-13, arch: x86_64, py: '3.13t' }
68+ - { os: macos-15, arch: arm64, py: '3.13t' }
69+
70+ # Windows
71+ - { os: windows-latest, arch: x64, py: '3.12' }
72+ - { os: windows-latest, arch: x64, py: '3.13t' }
73+
74+ env :
75+ MATCH : ${{ github.event_name != 'workflow_dispatch' || (
76+ (inputs.os == '' || matrix.os == inputs.os) &&
77+ (inputs.arch == '' || matrix.arch == inputs.arch) &&
78+ (inputs.py == '' || matrix.py == inputs.py)
79+ ) }}
80+
81+ steps :
82+ - uses : actions/checkout@v4
83+ if : ${{ env.MATCH }}
84+
85+ - uses : dtolnay/rust-toolchain@stable
86+ if : ${{ env.MATCH }}
87+
88+ - uses : actions/setup-python@v5
89+ if : ${{ env.MATCH }}
90+ with : { python-version: '3.12' }
91+
92+ - uses : astral-sh/setup-uv@v6
93+ if : ${{ env.MATCH }}
94+
95+ - name : Ensure requested interpreter (best effort)
96+ if : ${{ env.MATCH }}
97+ shell : bash
98+ run : |
99+ set -e
100+ uv python install "${{ matrix.py }}" || true
101+ uv python list --only-installed
102+
103+ - name : Select interpreter and flags
104+ id : envsel
105+ if : ${{ env.MATCH }}
106+ shell : bash
107+ run : |
108+ set -e
109+
110+ PY_TAG="${{ matrix.py }}"
111+
112+ if [[ "$PY_TAG" == *t* ]]; then
113+ PY="$(uv python find "$PY_TAG" 2>/dev/null || true)"
114+ FLAGS=""
115+ else
116+ PY="$(which python)"
117+ FLAGS=""
118+ fi
119+
120+ if [[ -z "$PY" ]]; then
121+ echo "skip=1" >> $GITHUB_OUTPUT
122+ exit 0
123+ fi
124+
125+ echo "skip=0" >> $GITHUB_OUTPUT
126+ echo "py=$PY" >> $GITHUB_OUTPUT
127+ echo "flags=$FLAGS" >> $GITHUB_OUTPUT
128+
129+ - name : Build wheel (Linux)
130+ if : ${{ env.MATCH == 'true' && runner.os == 'Linux' && steps.envsel.outputs.skip == '0' }}
131+ uses : PyO3/maturin-action@v1
132+ env :
133+ PYO3_PYTHON : ${{ steps.envsel.outputs.py }}
134+ with :
135+ maturin-version : ' 1.9.4'
136+ command : build
137+ args : >
138+ --release
139+ -m py-radiate/Cargo.toml
140+ -o dist
141+ ${{ steps.envsel.outputs.flags }}
142+ ${{ matrix.target && format('--target {0}', matrix.target) || '' }}
143+ manylinux : auto
144+
145+ - name : Build wheel (macOS/Windows)
146+ if : ${{ env.MATCH == 'true' && runner.os != 'Linux' && steps.envsel.outputs.skip == '0' }}
147+ uses : PyO3/maturin-action@v1
148+ env :
149+ PYO3_PYTHON : ${{ steps.envsel.outputs.py }}
150+ with :
151+ maturin-version : ' 1.9.4'
152+ command : build
153+ args : >
154+ --release
155+ -m py-radiate/Cargo.toml
156+ -o dist
157+ ${{ steps.envsel.outputs.flags }}
158+
159+ - uses : actions/upload-artifact@v4
160+ if : always()
161+ with :
162+ name : wheels-${{ matrix.os }}-${{ matrix.arch }}-${{ contains(matrix.py, 't') && 'nogil' || 'gil' }}
163+ path : dist/*.whl
164+
165+ publish :
166+ needs : [ sdist, wheels ]
167+ runs-on : ubuntu-latest
168+ if : ${{ needs.sdist.result == 'success' && startsWith(github.ref, 'refs/tags/v') }}
169+ environment :
170+ name : publish_pypi
171+ steps :
172+ - uses : actions/download-artifact@v4
173+ with :
174+ path : dist
175+ merge-multiple : true
176+ - run : ls -R dist
177+ - name : Publish (Trusted Publisher)
178+ uses : pypa/gh-action-pypi-publish@release/v1
179+ with :
180+ verbose : true
181+ skip-existing : true
0 commit comments