Skip to content

Publish PyEmscripten wheel to PyPI#278

Merged
Alek99 merged 4 commits into
mainfrom
agent/publish-pyemscripten-wheel
Jul 25, 2026
Merged

Publish PyEmscripten wheel to PyPI#278
Alek99 merged 4 commits into
mainfrom
agent/publish-pyemscripten-wheel

Conversation

@Alek99

@Alek99 Alek99 commented Jul 25, 2026

Copy link
Copy Markdown
Member

What changed

  • Build the browser wheel with pinned cibuildwheel 4.1.0 for cp314-pyodide_wasm32 / Pyodide 314.0.0.
  • Target the standardized PEP 783 pyemscripten_2026_0_wasm32 platform and publish the runtime-verified wheel through the existing trusted-PyPI artifact batch.
  • Remove the separate GitHub Release asset publishing path; Pyodide users can now install with await micropip.install("xy").
  • Make the Hatch build hook package Emscripten cdylibs as libxy_core.so based on the target rather than the build host, so cibuildwheel works from both Linux and macOS.
  • Update release guardrails, regression tests, README installation guidance, production-readiness notes, and the changelog.

Why

PEP 783 and Pyodide 314 make pyemscripten_* a standard PyPI wheel platform. The previous pyodide_2025_0_wasm32 wheel could not be uploaded to PyPI and had to be installed from a GitHub Release URL.

A production-equivalent macOS build also exposed that the build hook derived the packaged library suffix from the host. That produced libxy_core.dylib, while Pyodide's dynamic loader expects libxy_core.so; the target-aware destination fixes that masked cross-host bug.

Impact

The next tagged release will publish a Pyodide 314-compatible WASM wheel alongside the native wheels and sdist. Browser users get normal package-name installation through micropip, while the existing ABI/version/content/runtime gates remain release-blocking.

Validation

  • make check — 2,189 passed, 68 skipped; all 8 gates passed (the existing ty findings remain advisory)
  • Focused packaging/workflow tests — 58 passed
  • Real cibuildwheel 4.1.0 build produced xy-0.0.2-py3-none-pyemscripten_2026_0_wasm32.whl
  • scripts/verify_wheel.py --expect-native passed on that artifact
  • Real Pyodide 314.0.0 runtime probe passed: backend=native, ABI 41, min_max=(1,3)

Summary by CodeRabbit

  • New Features
    • WebAssembly wheels now target the standardized PEP 783 PyEmscripten platform and are published directly to PyPI via trusted publishing.
    • Added Pyodide 314 installation instructions for installing xy in the browser using micropip.
  • Bug Fixes
    • Cross-compiling WebAssembly now consistently packages the shared library as libxy_core.so for Pyodide’s loader expectations.
  • Documentation
    • Updated the README and production release checklist/changelog to reflect the new PyEmscripten distribution and Pyodide install flow.
  • Tests / CI
    • Updated CI/release workflow verification to remove the legacy Pyodide publishing path and add stricter wasm-job permission and artifact placement checks.

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Alek99, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 37 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 57ae236c-16e7-44bd-bd84-1f34f858fbfb

📥 Commits

Reviewing files that changed from the base of the PR and between 9eb3e67 and 46f942e.

📒 Files selected for processing (3)
  • scripts/verify_ci_workflow.py
  • spec/process/production-readiness.md
  • tests/test_verify_ci_workflow.py
📝 Walkthrough

Walkthrough

The WASM wheel build now targets PyEmscripten through cibuildwheel and Pyodide 314, packages libxy_core.so, publishes through PyPI, removes the legacy GitHub Release job, and updates workflow validation, tests, documentation, and changelog entries.

Changes

PyEmscripten release flow

