Borago Board logo Borago Board

Home / Docs / Tutorials

A nightly job with a flow

Write a Borago Board flow in plain language that runs your test suite every night, see its steps classified as code or AI, and get a notification when it fails.

Running the tests every night is the kind of job that should not cost an agent run. A flow in Borago Board is written as a few sentences, and a model reads them once to decide which steps are plain logic, which it writes as code that then runs free, and which need a model each time. This tutorial builds a two-step flow that runs your test suite at 02:00 and summarises the result, then makes a copy of it that runs whenever a task reaches Done.

You will build

A flow named Nightly tests with two steps, one code step that runs the test suite and fails when the suite fails, and one AI step that writes a two-line summary. It runs every night at 02:00 on the machine that runs the project. A copy of it runs after every task that reaches Done. A failing suite arrives as a notification in the bell.

You need

  • A project with a running container and a task runner, see Creating a project and Choosing an AI provider.
  • A test command that works inside the container, such as npm test, and finishes in under 2 minutes. A step is stopped at that ceiling.
  • The desktop app open. A flow can be written from any surface, but it is analysed and run only on the machine that runs the container.

Steps

1. Create the flow

With the project selected, press Flows in the board's filter bar. A page headed Flows opens with New flow and Back to board. Press New flow. The editor opens with a name box reading Name this flow, a Saved indicator, and a canvas holding one start card. Type Nightly tests as the name.

What happens. A flow belongs to one project and is edited on a page of its own, not in a dialog, because it is worked on over minutes and a notification can link straight to it. Everything typed autosaves, and the page flushes the last edit before you leave it. A new flow arrives switched off, so nothing runs by itself yet.

2. Write the two steps

Press Add step. A card appears below the start card, already joined to it, with a box asking What should this step do? Paste the first step. Press Add step again for the second card, joined to the first, and paste the second step. The first line of a step is its name on the canvas. Leave the start card's box empty.

The first step:

Run the test suite
Run npm test in the project workspace and capture its output and exit code.
If the exit code is not 0, fail this step with the last 40 lines of the
output as the error. Otherwise output the last 20 lines.

The second step:

Summarise the result
Read the test output from the previous step. Write two lines: how many
tests ran and passed, and anything that looks slow, skipped or flaky.

What happens. Each step is one sentence or two about one action. A step receives the output of the step joined to it, named by that step's title, so the second step's "test output from the previous step" is the first step's last 20 lines. Failing the step on purpose when the suite fails is what makes a red night reach you. A failed step stops the steps that depend on it, and the run is recorded as failed. There are no loops, no branches and no sub-flows, so a flow reads top to bottom.

3. Let the analysis classify the steps

On the desktop app the analysis starts by itself after a change to the steps. You can also press Analyse in the editor header, which reads Re-analyse while the analysis is current. Until it finishes, each card's badge reads ? and the panel headed What this flow does says Not analysed yet. Write your steps, then press Analyse. When it finishes, the first card carries CODE and the second AI. The panel names the service and model that did the analysis and lists any issues.

What happens. The analysis reads the whole flow and decides, per step, whether it can run as plain code, needs a model, or only carries data. A CODE step is written once as code and re-runs free and identically for ever. An AI step asks a model every time the flow runs, which costs one call. A DATA step is a constant passed along with nothing executed. A step the model could not place becomes a data step with a warning. The model used is the project's Flows role in the AI Roles tab of the project dialog, which inherits the pre-run review role, then the task runner, when it is not set. Editing a step's text later marks the analysis stale until it is analysed again. Moving cards on the canvas does not. If the first step came back as anything other than CODE, reword it so that the command is unmistakable and press Re-analyse.

4. Run it once by hand

Press Run in the editor header. The button reads Running and a Stop button appears beside it. Then press History. A Runs panel opens listing Run 1, then by hand, the time and the duration. Open it to see each step with its status, its duration and its output.

