Scripting the Shorebird CLI
The Shorebird CLI can run without a person at the keyboard, in a CI job, a script, or a coding agent. This page covers how it behaves there, how to get machine-readable output, and how to run destructive commands safely.
Non-interactive mode
Section titled “Non-interactive mode”Shorebird stops asking questions when any of these is true:
- The global
--jsonflag is passed. - stdout or stdin isn’t a terminal, for example when output is piped to a file.
- A CI environment variable is set, such as
CI(with any value),BOT=true, or the variables set by GitHub Actions, Azure Pipelines, Travis, AppVeyor, Cirrus CI, AWS CodeBuild, or Jenkins.
In non-interactive mode, nothing waits for input:
- Some prompts use a default.
shorebird inituses your pubspec name as the app’s display name.shorebird patchwithout--release-versionbuilds the app first to guess which release to patch, which costs an extra build or can build the patch without the release’s settings. Always pass--release-version; see Patching for details.shorebird patchwithout--trackpublishes tostable, and with Shorebird 1.6.135 or newer warns that a future release will require--track. - Other prompts fail. When there’s no safe default, the command exits with
an error and a hint, usually naming the flag that provides the answer. For
example,
shorebird patchfails when the patch build’s native code differs from the release unless you pass--allow-native-diffs, and when its assets differ unless you pass--allow-asset-diffs(see Patch stops in CI).shorebird initfails if you belong to several organizations and don’t pass--org-id. - Progress spinners become plain lines when stdout isn’t a terminal or
--jsonis passed. Each step printsStarting ...and thenDone ...orFailed ...to stderr.
To keep a job from failing or guessing, pass every input as a flag: the app with
--app-id or --flavor, the release with --release-version, and the track
with --track. For shorebird patch, --release-version=latest targets the
most recently updated release. Authenticate with a
service account’s key in the SHOREBIRD_TOKEN
environment variable, since shorebird login needs a browser. In GitHub
Actions, a job can
sign in with OIDC
instead, with Shorebird 1.6.129 or newer.
JSON output
Section titled “JSON output”Pass the global --json flag to get one JSON object on stdout instead of
human-readable text. --json also turns on non-interactive mode and removes
color codes.
These commands return structured JSON:
shorebird account:whoami,update,notifications,sessionsshorebird orgs:list,get,create,updateshorebird auth:status,tokenshorebird apps:list,rename,transfershorebird tokens:listshorebird invitations:list,accept,declineshorebird channels:list,create,deleteshorebird patches:list,info,set-track,promote,rollback,rollforwardshorebird releases:list,info,deleteshorebird members:list,add,set-role,removeshorebird service-accounts:list,get,create,set-role,delete,keys list,keys revoke,trust list,trust add,trust removeshorebird audit-log:list,exportshorebird metrics:active-hours,adoption,downloads,heatmap,installs,new-devices,users,versionsshorebird usageshorebird enterprise:get,members list,members set-role,guests,orgs list,apps list,audit-log list,audit-log export,usage,service-accounts listshorebird release,shorebird patch,shorebird doctor,shorebird flutter versions list, andshorebird --version
orgs, usage, members, service-accounts, and audit-log need Shorebird
1.6.135 or newer; before it, shorebird account orgs listed organizations.
enterprise needs Shorebird 1.6.136 or newer. Each of their commands’ --help
ends with an example --json run; run it to see which fields data holds.
audit-log returns events in the audit log’s
event format, and no service-accounts
command ever returns a key’s secret. The credential matters:
shorebird membersworks with ashorebird loginsession, a personal API key, or a service account’s key or GitHub Actions OIDC sign-in, unless the account is an Auditor. A release and patch only key can’t use it. Inviting, changing roles, and removing need the Admin or Owner role, which no service account holds.shorebird service-accountsneeds the Admin or Owner role. Reading works with a login session or an Admin’s or Owner’s personal API key (not a release and patch only key), but the commands that change something need ashorebird loginsession withSHOREBIRD_TOKENunset; the API refuses API keys and GitHub Actions OIDC for them.service-accounts keys createopens the console.shorebird audit-logworks with a login session, a key inSHOREBIRD_TOKEN, or GitHub Actions OIDC, as long as the credential belongs to an Owner, an Admin, or an Auditor service account; a release and patch only key can’t read it. It needs a plan that includes the audit log.shorebird enterpriseworks with ashorebird loginsession or a personal API key. An organization’s service account can’t use it, with a key or GitHub Actions OIDC; a service account the enterprise owns can read only what its role allows, such as the audit log for an Auditor.
Every other command, such as shorebird init or shorebird cache clean, also
accepts --json and runs non-interactively. Its logs go to stderr, and when it
succeeds it prints a success object whose data is empty ({}), so stdout
always holds exactly one JSON object. --help with --json works the same way:
the usage text goes to stderr. This needs Shorebird 1.6.129 or newer; earlier
releases leave stdout empty when these commands succeed.
shorebird api is the exception: it prints the API response body as-is and
rejects --json. See
Calling the API from the command line.
Success
Section titled “Success”A successful command prints an object with status set to success. The
command’s result is in data, and meta says which CLI version and command
produced it:
The fields inside data depend on the command.
Errors
Section titled “Errors”A failed command prints an object with status set to error and exits with a
non-zero code:
error.code is one of:
| Code | Meaning |
|---|---|
usage_error | Invalid or missing arguments. Exit code 64. |
interactive_prompt_required | The command needed an answer to a prompt. Exit code 64. |
fetch_failed | Shorebird couldn’t retrieve something it needed, such as an app. |
precondition_failed | A check before the command ran failed, such as not being logged in or not finding shorebird.yaml. |
software_error | The command failed unexpectedly. |
process_exit | The command stopped with a non-zero exit code. |
console_required | The action is done in the Shorebird console. error.hint holds the link. Exit code 69. |
When there’s a way to recover, error.hint says what to do, such as the flag to
add.
When the Shorebird API rejected the request, error.api_code holds the server’s
error code, such as shorebird_plan_insufficient_tier for a feature your plan
doesn’t include, and error.details holds any extra detail the server sent.
Branch on api_code rather than on the message text. These fields need
Shorebird 1.6.129 or newer.
Notices from Shorebird
Section titled “Notices from Shorebird”When the account that pays for an app needs attention, for example because patch
delivery is paused or nearing the plan’s install limit, or a payment failed,
Shorebird 1.6.135 and newer print a notice from the Shorebird server as the last
output of shorebird release and shorebird patch. The notice doesn’t change
the exit code. On GitHub Actions it’s a warning annotation, so it shows on the
run’s summary page without opening the log. With --json, it goes to stderr,
and stdout still holds only the JSON object.
Destructive commands
Section titled “Destructive commands”Commands that delete or remove something in the CLI, such as
shorebird releases delete, shorebird channels delete,
shorebird members remove and shorebird service-accounts delete, ask for
confirmation in a terminal. Without a terminal, in CI, or with --json, they
never prompt, so confirm with --yes or the command fails with a usage error
and nothing is deleted:
releases delete and --yes for channels delete need Shorebird 1.6.129 or
newer; earlier releases confirmed channels delete with --confirm-name.
members remove and the service-accounts commands need Shorebird 1.6.135 or
newer.
Some commands, such as shorebird apps delete, shorebird account delete and
shorebird service-accounts keys create, don’t perform the action: a person
finishes it in the Shorebird console. In CI or with --json, they change
nothing and exit with code 69 and the console_required error, whose hint holds
the console link. See
Commands that finish in the console
for the full list. From 1.6.121 to 1.6.134,
shorebird apps delete --confirm-name "<display name>" still deletes the app.
Retrying rollbacks
Section titled “Retrying rollbacks”shorebird patches rollback and shorebird patches rollforward succeed when
the patch is already in the requested state, so a retried job doesn’t fail. Pass
--require-change to make the command exit with a usage error when nothing
changed, if your script needs to know. With --json, the data.changed field
reports the same thing:
See Roll back from the CLI for the command’s options, and What happens when a patch is rolled back? for what it does on devices.