Workflow Execution
π Workflow Execution
Section titled βπ Workflow ExecutionβWorkflows in Bflow are declarative, version-controllable JSON files. You can execute them headless in CI/CD pipelines or headed on your local desktop.
π Running a Workflow
Section titled βπ Running a WorkflowβHeadless Execution (Default / CI Mode)
Section titled βHeadless Execution (Default / CI Mode)βHeadless mode runs Chrome invisibly in the background. It is blazing fast and ideal for automated testing, cron jobs, and CI/CD pipelines:
bun flow workflows/hn-top-stories.jsonHeaded Execution (Visible Chrome Window)
Section titled βHeaded Execution (Visible Chrome Window)βHeaded mode launches a visible Chrome window so you can watch each step execute live in real time:
bun flow workflows/hn-top-stories.json --headedπ Dynamic Variable Overrides
Section titled βπ Dynamic Variable OverridesβYou can pass dynamic variables into any workflow via CLI arguments. This allows you to write reusable templates:
bun flow workflows/search-workflow.json --query="Bun runtime" --limit=10Inside your workflow JSON, use {{variableName}} syntax:
{ "name": "Search Workflow", "startUrl": "https://duckduckgo.com", "variables": { "query": "Default Query", "limit": 5 }, "steps": [ { "action": "goto", "url": "https://duckduckgo.com" }, { "action": "type", "selector": "input[name='q']", "text": "{{query}}" }, { "action": "click", "selector": "button[type='submit']" } ]}Nested paths and transformation pipelines are also supported:
{ "action": "type", "selector": "#email", "text": "{{row.contact.email | trim | lowercase}}"}Use {{env.SECRET_NAME}} for secrets. Missing environment references fail instead of being typed literally. Variable precedence from highest to lowest is system values, CLI overrides, workflow variables, row values, and step-local variables.
π§Ύ Running Once Per External Row
Section titled βπ§Ύ Running Once Per External RowβUse the data-aware command when every provider row should receive an isolated browser run:
bun workflow run workflows/signup.json \ --data='google-sheets://SPREADSHEET_ID/Users?range=A:E' \ --dry-runAfter reviewing the dry-run summary, remove --dry-run. Data runs can filter rows, use bounded parallel workers, retry transient failures, resume checkpoints, and write status/results back without changing source cells. See External Data for the full workflow structure.
π Example Workflow: Hacker News Scraper
Section titled βπ Example Workflow: Hacker News ScraperβHere is a complete workflow example (workflows/hn-top-stories.json):
{ "name": "Hacker News Top Stories", "startUrl": "https://news.ycombinator.com", "variables": { "targetSite": "news.ycombinator.com" }, "steps": [ { "action": "goto", "url": "https://news.ycombinator.com", "waitUntil": "domcontentloaded" }, { "action": "assert", "text": "Hacker News", "contains": "Hacker News" }, { "action": "extractMultiple", "containerSelector": ".athing", "as": "topStories", "limit": 10, "fields": { "title": ".titleline > a", "url": ".titleline > a@href" } }, { "action": "screenshot", "path": "output/hn-top.png", "fullPage": true }, { "action": "save", "path": "output/hn-stories.json", "format": "json" } ]}π Workflow Execution Output
Section titled βπ Workflow Execution OutputβWhen a workflow runs, the CLI logs a step-by-step progress report with execution times:
π Starting flow: Hacker News Top Stories (5 steps) [1/5] π goto https://news.ycombinator.com ... β (284ms) [2/5] π assert "Hacker News" ... β (12ms) [3/5] π extractMultiple (.athing) -> topStories (10 items) ... β (45ms) [4/5] π· screenshot -> output/hn-top.png ... β (120ms) [5/5] πΎ save -> output/hn-stories.json ... β (4ms)
β¨ Flow completed successfully in 465ms!Normal workflow results, screenshots, PDFs, and saved extracts are written beneath output/ relative to the current working directory. Data-driven runs suppress per-row result files and write one workflow-<run-id>-summary.json plus a resumable workflow state file.