0019: Runtimes build in a public repository

On this page

Status: accepted. It changes where the builds from 0017 run; how Short Leash trusts them is unchanged.

Context

Short Leash's own builds of PHP, Ruby and pgvector ran on macOS and Windows runners in Short Leash's private repository, where GitHub counts each macOS minute ten times against the plan. One PHP patch release (four versions on two Mac architectures) cost more than a month's included minutes. GitHub-hosted runners are free for public repositories, and the build scripts only wrap open-source projects. The updater key that signs the builds manifest also signs app updates, so it must not reach a public repository.

Decision

  • The build scripts and the workflow that runs them live in a separate public repository, ShortLeash/runtimes, under the MIT license. Its Build workflow:
    • runs daily and builds each PHP patch release php.net has published that isn't released there yet, or builds everything when run by hand;
    • attaches each file to a GitHub release per version (php-8.4.26, ruby-3.4.7, pgvector-0.8.7), with a build provenance attestation, only from main;
    • has no secrets, and re-enables its own schedule each day, since GitHub turns off schedules in public repositories after 60 days without activity.
  • Short Leash's private repository keeps everything that needs a secret. Its Publish runtimes workflow (.github/workflows/publish-runtimes.yml) runs daily on Linux after the build, or by hand. It:
    • takes each release file the published manifest doesn't have, or has with another SHA-256;
    • checks it against GitHub's digest (apps/desktop/builds/fetch.py);
    • verifies its attestation: built by ShortLeash/runtimes' build.yml, from refs/heads/main, on a GitHub-hosted runner;
    • writes the manifest, signs it with the updater key, and uploads the files and then the manifest to R2, as in 0017.
  • It also fails when the newest pgvector release lacks a build for a Postgres version in the service catalog. A test keeps that workflow's Postgres list equal to the catalog.
  • The app doesn't change. It still downloads only from Short Leash's server, checks the manifest's signature against the updater key and each file against the manifest.

Consequences

  • Building costs no GitHub minutes. The private repository spends about one Linux minute a day on publishing.
  • The build recipes are public, which makes the LGPL libraries in PHP straightforward to rebuild against. Short Leash stays closed source; the public repository holds no Short Leash code.
  • Trust gains a step. A file is published only if GitHub's attestation ties it to ShortLeash/runtimes' workflow on main. Anyone with write access to ShortLeash/runtimes can change what is built, so that repository's access matters as much as the private one's.
  • The Postgres version list lives in two places, ShortLeash/runtimes' build matrix and the publish workflow. Publishing fails loudly when they drift.
  • Builds reach Short Leash up to about four hours after they finish, or sooner with a run by hand.