Repository navigation
Conversation
Add a release workflow that builds abi3 wheels for linux x86_64/aarch64, macOS x86_64/arm64 and windows x86_64 plus an sdist, runs the Python test suite against each installed wheel, and publishes to PyPI via trusted publishing on `v*` tags. Manual runs default to a build-and-test dry run. Rename the distribution to `bloqade-ppvm` (`ppvm` is taken on PyPI; the import name is unchanged), fill in the package metadata, and take the version from ppvm-python-native's Cargo.toml. Enable AES for aarch64 Linux in .cargo/config.toml: gxhash refuses to compile there otherwise, which would break the linux-aarch64 wheel. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Apache-2.0 requires redistributions to carry the license text and the NOTICE file. Packaging can't reference files outside ppvm-python/, so copy the repo-root files there and list them in `license-files`. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Move version, edition, license and repository into [workspace.package] and inherit them in every crate, so the Rust crates and the bloqade-ppvm Python package (via ppvm-python-native) release under one version. Add a description to the 12 crates that will be published, and mark the root examples package, ppvm-traits-2 and ppvm-python-native `publish = false`. Symlink LICENSE and NOTICE into each published crate so the crates.io packages carry them, as Apache-2.0 requires. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Replace the tag-triggered release.yml with release-plz.yml, modelled on vihaco. On each push to main, release-plz maintains a release PR and, once it is merged, publishes the crates to crates.io and creates a single `v0.x.y` tag and GitHub release. When it released, the same run builds, tests and publishes the bloqade-ppvm wheels to PyPI. Manual runs do a wheel dry run, with an opt-in PyPI publish for bootstrap and recovery. release-plz.toml keeps all published crates in one version group with `ppvm-cli` owning the tag and the root CHANGELOG.md. Pin release-plz in mise.toml for local previews, and document the release process, including the one-time 0.1.0 bootstrap, in the Developer Guide. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Release serialization, portable wheel CPU targeting, and release documentation need correction before publishing.
Review effort: Balanced
Findings: 2
Open (4)
What changed in this PR
Adds lockstep Rust/Python release automation using a shared workspace version and release-plz.
Changes:
- Configures crates.io and PyPI publishing with tested cross-platform artifacts.
- Renames the Python distribution to
bloqade-ppvmand adds package metadata. - Documents releases and enables aarch64 compilation.
| File | Description |
|---|---|
.cargo/config.toml |
Enables aarch64 AES compilation. |
.github/workflows/release-plz.yml |
Builds, tests, and publishes releases. |
Cargo.toml |
Defines shared workspace metadata. |
release-plz.toml |
Configures lockstep crate releases. |
mise.toml |
Pins release-plz locally. |
docs/src/pages/develop.astro |
Documents the release process. |
ppvm-python/pyproject.toml |
Renames and enriches Python metadata. |
ppvm-python/uv.lock |
Records the renamed distribution. |
ppvm-python/LICENSE |
Packages licensing terms. |
ppvm-python/NOTICE |
Packages attribution notices. |
ppvm-python/AUTHORS |
Packages copyright holders. |
crates/ppvm-cli/Cargo.toml |
Adds publish metadata. |
crates/ppvm-pauli-sum/Cargo.toml |
Adds publish metadata. |
crates/ppvm-pauli-word/Cargo.toml |
Adds publish metadata. |
crates/ppvm-python-native/Cargo.toml |
Inherits version; disables publishing. |
crates/ppvm-stim/Cargo.toml |
Adds publish metadata. |
crates/ppvm-sym/Cargo.toml |
Adds publish metadata. |
crates/ppvm-tableau/Cargo.toml |
Adds publish metadata. |
crates/ppvm-tableau-sum/Cargo.toml |
Adds publish metadata. |
crates/ppvm-traits/Cargo.toml |
Adds publish metadata. |
crates/ppvm-traits-2/Cargo.toml |
Inherits version; disables publishing. |
crates/ppvm-tui/Cargo.toml |
Adds publish metadata. |
crates/ppvm-vihaco/Cargo.toml |
Adds publish metadata. |
crates/stim-parser/Cargo.toml |
Adds publish metadata. |
crates/vihaco-circuit-isa/Cargo.toml |
Adds publish metadata. |
crates/ppvm-cli/LICENSE |
Includes the workspace license. |
crates/ppvm-cli/NOTICE |
Includes workspace notices. |
crates/ppvm-pauli-sum/LICENSE |
Includes the workspace license. |
crates/ppvm-pauli-sum/NOTICE |
Includes workspace notices. |
crates/ppvm-pauli-word/LICENSE |
Includes the workspace license. |
crates/ppvm-pauli-word/NOTICE |
Includes workspace notices. |
crates/ppvm-stim/LICENSE |
Includes the workspace license. |
crates/ppvm-stim/NOTICE |
Includes workspace notices. |
crates/ppvm-sym/LICENSE |
Includes the workspace license. |
crates/ppvm-sym/NOTICE |
Includes workspace notices. |
crates/ppvm-tableau/LICENSE |
Includes the workspace license. |
crates/ppvm-tableau/NOTICE |
Includes workspace notices. |
crates/ppvm-tableau-sum/LICENSE |
Includes the workspace license. |
crates/ppvm-tableau-sum/NOTICE |
Includes workspace notices. |
crates/ppvm-traits/LICENSE |
Includes the workspace license. |
crates/ppvm-traits/NOTICE |
Includes workspace notices. |
crates/ppvm-tui/LICENSE |
Includes the workspace license. |
crates/ppvm-tui/NOTICE |
Includes workspace notices. |
crates/ppvm-vihaco/LICENSE |
Includes the workspace license. |
crates/ppvm-vihaco/NOTICE |
Includes workspace notices. |
crates/stim-parser/LICENSE |
Includes the workspace license. |
crates/stim-parser/NOTICE |
Includes workspace notices. |
crates/vihaco-circuit-isa/LICENSE |
Includes the workspace license. |
crates/vihaco-circuit-isa/NOTICE |
Includes workspace notices. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| - os: ubuntu-latest | ||
| target: x86_64-unknown-linux-gnu | ||
| - os: ubuntu-latest | ||
| target: aarch64-unknown-linux-gnu |
| name = "ppvm" | ||
| version = "0.1.0" | ||
| description = "Add your description here" | ||
| name = "bloqade-ppvm" |
|
Give the release job a concurrency group so two quick merges can't race to publish the same version. In the Developer Guide, add the internal dependency requirements and Cargo.lock refresh to the manual bump recipe (a minor bump otherwise fails to resolve), and use the new `bloqade-ppvm` name in the reinstall command. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Published crates and generic aarch64 wheels currently rely on an AES configuration that is either unavailable to consumers or unsafe on CPUs without AES.
Review effort: Balanced
Findings: 2
Open (3)
Resolved since last review (2)
| [target.'cfg(all(target_arch = "aarch64", target_os = "linux"))'] | ||
| rustflags = ["-C", "target-feature=+aes,+neon"] |
## Summary gxhash only compiles when AES is enabled at compile time. The repo's `.cargo/config.toml` enables it for builds inside this repo, but that config doesn't apply to crates that depend on ppvm. So any crate depending on `ppvm-pauli-sum`, `ppvm-tableau-sum` and so on failed to build on x86_64 and aarch64 Linux unless its users set `RUSTFLAGS` themselves. That blocks publishing to crates.io (#237). `ppvm-tableau-sum` uses gxhash unconditionally, so turning the feature off wasn't a workaround. This extends the existing wasm32 fallback. The gxhash dependency and every use of it are now gated on `all(target_feature = "aes", any(target_arch = "x86_64", target_arch = "aarch64"))` instead of "not wasm32": - **Without AES,** the gxhash configs are left out and the fingerprint in `ppvm-tableau-sum` uses fxhash, as on wasm. - **With AES** (repo builds, Apple Silicon, or `RUSTFLAGS="-C target-feature=+aes"`), nothing changes. - **Side fix:** the dashmap `ByteGxHash` configs were never gated, so `--no-default-features --features dashmap` failed to compile. It now builds. - **Docs:** the landing page, Developer Guide and usage skill no longer tell non-x86 users to drop gxhash by hand. No simulator or gate code changes. The edits are 13 `cfg` attributes on the hashing configs, the hashing hook and the fingerprint function, plus the four `Cargo.toml` dependency tables. ## Test plan - [x] A scratch crate outside the repo that depends on `ppvm-pauli-sum` + `ppvm-tableau-sum` builds on x86_64, aarch64 Linux and Apple Silicon (previously failed on the first two), and uses gxhash with `+aes`. - [x] `cargo test --workspace` (gxhash path): 1141 passed. - [x] Fallback path, with AES forced off (`-C target-feature=-aes`): 678 passed across traits, pauli-word, pauli-sum, tableau-sum, tableau and stim, doctests included. - [x] `cargo clippy --workspace --all-targets -D warnings`, the x86_64 all-targets build, the wasm32 CI build, `--no-default-features --features dashmap`. - [x] Python tests: 221 passed. The docs build and the pre-commit hooks pass. The benches still use the gxhash configs unguarded. They're only built by `cargo bench` / `--all-targets`, which CI runs on x86_64 with AES enabled. **Follow-up for #237:** with this merged, the linux-aarch64 wheel no longer needs the `+aes,+neon` flag that #237 adds. Removing it makes that wheel portable to CPUs without AES (e.g. Raspberry Pi 4), at some speed cost on AES-capable ARM servers. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🔵 Needs a closer look
Generic wheels currently require optional AES CPU instructions and may crash on otherwise supported systems.
3 open findings
🧠 Review effort: Balanced
Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.



