Skip to content

Commit b0103f1

Browse files
committed
Refactor release workflow to enhance caching and installation of dependencies for Linux builds; streamline manylinux configurations and improve clarity in environment setup.
1 parent 34648be commit b0103f1

1 file changed

Lines changed: 193 additions & 82 deletions

File tree

.github/workflows/release.yml

Lines changed: 193 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,20 @@ on:
66
- "v*"
77
workflow_dispatch:
88

9-
# ---- Centralized version pins for Linux path ----
10-
env:
11-
# Tooling
12-
CCACHE_VER: "4.11.3" # Linux tarballs (x86_64/aarch64)
13-
CIBW_VER: "v3.0.1" # cibuildwheel tag
14-
PYTHON_VER: "3.12" # runner Python to drive builds
15-
16-
# Native deps (Linux build)
17-
FFTW_VER: "3.3.10"
18-
BOOST_VER_U: "1_89_0" # underscored for URL
19-
BOOST_VER_D: "1.89.0" # dotted for path
20-
219
jobs:
2210
sdist:
2311
name: Build sdist
2412
runs-on: ubuntu-latest
2513
permissions:
2614
contents: read
2715
steps:
28-
- uses: actions/checkout@v5
16+
- uses: actions/checkout@v4
2917
with:
3018
fetch-depth: 0
3119

32-
- uses: actions/setup-python@v6
20+
- uses: actions/setup-python@v5
3321
with:
34-
python-version: ${{ env.PYTHON_VER }}
22+
python-version: "3.12"
3523

