Skip to content

Commit f1d8dab

Browse files
committed
Refactor static dependency builder and cache dependency archives in CI
Extract static dependency preparation into a reusable builder and wire CI to reuse downloaded archives across jobs/platforms. This reduces duplicated build logic, improves maintainability, and speeds up wheel/sdist workflows. - Introduce `build_support/lib_xmlsec_dependency_builder.py`: - Centralize dependency version resolution, source/archive download, extract, and build steps for OpenSSL, zlib, libiconv, libxml2, libxslt, and xmlsec1. - Support both Unix and Windows dependency preparation paths. - Preserve cross-compilation handling via `CrossCompileInfo` (now a dataclass). - Expose resolved library versions for callers. - Add `build_libs_xmlsec.py` CLI: - Provide a standalone entrypoint to prepare dependencies. - Support `--download-only`, custom `--libs-dir`, custom `--buildroot`, and target platform/plat-name overrides. - Refactor `build_support/static_build.py`: - Delegate dependency preparation to `LibXmlsecDependencyBuilder`. - Keep extension configuration focused on platform-specific compiler/linker flags and include/lib wiring. - Preserve static-link behavior while removing duplicated dependency logic. - Update `build_support/build_ext.py`: - Initialize build flags (`PYXMLSEC_ENABLE_DEBUG`, `PYXMLSEC_STATIC_DEPS`, `PYXMLSEC_OPTIMIZE_SIZE`) in `__init__`. - Keep build flow unchanged, but use the refactored static helper path. - Modernize packaging metadata: - Move project metadata from `setup.py` into PEP 621 fields in `pyproject.toml` (`[project]`, `[project.urls]`, `[tool.setuptools]`). - Simplify `setup.py` to extension setup only. - Delete legacy `setup.cfg`. - Relax build-system pins and align build requirements with setuptools_scm>=8. - Bump `ruff[format]` in `requirements-test.txt` to `0.14.4`. - Add reusable dependency-cache workflow: - New `.github/workflows/cache_libs.yml` workflow_call job that downloads and caches `libs/*.{xz,gz,zip}` per OS/arch/version inputs. - Export cache/version outputs for downstream jobs. - Validate expected Windows archive filenames. - Rework wheel/manylinux CI to consume cached libs: - `manylinux.yml` now depends on `cache_libs`, restores cache, and runs build + test inside container via new script `.github/scripts/manylinux_build_and_test.sh`. - Script sets `PYTHONPATH` and `PYXMLSEC_LIBS_DIR` explicitly so isolated PEP 517 builds can import local helpers and reuse cached archives. - `wheels.yml` now depends on `cache_libs`, restores cache before cibuildwheel, updates action versions, and refreshes matrix generation (`generate_wheels_matrix`) including ARM Linux runner mapping. - `sdist.yml` installs `setuptools_scm>=8` during build deps setup. - Minor workflow hygiene updates: - Normalize formatting and small ordering/conditional tweaks in `linuxbrew.yml` and `macosx.yml`.
1 parent 8d98ff2 commit f1d8dab

File tree

15 files changed

+836
-501
lines changed

15 files changed

+836
-501
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/bin/sh
2+
set -eu
3+
4+
: "${PY_ABI:?PY_ABI is required}"
5+
: "${MANYLINUX_IMAGE:?MANYLINUX_IMAGE is required}"
6+
7+
# Make local build helpers importable for isolated PEP 517 backend subprocesses.
8+
export PYTHONPATH="$PWD${PYTHONPATH:+:${PYTHONPATH}}"
9+
# Ensure dependency archives are read from the restored workspace cache even in isolated builds.
10+
export PYXMLSEC_LIBS_DIR="$PWD/libs"
11+
12+
# Step: Install system build dependencies (manylinux only)
13+
echo "== [container] Step: Install system build dependencies (manylinux only) =="
14+
case "$MANYLINUX_IMAGE" in
15+
manylinux*)
16+
yum install -y perl-core
17+
;;
18+
esac
19+
20+
# Step: Install python build dependencies
21+
echo "== [container] Step: Install python build dependencies =="
22+
/opt/python/${PY_ABI}/bin/pip install --upgrade pip setuptools wheel build 'setuptools_scm>=8'
23+
24+
# Step: Set environment variables
25+
echo "== [container] Step: Set environment variables =="
26+
PKGVER=$(/opt/python/${PY_ABI}/bin/python setup.py --version)
27+
echo "PKGVER=$PKGVER"
28+
29+
# Step: Build linux_x86_64 wheel
30+
echo "== [container] Step: Build linux_x86_64 wheel =="
31+
/opt/python/${PY_ABI}/bin/python -m build
32+
33+
# Step: Label manylinux wheel
34+
echo "== [container] Step: Label manylinux wheel =="
35+
ls -la dist/
36+
auditwheel show dist/xmlsec-${PKGVER}-${PY_ABI}-linux_x86_64.whl
37+
auditwheel repair dist/xmlsec-${PKGVER}-${PY_ABI}-linux_x86_64.whl
38+
ls -la wheelhouse/
39+
auditwheel show wheelhouse/xmlsec-${PKGVER}-${PY_ABI}-*${MANYLINUX_IMAGE}*.whl
40+
41+
# Step: Install test dependencies
42+
echo "== [container] Step: Install test dependencies =="
43+
/opt/python/${PY_ABI}/bin/pip install --upgrade -r requirements-test.txt
44+
/opt/python/${PY_ABI}/bin/pip install xmlsec --only-binary=xmlsec --no-index --find-links=wheelhouse/
45+
46+
# Step: Run tests
47+
echo "== [container] Step: Run tests =="
48+
/opt/python/${PY_ABI}/bin/pytest -v --color=yes
49+
50+
# Step: Fix mounted workspace file ownership on host
51+
echo "== [container] Step: Fix mounted workspace file ownership on host =="
52+
chown -R "${HOST_UID}:${HOST_GID}" dist wheelhouse build libs || true

