Skip to content

CI Usage

Recommended path: start CI jobs from an Astral uv image, cache $IXT_CACHE_HOME, and let ixt reuse whatever runtimes are already available.

ixt itself is a Python CLI with no third-party Python dependencies. Extra runtimes are backend-specific and lazy:

  • Python tools need uv.
  • Node tools use bun by default, or npm with --runtime node.
  • Binary tools from GitHub/GitLab Releases need neither uv nor bun.

ixt first looks for a valid runtime on PATH. If a backend needs a runtime that is missing, ixt bootstraps only that runtime.


Use an Astral uv image when possible. It gives the CI job Python + uv without making ixt bootstrap its own uv runtime.

image: ghcr.io/astral-sh/uv:python3.13-trixie-slim

variables:
  IXT_HOME: "$CI_PROJECT_DIR/.ixt/home"
  IXT_CACHE_HOME: "$CI_PROJECT_DIR/.ixt/cache"
  UV_CACHE_DIR: "$CI_PROJECT_DIR/.ixt/uv/cache"
  UV_TOOL_DIR: "$CI_PROJECT_DIR/.ixt/uv/tools"
  UV_TOOL_BIN_DIR: "$CI_PROJECT_DIR/.ixt/uv/bin"

cache:
  key: ixt-uv
  paths:
    - .ixt/cache/
    - .ixt/uv/

before_script:
  - apt-get update -qq
  - apt-get install -y -qq --no-install-recommends git ca-certificates
  - export PATH="$UV_TOOL_BIN_DIR:$IXT_HOME/installed/bin:$PATH"
  - uv tool install git+https://gitlab.com/pytgaen-group/ixt.git@v0.7.0
  - ixt environment --sizes
  - ixt cache info
  - ixt doctor --no-network

lint:
  script:
    - ixt tool install ruff
    - ruff check .

Expected behavior:

  • Python tools reuse uv from the image.
  • Binary tools do not require uv or bun.
  • npm tools bootstrap bun only if no suitable bun is already on PATH.

Minimal Ubuntu

ubuntu:* images are intentionally bare. The clean fallback is to install standalone uv first, then install ixt through uv tool.

apt-get update -qq
apt-get install -y -qq --no-install-recommends curl git ca-certificates

curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"

uv tool install git+https://gitlab.com/pytgaen-group/ixt.git@v0.7.0

export IXT_HOME="$PWD/.ixt/home"
export IXT_CACHE_HOME="$PWD/.ixt/cache"
export PATH="$IXT_HOME/installed/bin:$PATH"

ixt environment --sizes
ixt cache info
ixt doctor --no-network

Use the plain python + pip route only when the job explicitly needs to test wheel installation without uv.


Runtime Behavior

Base CI Recommendation ixt reuses ixt may bootstrap
ghcr.io/astral-sh/uv:* Recommended default uv, Python bun if npm backend is used
Ubuntu minimal Install standalone uv, then ixt uv after install bun if npm backend is used
python:* OK for wheel/pip validation Python/pip uv, then bun if needed
node:* Use --runtime node for npm tools node/npm uv if Python backend is used
oven/bun:* Good for npm-heavy jobs bun uv if Python backend is used
Binary-only job No external tool runtime needed none none

The table is the contract: ixt tries to reuse a valid runtime before it downloads anything. Backend installs remain independent.


Cache Policy

Cache regenerable artifacts, not installed environments:

Path Cache? Purpose
$IXT_CACHE_HOME yes downloaded archives, metadata, resolve cache, learned asset patterns
uv cache/tool dirs yes for uv-first jobs uv wheels, metadata, managed Python data, uv tool install result
$IXT_HOME/installed/envs no per-job installed tools; rebuild from declarations
$IXT_HOME/installed/runtimes usually no extracted runtimes; recreate quickly from $IXT_CACHE_HOME

Useful commands:

