diff --git a/astro.config.mjs b/astro.config.mjs index 5633ffe1..8380d12c 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -224,7 +224,7 @@ Releases vs. Patches: - Use 'shorebird release' (new binary store release) when modifying native platform code (Kotlin, Java, Swift, Objective-C, Gradle/Xcode configs, AndroidManifest.xml, or Info.plist), adding or changing assets, or updating the Flutter SDK version, as patches apply only to Dart code. Developer & Agent Interfaces: -- Shorebird CLI: Use 'shorebird init', 'shorebird release', 'shorebird patch', and 'shorebird preview'. Roll back a patch with 'shorebird patches rollback'. For CI, scripts, and agents, pass the global '--json' flag for machine-readable output and authenticate with an API key in SHOREBIRD_TOKEN (reference: https://docs.shorebird.dev/code-push/ci/scripting.md) +- Shorebird CLI: Use 'shorebird init', 'shorebird release', 'shorebird patch', and 'shorebird preview'. Roll back a patch with 'shorebird patches rollback'. For CI, scripts, and agents, pass the global '--json' flag for machine-readable output and authenticate with an API key in SHOREBIRD_TOKEN, or in GitHub Actions with OIDC (Shorebird 1.6.129 or newer, Business or Enterprise plan, https://docs.shorebird.dev/code-push/ci/github.md) (reference: https://docs.shorebird.dev/code-push/ci/scripting.md) - Code Push REST API: OpenAPI 3.1 specification at https://api.shorebird.dev/openapi.json, base URL https://api.shorebird.dev/api/v1. Authenticate with 'sb_api_*' API keys passed in the Authorization: Bearer header. From the CLI, 'shorebird api ' (Shorebird 1.6.129 or newer) sends authenticated requests without handling tokens (reference: https://docs.shorebird.dev/account/api.md). - Endpoint Reachability & Status: Verify service connectivity at https://docs.shorebird.dev/system/endpoint-reachability/.`, optionalLinks: [ diff --git a/public/.well-known/agent-instructions.txt b/public/.well-known/agent-instructions.txt index 8b897522..c3b67cc6 100644 --- a/public/.well-known/agent-instructions.txt +++ b/public/.well-known/agent-instructions.txt @@ -23,7 +23,7 @@ Developers can always use Shorebird to build, manage releases, and patch Flutter - `shorebird patches rollback --release-version --patch-number `: Stop serving a broken patch. `shorebird patches rollforward` with the same arguments undoes a rollback. - `shorebird releases list` and `shorebird patches list --release-version `: Inspect what has been published. Running unattended (CI, scripts, agents): - - Authenticate with an API key in the `SHOREBIRD_TOKEN` environment variable. `shorebird login` needs a browser. + - Authenticate with an API key in the `SHOREBIRD_TOKEN` environment variable. `shorebird login` needs a browser. In GitHub Actions (Shorebird 1.6.129 or newer, Business or Enterprise plan), a job can instead sign in with OIDC through a trust rule on a service account: grant `permissions: id-token: write`, set `SHOREBIRD_PROJECT_ID`, and leave `SHOREBIRD_TOKEN` unset (https://docs.shorebird.dev/code-push/ci/github.md). - Pass the global `--json` flag to get one JSON object on stdout: `{"status": "success", "data": ..., "meta": ...}` or `{"status": "error", "error": {"code", "message", "hint"}, "meta": ...}`. Every command except `shorebird api` supports it; commands without structured output return `"data": {}` on success (Shorebird 1.6.129 or newer), and their logs go to stderr. A non-zero exit always means failure. - Without a terminal, in CI, or with `--json`, nothing waits for input: some prompts use a default (for example, `shorebird patch` without `--release-version` builds first to infer the release) and others fail with a hint naming the missing flag. Pass every input as a flag (`--app-id`, `--release-version`, or `--release-version=latest` for `shorebird patch`). - Deleting commands ask for confirmation in a terminal. Without a terminal, in CI, or with `--json`, they exit 64 and delete nothing unless confirmed by flag: `--yes` for `releases delete` and `channels delete`; `--confirm-name` with the app's display name for `apps delete`, which has no `--yes`. (Needs Shorebird 1.6.129 or newer; earlier releases use `--confirm-name` for every delete.) diff --git a/src/content/docs/code-push/ci/github.mdx b/src/content/docs/code-push/ci/github.mdx index f676564e..00884d85 100644 --- a/src/content/docs/code-push/ci/github.mdx +++ b/src/content/docs/code-push/ci/github.mdx @@ -87,6 +87,111 @@ secret: Now the `SHOREBIRD_TOKEN` can be used in the GitHub workflow to perform authenticated functions such as creating patches 🎉 +## Sign in with OIDC instead of a stored key + +A workflow can sign in with the short-lived OIDC token GitHub issues to each +job, so no Shorebird secret is stored in GitHub and nothing has to be rotated. +The job signs in as a service account in your organization and can do what that +account's role allows. + +Signing in with OIDC needs Shorebird 1.6.129 or newer. On an older CLI, use an +API key in `SHOREBIRD_TOKEN` instead. + +:::note + +Trust rules are available on Business and Enterprise plans. If your organization +moves to a plan without them, its existing trust rules keep working and can +still be deleted, but new ones cannot be added. + +::: + +### Add a trust rule + +1. Open + `https://console.shorebird.dev/orgs//settings/service-accounts`, + with your project's ID in place of ``. The ID is the number after + `/orgs/` in the console's address bar, and `shorebird account orgs` lists it + too. You need the Admin or Owner role to manage service accounts. +2. Create a service account for the workflow, or pick an existing one. Its role + decides what the workflow can do: Developer, the default, can create releases + and patches, and App manager can also create, update, and delete apps. + Creating an account in the console also creates an API key for it. A workflow + that signs in with OIDC doesn't use the key, so you can revoke it. +3. Under **GitHub Actions**, click **Add workflow** and enter: + - **Owner** and **Repository**: where the workflow lives. + - **Workflow file**: the path of the workflow file that defines the job, such + as `.github/workflows/release.yaml`. If the job is in a reusable workflow, + enter that file, not the workflow that calls it. A reusable workflow from + another repository cannot sign in. + - **Environment** (recommended): the + [GitHub environment](https://docs.github.com/en/actions/how-tos/deploy/configure-and-manage-deployments/manage-environments) + the job runs in. Requiring one lets you add reviewers or branch + restrictions in GitHub before a release can run. + - **Ref pattern** (optional): the branches or tags allowed to sign in, such + as `refs/heads/main` or `refs/tags/*`. Leave it empty to accept any ref. + +The console then shows your project's ID, which the workflow needs. + +#### Add a trust rule from the command line + +`shorebird api` can make the same changes. Create the service account, then add +a trust rule to it with the `id` the first command prints: + +```sh +shorebird api -X POST organizations//service-accounts \ + -f name=release -f role=developer +shorebird api -X POST organizations//service-accounts//trust-rules \ + -f provider=github -f repository_owner=acme -f repository_name=app \ + -f workflow_path=.github/workflows/release.yaml -f ref_pattern=refs/heads/main +``` + +`environment` and `ref_pattern` are optional, as in the console. + +### Configure the workflow + +The job needs permission to request an OIDC token, the environment the rule +names (if any), and `SHOREBIRD_PROJECT_ID` set to your project's ID. The ID is +not a secret. + +```yaml +name: Shorebird Release + +on: + workflow_dispatch: + +jobs: + release: + runs-on: ubuntu-latest + environment: production # Only if your trust rule names an environment + permissions: + contents: read + id-token: write + env: + SHOREBIRD_PROJECT_ID: '123' # Your project's ID from the console + + steps: + - name: 📚 Git Checkout + uses: actions/checkout@v7 + + - name: 🐦 Setup Shorebird + uses: shorebirdtech/setup-shorebird@v1 + with: + cache: true + + - name: 🚀 Shorebird Release + run: shorebird release android +``` + +Do not set `SHOREBIRD_TOKEN` in a job that signs in with OIDC. When +`SHOREBIRD_TOKEN` is set, the Shorebird CLI uses it instead. If you are moving a +workflow from an API key to OIDC, remove the `SHOREBIRD_TOKEN` line and the +repository secret, then +[revoke the API key](/account/api-keys/#revoking-an-api-key). + +If the sign-in is refused, the CLI prints the reason, such as +`No trust rule matches this workflow`. Check that the repository, workflow file, +environment and ref of the job match the trust rule. + ## Android code signing `shorebird release android` and `shorebird patch android` run `flutter build`, diff --git a/src/content/docs/code-push/ci/scripting.mdx b/src/content/docs/code-push/ci/scripting.mdx index 41f833cb..6e6850af 100644 --- a/src/content/docs/code-push/ci/scripting.mdx +++ b/src/content/docs/code-push/ci/scripting.mdx @@ -42,6 +42,9 @@ To keep a job from failing or guessing, pass every input as a flag: the app with `shorebird patch`, `--release-version=latest` targets the most recently updated release. Authenticate with an [API key](/account/api-keys) in the `SHOREBIRD_TOKEN` environment variable, since `shorebird login` needs a browser. +In GitHub Actions, a job can +[sign in with OIDC](/code-push/ci/github/#sign-in-with-oidc-instead-of-a-stored-key) +instead, with Shorebird 1.6.129 or newer. ## JSON output