Skip to content

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 ci writes the status ci (app buildkite, creator app:buildkite), so required_checks = ["ci"] in .pando/pando.toml gates 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_monorepo and pando_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", with retry_after_ms). A reader of a log, annotations or artifacts gets the last copy instead, when there is one: 200 with cached: true, complete: false and retry_after_ms. pipeline.yml shows its stored copy with configuration_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).

Navigation

Type to search…

↑↓ navigate↵ selectEsc close