The bakery CLI
bakery lets you do from a terminal or CI everything you'd do on the site: bake the folder you're in, follow batches live, fetch artifacts, and manage recipes, ingredients and caches. One small binary for macOS, Linux and Windows.
Install
macOS and Linux (Intel or ARM):
curl -fsSL https://buildbakery.com/install-cli.sh | sh
Windows, in PowerShell:
irm https://buildbakery.com/install-cli.ps1 | iex
The script installs to ~/.local/bin (Windows: %LOCALAPPDATA%\BuildBakery\bin), adds it to your PATH and points the CLI at this server. Run the same command again to update.
Sign in
bakery login
Your browser opens on BuildBakery and shows a short code; check it matches the one in your terminal and click Approve. The CLI stores a personal token (in your user config folder, readable only by you). It appears as "CLI · your-machine" on Account → API tokens, where you can revoke it.
No browser on this machine (a server over SSH)? Either approve from any other device, or use your password right here:
bakery login --no-browser # prints the code and URL: approve on your phone or laptop bakery login --email you@example.com # asks for your password in the terminal
Both give the same revocable "CLI · machine" token. Too many wrong passwords pause sign-ins from that address for 15 minutes.
In CI, skip the browser: create a token on Account → API tokens, store it as a CI secret, and either run bakery login --token "$BAKERY_TOKEN" or simply export BAKERY_TOKEN.
Choosing a project
bakery projects # list them bakery link "My App" # this folder now uses My App (writes .bakery.json) bakery bake --project "Other App" # or pick one per command
Commands use, in order: --project, the nearest .bakery.json (commit it so your team shares it), or your only project.
bakery project create "My App" --repo octo/my-app # from a linked GitHub/GitLab/Bitbucket account bakery project create "My App" --git-url https://git.example.com/app.git bakery project create "My App" # uploads only
Baking
bakery bake # upload this folder, follow the batch bakery bake --git --branch release/2.0 # bake the linked repository instead bakery bake --workflows ios -m "RC 3" # only some workflows, with a note bakery bake --download ./out # download artifacts when it's fresh bakery bake --logs # stream every job's full log bakery bake --recipe ci/codebuilder.yaml # a different recipe for this batch only bakery bake --no-wait # start it and return
Uploads include tracked and untracked files but respect .gitignore (outside git, common build folders like node_modules, Pods, build are skipped). The current git branch and last commit message are attached to the batch.
While following, Ctrl+C stops watching; the batch keeps baking. The exit code is 0 when the batch is fresh, 1 when it burns (the failing job's last log lines are printed), and 2 when it's scrapped.
Batches, logs and artifacts
bakery batches # recent batches bakery status # latest batch: jobs, steps, ovens, artifacts bakery status 12 # a specific batch (12, #12 or an id) bakery logs --job ios # full log of one job bakery logs -f # follow all jobs live bakery artifacts 12 --download ./out bakery artifacts 12 # with each APK/AAB/IPA signer and its SHA-256 bakery wait 12 --timeout 30m # exit 0 fresh, 1 burnt, 2 scrapped, 3 timeout bakery deliver 12 # send #12 to the project's servers again bakery cancel # pull the latest batch from the oven bakery cancel 12 --job ios # just one job; the rest carry on bakery keep-waiting 12 --job ios # no oven can run it yet: keep it queued for a new one bakery rebake 12 # bake #12 again with the same source bakery open 12 # open it in the browser
Failures, trends and provenance
bakery why 12 # AI: why the failed job burnt, and the fix bakery why 12 --job ios --recipe-out fixed.yaml # save the suggested recipe bakery insights --days 60 # times, success rate, waits, cache hits per workflow bakery provenance 12 --job android -o android.intoto.jsonl # signed SLSA attestation bakery provenance --verify android.intoto.jsonl
Automatic batches
bakery triggers # push, pull request and schedule settings bakery triggers --push on --push-branches 'main,release/*' bakery triggers --prs on --install-webhook # create the webhook on GitHub/GitLab/Bitbucket
Ovens
bakery ovens # what you can bake on: host, size, labels, jobs at once bakery ovens add # install command (with a fresh token) for this kind of machine bakery ovens add --os windows # … or for another one: linux, mac, windows
Recipes
bakery recipe init --template android-expo # start from a template (bakery recipe init lists them) bakery recipe validate # check ./codebuilder.yaml, and that an online oven can run it bakery recipe show --resolved # what will actually run: added steps, caches, matching ovens bakery recipe schema # JSON Schema (unknown keys are errors) bakery recipe show # the recipe builds actually use bakery recipe push codebuilder.yaml # save as the project recipe (overrides the repo) bakery recipe reset # go back to codebuilder.yaml from the source
See Writing recipes for the format.
Ingredients (environment variables and secrets)
bakery env # list (secrets are hidden) bakery env set API_URL https://api.example.com bakery env set API_TOKEN 's3cr3t' --secret bakery env set KEYSTORE --file release.jks --base64 --secret op read op://ci/api-token | bakery env set API_TOKEN --stdin --secret # not in shell history bakery env unset API_URL
Deliveries and destination accounts
# accounts are yours, usable by every project
bakery accounts # everything connected
bakery servers # just SFTP servers
bakery servers add --host files.example.com --user deploy --key ~/.ssh/buildbakery
bakery accounts add bucket --provider r2 --account-id <id> --bucket releases --access-key-id <id>
bakery accounts add google play-uploader.json
bakery accounts add webhook https://example.com/hooks/bakery
bakery accounts test files.example.com
# deliveries belong to the project
bakery deliveries # numbered list
bakery deliveries add sftp --to files.example.com --folder '/srv/releases/{project}/{batch}' --latest
bakery deliveries add google-play --to play-uploader --package com.acme.shop --track internal
bakery deliveries add firebase --to play-uploader --app-id 1:123:android:abc --groups qa
bakery deliveries add github-release --repo acme/shop --tag 'v1.{batch}'
bakery deliveries set 1 --folder '/srv/apps/{project}/{batch}' # change only what you pass
bakery deliveries set 2 --workflows android --branches 'main,release/*'
bakery deliveries test 1 | pause 1 | resume 1 | remove 1
bakery deliver 12 # send batch #12 again
bakery deliver 12 --dry-run # what would go where, without sending
bakery retention --days 30 --keep 20 # artifact retention (bakery retention clean = now)
bakery help deliveries lists every option. New deliveries are tested before they're saved. To give each job its own subfolder inside a delivery's folder, set deliver.folder in the recipe (one folder per job); bakery recipe show --resolved shows it and bakery deliver 12 --dry-run shows the exact folder each job would go to.
Tokens for scripts and other apps
bakery token create --project Shop --scopes bake,read,artifacts --expires 90d bakery token # list bakery token revoke <id>
A project token can only start batches, read their status and logs, and download artifacts for that one project (scopes read, bake, artifacts, deliver). It never sees ingredients, keystores, deliveries, accounts or other projects, which makes it safe to give to an app that builds through BuildBakery.
Reference in the terminal
bakery docs recipes # every recipe field and default bakery docs env # CB_* variables, CB_KEYSTORE_*, BB_* for delivery commands bakery docs deliveries bakery docs automation # triggers, previews, AI triage, insights, provenance, MCP bakery ovens # what each oven runs: labels and tools
The same Markdown is at /llms.txt and /llms-full.txt for AI agents.
More
bakery cache clear # fresh dependency caches on every oven bakery plan # your plan and this month's usage bakery whoami bakery version bakery help why # flags for one command bakery config # server, signed-in user, config file location bakery logout
Add --json to any command for machine-readable output, e.g. bakery --json status | jq -r .status.
Using it in CI
# GitHub Actions
- name: Bake with BuildBakery
env:
BAKERY_TOKEN: ${{ secrets.BAKERY_TOKEN }}
run: |
curl -fsSL https://buildbakery.com/install-cli.sh | sh
~/.local/bin/bakery bake --project "My App" -m "${{ github.sha }}" --download ./out
| BAKERY_TOKEN | API token to use (instead of bakery login) |
| BAKERY_SERVER | Server URL (default https://buildbakery.com) |
| BAKERY_CONFIG | Path of the config file |
| NO_COLOR | Plain output without colours |