ixt tool apply
ixt tool upgrade --all
ixt tool upgrade --all -v
ixt cache info
ixt cache prune
ixt runtime info
ixt runtime prune
ixt asset-index export > asset_index.json
ixt cache clear downloads

ixt cache prune keeps the newest two indexed download artifacts per binary repository by default: current + previous. It does not touch installed tools, shims, config, or runtimes.

ixt runtime prune removes unused ixt-managed runtimes from $IXT_HOME/installed/runtimes. It does not touch installed tool envs, shims, config, or cache metadata.

ixt asset-index export is useful when a CI warmup job has already resolved binary assets and you want to keep the learned metadata as a pipeline artifact.

Use ixt tool upgrade --all -v when a CI job needs a compact audit of version resolution work. The final summary separates GitHub latest redirects from real GitHub API calls and also reports GitLab API, PyPI registry, and npm registry lookups. Use -vv only when you need per-package resolver traces in the job logs.

To replay with preloaded metadata and forbid api.github.com calls:

export IXT_ASSET_INDEX="$PWD/asset_index.json"
export IXT_GITHUB_API=never
ixt tool apply

IXT_GITHUB_API=never disables only the GitHub Releases API fallback. Direct latest redirects and release downloads remain allowed.

Asset index and no-API details

For ongoing maintenance, use ixt tool apply to replay the committed ixt.toml, ixt tool upgrade to refresh installed tools within the declared version policy, ixt cache prune to keep regenerable downloads bounded, and ixt runtime prune to remove unused ixt-managed runtimes. A strict lockfile mode is intentionally future work; today, exact pins are the reproducibility tool for CI.


Docker Multi-Stage Images

For a final Docker image that already contains ixt-installed tools, treat $IXT_HOME/installed as the ixt layer. Do not copy the build cache or the user config into the final image.

ixt-owned shims and metadata are relative to the installed layer, so the build stage may assemble the layer under one absolute path and the final stage may copy it under another IXT_HOME.

For mixed Python/npm/binary tools, keep the final image on the same Python base as the build stage, and keep runtime-specific absolute paths in mind. Python venvs created by uv venv can contain absolute interpreter links or script shebangs. npm tools whose shebangs were rewritten to ixt-managed bun can pin that bun path; a final image with system node on PATH avoids that rewrite.

FROM ghcr.io/astral-sh/uv:python3.13-trixie-slim AS tools

ENV IXT_HOME=/opt/ixt \
    IXT_CACHE_HOME=/var/cache/ixt \
    PATH="/opt/ixt/installed/bin:${PATH}"

RUN uv tool install git+https://gitlab.com/pytgaen-group/ixt.git@v0.7.0
COPY ixt.toml /tmp/ixt.toml
RUN ixt tool apply /tmp/ixt.toml
RUN ixt runtime prune

FROM ghcr.io/astral-sh/uv:python3.13-trixie-slim

ENV IXT_HOME=/opt/ixt \
    PATH="/opt/ixt/installed/bin:${PATH}"

COPY --from=tools /opt/ixt/installed /opt/ixt/installed

The final stage needs $IXT_HOME/installed/bin and $IXT_HOME/installed/envs. Managed runtimes under $IXT_HOME/installed/runtimes are copied only if ixt runtime prune kept them. $IXT_CACHE_HOME, uv caches, build temp files, and $IXT_HOME/config stay in the build stage.

For binary-only images, the final stage can be a smaller base such as debian:trixie-slim, as long as the extracted binaries' shared-library requirements are satisfied. Do not use the binary-only pattern for Python tools unless the final image also preserves or repairs the venv's runtime paths.


Diagnostics

For a normal CI job:

ixt environment --sizes
ixt cache info
ixt doctor --no-network

For runtime bootstrap regressions, use the manual Docker matrix from the repo:

./tests/e2e/runtime_matrix.sh --case all

The matrix checks that each backend bootstraps only what it needs.