Skip to content

feat(cli): publish the bca CLI to PyPI as a pip-installable binary #408

@dekobon

Description

@dekobon

Summary

Build and publish the bca CLI as a pip-installable package so Python
users can install the command-line tool with a single pip install and run
bca from their PATH — no Rust toolchain, no cargo install.

This is distinct from what we already ship:

What PyPI dist Installs Status
PyO3 library bindings (native extension big_code_analysis._native) big-code-analysis (v1.1.0, live) an importable Python module shipped via python-wheels.yml
CLI binary (bca) — this issue big-code-analysis-cli (available) a bca executable on PATH not yet shipped

The library wheel lets you import big_code_analysis. This issue is about
letting pip install … drop the bca executable onto your PATH, the way
pip install ruff gives you the ruff command. The two are independent
deliverables that happen to share a build backend (maturin).

Naming (decided)

Distribution name: big-code-analysis-cli (available on PyPI), shipping a
console command named bca. Users run pip install big-code-analysis-cli,
then bca ….

The literal original ask — pip install bca — is not available: the bca
name on PyPI is already taken by an unrelated project ("Binary Coordinate
Ascent algorithm for feature subset selection", v0.1.0), and our own
big-code-analysis name belongs to our library bindings. The PyPI
distribution name and the installed command name are independent (as
with many tools), so we ship under big-code-analysis-cli — which also lines
up with our crate name and the existing Debian/RPM package name — while the
installed binary stays bca.

Because the dist name differs from the command name, the README and book docs
must state the install command and the resulting bca binary name explicitly
so the split isn't surprising.

Approach

maturin already builds and publishes our library wheels and supports
packaging a Rust binary directly: with bin bindings, the compiled
binary is placed into the wheel as a script and lands on the user's PATH
on install. big-code-analysis-cli is already a pure-binary crate (single
[[bin]] name = "bca", no PyO3 / cdylib), which is exactly the shape maturin
auto-detects for -b bin.

Notable differences from the library-wheel build (python-wheels.yml):

  • Not an extension module, so abi3 is irrelevant. A bin wheel is tagged
    py3-none-<platform> — one wheel per (OS, arch), but a single wheel covers
    every CPython 3.x (and PyPy) on that platform. No per-Python-version matrix.
  • -b bin requires its own pyproject.toml separate from the PyO3
    crate's, because maturin only auto-detects bin bindings when there is no
    pyo3/cdylib target. Land it either in big-code-analysis-cli/ or a small
    dedicated packaging directory; set the [project].name to the chosen dist
    name and read the version from the workspace Cargo.toml (mirror the
    dynamic = ["version"] + [tool.maturin].version setup the library
    pyproject uses, so the wheel version stays in lockstep with the workspace).
  • Feature set: the wheel build must pin the CLI's full grammar set
    (big-code-analysis with all-languages), matching the crate's existing
    dependency (feat(lib): per-language Cargo features for grammar selection #252) — a default-features build would silently drop grammars
    from the published binary.

Build & publish matrix

A new workflow (e.g. python-cli-wheels.yml) modelled on python-wheels.yml:

  • Platform matrix: manylinux_2_28 x86_64 + aarch64 (native ARM runners,
    as the library workflow already does), macOS x86_64 + arm64, Windows
    x86_64. Optionally a musllinux target.
  • Build wheels with maturin build -b bin --release per target; build an
    sdist once.
  • Smoke-test each wheel: pip install it in a clean venv and assert
    bca --version / bca list-metrics runs.
  • Publish to PyPI via Trusted Publishing (OIDC), consistent with how we
    already publish to crates.io in release.yml — no long-lived API token.
  • Decide trigger: tag-driven in lockstep with the workspace release (the
    cleanest, matches release.yml's version contract) vs. its own cadence.

Open questions

  1. Dist namedecided: big-code-analysis-cli (command stays bca).
  2. Scope — CLI (bca) only, or also ship the web server binary
    (bca-web) as a second pip package? Default: bca only this round.
  3. Release coupling — fold CLI-wheel publish into the existing
    release.yml tag flow, or keep a standalone workflow like
    python-wheels.yml. Lockstep versioning argues for coupling to the tag.
  4. Docs — add an install section to big-code-analysis-cli/README.md
    and the book covering the pip path, clearly labelling the dist name and
    the bca command name.
  5. License artefacts — the deb/rpm packaging ships THIRD-PARTY-LICENSES-bca.md
    and man pages; decide whether the wheel should bundle the TPL (and man
    pages) too.

Acceptance criteria

  • A clean machine with only Python (no Rust) can pip install <dist> and
    run bca --version successfully on Linux (x86_64 + aarch64), macOS
    (x86_64 + arm64), and Windows (x86_64).
  • The published wheel carries the full all-languages grammar set
    (verified, e.g., via bca list-metrics / a parse smoke test).
  • Wheels + sdist publish to PyPI via Trusted Publishing, version in
    lockstep with the workspace.
  • README + book document the install command and the dist-vs-command
    naming clearly.
  • CI builds and smoke-tests every target wheel before publish.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestgithub_actionsPull requests that update GitHub Actions codepython-wheelsPR opts in to the manylinux wheel CI matrix

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions