GitHub Action that installs the Cartesi Machine emulator and the Cartesi CLI on CI runners, so workflows can build, run and test Cartesi applications.
Works on Linux and macOS runners, on both x86_64 and arm64.
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: cartesi/setup-action@v1
- run: cartesi-machine --version
- run: cartesi --versionBy default this installs:
- the latest Cartesi Machine emulator release, together with the kernel and rootfs images pinned
by that release, so
cartesi-machinecan boot a machine right away; - the Cartesi CLI from the
alphanpm dist-tag; - the
riscv64QEMU emulator, registered via Docker, sodocker buildx/cartesi buildcan run Cartesi Machine's RISC-V images (Linux only).
- uses: cartesi/setup-action@v1
with:
machine-version: 0.21.0
cli-version: 2.0.0-alpha.35- uses: cartesi/setup-action@v1
with:
machine-version: none # only the CLIThe images are around 100 MB. If the job only needs the emulator binary and libraries — to build
against libcartesi, or to run a machine from a snapshot the job provides itself — they can be
skipped:
- uses: cartesi/setup-action@v1
with:
machine-images: falseQEMU registration is Linux only and adds a small amount of time to every run; skip it when the job doesn't build or run multi-arch images:
- uses: cartesi/setup-action@v1
with:
setup-qemu: false| Input | Default | Description |
|---|---|---|
machine-version |
latest |
Emulator version: latest, an exact version such as 0.21.0 (a leading v is accepted), or none to skip. |
machine-images |
true |
Also install the kernel (linux.bin) and rootfs (rootfs.ext2) images pinned by the emulator release. |
machine-checksum |
— | Expected SHA-256 of the emulator Debian package. When set, the download must match it. Linux only. |
cli-version |
alpha |
CLI version: an npm dist-tag such as alpha or latest, an exact version such as 2.0.0-alpha.35, or none to skip. |
github-token |
${{ github.token }} |
Token used for GitHub API reads (release lookup and asset download). Only needs contents: read. |
setup-qemu |
true |
Whether to register the riscv64 QEMU emulator via Docker. Linux only; ignored on macOS. |
| Output | Description |
|---|---|
machine-version |
Resolved emulator version, for example 0.21.0. Empty when not installed. |
cli-version |
Resolved CLI version, for example 2.0.0-alpha.35. Empty when not installed. |
images-path |
Directory holding the machine images. |
The action also exports CARTESI_IMAGES_PATH to the job environment, pointing at the directory
where the images live.
| Linux | macOS | |
|---|---|---|
| Emulator | machine-emulator_<arch>.deb from the machine-emulator releases, installed with apt-get so its runtime dependencies (lua5.4, lua-lpeg, libslirp0, libgomp1) are resolved |
brew install cartesi/tap/cartesi-machine from the cartesi/tap Homebrew tap |
| Images | Downloaded from the machine-linux-image and machine-guest-tools releases pinned in the emulator release's dependencies.lock, installed into /usr/share/cartesi-machine/images |
Pulled in by the cartesi-machine formula |
| CLI | @cartesi/cli from npm, installed into the runner tool cache and added to the PATH |
same |
| QEMU | docker run --privileged docker.io/tonistiigi/binfmt:qemu-v10.2.3@sha256:400a4873… --install riscv64 |
not installed (skipped) |
Homebrew formulae are not versioned: the tap always provides one version of the Cartesi Machine.
On macOS, machine-version is therefore verified rather than selected — if the tap does not
provide the requested version, the action fails with an explanatory message. Use
machine-version: latest on macOS, or pin versions in a Linux job.
The cartesi/tap formulae currently ship bottles for Apple Silicon only. On an Intel macOS runner
Homebrew falls back to building the emulator from source, which is slow; the action warns when it
detects that case.
The Cartesi CLI drives Docker for most of its commands (cartesi build, cartesi run), and QEMU
registration (setup-qemu) also runs through Docker. GitHub-hosted Linux runners already provide
Docker, so this action never installs it there.
The tonistiigi/binfmt installer exits 0 even when it fails to register anything — it only logs
the error. Rather than trust that exit code, the action checks
/proc/sys/fs/binfmt_misc/qemu-riscv64 directly afterwards and fails the step with an explanatory
message if it's missing, instead of reporting success while docker buildx/cartesi build are
left unable to run RISC-V images.
- The action only ever downloads from a fixed set of hardcoded sources: the
cartesi/machine-emulator,cartesi/machine-linux-imageandcartesi/machine-guest-toolsGitHub releases, thecartesi/tapHomebrew tap, the npm registry, and thedocker.io/tonistiigi/binfmtimage used to register QEMU. No input can redirect an installation to another host. - Every downloaded file is checked against a SHA-256 digest: the digest published by the GitHub
releases API for the Debian package, and the digests pinned in the emulator release's
dependencies.lockfor the images. A workflow can pin the Debian package itself withmachine-checksum. When no digest is available, the action logs the digest it computed and warns instead of accepting the file silently. The QEMU image is pinned by digest too, as a fixedtag@sha256:...reference rather than the floating:latesttag, so the same image bytes are pulled on every run. - Every input is validated against a strict pattern before use, and external commands are invoked with argument arrays, never through a shell.
- The CLI is installed into a private prefix with
--ignore-scripts, so npm lifecycle scripts from the dependency tree do not run on the runner, and no elevated privileges are needed. - Root is used only for
apt-getand for copying the images into/usr/share/cartesi-machine/images.
See SECURITY.md for how to report a vulnerability.
npm ci
npm test # unit tests
npm run all # format, typecheck, test and bundledist/index.js is the bundle the runner executes and is committed to the repository. Rebuild it
with npm run build and commit the result; CI fails when it is out of date.
See RELEASING.md for how versions are tagged and published.
Apache-2.0. See LICENSE.