Skip to content

[AAASM-1215] 🔧 (build): Configure maturin build backend for platform wheel generation#53

Merged
Chisanan232 merged 9 commits into
masterfrom
v0.0.1/AAASM-1215/config/maturin_build_backend
May 23, 2026
Merged

[AAASM-1215] 🔧 (build): Configure maturin build backend for platform wheel generation#53
Chisanan232 merged 9 commits into
masterfrom
v0.0.1/AAASM-1215/config/maturin_build_backend

Conversation

@Chisanan232
Copy link
Copy Markdown
Contributor

@Chisanan232 Chisanan232 commented May 22, 2026

Description

Configures [tool.maturin] in pyproject.toml so AAASM-1217's release workflow (PR #55) can invoke maturin via maturin-action to produce per-platform wheels with the aasm sidecar binary bundled at agent_assembly/bin/aasm.

Hybrid build-backend architecture

The original AC of AAASM-1215 said "Add maturin as the build backend in [build-system]". The literal switch was applied in the first commits, but CI surfaced a real architectural cost:

  • uv sync (run by every test shard) would invoke maturin's pep517 hook
  • That forces a full cargo build of the aa-ffi-python crate on every shard
  • aa-ffi-python transitively needs aa-proto, whose build.rs requires protoc on the runner
  • pyo3 0.20 caps at Python 3.12 while CI runs Python 3.13 (needs PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 env)
  • The existing test pattern already skips tests that need _core when the native module isn't built — making the rust build during uv sync net-negative

After confirming with @bulls23mj1991, this PR adopts a hybrid backend:

Surface Backend used What it does
pip install agent-assembly / uv sync hatchling (default) Builds the universal pure-Python wheel — fast, no rust toolchain, no protoc
Release workflow (release-python.yml) maturin (via maturin-action) Builds per-platform wheels with agent_assembly/bin/aasm bundled

Net diff vs master is 15 lines added — just the new [tool.maturin] block. maturin-action reads [tool.maturin] directly via CLI and doesn't require it to be set as the pep517 backend.

Type of Change

  • 🔧 Configuration

Breaking Changes

  • No

Install path unchanged. New maturin tooling is dormant until the AAASM-1217 release workflow invokes it.

Related Issues

  • Related JIRA ticket: AAASM-1215 (sub-task of Story AAASM-1202, Epic AAASM-1199)

Testing

  • Manual testing performed
  • No tests required (config-only)

Local validations:

  • python -c "import tomllib; tomllib.loads(open('pyproject.toml').read())" parses cleanly
  • uv lock --check — runtime deps unchanged, lock still in sync
  • [tool.maturin].module-name = "agent_assembly._core" matches the existing #[pyclass(module = "agent_assembly._core")] annotation in rust/aa-ffi-python/src/lib.rs

End-to-end exercise of the maturin path (with PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 set at the workflow env block) is the verification scope of AAASM-1217 + AAASM-1219.

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Comments added for complex logic
  • All tests passing

Commit trail

Initial attempt (build-backend = maturin) and subsequent investigation:

  1. 🔧 (pyproject): Switch build-backend from hatchling to maturin
  2. ✨ (pyproject): Add [tool.maturin] config for PyO3 extension build
  3. ✨ (pyproject): Bundle aasm binary at agent_assembly/bin/aasm in wheel
  4. 🗑️ (pyproject): Drop obsolete [tool.hatch.build.targets.*] sections
  5. 🔧 (cargo): Set PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 via .cargo/config.toml
  6. 🔧 (cargo): Move .cargo/config.toml to repo root for cwd-based discovery

Hybrid revert after CI showed protoc dependency would explode CI scope:

  1. 🔧 (pyproject): Restore hatchling as the install-time build backend
  2. 🔧 (pyproject): Restore [tool.hatch.build.targets.*] sections
  3. 🗑️ (cargo): Remove .cargo/config.toml — no longer needed

The commit history preserves the investigation so reviewers see why the hybrid was chosen.