Summary
Sets up automated releases of the Rust crates (crates.io) and the Python package (PyPI) under one shared version, modelled on vihaco's release-plz setup.
bloqade-ppvm(ppvmis taken on PyPI);import ppvmis unchanged. Adds real metadata (description,Apache-2.0, URLs, classifiers) and shipsLICENSE,NOTICEandAUTHORSin the wheel and sdist. The version now comes from Cargo.[workspace.package]holds version/edition/license/repository and every crate inherits it, includingppvm-python-native, so the Python version follows automatically.LICENSE/NOTICEsymlinks so the packages carry them. The rootppvmexamples package,ppvm-traits-2andppvm-python-nativearepublish = false..github/workflows/release-plz.yml: on each push tomain, release-plz maintains a release PR. Once that PR is merged, it publishes the crates and creates onev0.x.ytag and GitHub release. If something was released, the same run builds abi3 wheels (linux x86_64/aarch64, macOS x86_64/arm64, windows x86_64) and an sdist, runs the Python test suite against each installed wheel, and publishes to PyPI. Both registries use trusted publishing (OIDC). Manual runs build and test only, with an opt-inpublish_pypiswitch for the first release and for recovery..cargo/config.toml.Known limitation: release-plz only tracks published crates, so changes confined to
ppvm-python/orppvm-python-nativedon't open a release PR. To release them, merge a PR that bumps[workspace.package].version(see § 8.2).Before / after merge
pypienvironment (the PyPI pending publisher already points atrelease-plz.yml+pypi).ppvm-tableau-sum,vihaco-circuit-isa,ppvm-vihaco) are drafts.vihaco-circuit-isafrom this repo is OK.main.Test plan
cargo package --workspace: every crate builds from its packaged form (largest is 1.5 MiB).cargo check --target aarch64-unknown-linux-gnuon the gxhash crates fails without the fix and passes with it.uv build(sdist, then a wheel built from it):twine checkpasses, the metadata is correct, and the license files are included.release-plz updateon a scratch copy reads the config: 12 crates in one group,ppvm-clilast, single rootCHANGELOG.md.npm run astro:build) pass.🤖 Generated with Claude Code