.github/workflows/cache_libs.yml

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
name: Cache library dependencies
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
LIBICONV_VERSION:
7+
default: "1.18"
8+
required: false
9+
type: string
10+
LIBXML2_VERSION:
11+
default: "2.14.6"
12+
required: false
13+
type: string
14+
LIBXSLT_VERSION:
15+
default: "1.1.43"
16+
required: false
17+
type: string
18+
OPENSSL_VERSION:
19+
default: "3.6.0"
20+
required: false
21+
type: string
22+
XMLSEC1_VERSION:
23+
default: "1.3.9"
24+
required: false
25+
type: string
26+
ZLIB_VERSION:
27+
default: "1.3.1"
28+
required: false
29+
type: string
30+
WIN_LIBICONV_VERSION:
31+
default: "1.18-1"
32+
required: false
33+
type: string
34+
WIN_LIBXML2_VERSION:
35+
default: "2.11.9-3"
36+
required: false
37+
type: string
38+
WIN_LIBXSLT_VERSION:
39+
default: "1.1.39"
40+
required: false
41+
type: string
42+
WIN_OPENSSL_VERSION:
43+
default: "3.0.16.pl1"
44+
required: false
45+
type: string
46+
WIN_XMLSEC1_VERSION:
47+
default: "1.3.7"
48+
required: false
49+
type: string
50+
WIN_ZLIB_VERSION:
51+
default: "1.3.1"
52+
required: false
53+
type: string
54+
55+
outputs:
56+
LIBICONV_VERSION:
57+
value: ${{ inputs.LIBICONV_VERSION }}
58+
LIBXML2_VERSION:
59+
value: ${{ inputs.LIBXML2_VERSION }}
60+
LIBXSLT_VERSION:
61+
value: ${{ inputs.LIBXSLT_VERSION }}
62+
OPENSSL_VERSION:
63+
value: ${{ inputs.OPENSSL_VERSION }}
64+
XMLSEC1_VERSION:
65+
value: ${{ inputs.XMLSEC1_VERSION }}
66+
ZLIB_VERSION:
67+
value: ${{ inputs.ZLIB_VERSION }}
68+
WIN_LIBICONV_VERSION:
69+
value: ${{ inputs.WIN_LIBICONV_VERSION }}
70+
WIN_LIBXML2_VERSION:
71+
value: ${{ inputs.WIN_LIBXML2_VERSION }}
72+
WIN_LIBXSLT_VERSION:
73+
value: ${{ inputs.WIN_LIBXSLT_VERSION }}
74+
WIN_OPENSSL_VERSION:
75+
value: ${{ inputs.WIN_OPENSSL_VERSION }}
76+
WIN_XMLSEC1_VERSION:
77+
value: ${{ inputs.WIN_XMLSEC1_VERSION }}
78+
WIN_ZLIB_VERSION:
79+
value: ${{ inputs.WIN_ZLIB_VERSION }}
80+
81+
jobs:
82+
cache_libs:
83+
strategy:
84+
fail-fast: false
85+
matrix:
86+
os:
87+
- "ubuntu-22.04"
88+
- "ubuntu-22.04-arm"
89+
- "macos-latest"
90+
- "windows-2022"
91+
- "windows-11-arm"
92+
93+
runs-on: ${{ matrix.os }}
94+
95+
env:
96+
LIBICONV_VERSION: ${{ contains(matrix.os, 'windows-') && inputs.WIN_LIBICONV_VERSION || inputs.LIBICONV_VERSION }}
97+
LIBXML2_VERSION: ${{ contains(matrix.os, 'windows-') && inputs.WIN_LIBXML2_VERSION || inputs.LIBXML2_VERSION }}
98+
LIBXSLT_VERSION: ${{ contains(matrix.os, 'windows-') && inputs.WIN_LIBXSLT_VERSION || inputs.LIBXSLT_VERSION }}
99+
OPENSSL_VERSION: ${{ contains(matrix.os, 'windows-') && inputs.WIN_OPENSSL_VERSION || inputs.OPENSSL_VERSION }}
100+
XMLSEC1_VERSION: ${{ contains(matrix.os, 'windows-') && inputs.WIN_XMLSEC1_VERSION || inputs.XMLSEC1_VERSION }}
101+
ZLIB_VERSION: ${{ contains(matrix.os, 'windows-') && inputs.WIN_ZLIB_VERSION || inputs.ZLIB_VERSION }}
102+
103+
steps:
104+
- uses: actions/checkout@v6
105+
106+
- name: Cache [libs]
107+
uses: actions/cache@v4.3.0
108+
with:
109+
path: |
110+
libs/*.xz
111+
libs/*.gz
112+
libs/*.zip
113+
key: libs-${{ runner.os }}-${{ runner.arch }}-${{ env.LIBXML2_VERSION }}-${{ env.LIBXSLT_VERSION }}
114+
115+
- uses: actions/setup-python@v6
116+
with:
117+
python-version: "3.13"
118+
119+
- name: Install setuptools shim
120+
run: python -m pip install --upgrade pip setuptools
121+
122+
- name: Download latest libraries
123+
env:
124+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
125+
run: python build_libs_xmlsec.py --download-only
126+
127+
- name: Check Windows library versions
128+
if: ${{ contains(matrix.os, 'windows-') }}
129+
run: |
130+
bash -c '
131+
for file in libs/iconv-${{ inputs.WIN_LIBICONV_VERSION }}.*.zip libs/libxml2-${{ inputs.WIN_LIBXML2_VERSION }}.*.zip libs/libxslt-${{ inputs.WIN_LIBXSLT_VERSION }}.*.zip libs/openssl-${{ inputs.WIN_OPENSSL_VERSION }}.*.zip libs/xmlsec-${{ inputs.WIN_XMLSEC1_VERSION }}.*.zip libs/zlib-${{ inputs.WIN_ZLIB_VERSION }}.*.zip; do
132+
[[ -f "$file" ]] || { echo "MISSING: $file" ; exit 1; }
133+
done
134+
'

.github/workflows/linuxbrew.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,34 @@ on: [push, pull_request]
33
concurrency:
44
group: ${{ github.workflow }}-${{ github.ref }}
55
cancel-in-progress: ${{ github.ref_name != 'master' }}
6+
67
jobs:
78
linuxbrew:
89
runs-on: ubuntu-latest
10+
911
strategy:
1012
matrix:
1113
python: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
14+
1215
env:
1316
# For some unknown reason, linuxbrew tries to use "gcc-11" by default, which doesn't exist.
1417
CC: gcc
18+
1519
steps:
1620
- uses: actions/checkout@v3
21+
1722
- name: Install brew
1823
run: |
1924
sudo apt install -y build-essential procps curl file git
2025
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
2126
echo "/home/linuxbrew/.linuxbrew/bin" >> $GITHUB_PATH
27+
2228
- name: Install build dependencies
2329
run: |
2430
brew update
2531
brew install python@${{ matrix.python }} gcc libxml2 libxmlsec1 pkg-config
2632
echo "/home/linuxbrew/.linuxbrew/opt/python@${{ matrix.python }}/libexec/bin" >> $GITHUB_PATH
33+
2734
- name: Build wheel
2835
run: |
2936
python3 -m venv build_venv
@@ -33,6 +40,7 @@ jobs:
3340
export LDFLAGS="-L$(brew --prefix)/lib"
3441
python3 -m build
3542
rm -rf build/
43+
3644
- name: Run tests
3745
run: |
3846
python3 -m venv test_venv

.github/workflows/macosx.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,29 @@ on: [push, pull_request]
33
concurrency:
44
group: ${{ github.workflow }}-${{ github.ref }}
55
cancel-in-progress: ${{ github.ref_name != 'master' }}
6+
67
jobs:
78
macosx:
89
runs-on: macos-latest
10+
911
strategy:
1012
matrix:
1113
python: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
1214
static_deps: ["static", ""]
15+
1316
steps:
1417
- uses: actions/checkout@v3
18+
1519
- name: Setup Python
1620
uses: actions/setup-python@v4
1721
with:
1822
python-version: ${{ matrix.python }}
23+
1924
- name: Install build dependencies
2025
run: |
2126
pip install --upgrade pip setuptools wheel build
2227
brew install libxml2 libxmlsec1 pkg-config
28+
2329
- name: Build macosx_x86_64 wheel
2430
env:
2531
CC: clang
@@ -32,23 +38,27 @@ jobs:
3238
export PYXMLSEC_LIBXML2_VERSION="$(pkg-config --modversion libxml-2.0)"
3339
python -m build
3440
rm -rf build/
41+
3542
- name: Set environment variables
3643
shell: bash
3744
run: |
3845
echo "PKGVER=$(python setup.py --version)" >> $GITHUB_ENV
3946
echo "LLVM_PROFILE_FILE=pyxmlsec.profraw" >> $GITHUB_ENV
47+
4048
- name: Install test dependencies
4149
run: |
4250
export PKG_CONFIG_PATH="$(brew --prefix)/opt/libxml2/lib/pkgconfig"
4351
pip install coverage --upgrade --no-binary=lxml -r requirements-test.txt
4452
pip install xmlsec --only-binary=xmlsec --no-index --find-links=dist/
4553
echo "PYXMLSEC_LIBFILE=$(python -c 'import xmlsec; print(xmlsec.__file__)')" >> $GITHUB_ENV
54+
4655
- name: Run tests
4756
run: |
4857
coverage run -m pytest -v --color=yes
58+
4959
- name: Report coverage to codecov
60+
if: matrix.static_deps != 'static'
5061
run: |
5162
/Library/Developer/CommandLineTools/usr/bin/llvm-profdata merge -sparse ${{ env.LLVM_PROFILE_FILE }} -output pyxmlsec.profdata
5263
/Library/Developer/CommandLineTools/usr/bin/llvm-cov show ${{ env.PYXMLSEC_LIBFILE }} --arch=$(uname -m) --instr-profile=pyxmlsec.profdata src > coverage.txt
5364
bash <(curl -s https://codecov.io/bash) -f coverage.txt
54-
if: matrix.static_deps != 'static'

.github/workflows/manylinux.yml

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,50 +3,60 @@ on: [push, pull_request]
33
concurrency:
44
group: ${{ github.workflow }}-${{ github.ref }}
55
cancel-in-progress: ${{ github.ref_name != 'master' }}
6+
67
jobs:
8+
cache_libs:
9+
uses: ./.github/workflows/cache_libs.yml
10+
secrets: inherit
11+
712
manylinux:
13+
needs: cache_libs
814
runs-on: ubuntu-latest
15+
16+
env:
17+
LIBXML2_VERSION: ${{ needs.cache_libs.outputs.LIBXML2_VERSION }}
18+
LIBXSLT_VERSION: ${{ needs.cache_libs.outputs.LIBXSLT_VERSION }}
19+
920
strategy:
1021
matrix:
1122
python-abi: [cp39-cp39, cp310-cp310, cp311-cp311, cp312-cp312, cp313-cp313, cp314-cp314]
1223
image:
1324
- manylinux2014_x86_64
1425
- manylinux_2_28_x86_64
1526
- musllinux_1_2_x86_64
16-
container: quay.io/pypa/${{ matrix.image }}
27+
1728
steps:
18-
- uses: actions/checkout@v1
19-
- name: Install python build dependencies
20-
run: |
21-
# https://github.com/actions/runner/issues/2033
22-
chown -R $(id -u):$(id -g) $PWD
23-
/opt/python/${{ matrix.python-abi }}/bin/pip install --upgrade pip setuptools wheel build
24-
- name: Install system build dependencies (manylinux)
25-
run: |
26-
yum install -y perl-core
27-
if: contains(matrix.image, 'manylinux')
28-
- name: Set environment variables
29-
shell: bash
30-
run: |
31-
echo "PKGVER=$(/opt/python/${{ matrix.python-abi }}/bin/python setup.py --version)" >> $GITHUB_ENV
32-
- name: Build linux_x86_64 wheel
29+
- uses: actions/checkout@v5.0.0
30+
with:
31+
fetch-depth: 0
32+
33+
- name: Cache [libs]
34+
uses: actions/cache/restore@v4.3.0
35+
with:
36+
path: |
37+
libs/*.xz
38+
libs/*.gz
39+
libs/*.zip
40+
key: libs-${{ runner.os }}-${{ runner.arch }}-${{ env.LIBXML2_VERSION }}-${{ env.LIBXSLT_VERSION }}
41+
42+
# Keep this job on the host runner so JS-based actions (for example actions/cache)
43+
# can run, then execute build/test inside the target manylinux/musllinux container.
44+
- name: Build and test in container
3345
env:
3446
PYXMLSEC_STATIC_DEPS: true
35-
PYXMLSEC_LIBXML2_VERSION: 2.14.6 # Lock it to libxml2 2.14.6 to match it with lxml
3647
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
48+
PY_ABI: ${{ matrix.python-abi }}
49+
MANYLINUX_IMAGE: ${{ matrix.image }}
3750
run: |
38-
/opt/python/${{ matrix.python-abi }}/bin/python -m build
39-
- name: Label manylinux wheel
40-
run: |
41-
ls -la dist/
42-
auditwheel show dist/xmlsec-${{ env.PKGVER }}-${{ matrix.python-abi }}-linux_x86_64.whl
43-
auditwheel repair dist/xmlsec-${{ env.PKGVER }}-${{ matrix.python-abi }}-linux_x86_64.whl
44-
ls -la wheelhouse/
45-
auditwheel show wheelhouse/xmlsec-${{ env.PKGVER }}-${{ matrix.python-abi }}-*${{ matrix.image }}*.whl
46-
- name: Install test dependencies
47-
run: |
48-
/opt/python/${{ matrix.python-abi }}/bin/pip install --upgrade -r requirements-test.txt
49-
/opt/python/${{ matrix.python-abi }}/bin/pip install xmlsec --only-binary=xmlsec --no-index --find-links=wheelhouse/
50-
- name: Run tests
51-
run: |
52-
/opt/python/${{ matrix.python-abi }}/bin/pytest -v --color=yes
51+
set -euxo pipefail
52+
docker run --rm \
53+
-v "$PWD:$PWD" \
54+
-w "$PWD" \
55+
-e GH_TOKEN \
56+
-e PYXMLSEC_STATIC_DEPS \
57+
-e PY_ABI \
58+
-e MANYLINUX_IMAGE \
59+
-e HOST_UID="$(id -u)" \
60+
-e HOST_GID="$(id -g)" \
61+
"quay.io/pypa/${MANYLINUX_IMAGE}" \
62+
sh .github/scripts/manylinux_build_and_test.sh

0 commit comments

Comments
 (0)