Build a custom cx binary#
This guide shows how to build a cx binary with your own set of conda packages baked in. This is useful when you want to distribute a bootstrapper that includes domain-specific packages (e.g. numpy, pandas) out of the box.
Using the GitHub Action#
The simplest approach. Add a workflow to your repo that calls the cx composite action:
name: Build custom cx
on: [push]
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: jezdez/conda-express@main
id: cx
with:
packages: "python >=3.12, conda >=25.1, conda-rattler-solver, conda-spawn, numpy, pandas"
- uses: actions/upload-artifact@v4
with:
name: ${{ steps.cx.outputs.asset-name }}
path: ${{ steps.cx.outputs.binary-path }}
The action builds cx for the runner’s platform and outputs the path to the binary. Use a matrix to build for multiple platforms.
See the GitHub Action reference for all inputs and outputs.
Using the reusable workflow#
If you want all 5 platforms built without managing a matrix yourself:
name: Build custom cx
on: [push]
jobs:
build-cx:
uses: jezdez/conda-express/.github/workflows/build.yml@main
with:
packages: "python >=3.12, conda >=25.1, conda-rattler-solver, conda-spawn, numpy, pandas"
channels: "conda-forge"
exclude: "conda-libmamba-solver"
Binary artifacts for all platforms are uploaded automatically.
Building locally#
Set environment variables to override the default package list, then build:
git clone https://github.com/jezdez/conda-express.git
cd conda-express
CX_PACKAGES="python >=3.12, conda >=25.1, conda-rattler-solver, conda-spawn, numpy" \
pixi run build
The binary is at target/release/cx.
Available overrides#
Variable |
Effect |
|---|---|
|
Replace the default package list |
|
Replace the default channels |
|
Replace the default exclusions |
Empty values are ignored. See the configuration reference for details on how overrides interact with the lockfile cache.
Choosing packages#
When specifying packages, keep in mind:
Always include the core set:
python,conda,conda-rattler-solver, andconda-spawn(cx depends on these at runtime)Use MatchSpec syntax for version constraints (e.g.
numpy >=1.26)The build performs a full dependency solve at compile time, so all transitive dependencies are resolved and locked
The resulting binary is self-contained with an embedded lockfile