-
Notifications
You must be signed in to change notification settings - Fork 0
196 lines (172 loc) · 6.07 KB
/
python-release.yml
File metadata and controls
196 lines (172 loc) · 6.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
name: Python Release to PyPI
on:
push:
tags:
- 'v*'
jobs:
build-release-wheels:
name: Build release wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
fail-fast: false
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- uses: PyO3/maturin-action@v1
with:
manylinux: auto
args: --release --out dist -i python${{ matrix.python-version }}
- name: Upload wheels
uses: actions/upload-artifact@v7
with:
name: release-wheels-${{ matrix.os }}-${{ matrix.python-version }}
path: dist
build-cross-linux-wheels:
name: Build cross-compiled ${{ matrix.target }} wheel (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
matrix:
target: [aarch64-unknown-linux-gnu, i686-unknown-linux-gnu]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
fail-fast: false
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
manylinux: auto
args: --release --out dist -i python${{ matrix.python-version }}
- name: Upload wheels
uses: actions/upload-artifact@v7
with:
name: release-wheels-${{ matrix.target }}-${{ matrix.python-version }}
path: dist
validate-cross-wheels:
name: Validate ${{ matrix.target }} wheel (Python ${{ matrix.python-version }})
needs: build-cross-linux-wheels
runs-on: ubuntu-latest
strategy:
matrix:
target: [aarch64-unknown-linux-gnu, i686-unknown-linux-gnu]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
fail-fast: false
steps:
- uses: actions/download-artifact@v8
with:
name: release-wheels-${{ matrix.target }}-${{ matrix.python-version }}
path: dist
- name: Validate wheel exists with correct platform tag
run: |
if [ "${{ matrix.target }}" = "aarch64-unknown-linux-gnu" ]; then
EXPECTED_TAG="aarch64"
elif [ "${{ matrix.target }}" = "i686-unknown-linux-gnu" ]; then
EXPECTED_TAG="i686"
fi
WHEEL=$(ls dist/*.whl 2>/dev/null | head -1)
if [ -z "$WHEEL" ]; then
echo "ERROR: No .whl file found in dist/"
ls -la dist/
exit 1
fi
echo "Found wheel: $WHEEL"
if echo "$WHEEL" | grep -q "$EXPECTED_TAG"; then
echo "OK: Wheel filename contains expected tag '$EXPECTED_TAG'"
else
echo "ERROR: Wheel filename does not contain expected tag '$EXPECTED_TAG'"
exit 1
fi
test-release-wheels:
name: Test release wheels on ${{ matrix.os }}
needs: build-release-wheels
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
fail-fast: false
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@v7
- uses: actions/download-artifact@v8
with:
name: release-wheels-${{ matrix.os }}-${{ matrix.python-version }}
path: dist
- name: Install wheel and test dependencies
shell: bash
run: |
uv pip install --system dist/mrrc-*.whl
uv pip install --system pytest pytest-benchmark mypy pyright
- name: Run pytest (core tests, excludes benchmarks)
run: |
pytest tests/python/ -m "not benchmark" -v
# Retry on macOS due to intermittent runner flakiness
if: runner.os != 'macOS'
- name: Run pytest with retry (macOS)
if: runner.os == 'macOS'
run: |
max_attempts=3
attempt=1
while [ $attempt -le $max_attempts ]; do
echo "Attempt $attempt of $max_attempts"
if pytest tests/python/ -m "not benchmark" -v; then
echo "Tests passed on attempt $attempt"
exit 0
fi
echo "Attempt $attempt failed, retrying..."
attempt=$((attempt + 1))
sleep 5
done
echo "All $max_attempts attempts failed"
exit 1
shell: bash
- name: Run type checking
run: |
mypy tests/python/ --strict || true
pyright tests/python/ || true
publish-pypi:
name: Publish to PyPI
needs: [test-release-wheels, validate-cross-wheels]
runs-on: ubuntu-latest
permissions:
id-token: write
contents: write
steps:
- uses: actions/download-artifact@v8
with:
pattern: release-wheels-*
path: dist
merge-multiple: true
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
- uses: actions/checkout@v6
with:
sparse-checkout: CHANGELOG.md
sparse-checkout-cone-mode: false
- name: Extract release notes from CHANGELOG
id: changelog
run: |
VERSION="${GITHUB_REF_NAME#v}"
# Extract the section for this version (between its header and the next ## header)
NOTES=$(awk "/^## \[${VERSION}\]/{found=1; next} /^## \[/{if(found) exit} found{print}" CHANGELOG.md)
# Write to file to avoid shell quoting issues
echo "$NOTES" > release_notes.md
- name: Create GitHub Release
uses: softprops/action-gh-release@v3
if: startsWith(github.ref, 'refs/tags/')
with:
files: dist/*
body_path: release_notes.md
draft: false
prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') }}