Skip to content

Commit 9e307f5

Browse files
authored
Merge pull request #251 from ducflair/jorgedanisc
fix(ducpy): centralize Pyodide build tooling into a reusable composit…
2 parents 9da3c7b + a5b13fd commit 9e307f5

4 files changed

Lines changed: 127 additions & 71 deletions

File tree

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
name: 'Setup Pyodide Build'
2+
description: 'Install pyodide-build tooling, cross-build environment, and validate wheel platform tag compatibility.'
3+
4+
inputs:
5+
pyodide-version:
6+
description: 'Pyodide version (e.g. 0.29.3). Used for both pyodide-build and xbuildenv.'
7+
required: true
8+
python-version:
9+
description: 'Python version for setup-python step'
10+
required: false
11+
default: '3.13'
12+
13+
outputs:
14+
emscripten-version:
15+
description: 'Emscripten SDK version required by this Pyodide build'
16+
value: ${{ steps.validate.outputs.emscripten_version }}
17+
pyodide-root:
18+
description: 'Path to the Pyodide cross-build root directory'
19+
value: ${{ steps.validate.outputs.pyodide_root }}
20+
wheel-platform-tag:
21+
description: 'Wheel platform tag (e.g. pyodide_2025_0_wasm32)'
22+
value: ${{ steps.validate.outputs.wheel_platform_tag }}
23+
24+
runs:
25+
using: 'composite'
26+
steps:
27+
- name: Setup Python
28+
uses: actions/setup-python@v5
29+
with:
30+
python-version: ${{ inputs.python-version }}
31+
32+
- name: Install pyodide-build and validate tooling
33+
id: validate
34+
shell: bash
35+
run: |
36+
PYODIDE_VERSION="${{ inputs.pyodide-version }}"
37+
38+
python -m pip install --upgrade pip
39+
pip install "pyodide-build==${PYODIDE_VERSION}" "wheel<0.44"
40+
41+
# Verify pyodide CLI works (catches import errors like wheel.cli removal)
42+
pyodide --help > /dev/null
43+
44+
# Install the matching cross-build environment explicitly.
45+
# Without this, `pyodide build` would auto-install the latest xbuildenv,
46+
# which may have an incompatible lockfile format (e.g. 0.29.4 lockfile
47+
# missing `info.version` causes pydantic ValidationError in 0.29.3).
48+
pyodide xbuildenv install "${PYODIDE_VERSION}"
49+
50+
# Derive PYODIDE_ROOT — the xbuildenv install prints its path,
51+
# and `pyodide config` requires a full Pyodide checkout Makefile.
52+
XBUILD_DIR="$(pwd)/.pyodide-xbuildenv-${PYODIDE_VERSION}/${PYODIDE_VERSION}/xbuildenv"
53+
if [ ! -d "$XBUILD_DIR/pyodide-root" ]; then
54+
XBUILD_DIR="$HOME/.pyodide-xbuildenv-${PYODIDE_VERSION}/${PYODIDE_VERSION}/xbuildenv"
55+
fi
56+
PYODIDE_ROOT="$XBUILD_DIR/pyodide-root"
57+
58+
if [ ! -d "$PYODIDE_ROOT" ]; then
59+
echo "ERROR: PYODIDE_ROOT not found at $PYODIDE_ROOT"
60+
exit 1
61+
fi
62+
63+
echo "PYODIDE_ROOT=$PYODIDE_ROOT" >> $GITHUB_ENV
64+
echo "pyodide_root=$PYODIDE_ROOT" >> $GITHUB_OUTPUT
65+
66+
# Get Emscripten version (needed for emsdk setup in release workflow)
67+
EMSCRIPTEN_VERSION=$(python3 -c "
68+
import os
69+
os.environ['PYODIDE_ROOT'] = '$PYODIDE_ROOT'
70+
from pyodide_build.build_env import get_build_environment_vars
71+
from pathlib import Path
72+
print(get_build_environment_vars(Path(os.environ['PYODIDE_ROOT']))['PYODIDE_EMSCRIPTEN_VERSION'])
73+
")
74+
echo "emscripten_version=${EMSCRIPTEN_VERSION}" >> $GITHUB_OUTPUT
75+
echo "Emscripten version: ${EMSCRIPTEN_VERSION}"
76+
77+
# Verify wheel platform tag — this is the tag used in the .whl filename.
78+
# wheel_platform() returns the build platform tag (e.g. pyodide_2025_0_wasm32)
79+
# NOT the install-compatibility tags from pyodide_tags() where emscripten comes first.
80+
TAG=$(python3 -c "
81+
import os
82+
os.environ['PYODIDE_ROOT'] = '$PYODIDE_ROOT'
83+
from pyodide_build.build_env import wheel_platform
84+
print(wheel_platform())
85+
")
86+
echo "wheel_platform_tag=$TAG" >> $GITHUB_OUTPUT
87+
echo "Pyodide wheel platform tag: $TAG"
88+
89+
if echo "$TAG" | grep -q "pyodide_"; then
90+
echo "Wheel platform tag is pyodide_* — OK (compatible with Pyodide ${PYODIDE_VERSION} runtime)"
91+
else
92+
echo "ERROR: Wheel platform tag is '$TAG', expected pyodide_*"
93+
echo "This means the built wheel will NOT be compatible with the Pyodide ${PYODIDE_VERSION} runtime."
94+
exit 1
95+
fi

.github/workflows/pr-checks.yml

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -226,39 +226,9 @@ jobs:
226226

227227
- name: Validate Pyodide build tooling
228228
if: needs.release-check.outputs.ducpy == 'true'
229-
run: |
230-
python -m pip install --upgrade pip
231-
pip install "pyodide-build==0.29.3" "wheel<0.44"
232-
233-
# Verify pyodide CLI works (catches import errors like the wheel.cli removal)
234-
pyodide --help > /dev/null
235-
236-
# Install cross-build environment
237-
pyodide xbuildenv install 0.29.3
238-
XBUILD_DIR="$(pwd)/.pyodide-xbuildenv-0.29.3/0.29.3/xbuildenv"
239-
if [ ! -d "$XBUILD_DIR/pyodide-root" ]; then
240-
XBUILD_DIR="$HOME/.pyodide-xbuildenv-0.29.3/0.29.3/xbuildenv"
241-
fi
242-
export PYODIDE_ROOT="$XBUILD_DIR/pyodide-root"
243-
echo "PYODIDE_ROOT=$PYODIDE_ROOT"
244-
245-
# Check wheel platform tag — this is the tag used in the .whl filename.
246-
# pyodide_tags() returns install-compatibility tags (emscripten first), but
247-
# wheel_platform() returns the actual build platform tag (e.g. pyodide_2025_0_wasm32).
248-
TAG=$(python3 -c "
249-
import os
250-
os.environ['PYODIDE_ROOT'] = '$PYODIDE_ROOT'
251-
from pyodide_build.build_env import wheel_platform
252-
print(wheel_platform())
253-
")
254-
echo "Pyodide wheel platform tag: $TAG"
255-
if echo "$TAG" | grep -q "pyodide_"; then
256-
echo "Wheel platform tag is pyodide_* — OK (compatible with Pyodide 0.29.3 runtime)"
257-
else
258-
echo "ERROR: Wheel platform tag is '$TAG', expected pyodide_*"
259-
echo "This means the built wheel will NOT be compatible with the Pyodide 0.29.3 runtime."
260-
exit 1
261-
fi
229+
uses: ./.github/actions/setup-pyodide-build
230+
with:
231+
pyodide-version: '0.29.3'
262232

263233
# ──────────────────────────────────────────────────────────────────────
264234
# Phase 3: Summary & gate check

.github/workflows/release-ducpy.yml

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ jobs:
1414
runs-on: ubuntu-latest
1515
env:
1616
UV_PYTHON: "3.13"
17+
PYODIDE_VERSION: "0.29.3"
1718
concurrency:
1819
group: release-ducpy
1920
cancel-in-progress: false
@@ -69,49 +70,18 @@ jobs:
6970
fi
7071
working-directory: ./packages/ducpy
7172

72-
- name: Install Pyodide build tooling
73+
- name: Setup Pyodide build tooling
7374
id: pyodide_tooling
7475
if: steps.release.outputs.status == 'success'
75-
run: |
76-
python -m pip install --upgrade pip
77-
pip install "pyodide-build==0.29.3" "wheel<0.44"
78-
pyodide xbuildenv install 0.29.3
79-
XBUILD_DIR="$(pwd)/.pyodide-xbuildenv-0.29.3/0.29.3/xbuildenv"
80-
if [ ! -d "$XBUILD_DIR/pyodide-root" ]; then
81-
XBUILD_DIR="$HOME/.pyodide-xbuildenv-0.29.3/0.29.3/xbuildenv"
82-
fi
83-
export PYODIDE_ROOT="$XBUILD_DIR/pyodide-root"
84-
85-
# Get Emscripten version (needed for emsdk setup)
86-
EMSCRIPTEN_VERSION=$(python3 -c "
87-
import os
88-
os.environ['PYODIDE_ROOT'] = '$PYODIDE_ROOT'
89-
from pyodide_build.build_env import get_build_environment_vars
90-
from pathlib import Path
91-
print(get_build_environment_vars(Path(os.environ['PYODIDE_ROOT']))['PYODIDE_EMSCRIPTEN_VERSION'])
92-
")
93-
echo "emscripten_version=${EMSCRIPTEN_VERSION}" >> $GITHUB_OUTPUT
94-
95-
# Verify wheel platform tag is pyodide_* (not pyemscripten_*)
96-
TAG=$(python3 -c "
97-
import os
98-
os.environ['PYODIDE_ROOT'] = '$PYODIDE_ROOT'
99-
from pyodide_build.build_env import wheel_platform
100-
print(wheel_platform())
101-
")
102-
echo "Pyodide wheel platform tag: $TAG"
103-
if echo "$TAG" | grep -q "pyodide_"; then
104-
echo "Wheel platform tag is pyodide_* — OK"
105-
else
106-
echo "ERROR: Wheel platform tag is '$TAG', expected pyodide_*"
107-
exit 1
108-
fi
76+
uses: ./.github/actions/setup-pyodide-build
77+
with:
78+
pyodide-version: ${{ env.PYODIDE_VERSION }}
10979

11080
- name: Setup Emscripten SDK
11181
if: steps.release.outputs.status == 'success'
11282
uses: mymindstorm/setup-emsdk@v14
11383
with:
114-
version: ${{ steps.pyodide_tooling.outputs.emscripten_version }}
84+
version: ${{ steps.pyodide_tooling.outputs.emscripten-version }}
11585

11686
- name: Setup Rust nightly for Pyodide
11787
if: steps.release.outputs.status == 'success'
@@ -122,13 +92,34 @@ jobs:
12292
- name: Build Pyodide wheel
12393
if: steps.release.outputs.status == 'success'
12494
working-directory: ./packages/ducpy
95+
env:
96+
PYODIDE_ROOT: ${{ steps.pyodide_tooling.outputs.pyodide-root }}
12597
run: |
12698
TAG=$(git describe --tags --abbrev=0 --match 'ducpy@*')
12799
VERSION="${TAG#ducpy@}"
128100
echo "Building Pyodide wheel for version ${VERSION}"
129101
uv run python scripts/sync_schema.py
130102
RUSTUP_TOOLCHAIN=nightly SETUPTOOLS_SCM_PRETEND_VERSION="${VERSION}" pyodide build --outdir dist
131103
104+
- name: Verify wheel platform tag
105+
if: steps.release.outputs.status == 'success'
106+
working-directory: ./packages/ducpy
107+
run: |
108+
WHEEL=$(find dist -name '*.whl' | head -1)
109+
if [ -z "$WHEEL" ]; then
110+
echo "ERROR: No wheel found in dist/"
111+
exit 1
112+
fi
113+
echo "Built wheel: $WHEEL"
114+
EXPECTED_TAG="${{ steps.pyodide_tooling.outputs.wheel-platform-tag }}"
115+
if echo "$WHEEL" | grep -q "$EXPECTED_TAG"; then
116+
echo "Wheel filename contains expected tag '$EXPECTED_TAG' — OK"
117+
else
118+
echo "ERROR: Wheel filename does not contain expected tag '$EXPECTED_TAG'"
119+
echo "This means the built wheel is incompatible with the Pyodide ${{ env.PYODIDE_VERSION }} runtime."
120+
exit 1
121+
fi
122+
132123
- name: Upload wheels to GitHub release
133124
if: steps.release.outputs.status == 'success'
134125
env:
@@ -158,4 +149,4 @@ jobs:
158149
event-type: trigger-web-deployment
159150
token: ${{ secrets.GITHUB_TOKEN }}
160151
client-payload: |
161-
{"source": "release-ducpy", "web_changed": "false", "success": "true"}
152+
{"source": "release-ducpy", "web_changed": "false", "success": "true"}

packages/ducpy/src/ducpy/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@
2727
from .enums import *
2828
from .parse import (DucData, get_external_file, list_external_files, parse_duc,
2929
parse_duc_lazy)
30-
from .search import *
3130
from .serialize import DUC_SCHEMA_VERSION, serialize_duc
31+
from .search import *
3232
from .utils import *

0 commit comments

Comments
 (0)