Skip to content

Commit b71b23f

Browse files
committed
CI: add wheels.yml, unmodified from the main repo at commit e740470a9
1 parent bd918f9 commit b71b23f

File tree

1 file changed

+308
-0
lines changed

1 file changed

+308
-0
lines changed

.github/workflows/wheels.yml

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
# Workflow to build and test wheels.
2+
# To work on the wheel building infrastructure on a fork, comment out:
3+
#
4+
# if: github.repository == 'numpy/numpy'
5+
#
6+
# in the get_commit_message job. Be sure to include [wheel build] in your commit
7+
# message to trigger the build. All files related to wheel building are located
8+
# at tools/wheels/
9+
# Alternatively, you can add labels to the pull request in order to trigger wheel
10+
# builds.
11+
# The labels that trigger builds are:
12+
# 36 - Build(for changes to the building process,
13+
# 14 - Release(ensure wheels build before release)
14+
name: Wheel builder
15+
16+
on:
17+
schedule:
18+
# ┌───────────── minute (0 - 59)
19+
# │ ┌───────────── hour (0 - 23)
20+
# │ │ ┌───────────── day of the month (1 - 31)
21+
# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
22+
# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
23+
# │ │ │ │ │
24+
- cron: "42 2 * * SUN,WED"
25+
pull_request:
26+
branches:
27+
- main
28+
- maintenance/**
29+
push:
30+
tags:
31+
- v*
32+
workflow_dispatch:
33+
34+
concurrency:
35+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
36+
cancel-in-progress: true
37+
38+
permissions:
39+
contents: read # to fetch code (actions/checkout)
40+
41+
jobs:
42+
get_commit_message:
43+
name: Get commit message
44+
runs-on: ubuntu-latest
45+
# Only workflow_dispatch is enabled on forks.
46+
# To enable this job and subsequent jobs on a fork for other events, comment out:
47+
if: github.repository == 'numpy/numpy' || github.event_name == 'workflow_dispatch'
48+
outputs:
49+
message: ${{ steps.commit_message.outputs.message }}
50+
steps:
51+
- name: Checkout numpy
52+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
53+
# Gets the correct commit message for pull request
54+
with:
55+
ref: ${{ github.event.pull_request.head.sha }}
56+
persist-credentials: false
57+
- name: Get commit message
58+
id: commit_message
59+
env:
60+
HEAD: ${{ github.ref }}
61+
run: |
62+
set -xe
63+
COMMIT_MSG=$(git log --no-merges -1 --oneline)
64+
echo "message=$COMMIT_MSG" >> $GITHUB_OUTPUT
65+
echo github.ref "$HEAD"
66+
67+
build_wheels:
68+
name: Build wheel ${{ matrix.python }}-${{ matrix.buildplat[1] }}-${{ matrix.buildplat[2] }}
69+
needs: get_commit_message
70+
if: >-
71+
contains(needs.get_commit_message.outputs.message, '[wheel build]') ||
72+
github.event_name == 'schedule' ||
73+
github.event_name == 'workflow_dispatch' ||
74+
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && ( ! endsWith(github.ref, 'dev0')))
75+
runs-on: ${{ matrix.buildplat[0] }}
76+
strategy:
77+
# Ensure that a wheel builder finishes even if another fails
78+
fail-fast: false
79+
matrix:
80+
# Github Actions doesn't support pairing matrix values together, let's improvise
81+
# https://github.com/github/feedback/discussions/7835#discussioncomment-1769026
82+
buildplat:
83+
- [ubuntu-22.04, manylinux_x86_64, ""]
84+
- [ubuntu-22.04, musllinux_x86_64, ""]
85+
- [ubuntu-22.04-arm, manylinux_aarch64, ""]
86+
- [ubuntu-22.04-arm, musllinux_aarch64, ""]
87+
- [macos-13, macosx_x86_64, openblas]
88+
89+
# targeting macos >= 14. Could probably build on macos-14, but it would be a cross-compile
90+
- [macos-13, macosx_x86_64, accelerate]
91+
- [macos-14, macosx_arm64, accelerate] # always use accelerate
92+
- [windows-2022, win_amd64, ""]
93+
- [windows-2022, win32, ""]
94+
- [windows-11-arm, win_arm64, ""]
95+
python: ["cp311", "cp312", "cp313", "cp313t", "cp314", "cp314t", "pp311"]
96+
exclude:
97+
# Don't build PyPy 32-bit windows
98+
- buildplat: [windows-2022, win32, ""]
99+
python: "pp311"
100+
# Don't build PyPy arm64 windows
101+
- buildplat: [windows-11-arm, win_arm64, ""]
102+
python: "pp311"
103+
# No PyPy on musllinux images
104+
- buildplat: [ ubuntu-22.04, musllinux_x86_64, "" ]
105+
python: "pp311"
106+
- buildplat: [ ubuntu-22.04-arm, musllinux_aarch64, "" ]
107+
python: "pp311"
108+
- buildplat: [ macos13, macosx_x86_64, openblas ]
109+
python: "cp313t"
110+
- buildplat: [ macos13, macosx_x86_64, openblas ]
111+
python: "cp314t"
112+
113+
env:
114+
IS_32_BIT: ${{ matrix.buildplat[1] == 'win32' }}
115+
IS_PUSH: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }}
116+
IS_SCHEDULE_DISPATCH: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }}
117+
steps:
118+
- name: Checkout numpy
119+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
120+
with:
121+
submodules: true
122+
persist-credentials: false
123+
124+
- name: Setup MSVC (32-bit)
125+
if: ${{ matrix.buildplat[1] == 'win32' }}
126+
uses: bus1/cabuild/action/msdevshell@e22aba57d6e74891d059d66501b6b5aed8123c4d # v1
127+
with:
128+
architecture: 'x86'
129+
130+
- name: Setup LLVM for Windows ARM64
131+
if: ${{ matrix.buildplat[1] == 'win_arm64' }}
132+
uses: ./.github/windows_arm64_steps
133+
134+
- name: pkg-config-for-win
135+
run: |
136+
choco install -y --no-progress --stoponfirstfailure --checksum 6004DF17818F5A6DBF19CB335CC92702 pkgconfiglite
137+
$CIBW = "${{ github.workspace }}/.openblas"
138+
# pkgconfig needs a complete path, and not just "./openblas since the
139+
# build is run in a tmp dir (?)
140+
# It seems somewhere in the env passing, `\` is not
141+
# passed through, so convert it to '/'
142+
$CIBW = $CIBW.replace("\","/")
143+
echo "CIBW_ENVIRONMENT_WINDOWS=PKG_CONFIG_PATH=$CIBW" >> $env:GITHUB_ENV
144+
if: runner.os == 'windows'
145+
146+
# Used to push the built wheels
147+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
148+
with:
149+
python-version: "3.x"
150+
151+
- name: Setup macOS
152+
if: matrix.buildplat[0] == 'macos-13' || matrix.buildplat[0] == 'macos-14'
153+
run: |
154+
# Needed due to https://github.com/actions/runner-images/issues/3371
155+
# Supported versions: https://github.com/actions/runner-images/blob/main/images/macos/macos-14-arm64-Readme.md
156+
echo "FC=gfortran-13" >> "$GITHUB_ENV"
157+
echo "F77=gfortran-13" >> "$GITHUB_ENV"
158+
echo "F90=gfortran-13" >> "$GITHUB_ENV"
159+
if [[ ${{ matrix.buildplat[2] }} == 'accelerate' ]]; then
160+
# macosx_arm64 and macosx_x86_64 with accelerate
161+
# only target Sonoma onwards
162+
CIBW="MACOSX_DEPLOYMENT_TARGET=14.0 INSTALL_OPENBLAS=false RUNNER_OS=macOS"
163+
echo "CIBW_ENVIRONMENT_MACOS=$CIBW" >> "$GITHUB_ENV"
164+
165+
# the macos-13 image that's used for building the x86_64 wheel can't test
166+
# a wheel with deployment target >= 14 without further work
167+
echo "CIBW_TEST_SKIP=*-macosx_x86_64" >> "$GITHUB_ENV"
168+
else
169+
# macosx_x86_64 with OpenBLAS
170+
# if INSTALL_OPENBLAS isn't specified then scipy-openblas is automatically installed
171+
CIBW="RUNNER_OS=macOS"
172+
PKG_CONFIG_PATH="$PWD/.openblas"
173+
DYLD="$DYLD_LIBRARY_PATH:/$PWD/.openblas/lib"
174+
echo "CIBW_ENVIRONMENT_MACOS=$CIBW PKG_CONFIG_PATH=$PKG_CONFIG_PATH DYLD_LIBRARY_PATH=$DYLD" >> "$GITHUB_ENV"
175+
fi
176+
177+
- name: Build wheels
178+
uses: pypa/cibuildwheel@5f22145df44122af0f5a201f93cf0207171beca7 # v3.0.0
179+
env:
180+
CIBW_BUILD: ${{ matrix.python }}-${{ matrix.buildplat[1] }}
181+
182+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
183+
with:
184+
name: ${{ matrix.python }}-${{ matrix.buildplat[1] }}-${{ matrix.buildplat[2] }}
185+
path: ./wheelhouse/*.whl
186+
187+
- name: install micromamba
188+
uses: mamba-org/setup-micromamba@b09ef9b599704322748535812ca03efb2625677b
189+
if: ${{ matrix.buildplat[1] != 'win_arm64' }} # unsupported platform at the moment
190+
with:
191+
# for installation of anaconda-client, required for upload to
192+
# anaconda.org
193+
# Note that this step is *after* specific pythons have been used to
194+
# build and test the wheel
195+
# for installation of anaconda-client, for upload to anaconda.org
196+
# environment will be activated after creation, and in future bash steps
197+
init-shell: bash
198+
environment-name: upload-env
199+
create-args: >-
200+
anaconda-client
201+
202+
- name: win-arm64 install anaconda client
203+
if: ${{ matrix.buildplat[1] == 'win_arm64' }}
204+
run: |
205+
# Rust installation needed for rpds-py.
206+
Invoke-WebRequest https://static.rust-lang.org/rustup/dist/aarch64-pc-windows-msvc/rustup-init.exe -UseBasicParsing -Outfile rustup-init.exe
207+
.\rustup-init.exe -y
208+
$env:PATH="$env:PATH;$env:USERPROFILE\.cargo\bin"
209+
pip install anaconda-client
210+
211+
212+
- name: Upload wheels
213+
if: success() && github.repository == 'numpy/numpy'
214+
shell: bash -el {0}
215+
# see https://github.com/marketplace/actions/setup-miniconda for why
216+
# `-el {0}` is required.
217+
env:
218+
NUMPY_STAGING_UPLOAD_TOKEN: ${{ secrets.NUMPY_STAGING_UPLOAD_TOKEN }}
219+
NUMPY_NIGHTLY_UPLOAD_TOKEN: ${{ secrets.NUMPY_NIGHTLY_UPLOAD_TOKEN }}
220+
run: |
221+
source tools/wheels/upload_wheels.sh
222+
set_upload_vars
223+
# trigger an upload to
224+
# https://anaconda.org/scientific-python-nightly-wheels/numpy
225+
# for cron jobs or "Run workflow" (restricted to main branch).
226+
# Tags will upload to
227+
# https://anaconda.org/multibuild-wheels-staging/numpy
228+
# The tokens were originally generated at anaconda.org
229+
upload_wheels
230+
231+
build_sdist:
232+
name: Build sdist
233+
needs: get_commit_message
234+
if: >-
235+
contains(needs.get_commit_message.outputs.message, '[wheel build]') ||
236+
github.event_name == 'schedule' ||
237+
github.event_name == 'workflow_dispatch' ||
238+
(github.event_name == 'pull_request' &&
239+
(contains(github.event.pull_request.labels.*.name, '36 - Build') ||
240+
contains(github.event.pull_request.labels.*.name, '14 - Release'))) ||
241+
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && ( ! endsWith(github.ref, 'dev0')))
242+
runs-on: ubuntu-latest
243+
env:
244+
IS_PUSH: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }}
245+
# commented out so the sdist doesn't upload to nightly
246+
# IS_SCHEDULE_DISPATCH: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }}
247+
steps:
248+
- name: Checkout numpy
249+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
250+
with:
251+
submodules: true
252+
persist-credentials: false
253+
# Used to push the built wheels
254+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
255+
with:
256+
# Build sdist on lowest supported Python
257+
python-version: "3.11"
258+
- name: Build sdist
259+
run: |
260+
python -m pip install -U pip build
261+
python -m build --sdist -Csetup-args=-Dallow-noblas=true
262+
- name: Test the sdist
263+
run: |
264+
# TODO: Don't run test suite, and instead build wheels from sdist
265+
# Depends on pypa/cibuildwheel#1020
266+
python -m pip install dist/*.gz -Csetup-args=-Dallow-noblas=true
267+
pip install -r requirements/test_requirements.txt
268+
cd .. # Can't import numpy within numpy src directory
269+
python -c "import numpy, sys; print(numpy.__version__); sys.exit(numpy.test() is False)"
270+
271+
- name: Check README rendering for PyPI
272+
run: |
273+
python -mpip install twine
274+
twine check dist/*
275+
276+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
277+
with:
278+
name: sdist
279+
path: ./dist/*
280+
281+
- uses: conda-incubator/setup-miniconda@835234971496cad1653abb28a638a281cf32541f # v3.2.0
282+
with:
283+
# for installation of anaconda-client, required for upload to
284+
# anaconda.org
285+
# default (and activated) environment name is test
286+
# Note that this step is *after* specific pythons have been used to
287+
# build and test
288+
auto-update-conda: true
289+
python-version: "3.11"
290+
291+
- name: Upload sdist
292+
if: success() && github.repository == 'numpy/numpy'
293+
shell: bash -el {0}
294+
env:
295+
NUMPY_STAGING_UPLOAD_TOKEN: ${{ secrets.NUMPY_STAGING_UPLOAD_TOKEN }}
296+
# commented out so the sdist doesn't upload to nightly
297+
# NUMPY_NIGHTLY_UPLOAD_TOKEN: ${{ secrets.NUMPY_NIGHTLY_UPLOAD_TOKEN }}
298+
run: |
299+
conda install -y anaconda-client
300+
source tools/wheels/upload_wheels.sh
301+
set_upload_vars
302+
# trigger an upload to
303+
# https://anaconda.org/scientific-python-nightly-wheels/numpy
304+
# for cron jobs or "Run workflow" (restricted to main branch).
305+
# Tags will upload to
306+
# https://anaconda.org/multibuild-wheels-staging/numpy
307+
# The tokens were originally generated at anaconda.org
308+
upload_wheels

0 commit comments

Comments
 (0)