Layer / File(s) Summary
Emscripten library packaging
hatch_build.py, tests/test_hatch_build.py
Library naming uses the cargo target and emits libxy_core.so for Emscripten builds, with macOS-host regression coverage.
WASM build and publishing workflow
.github/workflows/release.yml, scripts/verify_ci_workflow.py, tests/test_verify_ci_workflow.py
The WASM job uses cibuildwheel and Pyodide 314, uploads dist-pyemscripten, removes the separate publish-pyodide job, and updates workflow invariants and artifact-placement tests.
Installation and release documentation
README.md, CHANGELOG.md, spec/process/production-readiness.md, tests/test_pyodide_load_smoke.py
Documentation and smoke-test fixtures describe PyPI-hosted PyEmscripten wheels installed with micropip.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ReleaseWASM
  participant CIBuildwheel
  participant Pyodide314
  participant PyPI
  ReleaseWASM->>CIBuildwheel: Build the PyEmscripten wheel
  CIBuildwheel->>ReleaseWASM: Produce wheelhouse/*.whl
  ReleaseWASM->>Pyodide314: Install wheel and run load probe
  Pyodide314->>ReleaseWASM: Return runtime verification
  ReleaseWASM->>PyPI: Publish dist-pyemscripten artifact
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: publishing the PyEmscripten wheel to PyPI.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/publish-pyemscripten-wheel

Comment @coderabbitai help to get the list of available commands.

@Alek99
Alek99 marked this pull request as ready for review July 25, 2026 01:57
@codspeed-hq

codspeed-hq Bot commented Jul 25, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 102 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing agent/publish-pyemscripten-wheel (46f942e) with main (58a3782)

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
tests/test_pyodide_load_smoke.py (1)

22-45: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Cover package-name installation separately.

This test only verifies direct URL forwarding, while the release documentation now promises micropip.install("xy"). Add a Pyodide/PyPI smoke case for package-name resolution, or explicitly identify an existing test that validates the pyemscripten_2026_0_wasm32 wheel is selected.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_pyodide_load_smoke.py` around lines 22 - 45, Add a separate smoke
test alongside test_remote_wheel_url_is_installed_directly that passes the
package name "xy" to pyodide_load_smoke.main and verifies the generated driver
calls micropip.install with that package name, while preserving the existing
direct-URL forwarding assertion. If an existing test already exercises PyPI
resolution, update or reference it to assert selection of the
pyemscripten_2026_0_wasm32 wheel.
.github/workflows/release.yml (1)

134-188: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Add an explicit permissions: block to the wasm job.

This job runs several third-party actions plus cargo build and an ad-hoc npm i under the default (broader) GITHUB_TOKEN permissions. Static analysis (zizmor) flags this as excessive-permissions since no permissions: block scopes it down.

🔒 Proposed fix: scope down default permissions
   wasm:
     name: Wheel PyEmscripten (runtime verified)
     runs-on: ubuntu-latest
+    permissions:
+      contents: read
     steps:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 134 - 188, Add an explicit
least-privilege permissions block to the wasm job, granting only the permissions
required by its checkout and artifact upload steps. Keep the existing build,
verification, runtime probe, and third-party action configuration unchanged.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Around line 60-65: Update the Pyodide 314 installation example in README.md to
load the micropip package with pyodide.loadPackage before the Python import,
preserving the existing micropip.install flow and showing the required
JavaScript/Python sequence.

---

Nitpick comments:
In @.github/workflows/release.yml:
- Around line 134-188: Add an explicit least-privilege permissions block to the
wasm job, granting only the permissions required by its checkout and artifact
upload steps. Keep the existing build, verification, runtime probe, and
third-party action configuration unchanged.

In `@tests/test_pyodide_load_smoke.py`:
- Around line 22-45: Add a separate smoke test alongside
test_remote_wheel_url_is_installed_directly that passes the package name "xy" to
pyodide_load_smoke.main and verifies the generated driver calls micropip.install
with that package name, while preserving the existing direct-URL forwarding
assertion. If an existing test already exercises PyPI resolution, update or
reference it to assert selection of the pyemscripten_2026_0_wasm32 wheel.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f47cb542-bdd3-4191-9d07-dcf1cfbea429

📥 Commits

Reviewing files that changed from the base of the PR and between e94f9de and 29d6bb3.

📒 Files selected for processing (9)
  • .github/workflows/release.yml
  • CHANGELOG.md
  • README.md
  • hatch_build.py
  • scripts/verify_ci_workflow.py
  • spec/process/production-readiness.md
  • tests/test_hatch_build.py
  • tests/test_pyodide_load_smoke.py
  • tests/test_verify_ci_workflow.py

Comment thread README.md
@Alek99
Alek99 merged commit adda414 into main Jul 25, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant