CI, containers and agents#

One file, every machine#

Commit scikitplot-env.toml and run the same command on a laptop, in CI and in a container:

$ scikitplot env create --profile ci --yes

In a Dockerfile the environment is one layer, rebuilt only when the file or a dependency file changes:

COPY scikitplot-env.toml requirements.txt ./
RUN pip install scikit-plots && scikitplot env create --profile ci --yes

Offline and air-gapped machines#

--offline (network = "offline", preset airgap) plans only steps that need no network: uv and micromamba run with --offline, pip with --no-index (give --find-links for a wheel directory), and a step that would download is refused at planning time. To bootstrap micromamba on a machine without network, copy the archive named in the error to ~/.scikitplot/env/tools/cache; its SHA-256 is checked as for a download. A uv bootstrap is installed by pip with --require-hashes: only a wheel whose SHA-256 is pinned in the builder is accepted, from whatever index pip is configured for.

Machine-readable output#

--format json prints one JSON document on stdout: the plan, the result, or {"ok": false, "error": {...}}. --events FILE appends JSON Lines events (plan.started, approval.granted, step.started, step.finished, step.failed, plan.finished), each with a schema, a sequence number and a time. -v and -vv log to stderr; -vv includes the tools’ output.

Every error has a stable code and a hint:

code

Meaning

config_invalid

the request or a file is invalid (exit 2)

config_authority

a file tried to grant an approval (exit 2)

config_schema

a file declares another schema (exit 2)

source_invalid

a dependency file is invalid (exit 2)

backend_unavailable

no usable tool for this request (exit 3)

target_unsupported

the target cannot be built (exit 3)

conversion_refused

Conda packages for a PyPI-only backend (exit 3)

network_forbidden

offline, but a step needs the network (exit 3)

plan_impossible

another reason the plan cannot be made (exit 3)

approval_required

an approval was not given (exit 4)

lock_busy

another run holds the environment (exit 5)

step_failed

a command failed; step and returncode say which (exit 1)

plan_stale

the environment appeared or disappeared while the run waited for the lock; run again (exit 1)

command_not_found

run: the command is not in the environment nor on PATH (exit 127)

Agents#

An agent plans first (scikitplot env plan --format json --profile agent), shows the plan or checks it, and passes approvals explicitly (--approve bootstrap); it never needs a terminal, never gets a prompt, and reads the outcome from --format json and the events. A batch of requests runs from a JSON Lines file:

{"schema": "scikitplot.env.request/v1", "id": "docs", "request": {"name": "docs", "sources": ["docs/requirements.txt"]}}
{"schema": "scikitplot.env.request/v1", "id": "lite", "request": {"name": "lite", "target": "pyodide", "packages": ["six"]}}
$ scikitplot env --format json batch requests.jsonl --dry-run --keep-going