Metadata-Version: 2.4
Name: conda-ship
Version: 0.2.0
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Rust
Requires-Dist: conda>=25.1
Requires-Dist: pyproject-hooks>=1.2
Requires-Dist: tomli>=1.1 ; python_full_version < '3.11'
License-File: LICENSE
Summary: Conda plugin entry point for the conda-ship runtime builder.
Home-Page: https://jezdez.github.io/conda-ship/
Author-email: Jannis Leidel <jannis@leidel.info>
License-Expression: BSD-3-Clause
Requires-Python: >=3.10
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: repository, https://github.com/jezdez/conda-ship

# conda-ship

[![CI](https://github.com/jezdez/conda-ship/actions/workflows/ci.yml/badge.svg)](https://github.com/jezdez/conda-ship/actions/workflows/ci.yml)
[![Docs](https://github.com/jezdez/conda-ship/actions/workflows/docs.yml/badge.svg)](https://jezdez.github.io/conda-ship/)
[![zizmor](https://img.shields.io/badge/%F0%9F%8C%88-zizmor-white?labelColor=white)](https://github.com/jezdez/conda-ship/actions/workflows/zizmor.yml)
[![License](https://img.shields.io/github/license/jezdez/conda-ship)](https://github.com/jezdez/conda-ship/blob/main/LICENSE)
[![Python: 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://python.org)

Build ready-to-run conda runtimes from solved conda environments.

`conda-ship` is a generic builder for single-binary conda runtimes. It
provides the `cs` builder CLI, the `cs-template` generic runtime template, a
composite GitHub Action, and an optional Python adapter that exposes
`conda ship` inside conda.

The project is currently alpha and pre-1.0. The split from
[`conda-express`](https://jezdez.github.io/conda-express/) is now explicit:
conda-ship owns the reusable build/runtime machinery, while downstream
distributions own their package sets, runtime names, release channels, installer
wrappers, and user documentation. conda-express is one downstream distribution
maintained by Jannis Leidel; it uses conda-ship to publish the `cx` and `cxz`
runtimes.

## Quickstart

This shortest path uses conda-workspaces to create a solved source environment,
then builds an online runtime named `demo`:

```bash
conda create -n cs-demo -c conda-forge python pip conda-workspaces
conda activate cs-demo
python -m pip install conda-ship

mkdir demo-runtime
cd demo-runtime
conda workspace init --format conda --name demo-runtime
conda workspace add --feature ship --no-lockfile-update \
  "python>=3.12" \
  "conda>=25.1" \
  conda-rattler-solver \
  "conda-spawn>=0.1.0"
cat >> conda.toml <<'TOML'

[tool.conda-ship]
runtime = "demo"
delegate = "conda"
layout = "online"
source-environment = "ship"
exclude = ["conda-libmamba-solver"]
TOML

conda workspace lock
cs inspect
cs build --dry-run
cs build
./dist/demo --version
```

![Quickstart: inspect, preview, build, and run a stamped runtime](demos/quickstart.gif)

For a guided walkthrough with Pixi, bootstrap, status, uninstall, and embedded
runtime examples, see the
[first runtime tutorial](https://jezdez.github.io/conda-ship/tutorials/first-runtime/).

## What It Builds

conda-ship stages a runtime binary plus release metadata:

- `.runtime.lock`: the lockfile stamped into the runtime
- `.packages.txt`: tab-separated package records for quick inspection
- `.info.json`: artifact metadata for release tooling
- `.sha256`: checksums for staged files
- optional `.bundle.tar.zst`: compressed package archives for offline builds

The runtime itself has a small management surface: `bootstrap`, `status`,
`shell`, and `uninstall`. Other commands pass through to the configured
delegate executable after bootstrap, usually `conda`.

## Artifact Layouts

| Layout | Output | Bootstrap behavior |
| --- | --- | --- |
| `online` | `<runtime>` | Downloads packages from the stamped runtime lock. |
| `external` | `<runtime>` plus `<runtime>.bundle.tar.zst` | Uses a separate package bundle for offline-capable installs. |
| `embedded` | `<runtime>z` | Embeds the compressed package bundle in one binary. |

## Project Input

conda-ship builds from an already solved source environment. It does not solve
loose matchspecs in the GitHub Action and it does not define a package set of
its own.

Supported manifest and lockfile pairs:

- `conda.toml` plus `conda.lock`
- `pyproject.toml` with `[tool.conda]` plus `conda.lock`
- `pixi.toml` plus `pixi.lock`
- `pyproject.toml` with `[tool.pixi]` plus `pixi.lock`

The package and channel intent lives in the selected source environment.
`[tool.conda-ship]` only records conda-ship build policy:

```toml
[tool.conda-ship]
runtime = "demo"
delegate = "conda"
layout = "online"
source-environment = "ship"
exclude = ["conda-libmamba-solver"]
```

The selected source environment must include the runtime contract packages:
`conda`, `conda-rattler-solver`, and `conda-spawn`.

## Local Workflow

Packaged builds find `cs-template` next to the installed `cs` executable.
Use `--template` only for an explicit template path, custom packaging, or
cross-builds.

```bash
cs inspect
cs build --dry-run
cs build
cs build --layout embedded
cs run -- --path /tmp/demo-smoke bootstrap
```

`cs inspect` is the preflight command. It derives the runtime lock, validates the
selected source environment, applies package exclusions, and prints the package
set without writing artifacts.

![Inspect a source environment before shipping it](demos/inspect.gif)

Use `cs build --dry-run` to preview the runtime metadata and staged release
asset paths before writing files.

![Preview conda-ship runtime artifacts](demos/dry-run.gif)

After a real build, verify the staged artifacts and inspect the release metadata
before handing them to downstream packaging or signing.

![Verify staged conda-ship artifacts](demos/verify.gif)

The staged runtime is a stamped copy of the generic runtime template with its
own command surface before pass-through to the configured delegate.

![Run a generated conda-ship runtime](demos/runtime-cli.gif)

## GitHub Actions

The repository root is also a composite GitHub Action for downstream release
jobs:

```yaml
- uses: jezdez/conda-ship@0.2.0
  id: cs
  with:
    layout: embedded
```

The action expects a committed manifest and matching lockfile. It downloads the
tagged `cs`, `cs-template`, and `SHA256SUMS` release assets for the runner,
verifies their GitHub Artifact Attestations, checks the release checksums, runs
`cs build --dry-run`, and then stages the runtime into a `dist-path` output.

Use release tags for release builds. Branch refs do not have matching
conda-ship release assets.

## Packaging

conda-ship is not an OS installer generator. It does not target `.sh`, `.pkg`,
or `.msi` output directly. It produces runtimes that can be distributed as
GitHub Release assets or wrapped by Homebrew, constructor, Docker, enterprise
packaging systems, and other release tooling.

The PyPI package installs the `cs` builder, the `cs-template` runtime template,
and the Python adapter together. The adapter makes `conda ship` a shortcut for
the same builder when installed in a conda environment; it does not make
conda-ship part of conda itself. A future conda package should install the same
pieces into one environment.

## What Belongs Downstream

Downstream distributions decide:

- runtime names and delegates
- package sets and channels
- package exclusions
- install schemes and install names
- documentation URLs
- release channels and installers
- signing, SBOM, and in-toto provenance for final artifacts

conda-ship verifies the inputs it consumes and the package archives it stages or
installs, but downstream release systems should sign and attest the final
runtime artifacts after `cs build`.

## Documentation

Full documentation is available at
[jezdez.github.io/conda-ship](https://jezdez.github.io/conda-ship/).

Useful starting points:

- [Build your first runtime](https://jezdez.github.io/conda-ship/tutorials/first-runtime/)
- [Build in GitHub Actions](https://jezdez.github.io/conda-ship/how-to/build-in-github-actions/)
- [Configuration reference](https://jezdez.github.io/conda-ship/reference/configuration/)
- [Project boundaries](https://jezdez.github.io/conda-ship/explanation/project-boundaries/)

## Development

```bash
pixi install
pixi run test
pixi run lint
pixi run -e test pytest
pixi run docs
```

The terminal demos are generated from `demos/*.tape` with
[VHS](https://github.com/charmbracelet/vhs):

```bash
pixi run demos
pixi run demos inspect
```

The tapes build local debug `cs` and `cs-template` binaries in hidden setup so
the visible commands match the packaged workflow.

Run `cargo generate-lockfile` after changing Cargo metadata and `pixi lock`
after changing pixi metadata.

## License

BSD-3-Clause