3624
- name: Build source distribution
3725
run: |
@@ -44,48 +32,112 @@ jobs:
4432
name: dist-sdist
4533
path: dist/*
4634

47-
35+
# ----- Linux x86_64 (native) -----
4836
wheels-linux-x86_64:
4937
name: Build Linux wheels (x86_64)
5038
runs-on: ubuntu-latest
51-
permissions: { contents: read }
39+
permissions:
40+
contents: read
5241
steps:
53-
- uses: actions/checkout@v5
54-
with: { fetch-depth: 0 }
42+
- uses: actions/checkout@v4
43+
with:
44+
fetch-depth: 0
5545

56-
- name: Build wheels with cibuildwheel
57-
uses: pypa/cibuildwheel@${{ env.CIBW_VER }}
46+
# Cache compiled objects across ABIs & runs
47+
- name: Restore ccache
48+
uses: actions/cache@v4
49+
with:
50+
path: .ccache
51+
key: ccache-linux-x86_64-${{ hashFiles('**/CMakeLists.txt', '**/*.cmake', '**/*.cpp', '**/*.h', 'pyproject.toml') }}
52+
53+
# Cache third-party source tarballs so BEFORE_ALL can just extract
54+
- name: Restore 3rdparty source cache
55+
uses: actions/cache@v4
56+
with:
57+
path: build-cache
58+
key: thirdparty-src-x86_64-fftw-3.3.10-boost-1_84_0
59+
60+
- name: Pre-fetch Boost/FFTW (host)
61+
run: |
62+
set -eux
63+
mkdir -p build-cache
64+
# FFTW
65+
test -f build-cache/fftw-3.3.10.tar.gz || \
66+
curl -fsSL -o build-cache/fftw-3.3.10.tar.gz http://www.fftw.org/fftw-3.3.10.tar.gz
67+
# Boost headers
68+
test -f build-cache/boost_1_84_0.tar.gz || \
69+
curl -fsSL -o build-cache/boost_1_84_0.tar.gz https://archives.boost.io/release/1.84.0/source/boost_1_84_0.tar.gz
70+
71+
- name: Build wheels with cibuildwheel (x86_64)
72+
uses: pypa/cibuildwheel@v2.21.3
5873
env:
59-
CIBW_BUILD: cp310-manylinux_x86_64 cp311-manylinux_x86_64 cp312-manylinux_x86_64
74+
CIBW_BUILD: cp310-* cp311-* cp312-*
75+
CIBW_SKIP: pp* *-musllinux_*
6076
CIBW_ARCHS_LINUX: x86_64
6177
CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28
62-
63-
# ---- same pinned prebuilds as before ----
6478
CIBW_BEFORE_ALL_LINUX: |
6579
set -eux
66-
if command -v yum >/dev/null 2>&1; then yum -y install pkgconfig xz || true; fi
67-
ARCH="x86_64"; CCACHE_ARCH="linux-x86_64"
68-
curl -fsSL -o /tmp/ccache.tar.xz "https://github.com/ccache/ccache/releases/download/v${CCACHE_VER}/ccache-${CCACHE_VER}-${CCACHE_ARCH}.tar.xz"
69-
mkdir -p /opt/ccache && tar -C /opt/ccache -xJf /tmp/ccache.tar.xz --strip-components=1
70-
export PATH="/opt/ccache/bin:$PATH"; ccache --version; ccache --set-config=max_size=2G || true
71-
curl -fsSL -o /tmp/fftw.tar.gz "http://www.fftw.org/fftw-${FFTW_VER}.tar.gz"
72-
tar -C /tmp -xzf /tmp/fftw.tar.gz
73-
pushd /tmp/fftw-${FFTW_VER}; ./configure --prefix=/opt/fftw --enable-shared --enable-threads
74-
make -j"$(nproc)"; make install; popd
75-
curl -fsSL -o /tmp/boost.tar.gz "https://archives.boost.io/release/${BOOST_VER_D}/source/boost_${BOOST_VER_U}.tar.gz"
76-
tar -C /tmp -xzf /tmp/boost.tar.gz
77-
mkdir -p /opt/boost/include; cp -r /tmp/boost_${BOOST_VER_U}/boost /opt/boost/include/
80+
81+
# --- Ensure ccache & ninja exist inside the manylinux container ---
82+
have_ccache=0
83+
if command -v dnf >/dev/null 2>&1; then
84+
dnf -y install ccache pkgconfig ninja-build || true
85+
elif command -v yum >/dev/null 2>&1; then
86+
yum -y install ccache pkgconfig ninja-build || true
87+
elif command -v microdnf >/dev/null 2>&1; then
88+
microdnf -y install ccache pkgconfig ninja-build || true
89+
fi
90+
if command -v ccache >/dev/null 2>&1; then
91+
have_ccache=1
92+
else
93+
# Fallback: fetch a static ccache binary (no package manager needed)
94+
arch="$(uname -m)"
95+
ver="4.11.3"
96+
url_x86_64="https://github.com/ccache/ccache/releases/download/v${ver}/ccache-${ver}-linux-x86_64.tar.xz"
97+
url_aarch64="https://github.com/ccache/ccache/releases/download/v${ver}/ccache-${ver}-linux-aarch64.tar.xz"
98+
url="${url_x86_64}"
99+
[ "$arch" = "aarch64" ] && url="${url_aarch64}"
100+
curl -fsSL "${url}" -o /tmp/ccache.tar.xz
101+
mkdir -p /usr/local/ccache && tar -xJf /tmp/ccache.tar.xz -C /usr/local/ccache --strip-components=1
102+
ln -sf /usr/local/ccache/bin/ccache /usr/local/bin/ccache
103+
have_ccache=1
104+
fi
105+
106+
# Ensure ninja exists too (fallback to portable binary if needed)
107+
if ! command -v ninja >/dev/null 2>&1; then
108+
curl -fsSL -o /usr/local/bin/ninja https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-linux.zip
109+
# some images have no unzip; use busybox if present, else fetch static:
110+
if command -v unzip >/dev/null 2>&1; then
111+
tmpd="$(mktemp -d)" && mv /usr/local/bin/ninja "$tmpd/ninja.zip"
112+
unzip -p "$tmpd/ninja.zip" > /usr/local/bin/ninja && chmod +x /usr/local/bin/ninja
113+
else
114+
# fallback: use curl to a pre-unzipped mirror if you have one; or install unzip via dnf/yum above
115+
echo "ninja fallback requires unzip; please enable unzip in package install above" >&2
116+
exit 1
117+
fi
118+
fi
119+
120+
# --- Build prerequisites we cache (FFTW & Boost headers) ---
121+
mkdir -p /opt/fftw /opt/boost/include
122+
tar -xzf /project/build-cache/fftw-3.3.10.tar.gz -C /tmp
123+
tar -xzf /project/build-cache/boost_1_84_0.tar.gz -C /tmp
124+
125+
pushd /tmp/fftw-3.3.10
126+
./configure --prefix=/opt/fftw --enable-shared --enable-threads --disable-fortran --disable-mpi
127+
make -j"$(nproc)"
128+
make install
129+
popd
130+
131+
cp -r /tmp/boost_1_84_0/boost /opt/boost/include/
78132
79133
CIBW_ENVIRONMENT_LINUX: >
80-
PATH=/opt/ccache/bin:$PATH
81-
CCACHE_DIR=/root/.ccache
82134
PKG_CONFIG_PATH=/opt/fftw/lib/pkgconfig
83135
CMAKE_PREFIX_PATH=/opt/fftw
84-
CMAKE_ARGS="-DHF_USE_OPENMP=ON -DHF_USE_FFTW_THREADS=ON -DBOOST_INCLUDE_DIR=/opt/boost/include"
85-
136+
CCACHE_DIR=/project/.ccache
137+
CMAKE_ARGS="-G Ninja -DHF_USE_OPENMP=ON -DHF_USE_FFTW_THREADS=ON -DBOOST_INCLUDE_DIR=/opt/boost/include -DCMAKE_CXX_COMPILER_LAUNCHER=ccache"
138+
CMAKE_BUILD_PARALLEL_LEVEL=$(nproc)
86139
CIBW_REPAIR_WHEEL_COMMAND_LINUX: >
87140
bash -lc 'LD_LIBRARY_PATH=/opt/fftw/lib auditwheel repair -w {dest_dir} {wheel}'
88-
89141
CIBW_TEST_REQUIRES: numpy
90142
CIBW_TEST_COMMAND: |
91143
python - <<'PY'
@@ -101,53 +153,117 @@ jobs:
101153
print("wheel ok", int(n), float(mu))
102154
PY
103155
104-
- uses: actions/upload-artifact@v4
156+
- name: Upload Linux x86_64 wheels
157+
uses: actions/upload-artifact@v4
105158
with:
106159
name: dist-wheels-linux-x86_64
107160
path: wheelhouse/*
108161
if-no-files-found: error
109162

163+
# ----- Linux aarch64 (native ARM runner) -----
110164
wheels-linux-aarch64:
111-
name: Build Linux wheels (aarch64, native)
165+
name: Build Linux wheels (aarch64 — native)
166+
# For public repos you can use ubuntu-24.04-arm / ubuntu-22.04-arm.
167+
# For private repos, switch to your self-hosted arm64 runner label.
112168
runs-on: ubuntu-24.04-arm
113-
permissions: { contents: read }
169+
permissions:
170+
contents: read
114171
steps:
115-
- uses: actions/checkout@v5
116-
with: { fetch-depth: 0 }
172+
- uses: actions/checkout@v4
173+
with:
174+
fetch-depth: 0
117175

118-
- name: Build wheels with cibuildwheel
119-
uses: pypa/cibuildwheel@${{ env.CIBW_VER }}
176+
- name: Restore ccache
177+
uses: actions/cache@v4
178+
with:
179+
path: .ccache
180+
key: ccache-linux-arm64-${{ hashFiles('**/CMakeLists.txt', '**/*.cmake', '**/*.cpp', '**/*.h', 'pyproject.toml') }}
181+
182+
- name: Restore 3rdparty source cache
183+
uses: actions/cache@v4
184+
with:
185+
path: build-cache
186+
key: thirdparty-src-arm64-fftw-3.3.10-boost-1_84_0
187+
188+
- name: Pre-fetch Boost/FFTW (host)
189+
run: |
190+
set -eux
191+
mkdir -p build-cache
192+
test -f build-cache/fftw-3.3.10.tar.gz || \
193+
curl -fsSL -o build-cache/fftw-3.3.10.tar.gz http://www.fftw.org/fftw-3.3.10.tar.gz
194+
test -f build-cache/boost_1_84_0.tar.gz || \
195+
curl -fsSL -o build-cache/boost_1_84_0.tar.gz https://archives.boost.io/release/1.84.0/source/boost_1_84_0.tar.gz
196+
197+
- name: Build wheels with cibuildwheel (aarch64)
198+
uses: pypa/cibuildwheel@v2.21.3
120199
env:
121-
CIBW_BUILD: cp310-manylinux_aarch64 cp311-manylinux_aarch64 cp312-manylinux_aarch64
200+
CIBW_BUILD: cp310-* cp311-* cp312-*
201+
CIBW_SKIP: pp* *-musllinux_*
122202
CIBW_ARCHS_LINUX: aarch64
123203
CIBW_MANYLINUX_AARCH64_IMAGE: manylinux_2_28
124-
125-
# identical prebuild steps, just set arch to aarch64 and pick the right ccache tarball
126204
CIBW_BEFORE_ALL_LINUX: |
127205
set -eux
128-
if command -v yum >/dev/null 2>&1; then yum -y install pkgconfig xz || true; fi
129-
ARCH="aarch64"; CCACHE_ARCH="linux-aarch64"
130-
curl -fsSL -o /tmp/ccache.tar.xz "https://github.com/ccache/ccache/releases/download/v${CCACHE_VER}/ccache-${CCACHE_VER}-${CCACHE_ARCH}.tar.xz"
131-
mkdir -p /opt/ccache && tar -C /opt/ccache -xJf /tmp/ccache.tar.xz --strip-components=1
132-
export PATH="/opt/ccache/bin:$PATH"; ccache --version; ccache --set-config=max_size=2G || true
133-
curl -fsSL -o /tmp/fftw.tar.gz "http://www.fftw.org/fftw-${FFTW_VER}.tar.gz"
134-
tar -C /tmp -xzf /tmp/fftw.tar.gz
135-
pushd /tmp/fftw-${FFTW_VER}; ./configure --prefix=/opt/fftw --enable-shared --enable-threads
136-
make -j"$(nproc)"; make install; popd
137-
curl -fsSL -o /tmp/boost.tar.gz "https://archives.boost.io/release/${BOOST_VER_D}/source/boost_${BOOST_VER_U}.tar.gz"
138-
tar -C /tmp -xzf /tmp/boost.tar.gz
139-
mkdir -p /opt/boost/include; cp -r /tmp/boost_${BOOST_VER_U}/boost /opt/boost/include/
206+
207+
# --- Ensure ccache & ninja exist inside the manylinux container ---
208+
have_ccache=0
209+
if command -v dnf >/dev/null 2>&1; then
210+
dnf -y install ccache pkgconfig ninja-build || true
211+
elif command -v yum >/dev/null 2>&1; then
212+
yum -y install ccache pkgconfig ninja-build || true
213+
elif command -v microdnf >/dev/null 2>&1; then
214+
microdnf -y install ccache pkgconfig ninja-build || true
215+
fi
216+
if command -v ccache >/dev/null 2>&1; then
217+
have_ccache=1
218+
else
219+
# Fallback: fetch a static ccache binary (no package manager needed)
220+
arch="$(uname -m)"
221+
ver="4.11.3"
222+
url_x86_64="https://github.com/ccache/ccache/releases/download/v${ver}/ccache-${ver}-linux-x86_64.tar.xz"
223+
url_aarch64="https://github.com/ccache/ccache/releases/download/v${ver}/ccache-${ver}-linux-aarch64.tar.xz"
224+
url="${url_x86_64}"
225+
[ "$arch" = "aarch64" ] && url="${url_aarch64}"
226+
curl -fsSL "${url}" -o /tmp/ccache.tar.xz
227+
mkdir -p /usr/local/ccache && tar -xJf /tmp/ccache.tar.xz -C /usr/local/ccache --strip-components=1
228+
ln -sf /usr/local/ccache/bin/ccache /usr/local/bin/ccache
229+
have_ccache=1
230+
fi
231+
232+
# Ensure ninja exists too (fallback to portable binary if needed)
233+
if ! command -v ninja >/dev/null 2>&1; then
234+
curl -fsSL -o /usr/local/bin/ninja https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-linux.zip
235+
# some images have no unzip; use busybox if present, else fetch static:
236+
if command -v unzip >/dev/null 2>&1; then
237+
tmpd="$(mktemp -d)" && mv /usr/local/bin/ninja "$tmpd/ninja.zip"
238+
unzip -p "$tmpd/ninja.zip" > /usr/local/bin/ninja && chmod +x /usr/local/bin/ninja
239+
else
240+
# fallback: use curl to a pre-unzipped mirror if you have one; or install unzip via dnf/yum above
241+
echo "ninja fallback requires unzip; please enable unzip in package install above" >&2
242+
exit 1
243+
fi
244+
fi
245+
246+
# --- Build prerequisites we cache (FFTW & Boost headers) ---
247+
mkdir -p /opt/fftw /opt/boost/include
248+
tar -xzf /project/build-cache/fftw-3.3.10.tar.gz -C /tmp
249+
tar -xzf /project/build-cache/boost_1_84_0.tar.gz -C /tmp
250+
251+
pushd /tmp/fftw-3.3.10
252+
./configure --prefix=/opt/fftw --enable-shared --enable-threads --disable-fortran --disable-mpi
253+
make -j"$(nproc)"
254+
make install
255+
popd
256+
257+
cp -r /tmp/boost_1_84_0/boost /opt/boost/include/
140258
141259
CIBW_ENVIRONMENT_LINUX: >
142-
PATH=/opt/ccache/bin:$PATH
143-
CCACHE_DIR=/root/.ccache
144260
PKG_CONFIG_PATH=/opt/fftw/lib/pkgconfig
145261
CMAKE_PREFIX_PATH=/opt/fftw
146-
CMAKE_ARGS="-DHF_USE_OPENMP=ON -DHF_USE_FFTW_THREADS=ON -DBOOST_INCLUDE_DIR=/opt/boost/include"
147-
262+
CCACHE_DIR=/project/.ccache
263+
CMAKE_ARGS="-G Ninja -DHF_USE_OPENMP=ON -DHF_USE_FFTW_THREADS=ON -DBOOST_INCLUDE_DIR=/opt/boost/include -DCMAKE_CXX_COMPILER_LAUNCHER=ccache"
264+
CMAKE_BUILD_PARALLEL_LEVEL=$(nproc)
148265
CIBW_REPAIR_WHEEL_COMMAND_LINUX: >
149266
bash -lc 'LD_LIBRARY_PATH=/opt/fftw/lib auditwheel repair -w {dest_dir} {wheel}'
150-
151267
CIBW_TEST_REQUIRES: numpy
152268
CIBW_TEST_COMMAND: |
153269
python - <<'PY'
@@ -163,12 +279,14 @@ jobs:
163279
print("wheel ok", int(n), float(mu))
164280
PY
165281
166-
- uses: actions/upload-artifact@v4
282+
- name: Upload Linux aarch64 wheels
283+
uses: actions/upload-artifact@v4
167284
with:
168285
name: dist-wheels-linux-aarch64
169286
path: wheelhouse/*
170287
if-no-files-found: error
171288

289+
# ----- macOS (Intel/Apple Silicon) -----
172290
wheels-macos:
173291
name: Build macOS wheels (Intel/Apple Silicon)
174292
strategy:
@@ -181,33 +299,24 @@ jobs:
181299
permissions:
182300
contents: read
183301
steps:
184-
- uses: actions/checkout@v5
302+
- uses: actions/checkout@v4
185303
with:
186304
fetch-depth: 0
187305

188-
# Homebrew-only on macOS (latest formulas)
189306
- name: Install Homebrew deps
190307
env:
191308
HOMEBREW_NO_AUTO_UPDATE: "1"
192309
run: |
193-
set -eux
194-
# Keep brew metadata stable during CI run, but accept current formula versions
195310
rm -f "$HOME/Library/Caches/Homebrew/downloads/"*libomp* || true
196-
brew install ccache fftw libomp boost cmake ninja || true
197-
# Make sure ccache is on PATH and usable
198-
echo 'export PATH="/opt/homebrew/opt/ccache/libexec:$PATH"' >> "$HOME/.bash_profile" || true
199-
echo 'export PATH="/usr/local/opt/ccache/libexec:$PATH"' >> "$HOME/.bash_profile" || true
200-
export PATH="/opt/homebrew/opt/ccache/libexec:$PATH:/usr/local/opt/ccache/libexec:$PATH"
201-
ccache --version || true
311+
brew install fftw libomp boost cmake ninja || true
202312
203313
- name: Build wheels with cibuildwheel
204-
uses: pypa/cibuildwheel@${{ env.CIBW_VER }}
314+
uses: pypa/cibuildwheel@v2.21.3
205315
env:
206316
CIBW_BUILD: cp310-* cp311-* cp312-*
207317
CIBW_SKIP: pp*
208318
CIBW_ARCHS_MACOS: native
209319
CIBW_ENVIRONMENT_MACOS: >
210-
PATH=/opt/homebrew/opt/ccache/libexec:/usr/local/opt/ccache/libexec:$PATH
211320
PKG_CONFIG_PATH=/opt/homebrew/lib/pkgconfig:/usr/local/lib/pkgconfig
212321
CMAKE_ARGS="-DHF_USE_OPENMP=ON -DHF_USE_FFTW_THREADS=ON -DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET}"
213322
CIBW_REPAIR_WHEEL_COMMAND_MACOS: >
@@ -234,11 +343,13 @@ jobs:
234343
path: wheelhouse/*
235344
if-no-files-found: error
236345

346+
# ----- Publish to PyPI -----
237347
publish:
238348
name: Publish to PyPI
239349
needs: [sdist, wheels-linux-x86_64, wheels-linux-aarch64, wheels-macos]
240350
runs-on: ubuntu-latest
241-
environment: cpp_hf_env # must match Trusted Publisher environment on PyPI
351+
# 🔐 Ensure the OIDC token includes the environment claim
352+
environment: cpp_hf_env
242353
permissions:
243354
contents: read
244355
id-token: write

0 commit comments

Comments
 (0)