-
Notifications
You must be signed in to change notification settings - Fork 84
200 lines (187 loc) · 7.99 KB
/
Copy pathwheels.yml
File metadata and controls
200 lines (187 loc) · 7.99 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
197
198
199
200
name: Wheels
on:
workflow_dispatch:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
build_sdist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- run: pipx run build --sdist
- run: pipx run twine check dist/* || exit 1 # Ensure failure on twine check errors
- uses: actions/upload-artifact@v4
with:
name: dist-sdist
path: dist/*.tar.gz
build_wheels:
runs-on: ${{ matrix.os }}
# windows-11-arm is newly added; its native toolchain may not build every
# dependency yet (embree / predicates use x86 SIMD), so don't let that leg
# block a release if it fails.
continue-on-error: ${{ matrix.os == 'windows-11-arm' }}
strategy:
fail-fast: false
# One runner per *native* target architecture; cibuildwheel builds the
# runner's native arch by default. Do NOT reintroduce a cross `arch`
# dimension: previously `arch: arm64` on the x86 ubuntu-24.04 / windows-latest
# runners silently built x86_64 / amd64 wheels (only CIBW_ARCHS_MACOS was
# wired up), producing duplicate wheels that collided during the release
# artifact download and left win_arm64 uncovered.
matrix:
os: [ubuntu-24.04, ubuntu-24.04-arm, macos-latest, macos-15-intel, windows-latest, windows-11-arm]
pybuilds: [cp38, cp39, cp310, cp311, cp312]
exclude:
# No macOS CPython 3.8 wheels are shipped.
- os: macos-latest
pybuilds: cp38
- os: macos-15-intel
pybuilds: cp38
# Windows on ARM64 has official CPython only for 3.11+.
- os: windows-11-arm
pybuilds: cp38
- os: windows-11-arm
pybuilds: cp39
- os: windows-11-arm
pybuilds: cp310
name: >
${{ matrix.pybuilds }} ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: pip install cibuildwheel==3.1.4
- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
env:
CIBW_BEFORE_ALL_LINUX: "yum install -y clang"
CIBW_ENVIRONMENT_LINUX: "CC=clang CXX=clang++"
CIBW_MANYLINUX_X86_64_IMAGE: "manylinux_2_28"
CIBW_MANYLINUX_AARCH64_IMAGE: "manylinux_2_28"
CIBW_BUILD: "${{ matrix.pybuilds }}-*"
# No CIBW_ARCHS_* override: each runner builds its native architecture.
CIBW_SKIP: "cp*-manylinux_i686 cp*-musllinux* cp*-win32"
# embree only enables its NEON (sse2neon) path when its build detects an
# ARM target; on Windows/MSVC-ARM64 that detection falls back to SSE2 and
# fails to compile (x86 immintrin.h). Drop embree on win_arm64 (the
# igl.embree submodule is simply absent from that wheel).
CIBW_ENVIRONMENT_WINDOWS: ${{ matrix.os == 'windows-11-arm' && 'CMAKE_ARGS=-DLIBIGL_EMBREE=OFF' || '' }}
- name: Upload Artifact
uses: actions/upload-artifact@v4
continue-on-error: true # Important: Continue if upload fails
with:
# Unique per (os, python); one native arch per runner so wheel
# filenames never collide when the release job merges artifacts.
name: wheels-${{ matrix.os }}-${{ matrix.pybuilds }}
path: ./wheelhouse/*.whl
if-no-files-found: error # Fail if no wheels are found
compression-level: 6
overwrite: false
include-hidden-files: false
check_version:
name: Check for a version bump
# Only a push to main can release; PRs and workflow_dispatch never do.
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
outputs:
should_release: ${{ steps.check.outputs.should_release }}
version: ${{ steps.check.outputs.version }}
prerelease: ${{ steps.check.outputs.prerelease }}
steps:
- uses: actions/checkout@v4
with:
# Need history to read pyproject.toml as of the previous commit
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: '3.12' # tomllib needs >=3.11
- name: Compare pyproject.toml version against the previous commit
id: check
env:
BEFORE: ${{ github.event.before }}
run: |
set -euo pipefail
# Read project.version from pyproject.toml at a given revision
# (empty revision = the working tree)
read_version() {
if [ -z "${1:-}" ]; then cat pyproject.toml; else git show "$1:pyproject.toml"; fi \
| python3 -c 'import sys,tomllib; print(tomllib.loads(sys.stdin.read())["project"]["version"])'
}
version=$(read_version)
echo "version=$version" >> "$GITHUB_OUTPUT"
# PEP 440 pre-releases (aN/bN/rcN/.devN) are flagged as such on GitHub.
# Note `.postN` is deliberately not a pre-release.
if printf '%s' "$version" | grep -Eq '(a[0-9]+|b[0-9]+|rc[0-9]+|\.dev[0-9]*)$'; then
echo "prerelease=true" >> "$GITHUB_OUTPUT"
else
echo "prerelease=false" >> "$GITHUB_OUTPUT"
fi
# `before` is all-zeros when the branch is first created, and can point
# at a vanished commit after a force-push; fall back to the first parent.
base="$BEFORE"
if [ -z "$base" ] || [ "$base" = "0000000000000000000000000000000000000000" ] \
|| ! git cat-file -e "$base^{commit}" 2>/dev/null; then
base=$(git rev-parse --verify --quiet HEAD^ || true)
fi
if [ -z "$base" ]; then
echo "No previous commit to compare against; not releasing."
echo "should_release=false" >> "$GITHUB_OUTPUT"
exit 0
fi
previous=$(read_version "$base")
echo "previous version: $previous"
echo "current version: $version"
if [ "$version" = "$previous" ]; then
echo "Version unchanged; not releasing."
echo "should_release=false" >> "$GITHUB_OUTPUT"
exit 0
fi
# Belt and braces: PyPI refuses to overwrite an existing version, and a
# re-run of this workflow would otherwise try to. Also covers the case
# where a bump was published by some other route.
if curl -sfL -o /dev/null "https://pypi.org/pypi/libigl/$version/json"; then
echo "libigl $version is already on PyPI; not releasing."
echo "should_release=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "Version bumped $previous -> $version; releasing."
echo "should_release=true" >> "$GITHUB_OUTPUT"
release_artifacts:
name: Publish ${{ needs.check_version.outputs.version }} to PyPI
needs: [check_version, build_sdist, build_wheels]
if: needs.check_version.outputs.should_release == 'true'
runs-on: ubuntu-latest
permissions:
id-token: write # for PyPI trusted publishing
contents: write # to create the tag and GitHub release
steps:
- uses: actions/download-artifact@v4
with:
path: ./artifacts
merge-multiple: true
- run: ls -R ./artifacts
- name: Tag and create a GitHub release
uses: ncipollo/release-action@v1
with:
tag: ${{ needs.check_version.outputs.version }}
commit: ${{ github.sha }}
name: ${{ needs.check_version.outputs.version }}
prerelease: ${{ needs.check_version.outputs.prerelease }}
allowUpdates: true
# Auto-populate the release body with the merged PRs since the
# previous tag (curated highlights live in CHANGELOG.md).
generateReleaseNotes: true
artifacts: "./artifacts/**/*"
token: ${{ secrets.GITHUB_TOKEN }}
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@v1.13.0
with:
packages-dir: ./artifacts
skip-existing: true