1
- name : Test win_arm64 Wheel builder
1
+ # Workflow to build wheels for upload to PyPI.
2
+ # Inspired by numpy's cibuildwheel config https://github.com/numpy/numpy/blob/main/.github/workflows/wheels.yml
3
+ #
4
+ # In an attempt to save CI resources, wheel builds do
5
+ # not run on each push but only weekly and for releases.
6
+ # Wheel builds can be triggered from the Actions page
7
+ # (if you have the permissions) on a commit to main.
8
+ #
9
+ # Alternatively, you can add labels to the pull request in order to trigger wheel
10
+ # builds.
11
+ # The label(s) that trigger builds are:
12
+ # - Build
13
+ name : Wheel builder
2
14
3
15
on :
16
+ schedule :
17
+ # 3:27 UTC every day
18
+ - cron : " 27 3 * * *"
19
+ push :
20
+ pull_request :
21
+ types : [labeled, opened, synchronize, reopened]
22
+ paths-ignore :
23
+ - " doc/**"
24
+ - " web/**"
4
25
workflow_dispatch :
5
26
6
27
concurrency :
@@ -11,57 +32,183 @@ permissions:
11
32
contents : read
12
33
13
34
jobs :
35
+ build_sdist :
36
+ name : Build sdist
37
+ if : >-
38
+ (github.event_name == 'schedule') ||
39
+ github.event_name == 'workflow_dispatch' ||
40
+ (github.event_name == 'pull_request' &&
41
+ contains(github.event.pull_request.labels.*.name, 'Build')) ||
42
+ (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && ( ! endsWith(github.ref, 'dev0')))
43
+ runs-on : ubuntu-24.04
44
+ env :
45
+ IS_PUSH : ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }}
46
+ IS_SCHEDULE_DISPATCH : ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }}
47
+ outputs :
48
+ sdist_file : ${{ steps.save-path.outputs.sdist_name }}
49
+ steps :
50
+ - name : Checkout pandas
51
+ uses : actions/checkout@v4
52
+ with :
53
+ fetch-depth : 0
54
+
55
+ - name : Set up Python
56
+ uses : actions/setup-python@v5
57
+ with :
58
+ python-version : ' 3.11'
59
+
60
+ - name : Build sdist
61
+ run : |
62
+ python -m pip install build
63
+ python -m build --sdist
64
+
65
+ - uses : actions/upload-artifact@v4
66
+ with :
67
+ name : sdist
68
+ path : ./dist/*
69
+
70
+ - name : Sanity check sdist files
71
+ run : |
72
+ ls ./dist
73
+
74
+ - name : Output sdist name
75
+ id : save-path
76
+ shell : bash -el {0}
77
+ run : echo "sdist_name=$(ls ./dist)" >> "$GITHUB_OUTPUT"
78
+
14
79
build_wheels :
15
- name : Build wheel for cp312-win_arm64
16
- runs-on : windows-11-arm
80
+ needs : build_sdist
81
+ name : Build wheel for ${{ matrix.python[0] }}-${{ matrix.buildplat[1] }}
82
+ if : >-
83
+ (github.event_name == 'schedule') ||
84
+ github.event_name == 'workflow_dispatch' ||
85
+ (github.event_name == 'pull_request' &&
86
+ contains(github.event.pull_request.labels.*.name, 'Build')) ||
87
+ (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && ( ! endsWith(github.ref, 'dev0')))
88
+ runs-on : ${{ matrix.buildplat[0] }}
17
89
strategy :
18
90
fail-fast : false
19
91
matrix :
92
+ # GitHub Actions doesn't support pairing matrix values together, let's improvise
93
+ # https://github.com/github/feedback/discussions/7835#discussioncomment-1769026
20
94
buildplat :
21
- - [windows-11-arm, win_arm64]
22
- python : [["cp313", "3.13"]]
95
+ # - [ubuntu-24.04, manylinux_x86_64]
96
+ # - [ubuntu-24.04, musllinux_x86_64]
97
+ # - [ubuntu-24.04-arm, manylinux_aarch64]
98
+ # - [macos-13, macosx_x86_64]
99
+ # # Note: M1 images on Github Actions start from macOS 14
100
+ # - [macos-14, macosx_arm64]
101
+ # - [windows-2022, win_amd64]
102
+ - [windows-11-arm, win_arm64] # Test only this platform
103
+ # TODO: support PyPy?
104
+ python : [["cp310", "3.10"], ["cp311", "3.11"], ["cp312", "3.12"], ["cp313", "3.13"], ["cp313t", "3.13"]]
105
+ include :
106
+ # Build Pyodide wheels and upload them to Anaconda.org
107
+ # NOTE: this job is similar to the one in unit-tests.yml except for the fact
108
+ # that it uses cibuildwheel instead of a standard Pyodide xbuildenv setup.
109
+ - buildplat : [ubuntu-24.04, pyodide_wasm32]
110
+ python : ["cp312", "3.12"]
111
+ cibw_build_frontend : ' build'
112
+ exclude :
113
+ - buildplat : [windows-11-arm, win_arm64]
114
+ python : ["cp310", "3.10"]
23
115
116
+ env :
117
+ IS_PUSH : ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }}
118
+ IS_SCHEDULE_DISPATCH : ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }}
24
119
steps :
25
120
- name : Checkout pandas
26
121
uses : actions/checkout@v4
27
122
with :
28
123
fetch-depth : 0
29
124
30
- - name : Set up MSVC environment
125
+ - name : Set up MSVC environment for ARM64
126
+ if : matrix.buildplat[1] == 'win_arm64'
31
127
uses : ilammy/msvc-dev-cmd@v1
32
128
with :
33
129
arch : arm64
34
130
131
+ # TODO: Build wheels from sdist again
132
+ # There's some sort of weird race condition?
133
+ # within Github that makes the sdist be missing files
134
+
135
+ # We need to build wheels from the sdist since the sdist
136
+ # removes unnecessary files from the release
137
+ - name : Download sdist (not macOS)
138
+ # if: ${{ matrix.buildplat[1] != 'macosx_*' }}
139
+ uses : actions/download-artifact@v4
140
+ with :
141
+ name : sdist
142
+ path : ./dist
143
+
144
+ - name : Output sdist name (macOS)
145
+ id : save-path
146
+ shell : bash -el {0}
147
+ run : echo "sdist_name=$(ls ./dist)" >> "$GITHUB_ENV"
148
+
149
+ # Python version used to build sdist doesn't matter
150
+ # wheel will be built from sdist with the correct version
151
+ - name : Unzip sdist (macOS)
152
+ if : ${{ startsWith(matrix.buildplat[1], 'macosx') }}
153
+ run : |
154
+ tar -xzf ./dist/${{ env.sdist_name }} -C ./dist
155
+
156
+ - name : Output sdist name (macOS)
157
+ id : save-path2
158
+ shell : bash -el {0}
159
+ run : echo "sdist_name=$(cd ./dist && ls -d */)" >> "$GITHUB_ENV"
160
+
35
161
- name : Build wheels
36
162
37
163
with :
38
- package-dir : ./ # Build from source checkout
164
+ package-dir : ./dist/${{ startsWith(matrix.buildplat[1], 'macosx') && env.sdist_name || needs.build_sdist.outputs.sdist_file }}
39
165
env :
40
166
CIBW_BUILD : ${{ matrix.python[0] }}-${{ matrix.buildplat[1] }}
41
- CIBW_BUILD_FRONTEND : ' pip'
42
- CIBW_PLATFORM : ' windows'
43
- CIBW_ARCHS : ' ARM64'
44
- CIBW_BEFORE_BUILD_WINDOWS : |
45
- python -m pip install delvewheel
46
- bash scripts/cibw_before_build_windows.sh
47
-
48
- # - name: Set up Python for validation
49
- # uses: mamba-org/setup-micromamba@v2
50
- # with:
51
- # environment-name: wheel-env
52
- # create-args: >-
53
- # python=${{ matrix.python[1] }}
54
- # wheel
55
- # cache-downloads: true
56
- # cache-environment: true
167
+ CIBW_BUILD_FRONTEND : ${{ matrix.cibw_build_frontend || 'pip' }}
168
+ CIBW_PLATFORM : ${{ (matrix.buildplat[1] == 'pyodide_wasm32' && 'pyodide') || (matrix.buildplat[1] == 'win_arm64' && 'windows') || 'auto' }}
169
+ CIBW_ARCHS : ${{ matrix.buildplat[1] == 'win_arm64' && 'ARM64' || 'auto' }}
170
+ CIBW_BEFORE_BUILD_WINDOWS : ${{ matrix.buildplat[1] == 'win_arm64' && format('python -m pip install delvewheel && bash {0}/scripts/cibw_before_build_windows.sh', github.workspace) || '' }}
171
+
172
+ - name : Set up Python for validation/upload (non-ARM64 Windows & other OS)
173
+ if : matrix.buildplat[1] != 'win_arm64'
174
+ uses : mamba-org/setup-micromamba@v2
175
+ with :
176
+ environment-name : wheel-env
177
+ # Use a fixed Python, since we might have an unreleased Python not
178
+ # yet present on conda-forge
179
+ create-args : >-
180
+ python=3.11
181
+ anaconda-client
182
+ wheel
183
+ cache-downloads : true
184
+ cache-environment : true
57
185
58
186
- name : Validate wheel RECORD
59
187
shell : bash -el {0}
60
188
run : |
61
- python -m pip install wheel
189
+ if [[ "${{ matrix.buildplat[1] }}" == "win_arm64" ]]; then
190
+ python -m pip install wheel
191
+ fi
62
192
for whl in $(ls wheelhouse); do wheel unpack wheelhouse/$whl -d /tmp; done
63
193
64
194
- uses : actions/upload-artifact@v4
65
195
with :
66
196
name : ${{ matrix.python[0] }}-${{ matrix.buildplat[1] }}
67
197
path : ./wheelhouse/*.whl
198
+
199
+ - name : Upload wheels & sdist
200
+ if : ${{ success() && (env.IS_SCHEDULE_DISPATCH == 'true' || env.IS_PUSH == 'true') }}
201
+ shell : bash -el {0}
202
+ env :
203
+ PANDAS_STAGING_UPLOAD_TOKEN : ${{ secrets.PANDAS_STAGING_UPLOAD_TOKEN }}
204
+ PANDAS_NIGHTLY_UPLOAD_TOKEN : ${{ secrets.PANDAS_NIGHTLY_UPLOAD_TOKEN }}
205
+ # trigger an upload to
206
+ # https://anaconda.org/scientific-python-nightly-wheels/pandas
207
+ # for cron jobs or "Run workflow" (restricted to main branch).
208
+ # Tags will upload to
209
+ # https://anaconda.org/multibuild-wheels-staging/pandas
210
+ # The tokens were originally generated at anaconda.org
211
+ run : |
212
+ source ci/upload_wheels.sh
213
+ set_upload_vars
214
+ upload_wheels
0 commit comments