Skip to main content

Running fyrer in CI with Caching and Plain Log Output

fyrer works in CI environments with the -n / --no-tui flag, which disables the interactive TUI and prints plain, prefixed log output to stdout. Combined with caching, fyrer can skip unchanged tasks across CI runs — so only the packages that actually changed get rebuilt.

Disable the TUI

Pass -n (or --no-tui) to get CI-friendly output:

fyrer run build -n

Each line of output is prefixed with the originating package and task:

[ui:build] $ bun build src/index.ts --outdir dist
[ui:build] Built 42 modules in 310ms
[api:build] $ cargo build --release
[api:build] Compiling api v0.1.0

Lines are colorized per package, making it easy to trace output even when multiple tasks run concurrently.

Exit codes

fyrer uses standard POSIX exit codes so your CI pipeline can react automatically:

  • Exit 0 — all tasks succeeded (including tasks that were cached or skipped).
  • Exit non-zero — one or more tasks failed.

Tasks whose dependencies failed are automatically skipped (not retried), and their skipped status does not itself cause a non-zero exit — only actual failures do. Use this behavior to fail your pipeline precisely on task failure:

fyrer run build -n || exit 1

Caching in CI

fyrer stores its content-addressed cache under .fyrer/cache/ relative to fyrer.yml. Each cached task is keyed by a blake3 hash of the task definition, environment, and the contents of every file matched by inputs. If the key matches a previous run, the task is reported as ⚡ Cached and skipped — its outputs are restored from the archive.

To benefit from caching across CI runs, persist the .fyrer/cache directory between jobs. Here is a GitHub Actions cache step:

- name: Cache fyrer build outputs
uses: actions/cache@v3
with:
path: .fyrer/cache
key: fyrer-${{ hashFiles('**/fyrer.yml') }}-${{ hashFiles('**/src/**') }}
restore-keys: |
fyrer-${{ hashFiles('**/fyrer.yml') }}-

Full CI workflow example

A complete GitHub Actions workflow that installs fyrer, restores the cache, and builds the monorepo:

name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Cache fyrer outputs
uses: actions/cache@v3
with:
path: .fyrer/cache
key: fyrer-${{ hashFiles('fyrer.yml') }}-${{ github.sha }}
restore-keys: fyrer-${{ hashFiles('fyrer.yml') }}-
- name: Install fyrer
run: curl -fsSL https://raw.githubusercontent.com/07calc/fyrer/main/install.sh | sh
- name: Build
run: fyrer run build -n

Use fyrer plan build before fyrer run build -n to print the topological execution plan without running any commands. This is helpful for debugging dependency ordering issues in CI without wasting build time.

i

Do not run persistent tasks (dev servers) in CI. A task with persistent: true never exits, so your CI job will block indefinitely. Only include tasks that have a finite lifecycle — i.e. tasks without persistent: true.