Skip to content

Commit 75a5550

Browse files
BoPengclaude
andcommitted
Add release workflow and update CI for Apple Silicon
- Add release.yml workflow for automated PyPI publishing - Add Apple Silicon (macos-14) to CI workflow - Split macOS builds into Intel (macos-13) and ARM (macos-14) - Add comprehensive DEVELOPMENT.md with release instructions Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 7574227 commit 75a5550

3 files changed

Lines changed: 374 additions & 11 deletions

File tree

.github/workflows/python-app.yml

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,46 @@ jobs:
5050
- name: Run tests (binary allele type)
5151
run: python ./test/run_tests.py binary -j2
5252

53-
build-macos:
54-
runs-on: macos-latest
53+
build-macos-intel:
54+
runs-on: macos-13
55+
timeout-minutes: 90
56+
strategy:
57+
fail-fast: false
58+
matrix:
59+
python-version: ["3.10", "3.11", "3.12"]
60+
61+
steps:
62+
- uses: actions/checkout@v4
63+
64+
- name: Set up Python ${{ matrix.python-version }}
65+
uses: actions/setup-python@v5
66+
with:
67+
python-version: ${{ matrix.python-version }}
68+
cache: 'pip'
69+
70+
- name: Install system dependencies
71+
run: |
72+
brew install swig libomp cmake ninja
73+
74+
- name: Install Python dependencies
75+
run: |
76+
python -m pip install --upgrade pip
77+
pip install build scikit-build-core cmake ninja
78+
pip install -r requirements.txt
79+
80+
- name: Build and install simuPOP
81+
env:
82+
OpenMP_ROOT: /usr/local/opt/libomp
83+
run: pip install -v .
84+
85+
- name: Run tests (short allele type)
86+
run: python ./test/run_tests.py short -j2
87+
88+
- name: Run tests (binary allele type)
89+
run: python ./test/run_tests.py binary -j2
90+
91+
build-macos-arm:
92+
runs-on: macos-14
5593
timeout-minutes: 90
5694
strategy:
5795
fail-fast: false
@@ -79,7 +117,6 @@ jobs:
79117
80118
- name: Build and install simuPOP
81119
env:
82-
# Help CMake find libomp on macOS
83120
OpenMP_ROOT: /opt/homebrew/opt/libomp
84121
run: pip install -v .
85122

