Customize A Runtime#
Use this guide when you want a conda-ship-built runtime with your own package set, runtime name, delegate executable, install location, channels, or documentation URL.
conda-ship is generic. It does not publish a first-party runtime, and it does
not reserve a default runtime name. conda-express
is one downstream distribution that uses conda-ship to publish cx and cxz;
use a runtime name owned by your distribution.
For exact field definitions and alternate manifest formats, see Configuration Reference.
Choose Runtime Identity#
Set runtime-name to the command and base identity users should see:
[tool.conda-ship]
runtime-name = "demo"
runtime-version = "0.1.0"
delegate-executable = "conda"
source-environment = "ship"
Add artifact-name only when the staged command or release file stem should
differ from the base runtime identity:
[tool.conda-ship]
runtime-name = "demo"
artifact-name = "demo-offline"
Avoid publishing downstream builds as cx or cxz; those names identify the
conda-express artifacts maintained in the jezdez/conda-express repository.
Choose An Install Location#
By default, a runtime uses the conda-home install scheme and installs below
~/.conda/RUNTIME, where RUNTIME is the runtime name. Use install-name
when a short command should install into a clearer directory:
[tool.conda-ship]
runtime-name = "cx"
install-scheme = "conda-home"
install-name = "express"
That builds a runtime named cx whose default install path resolves to
~/.conda/express on the user’s machine. Users can still override the resolved
path with the prefix variable derived from the runtime name, such as
CX_PREFIX=/tmp/express cx info.
Use install-scheme = "user-data" when the runtime should install below the
platform user data directory instead of ~/.conda.
If a package manager owns the runtime binary, set installer in the manifest
or pass it from the release job so the provider is retained in runtime
metadata:
[tool.conda-ship]
runtime-name = "demo"
installer = "homebrew"
During automatic bootstrap, that stamp writes Constructor-compatible
.installer.info JSON into the managed prefix. Its name, version, and
platform fields identify the stamped distribution, while type contains the
configured installer value. This metadata identifies the distribution and
installer. It is not a launcher ownership record.
Choose Runtime Packages#
The selected source environment is the complete runtime package set.
conda-ship does not add or require packages by name. Include the configured
delegate executable and everything that delegate needs. A conda distribution
usually includes python, conda, its selected solver plugin, and
conda-spawn when it exposes the conda shell alias.
Record the complete package set in the selected source environment and commit the matching lockfile.
Add conda-self when the generated runtime should let users reset the managed
base prefix back to the packages shipped by the runtime:
[feature.ship.dependencies]
python = ">=3.12"
conda = ">=25.1"
conda-rattler-solver = "*"
conda-spawn = ">=0.1.0"
conda-self = "*"
conda-ship writes conda-meta/initial-state.explicit.txt during bootstrap.
conda-self treats that file as the installer snapshot for reset commands.
Configure Condarc And Base Freezing#
By default, conda-ship does not create .condarc or freeze the managed base
prefix. A downstream conda distribution can opt into both behaviors:
[tool.conda-ship]
condarc-file = "runtime.condarc"
freeze-base = true
Keep runtime.condarc as YAML next to the selected manifest:
channels:
- conda-forge
solver: rattler
auto_activate_base: false
notify_outdated_conda: false
show_channel_urls: true
The builder validates that the file contains a YAML mapping and stamps its
exact text. It does not derive or merge lockfile channels into this file.
Omitting condarc-file leaves .condarc alone. Leaving freeze-base false
also preserves any frozen marker created by an installed package.
Configure Build Input#
Keep package and channel intent in the manifest format owned by your workspace
tool. Keep conda-ship build policy in [tool.conda-ship].
For conda.toml, a minimal downstream runtime project looks like this:
[workspace]
name = "demo"
channels = ["conda-forge"]
platforms = ["linux-64", "osx-arm64", "win-64"]
[feature.ship.dependencies]
python = ">=3.12"
conda = ">=25.1"
conda-rattler-solver = "*"
conda-spawn = ">=0.1.0"
numpy = "*"
pandas = "*"
[environments]
ship = { features = ["ship"], no-default-feature = true }
[tool.conda-ship]
runtime-name = "demo"
runtime-version = "0.1.0"
delegate-executable = "conda"
artifact-layout = "online"
source-environment = "ship"
exclude-packages = ["conda-libmamba-solver"]
docs-url = "https://example.com/demo/"
install-scheme = "conda-home"
install-name = "demo"
installer = "homebrew"
Refresh the source lockfile:
conda workspace lock
For pyproject.toml and Pixi layouts, keep the same [tool.conda-ship] policy
but place workspace package data under the tool-specific sections documented in
Configuration Reference.
Build Locally#
Build the runtime:
cs build
The staged runtime and metadata files are written to dist/.
Build In GitHub Actions#
For CI builds, commit the manifest and lockfile, then point the composite action at that project root:
- uses: actions/checkout@v4
- uses: jezdez/conda-ship@FULL_RELEASE_COMMIT_SHA # X.Y.Z
id: cs
with:
conda-ship-version: "X.Y.Z"
root: .
The action does not run conda workspace lock, pixi lock, or any other solve
step. That keeps release artifacts tied to reviewed project files.
Build An Embedded Variant#
Use the embedded layout when you want a larger single binary that carries the
package archives inside itself:
cs build --artifact-layout embedded
The embedded runtime uses runtime-name by default. Set
artifact-name = "demo-offline" or pass --artifact-name demo-offline when a
release artifact should have a distinct command name.
The embedded runtime detects its built-in bundle automatically during the first invocation. Users do not need to set the bundle or offline environment variables.