Platform-tagged wheels with bundled Rust binary require maturin
(PyO3 build tool). Hatchling's pure-Python wheel backend cannot
produce per-platform wheels needed for the [runtime] extra.

AAASM-1215
Wires maturin to the existing rust/aa-ffi-python crate. module-name
matches the #[pyclass(module = "agent_assembly._core")] annotation
in rust/aa-ffi-python/src/lib.rs so the compiled cdylib lands at
agent_assembly/_core inside the wheel.

python-source = "." tells maturin the pure-Python package root is
the repo root (i.e. the agent_assembly/ tree alongside pyproject.toml).

AAASM-1215
include with format="wheel" pulls the sidecar binary into the wheel
artifact only (not sdist), matching where runtime.py's
WHEEL_BUNDLED_BIN already searches. Listed unconditionally — maturin
skips entries whose path is missing on disk, so non-runtime builds
still succeed without the binary.

The .exe entry is forward-looking for the Phase 2 Windows wheel
target; current matrix omits it.

AAASM-1215
Hatchling is no longer the build backend; its sdist/wheel target
config is dead config. Maturin's own python-source + include
settings cover the same inclusion concerns.

AAASM-1215
…g.toml

CI runs uv sync on Python 3.13. With the new maturin build backend,
uv sync triggers an editable maturin build → cargo build →
pyo3-ffi build script, which errors because pyo3 0.20 (current pin
in aa-ffi-python) caps at CPython 3.12.

Place the env var in rust/.cargo/config.toml so Cargo (and its
child build scripts) see PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 for
every aa-ffi-python build, without touching CI workflows or the
external reusable workflow that runs uv sync.

The forward-compat flag uses the stable Python ABI subset, which is
already what abi3 wheels target — safe for the existing crate.

AAASM-1215
Cargo discovers .cargo/config.toml by walking PARENT directories of
the current working directory (not the manifest directory). When
maturin pep517 invokes cargo, the cwd is the python-sdk repo root,
not rust/. The previous placement at rust/.cargo/config.toml was
never picked up — CI re-ran with the same pyo3-ffi 3.12 ceiling error.

Move to .cargo/config.toml at the repo root so cargo finds it
regardless of which workspace it's building.

AAASM-1215
Hybrid setup: hatchling builds the universal SDK wheel that
`pip install agent-assembly` and `uv sync` resolve, while maturin
is retained under [tool.maturin] for the release workflow's CLI
invocation (AAASM-1217).

Why: switching the pep517 backend to maturin forced `uv sync` to
compile the Rust extension on every CI shard, which then required
the full Rust toolchain (cargo) + protobuf-compiler on each runner
(aa-proto's build.rs invokes protoc) — none of which the existing
test workflows provide. The native module is already optional at
runtime (tests skip when _core isn't built), so keeping the SDK
install pure-Python preserves that pattern. Platform wheels are
still produced by maturin-action in release-python.yml, which
doesn't read [build-system].

AAASM-1215
Companion to the previous commit's hatchling restore. Hatchling
needs explicit packages = ["agent_assembly"] to know which
directory to bundle into the sdist + universal wheel.

AAASM-1215
The PYO3_USE_ABI3_FORWARD_COMPATIBILITY env var was only needed
because uv sync triggered the pep517 maturin build chain on Python
3.13 (pyo3 0.20 ceiling). With hatchling restored as the install-time
build backend, the Rust extension is no longer built during uv sync;
the env var becomes dead config.

maturin-action in release-python.yml will still need the forward-compat
flag at build time — that's set inline in the workflow's env block
(see native-core-build.yml for the established pattern), not via
.cargo/config.toml.

AAASM-1215
@sonarqubecloud
Copy link
Copy Markdown

@codecov
Copy link
Copy Markdown

codecov Bot commented May 23, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@Chisanan232 Chisanan232 merged commit ca80387 into master May 23, 2026
23 checks passed
@Chisanan232 Chisanan232 deleted the v0.0.1/AAASM-1215/config/maturin_build_backend branch May 23, 2026 03:46
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