What happens. The code step runs inside the project's container, through the same path the agent's own commands take, with the project's environment variables injected at that moment. It never runs inside the app itself. The AI step then reads the first step's output and costs one model call, which appears on the run's row. When the suite fails, the first step fails with the last 40 lines as its error, the second step is recorded as skipped rather than failed, and the run is recorded as failed. Run is disabled with a reason when the flow cannot run, such as Analyse this flow before running it. or This flow has been edited since it was last analysed. Analyse it again first.

5. Set the schedule

Under When it runs the quick choices include Daily at 09:00. For a night run use Or set it exactly. Pick Every day, set Hour to 2 and Minute to 0. The summary line under the controls describes the schedule in words and reminds you that it only runs on its own once switched on.

What happens. The time is the local time of the machine that runs the flow. A daylight-saving change lands on the right wall-clock time. Missed windows are never caught up. A laptop shut for three days runs a daily flow once at its next 02:00, not three times. The other quick choices are Manually, Every 15 minutes, Hourly, Weekly on Monday, Monthly on the 1st, When any task is Done and When any task is Blocked. The exact kinds are Only when I press Run, Every N minutes, Every hour, Every day, Every week, Every month and When a task moves to a column. The last one's Column control offers all six columns, with Which task set to Any task in this project or one task.

6. Switch it on

Tick Run on its own in the editor header. Press Flows at the top left to return to the list. The row for Nightly tests shows its schedule, its step count, next followed by the next run time, a Ready badge, and On ticked. The list's On box is the same switch.

What happens. A flow is off when created and off again when copied, so nothing runs the moment it is saved. Once on, the desktop starts a flow within a minute of its due time. A flow already running is not started again, so a slow suite never piles up runs. Each step has a ceiling of 2 minutes and each run of 10 minutes. A flow changed since its analysis is refused, and the refusal is recorded as a blocked run rather than silently skipped.

7. Run it after every finished task

On the list, press Duplicate on the Nightly tests row. The copy opens in the editor named Nightly tests (copy), switched off, with the same steps and the same analysis. Rename it Tests after Done. Under When it runs press When any task is Done. Tick Run on its own.

What happens. A flow has one trigger, so the schedule and the task trigger are two flows with the same steps. The copy keeps the analysis because the steps are identical. Now a task reaching Done, whether a run ended there or you dragged the card, starts the copy. A task's own hooks are the narrower alternative. When writing or editing a task, expand When this task finishes and, under When moved to Done, click the flow's pill under Flows. That runs it after that one task only. A flow both watching the column and named by a task runs once. Hooks fire only on the desktop.

8. Read the output and the failure notice

The next morning, open the flow and press History. The newest run reads automatic with its time and duration, plus its cost when the AI step ran. A run that failed shows its error under the row, which is the last 40 lines of the test output. Open it to read each step.

What happens. The newest 50 runs are kept per flow, on the machine that ran them. Runs do not sync, though the flow, its schedule, its switch and its last outcome do, so a phone sees that last night failed and the desktop holds the transcript. A run that ended in error raises a notification in the bell reading Flow "Nightly tests" failed with the error as its body, and a run that could not start reads Flow "Nightly tests" could not run. Clicking it opens the flow's page. It is its own kind of notice because a flow has no card on the board to show it. See Notifications.

Check it worked

  • The Nightly tests row on the list shows next followed by tomorrow's 02:00, a Ready badge, and On ticked.
  • After the first night, History lists a run marked automatic, green when the suite passed, with the summary as the last step's output.
  • Move any task to Done. Within a minute the Tests after Done flow's History lists a new automatic run.
  • Break a test on purpose and press Run on Nightly tests. The run is marked failed, the summary step reads skipped, and a red notice arrives in the bell.

Where to go next

  • Flows is the complete guide, with every control and every failure.
  • Flows reference has the guards, the schedules and what a run records, in tables.
  • Deploy a project to AWS from a task is the same kind of job written as a task instead, for work that needs judgement about the code.

Related: Flows, Flows reference, Notifications, The terminal, scripts and the file browser, Deploy a project to AWS from a task

Source as Markdown: /docs/tutorials/nightly-flow.md · Updated 2026-10-07 · Was this right? Tell us