.github/workflows/release.yml

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
# Release workflow: build wheels for all platforms and upload to PyPI
2+
#
3+
# Triggers:
4+
# - On GitHub release creation
5+
# - Manual dispatch (workflow_dispatch)
6+
#
7+
# To release:
8+
# 1. Update version in src/simuPOP/_version.py
9+
# 2. Create a GitHub release with a tag like "v1.1.18"
10+
# 3. This workflow will automatically build and upload to PyPI
11+
12+
name: Release to PyPI
13+
14+
on:
15+
release:
16+
types: [published]
17+
workflow_dispatch:
18+
inputs:
19+
upload_to_pypi:
20+
description: 'Upload to PyPI (true/false)'
21+
required: true
22+
default: 'false'
23+
type: choice
24+
options:
25+
- 'true'
26+
- 'false'
27+
28+
permissions:
29+
contents: read
30+
31+
jobs:
32+
# Build source distribution (only needs to run once)
33+
build-sdist:
34+
name: Build source distribution
35+
runs-on: ubuntu-latest
36+
steps:
37+
- uses: actions/checkout@v4
38+
39+
- name: Set up Python
40+
uses: actions/setup-python@v5
41+
with:
42+
python-version: "3.11"
43+
44+
- name: Install dependencies
45+
run: |
46+
python -m pip install --upgrade pip
47+
pip install build
48+
49+
- name: Build sdist
50+
run: python -m build --sdist
51+
52+
- name: Upload sdist artifact
53+
uses: actions/upload-artifact@v4
54+
with:
55+
name: sdist
56+
path: dist/*.tar.gz
57+
58+
# Build wheels on Linux
59+
build-wheels-linux:
60+
name: Build wheels on Linux
61+
runs-on: ubuntu-latest
62+
steps:
63+
- uses: actions/checkout@v4
64+
65+
- name: Set up Python
66+
uses: actions/setup-python@v5
67+
with:
68+
python-version: "3.11"
69+
70+
- name: Install cibuildwheel
71+
run: pip install cibuildwheel
72+
73+
- name: Build wheels
74+
run: cibuildwheel --output-dir wheelhouse
75+
env:
76+
CIBW_BUILD: "cp39-manylinux_x86_64 cp310-manylinux_x86_64 cp311-manylinux_x86_64 cp312-manylinux_x86_64 cp313-manylinux_x86_64"
77+
CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014
78+
CIBW_BEFORE_ALL_LINUX: yum install -y zlib-devel
79+
CIBW_BEFORE_BUILD: pip install scikit-build-core cmake ninja swig
80+
CIBW_TEST_COMMAND: python -c "import simuPOP; print(simuPOP.moduleInfo())"
81+
82+
- name: Upload wheels
83+
uses: actions/upload-artifact@v4
84+
with:
85+
name: wheels-linux
86+
path: wheelhouse/*.whl
87+
88+
# Build wheels on macOS (Intel)
89+
build-wheels-macos-intel:
90+
name: Build wheels on macOS (Intel)
91+
runs-on: macos-13
92+
steps:
93+
- uses: actions/checkout@v4
94+
95+
- name: Set up Python
96+
uses: actions/setup-python@v5
97+
with:
98+
python-version: "3.11"
99+
100+
- name: Install system dependencies
101+
run: brew install libomp
102+
103+
- name: Install cibuildwheel
104+
run: pip install cibuildwheel
105+
106+
- name: Build wheels
107+
run: cibuildwheel --output-dir wheelhouse
108+
env:
109+
CIBW_BUILD: "cp39-macosx_x86_64 cp310-macosx_x86_64 cp311-macosx_x86_64 cp312-macosx_x86_64 cp313-macosx_x86_64"
110+
CIBW_BEFORE_BUILD: pip install scikit-build-core cmake ninja swig
111+
CIBW_ENVIRONMENT: OpenMP_ROOT=/usr/local/opt/libomp
112+
CIBW_TEST_COMMAND: python -c "import simuPOP; print(simuPOP.moduleInfo())"
113+
114+
- name: Upload wheels
115+
uses: actions/upload-artifact@v4
116+
with:
117+
name: wheels-macos-intel
118+
path: wheelhouse/*.whl
119+
120+
# Build wheels on macOS (Apple Silicon)
121+
build-wheels-macos-arm:
122+
name: Build wheels on macOS (Apple Silicon)
123+
runs-on: macos-14
124+
steps:
125+
- uses: actions/checkout@v4
126+
127+
- name: Set up Python
128+
uses: actions/setup-python@v5
129+
with:
130+
python-version: "3.11"
131+
132+
- name: Install system dependencies
133+
run: brew install libomp
134+
135+
- name: Install cibuildwheel
136+
run: pip install cibuildwheel
137+
138+
- name: Build wheels
139+
run: cibuildwheel --output-dir wheelhouse
140+
env:
141+
CIBW_BUILD: "cp39-macosx_arm64 cp310-macosx_arm64 cp311-macosx_arm64 cp312-macosx_arm64 cp313-macosx_arm64"
142+
CIBW_BEFORE_BUILD: pip install scikit-build-core cmake ninja swig
143+
CIBW_ENVIRONMENT: OpenMP_ROOT=/opt/homebrew/opt/libomp
144+
CIBW_TEST_COMMAND: python -c "import simuPOP; print(simuPOP.moduleInfo())"
145+
146+
- name: Upload wheels
147+
uses: actions/upload-artifact@v4
148+
with:
149+
name: wheels-macos-arm
150+
path: wheelhouse/*.whl
151+
152+
# Build wheels on Windows
153+
build-wheels-windows:
154+
name: Build wheels on Windows
155+
runs-on: windows-latest
156+
steps:
157+
- uses: actions/checkout@v4
158+
159+
- name: Set up Python
160+
uses: actions/setup-python@v5
161+
with:
162+
python-version: "3.11"
163+
164+
- name: Install zlib via vcpkg
165+
run: vcpkg install zlib:x64-windows
166+
167+
- name: Install cibuildwheel
168+
run: pip install cibuildwheel
169+
170+
- name: Build wheels
171+
run: cibuildwheel --output-dir wheelhouse
172+
env:
173+
CIBW_BUILD: "cp39-win_amd64 cp310-win_amd64 cp311-win_amd64 cp312-win_amd64 cp313-win_amd64"
174+
CIBW_BEFORE_BUILD: pip install scikit-build-core cmake ninja swig
175+
CIBW_ENVIRONMENT: CMAKE_TOOLCHAIN_FILE="C:/vcpkg/scripts/buildsystems/vcpkg.cmake"
176+
CIBW_TEST_COMMAND: python -c "import simuPOP; print(simuPOP.moduleInfo())"
177+
178+
- name: Upload wheels
179+
uses: actions/upload-artifact@v4
180+
with:
181+
name: wheels-windows
182+
path: wheelhouse/*.whl
183+
184+
# Upload to PyPI
185+
upload-pypi:
186+
name: Upload to PyPI
187+
needs: [build-sdist, build-wheels-linux, build-wheels-macos-intel, build-wheels-macos-arm, build-wheels-windows]
188+
runs-on: ubuntu-latest
189+
# Only upload on release or manual trigger with upload_to_pypi=true
190+
if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.upload_to_pypi == 'true')
191+
192+
environment:
193+
name: pypi
194+
url: https://pypi.org/project/simuPOP/
195+
196+
permissions:
197+
id-token: write # Required for trusted publishing
198+
199+
steps:
200+
- name: Download all artifacts
201+
uses: actions/download-artifact@v4
202+
with:
203+
path: dist
204+
merge-multiple: true
205+
206+
- name: List distribution files
207+
run: ls -la dist/
208+
209+
- name: Publish to PyPI
210+
uses: pypa/gh-action-pypi-publish@release/v1
211+
with:
212+
packages-dir: dist/
213+
214+
# Optional: Upload to TestPyPI for testing
215+
upload-testpypi:
216+
name: Upload to TestPyPI
217+
needs: [build-sdist, build-wheels-linux, build-wheels-macos-intel, build-wheels-macos-arm, build-wheels-windows]
218+
runs-on: ubuntu-latest
219+
# Only on manual trigger with upload_to_pypi=false (for testing)
220+
if: github.event_name == 'workflow_dispatch' && github.event.inputs.upload_to_pypi == 'false'
221+
222+
environment:
223+
name: testpypi
224+
url: https://test.pypi.org/project/simuPOP/
225+
226+
permissions:
227+
id-token: write
228+
229+
steps:
230+
- name: Download all artifacts
231+
uses: actions/download-artifact@v4
232+
with:
233+
path: dist
234+
merge-multiple: true
235+
236+
- name: List distribution files
237+
run: ls -la dist/
238+
239+
- name: Publish to TestPyPI
240+
uses: pypa/gh-action-pypi-publish@release/v1
241+
with:
242+
repository-url: https://test.pypi.org/legacy/
243+
packages-dir: dist/

0 commit comments

Comments
 (0)