Breadboard CI
Run your circuits as tests on every push: deterministic emulated-hardware runs on hosted workers, GitHub-annotated failures, and replayable flight recordings.
Breadboard CI runs a circuit plus a small test spec on Breadboard's servers — the same engine and emulated boards as the bench, headless — and turns the result into a pass/fail your pipeline can gate on. Deadlines in a spec are simulated time, never wall clock: the engine is deterministic on its 5 ms grid, so a verdict can never flake because a runner was slow. When a spec fails, the run comes back with a flight recording you can replay bit-exactly on your own bench. CI is part of the CI plan ($12/month or $96/year — everything in Pro, plus the hosted runners).
Quickstart: GitHub Actions
- 1Mint a token: in the app, account menu → CI tokens… → name it and Create token. The
ci_…secret is shown exactly once — copy it into a repository secret namedBREADBOARD_CI_TOKEN. Revoke it any time from the same dialog. - 2Commit your circuit: save the bench to a JSON file in the repo (File → Export → Project, e.g.
circuit.bb.json). - 3Write a spec: a
.bbtest.jsonfile (format below) next to it, e.g. intests/. - 4Add the workflow:
# .github/workflows/breadboard.yml
name: circuit-tests
on: [push, pull_request]
jobs:
breadboard:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Dollis-Hill/breadboard-ci-action@v1
with:
token: ${{ secrets.BREADBOARD_CI_TOKEN }}
doc: circuit.bb.json
specs: tests/
- uses: actions/upload-artifact@v4
if: failure()
with:
name: breadboard-ci-recordings
path: breadboard-ci-recordings/Failures land as error annotations on the spec file, with the failing step, the sim time it missed its deadline, and a tail of the serial output. The action wraps a small CLI, breadboard-ci: breadboard-ci run --doc circuit.bb.json tests/ submits and polls (token from BREADBOARD_CI_TOKEN), breadboard-ci ping checks a token. Exit codes: 0 every spec passed, 1 a spec failed, 2 setup or service trouble (bad token, missing plan, spent minutes).
The .bbtest.json spec format
{
"version": 1,
"name": "thermostat kicks in",
"boot": { "bootTimeoutSimS": 20, "settleSimS": 5 },
"wallBudgetMs": 120000,
"steps": [
{ "type": "expect-serial", "component": "esp1",
"pattern": "ready", "withinSimS": 10 },
{ "type": "set-param", "component": "tmp1", "params": { "temperatureC": 41 } },
{ "type": "expect-visual", "component": "led1",
"brightness": { "min": 0.5 }, "withinSimS": 5 }
]
}A spec boots the document (MicroPython banner → REPL on every board → the Code tab's script injected), runs the steps in order, then settles for settleSimS more simulated seconds. Every run also implicitly asserts that no firmware error or error-level diagnostic ever fires — a crashing program fails even if every explicit step passed. A spec must contain at least one expect-* step, and steps target components by their id (select a part on the bench to see it in the Inspector).
expect-serial— a regex must match the board's serial output withinwithinSimSsimulated seconds (output after your script started, and after the latest stimulus step).expect-serial-absentis its dual, checked once at the end of the run.interact— press the hardware:buttonDown/buttonUp,switchSet,dialChange,toggleDip,keypadDown/keypadUp,pirTrigger,turn(rotary encoder).set-param— set component parameters directly (sensor values, slider positions):{ "params": { "temperatureC": 41 } }.write-serial— type into a board's serial console (omitcomponentto broadcast to every serial-capable board).wait— advance the simulation bysimSseconds.expect-visual— poll a component's visible state until every given predicate holds:brightness(0..1 min/max),textContains(character displays),pixelsLit(LED strips),rpm,toneHz,fault.expect-voltage— a net voltage at a component pin, e.g.{ "component": "esp1", "pin": "g4", "min": 3.0 }.
Failure recordings
A failing run returns the whole session as a .bbrec.json flight recording — every simulation input at its exact sim time. The action writes recordings to breadboard-ci-recordings/ (keep them with an upload-artifact step, as in the quickstart). To debug one, download the artifact and open breadboard.build/app/?open-recording=1 — pick the file and the failure replays on the bench with the full time-travel deck: pause, scrub to the moment it went wrong, single-step, or resume live from any instant and take over.
Allowances and limits
- The CI plan includes 1500 simulated minutes a month (240 a day) and 2 runs in parallel. A run charges its simulated duration, rounded up to whole minutes.
- One run is one document plus one spec, up to 2 MB together; up to 100 steps per spec; results (verdict + recording) are kept for 24 hours.
wallBudgetMs(default 120 s, max 600 s) is a real-time safety valve for runaway programs, not a test input — a healthy run never hits it.