Extracted from ADR 0005. This document covers the GitHub Actions workflows that keep checked-in OpenAPI types in sync with the live Management API. For the three-layer generation strategy and architectural decisions, see the ADR.
Three GitHub Actions workflows keep the checked-in v1.d.ts in sync with the live Management API spec across the private API repo and the public CLI repo.
Triggered by three events:
repository_dispatch(openapi-spec-changed) — pushed from the API repo after production deployschedule(daily cron) — fallback in case a dispatch is lostworkflow_dispatch— manual trigger for debugging or ad-hoc sync
Steps:
- Check out the CLI repo
- Install dependencies (
bun install --frozen-lockfile) - Regenerate types (
bun run generate— runsopenapi-typescriptagainst the live spec URL) - Check
git diff --exit-code packages/api/src/v1.d.ts— if unchanged, exit early (no PR) - Run quality gates:
bun run ts:check,bun run lint,bun run fmt:check,bun run knip - Open or update a PR via
peter-evans/create-pull-requestwith:add-pathsrestricted topackages/api/src/v1.d.ts— prevents accidental lockfile or unrelated changes from being committed- Branch:
chore/openapi-sync - Labels:
automated,api-types
Concurrency:
concurrency:
group: openapi-sync
cancel-in-progress: trueThis ensures at most one sync PR exists at any time — a new dispatch cancels any in-flight run and supersedes the previous PR.
Scheduled twice weekly (e.g., Tuesday and Friday). Acts as a safety net for silent dispatch failures.
Steps:
- Check out the CLI repo
- Install dependencies
- Regenerate types (
bun run generate) - Run
git diff --exit-code packages/api/src/v1.d.ts - Fail the workflow if the checked-in types don't match what
openapi-typescriptproduces
This workflow does not open a PR — it only alerts. If it fails, a developer triggers the sync workflow manually or investigates why dispatches stopped arriving.
Fires after a production deploy completes, using workflow_run as the trigger (so it runs only after a successful deploy, not on every push).
Steps:
- Generate a short-lived installation token via
actions/create-github-app-token@v1scoped to the CLI repo - Dispatch the
openapi-spec-changedevent to the CLI repo viapeter-evans/repository-dispatch
- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ secrets.SYNC_APP_ID }}
private-key: ${{ secrets.SYNC_APP_PRIVATE_KEY }}
repositories: "cli"
- uses: peter-evans/repository-dispatch@v3
with:
token: ${{ steps.app-token.outputs.token }}
repository: supabase/cli
event-type: openapi-spec-changedWhy a GitHub App instead of a PAT: GitHub App installation tokens are short-lived (~1 hour), scoped to specific repositories, and don't tie permissions to a personal account. A long-lived PAT would need to be rotated manually and grants broader access than necessary.
- Change detection via
git diff— comparing the regenerated file against what's checked in is simpler and more robust than tracking spec hashes or ETags across repos. If the output is byte-identical, there's nothing to do. add-pathsrestriction —peter-evans/create-pull-requestcommits everything that changed in the working tree by default. Restricting tov1.d.tsprevents accidental lockfile updates or unrelated diffs from leaking into the sync PR.- Concurrency group with
cancel-in-progress— if the API deploys twice in quick succession, only the latest sync matters. The concurrency group ensures the first run is cancelled, avoiding duplicate PRs. - Verify as a separate workflow — decoupling verification from sync keeps failure signals clean. A verify failure means "types are stale", not "the PR couldn't be created".