ci
CI on one model for every service:
a service (buildkite today), a connection (one account of it:
a Buildkite organization), its pipelines (each builds one repo),
builds, jobs, and each job's check. Pando runs no CI.
- Stored by Pando, pushed by the service. A connection gets a
webhook URL; the service's webhooks keep builds and jobs (state,
times, links) in the monorepo's records, written in one step with
their events on the monorepo's stream (
ci.build,ci.job) before the webhook is answered. Viewers cost the service nothing. - A check is a job named by its step key: a job keyed
ciwrites the statusci(appbuildkite,creatorapp:buildkite), sorequired_checks = ["ci"]in.pando/pando.tomlgates merges on it. Commands and triggered builds report; waits and blocks do not. Only the newest job with that key, in the newest build of that pipeline for that commit, reports (a retry or a rebuild takes over). States: passed is success; failed is failure (soft failed: success); canceled, not run after a failure (broken) or not taken by an agent (expired) are error; a skipped step is success. - Fetched from the service when opened: a job's log (its last 1 MiB), a build's annotations and artifacts (first 100 of each), a pipeline's configuration (read at most every 5 minutes). Cached once settled (finished over 30 s ago), else for 10 s.
- Actions, any member: Rebuild (a new build of the same commit with fresh tokens; the service's own rebuild would reuse the old build's env), Cancel and Retry (passed through).
- Mapping a build to a repo: Pando's own builds carry
meta_data.pando_delivery,pando_monorepoandpando_repo; a build started in the service maps through the buildkite hook that names its pipeline. Other builds (another monorepo's, another organization's, an unmapped pipeline's) are answered 200 and ignored. - Who pushed comes from Pando's own records: the delivery that started the build, else the push or merge that made the commit.
- The service's rate limit: Buildkite allows 200 REST calls a
minute per organization and 50 per user token. A connection makes at
most 40 a minute (10 are left for starting builds); past that, or
after Buildkite answers 429, calls answer 429
ci_rate_limited("try again in N s", withretry_after_ms). A reader of a log, annotations or artifacts gets the last copy instead, when there is one: 200 withcached: true,complete: falseandretry_after_ms. pipeline.yml shows its stored copy withconfiguration_error. Never a 5xx for the hold.
Errors from the service: ci_unauthorized (502: the token lacks a
scope), ci_refused (409: Buildkite refused the action),
ci_service (502), ci_rate_limited (429), ci_token_missing (503:
the Worker secret BUILDKITE_API_TOKEN is not set).
- The CI tab's top - services, connections, pipelines, required checks
- Connect a CI service (owners)
- Disconnect a CI service (owners)
- Stored builds, newest first
- A build and its jobs
- A job's log, from the service (its last 1 MiB)
- A build's annotations, from the service (first 100)
- A build's artifacts, from the service (first 100)
- Download an artifact of this build
- Build the same commit again, with fresh tokens
- Cancel a running build (passed through)
- Retry a job (passed through)
- A pipeline - its configuration (pipeline.yml) and its builds
- New build - the pipeline builds a branch's head as Pando has it
- Buildkite's webhooks (the URL a connection shows)