Build In GitHub Actions#
Use the composite action when a downstream distribution repository wants conda-ship to build release artifacts in CI.
The action is the public CI interface for conda-ship-built runtimes. Downstream repositories, including conda-express, keep their package set in a committed manifest and lockfile. The action reads that project input and stamps a runtime instead of carrying a copy of the generic builder.
Pin the action to a conda-ship release tag. The action downloads the matching
cs and cs-template release assets, verifies their GitHub
artifact attestations and release SHA256SUMS, and stamps the generated
runtime. It runs cs build --dry-run before the real build so manifest,
lockfile, naming, template, install location, and bundle metadata issues fail
before artifact files are written.
GitHub-hosted runners already include the GitHub CLI used for attestation
verification. Self-hosted runners must provide gh.
Single-Platform Example#
The checked-out repository must contain conda.toml plus conda.lock,
pyproject.toml with [tool.conda] plus conda.lock, pixi.toml plus
pixi.lock, or pyproject.toml with [tool.pixi] plus pixi.lock. These
examples assume the manifest contains [tool.conda-ship].runtime,
[tool.conda-ship].delegate, and a downstream runtime version, unless those
values are supplied as action inputs.
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: jezdez/conda-ship@0.2.1
id: cs
- uses: actions/upload-artifact@v4
with:
name: ${{ steps.cs.outputs.asset-name }}
path: ${{ steps.cs.outputs.dist-path }}
Use a tag for release builds. Branch refs do not have matching release assets.
Project Root Example#
When the downstream manifest lives below the repository root, point the action at that directory:
steps:
- uses: actions/checkout@v4
- uses: jezdez/conda-ship@0.2.1
id: cs
with:
root: dist/demo
The action does not run a solve, generate a manifest, or refresh a lockfile.
Update and commit the lockfile before running release builds.
Release-job metadata such as runtime, runtime-version, delegate,
docs-url, install-scheme, install-name, and install-method can come
from the manifest or from action inputs. The action passes those inputs to
cs build --dry-run, so validation still happens in conda-ship.
External Bundle Example#
Set layout to external when you want to distribute the runtime and package
bundle as separate files:
- uses: jezdez/conda-ship@0.2.1
id: cs
with:
layout: external
- uses: actions/upload-artifact@v4
with:
name: ${{ steps.cs.outputs.asset-name }}
path: ${{ steps.cs.outputs.dist-path }}
Embedded Bundle Example#
Set layout to embedded when the runtime must bootstrap without network
access:
- uses: jezdez/conda-ship@0.2.1
id: cs
with:
layout: embedded
The output runtime uses the z suffix, for example demoz on Unix or
demoz.exe on Windows.
Matrix Builds#
Run the action across operating systems to produce platform-specific runtimes:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
layout: online
runtime: demo
install-method: standalone
- os: macos-15-intel
layout: embedded
runtime: demo
install-method: homebrew
- os: macos-15
layout: embedded
runtime: demo
install-method: homebrew
- os: windows-latest
layout: online
runtime: demo
install-method: standalone
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: jezdez/conda-ship@0.2.1
id: cs
with:
layout: ${{ matrix.layout }}
runtime: ${{ matrix.runtime }}
runtime-version: ${{ github.ref_name }}
delegate: conda
docs-url: https://example.com/demo/
install-scheme: conda-home
install-name: demo
install-method: ${{ matrix.install-method }}
Each job emits an asset name qualified with the runner target triple.
Downstream Release Preparation#
Use dist-path as the source of truth for artifact uploads. It contains the
runtime, optional external bundle, .info.json, .runtime.lock,
.packages.txt, and .sha256 files for that build. The individual path
outputs are still available when release tooling or package-manager wrappers
need to address one file directly.
Attest Runtime Outputs#
For release workflows, attest the complete dist-path before publishing or
wrapping the files. This records the GitHub workflow identity that produced the
runtime output set.
Warning
Use the latest reviewed actions/attest release in your workflow and pin it by
commit SHA. The SHA below is an example, not a recommendation to keep using that
exact revision indefinitely.
permissions:
contents: read
id-token: write
attestations: write
artifact-metadata: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: jezdez/conda-ship@0.2.1
id: cs
- uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0
with:
subject-path: ${{ steps.cs.outputs.dist-path }}/*
- uses: actions/upload-artifact@v4
with:
name: ${{ steps.cs.outputs.asset-name }}
path: ${{ steps.cs.outputs.dist-path }}
The attestation covers the runtime binary, .runtime.lock, .packages.txt,
.info.json, .sha256, and the optional external bundle for that job. Keep
package-manager signing and platform installer signing as separate downstream
steps when those distribution channels require them.