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.