Single-binary, local-first CI runner: YAML pipelines, DAG scheduling, artifact cache, and a live web dashboard. Ships the Rust binary as a console script, ruff-style.
Project description
forgewatch
A single-binary, local-first CI runner. Define a pipeline in YAML, run it from your terminal, or watch it re-run on every save — with a live web dashboard that streams logs as they happen. No Docker, no cloud, no daemon fleet. One Rust binary, one SQLite file, zero external services.
Think of it as the CI you actually run on your machine: the same pipeline that runs in the cloud, but fast, offline, and observable — great for tightening the edit → build → test loop before you ever push.
┌──────────────────────────────────────────────────────────────┐
│ forgewatch serve --watch │
│ • parses forgewatch.yml │
│ • schedules jobs as a DAG (needs:) │
│ • runs steps as subprocesses, streams stdout/stderr │
│ • caches unchanged jobs by content hash │
│ • serves a live dashboard at http://127.0.0.1:7878 │
└──────────────────────────────────────────────────────────────┘
Features
- DAG scheduling — jobs declare
needs:; independent jobs run concurrently, dependents wait, cycles are rejected up front. - Content-addressed cache — a job's
cache_keyglobs are hashed; on a match the job is skipped and itscacheoutputs restored. Rebuild only what changed. - Live dashboard — a self-contained web UI (zero external requests) streams logs over Server-Sent Events, with per-job status cards and full run history.
- Watch mode — edits matching
watch:globs re-trigger the pipeline, debounced, so saving a file kicks off a build automatically. - Full history — every run, job, and log line is persisted in a WAL-mode SQLite database, so you can replay any past build in the dashboard.
- Single binary — Rust + Tokio + axum. Copy it anywhere and go.
Install
cargo install --path .
# or
cargo build --release # -> target/release/forgewatch
Quickstart
forgewatch init # writes a starter forgewatch.yml
forgewatch run # run once, stream logs to the terminal
forgewatch serve --watch # dashboard at http://127.0.0.1:7878, auto-rerun
Pipeline format
name: demo-ci
# Files that re-trigger the pipeline in `serve --watch`.
watch:
- "src/**/*"
# Environment inherited by every job and step.
env:
APP: forgewatch
jobs:
- name: lint
steps:
- name: check
run: cargo clippy --all-targets
- name: build
needs: [lint] # runs after lint succeeds
cache_key: # hash these inputs...
- "src/**/*"
- "Cargo.toml"
cache: # ...restore these outputs on a cache hit
- "target/release"
steps:
- name: compile
run: cargo build --release
- name: test
needs: [build]
steps:
- name: unit
run: cargo test
- name: bench
continue_on_error: true # a non-zero exit here won't fail the job
run: cargo bench
Step fields
| field | meaning |
|---|---|
run |
command line to execute (required) |
shell |
shell override, e.g. bash -c (default: cmd /C on Windows, sh -c elsewhere) |
workdir |
working directory, relative to the pipeline file |
env |
step-level environment (overrides job/pipeline) |
continue_on_error |
if true, a non-zero exit does not fail the job |
Shell note: variable expansion follows the shell.
$VARworks undersh/bash; on the Windows default (cmd) use%VAR%, or setshell: bash -cfor a step.
Commands
| command | description |
|---|---|
forgewatch init |
scaffold a starter forgewatch.yml |
forgewatch run [-f file] |
run once; exit code is non-zero if any job fails |
forgewatch serve [-f file] [-p port] [-w] |
serve the dashboard; -w enables watch mode |
State lives in .forgewatch/ next to your pipeline (runs.db + cache/).
Examples
Runnable pipelines live in examples/:
| example | shows |
|---|---|
demo |
DAG deps, job caching, continue_on_error |
parallel |
fan-out / fan-in — concurrent jobs in one wave |
rust-ci |
real-world Rust CI template (fmt → clippy/build → test) |
forgewatch run --file examples/parallel/forgewatch.yml
How it fits together
main.rs CLI (init / run / serve)
config YAML pipeline schema ......... model.rs
engine DAG scheduler + streaming steps engine.rs
store SQLite run/job/log history ..... store.rs
cache content-addressed job cache .... cache.rs
watch debounced filesystem trigger ... watch.rs
server axum API + SSE + embedded UI ... server.rs + web/index.html
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file forgewatch_ci-0.1.1.tar.gz.
File metadata
- Download URL: forgewatch_ci-0.1.1.tar.gz
- Upload date:
- Size: 36.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
37b85273f5216fca218d7bc19f72803991aa25a0ddabb63162a2341e3c7b669a
|
|
| MD5 |
da47a0cdb9cf9cb3c95ac93ac460e7d3
|
|
| BLAKE2b-256 |
bc98807ce50d01a51a37f36215775fe6d5e807bf7ed7f33e6181721fa76cf451
|
Provenance
The following attestation bundles were made for forgewatch_ci-0.1.1.tar.gz:
Publisher:
pypi.yml on Makeph/forgewatch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
forgewatch_ci-0.1.1.tar.gz -
Subject digest:
37b85273f5216fca218d7bc19f72803991aa25a0ddabb63162a2341e3c7b669a - Sigstore transparency entry: 2224418751
- Sigstore integration time:
-
Permalink:
Makeph/forgewatch@5c14ac82cc640000923bfc9d7c927e46a51c8ce9 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/Makeph
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@5c14ac82cc640000923bfc9d7c927e46a51c8ce9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file forgewatch_ci-0.1.1-py3-none-win_amd64.whl.
File metadata
- Download URL: forgewatch_ci-0.1.1-py3-none-win_amd64.whl
- Upload date:
- Size: 2.3 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4d691888a52cc6dcec1cfe17fb794f7a56bfcf1120e1c0f1916ee5e5643975f2
|
|
| MD5 |
c243bd595ec8c1a2394772f46ddb7ed1
|
|
| BLAKE2b-256 |
b7ee63588d984e7bcd63debfea1186b25e681f3d7fa8bdbcefe61c0ac24c79eb
|
Provenance
The following attestation bundles were made for forgewatch_ci-0.1.1-py3-none-win_amd64.whl:
Publisher:
pypi.yml on Makeph/forgewatch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
forgewatch_ci-0.1.1-py3-none-win_amd64.whl -
Subject digest:
4d691888a52cc6dcec1cfe17fb794f7a56bfcf1120e1c0f1916ee5e5643975f2 - Sigstore transparency entry: 2224421337
- Sigstore integration time:
-
Permalink:
Makeph/forgewatch@5c14ac82cc640000923bfc9d7c927e46a51c8ce9 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/Makeph
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@5c14ac82cc640000923bfc9d7c927e46a51c8ce9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file forgewatch_ci-0.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: forgewatch_ci-0.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 2.4 MB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
73aa8b1e7b87dc3313fcf987eb9c059a9690b693fcd849a6cdce8c56e28903a5
|
|
| MD5 |
da5a172dec7faa725978d36760463ba8
|
|
| BLAKE2b-256 |
11a835e270a07f4bc11e6389513927414fa24378ed0f0766e5ab09eedd883106
|
Provenance
The following attestation bundles were made for forgewatch_ci-0.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
pypi.yml on Makeph/forgewatch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
forgewatch_ci-0.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
73aa8b1e7b87dc3313fcf987eb9c059a9690b693fcd849a6cdce8c56e28903a5 - Sigstore transparency entry: 2224419462
- Sigstore integration time:
-
Permalink:
Makeph/forgewatch@5c14ac82cc640000923bfc9d7c927e46a51c8ce9 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/Makeph
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@5c14ac82cc640000923bfc9d7c927e46a51c8ce9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file forgewatch_ci-0.1.1-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: forgewatch_ci-0.1.1-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.1 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8f26aebe907bcc4b17cc26d744b497e4a5bd1b36f006dbea608adac4f01a408e
|
|
| MD5 |
ea7eb94a46d27327728d8b1d2c16d802
|
|
| BLAKE2b-256 |
b1828dbea165d5415afeda8f866b554152ce68ed52af11c50c7dac90b104a4a2
|
Provenance
The following attestation bundles were made for forgewatch_ci-0.1.1-py3-none-macosx_11_0_arm64.whl:
Publisher:
pypi.yml on Makeph/forgewatch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
forgewatch_ci-0.1.1-py3-none-macosx_11_0_arm64.whl -
Subject digest:
8f26aebe907bcc4b17cc26d744b497e4a5bd1b36f006dbea608adac4f01a408e - Sigstore transparency entry: 2224420754
- Sigstore integration time:
-
Permalink:
Makeph/forgewatch@5c14ac82cc640000923bfc9d7c927e46a51c8ce9 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/Makeph
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@5c14ac82cc640000923bfc9d7c927e46a51c8ce9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file forgewatch_ci-0.1.1-py3-none-macosx_10_12_x86_64.whl.
File metadata
- Download URL: forgewatch_ci-0.1.1-py3-none-macosx_10_12_x86_64.whl
- Upload date:
- Size: 2.2 MB
- Tags: Python 3, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
726366ec28ae1ccfd6ea686fb46df57ccbab2eb536c158a55653c12900a9e49c
|
|
| MD5 |
0d2671c5a2f825a1b76b496d8899ecd7
|
|
| BLAKE2b-256 |
b0553612f3c724049333a70723754f49e5666f9fdd29b01ab69366869254fa3b
|
Provenance
The following attestation bundles were made for forgewatch_ci-0.1.1-py3-none-macosx_10_12_x86_64.whl:
Publisher:
pypi.yml on Makeph/forgewatch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
forgewatch_ci-0.1.1-py3-none-macosx_10_12_x86_64.whl -
Subject digest:
726366ec28ae1ccfd6ea686fb46df57ccbab2eb536c158a55653c12900a9e49c - Sigstore transparency entry: 2224420266
- Sigstore integration time:
-
Permalink:
Makeph/forgewatch@5c14ac82cc640000923bfc9d7c927e46a51c8ce9 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/Makeph
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@5c14ac82cc640000923bfc9d7c927e46a51c8ce9 -
Trigger Event:
push
-
Statement type: