Skip to content

mise

Recipe card from the charly-image plugin (Kinds — schema authoring).

mise — the dev-tool manager builder + verb

Section titled “mise — the dev-tool manager builder + verb”

The mise plugin provisions mise (jdx/mise) into images and runs mise commands as plan steps. It contributes two capabilities, both served by candy/plugin-mise:

Capability Surface
builder:mise a build-time multi-stage (OpResolve) that provisions mise into images
verb:mise a plan-step verb — mise: <command> — OpEmit at image build, OpExecute at check/deploy

A candy opts into the mise multi-stage with its external_builder: mise field (the reserved word of an OUT-OF-TREE builder plugin). The generator resolves the word, Invoke(OpResolve)s the provider, and splices the returned stage PRE-main-FROM plus its artifacts POST-main-FROM. The stage is distro-aware: it picks the base from the image’s builder box, installs a pinned mise release from the upstream tarball (Go-style arch mapping), stages MISE_DATA_DIR + shims, and writes /etc/mise/config.toml (the system-config path shims resolve against). See /charly-image:layer for the generic external_builder: mechanism.

A plan step runs mise: <command>. The scalar value is the command primary-field shorthand (mise: install == mise: {command: install}); the exclusive fields live INSIDE the mise: map.

- check: install go via mise
mise: install [email protected]
Field Meaning
command the mise subcommand (also the scalar-sugar primary) — install / use / run / exec / x / env / ls / doctor / version / shims / reshim / trust / any string
args extra arguments passed to the mise command
tool a tool spec (e.g. [email protected])
task a mise task name
config a config file path
tools a tool → version map
env environment variables for the run
run_as the user the step runs as

In the BUILD context the step’s OpEmit renders the shell the step runs at image build (an act-script wrapped in RUN with the step’s run_as); at check/deploy time OpExecute runs mise <command> on the venue.

Venue precondition — a tool archive comes from the BUILD VENUE

Section titled “Venue precondition — a tool archive comes from the BUILD VENUE”

A mise: step that installs a tool fetches that tool’s archive from the network of the venue the build runs in, NOT from the host running charly. mise’s own downloader is what performs the fetch, so the egress rules of the build venue decide whether it succeeds — and when a venue filters the CDN, the step fails inside the image build with mise’s own error (Failed to install core:[email protected]: HTTP status client error (404 Not Found) for url (...)), which reads like a plugin bug and is not one.

A mise: step carries an env: field, and that is the authored lever: point mise’s downloader at a mirror reachable from the venue. For Go:

- check: install go via mise, from a mirror the build venue can reach
mise:
command: use
env:
MISE_GO_DOWNLOAD_MIRROR: https://mirrors.aliyun.com/golang
MISE_GO_SKIP_CHECKSUM: "1" # a mirror's bytes are not the CDN's checksum

MEASURED 2026-10-08 on a dev host, inside the build venue rather than on the host (the distinction is the whole point):

$ podman run --rm quay.io/fedora/fedora:43 sh -c 'curl -s -o /dev/null -w "%{http_code}\n" <url>'
https://dl.google.com/go/go1.25.14.linux-amd64.tar.gz 200
https://mirrors.aliyun.com/golang/go1.25.14.linux-amd64.tar.gz 200

Both answer 200 here, so check-mise-<distro> — the R10 witness — has no precondition problem on THIS venue today. On a venue that DOES filter the Go CDN (measured 404 on 2026-10-03, same command, opencharly/plugin-mise#13), the same command returns 200 from the mirror, and the env: block above is the fix — no product change to charly or to this plugin is required. charly does not forward host environment variables into an image build, so the mirror has to be AUTHORED in the step (or the step has to avoid the CDN tool), not exported by whoever runs the build.

plan: check: steps assert the plugin module + its self-contained schema/mise.cue ship. The live R10 witness is charly check run check-mise-<distro>-pod (declared in the repo’s root charly.yml, one per distro charly supports): the shared mise-consumer’s mise.toml auto-triggers the DETECTION path, the builder stage installs a tool, the mise: verb step installs another, and the checks prove both resolve via the shims.