Skip to main content
Preloop is compatible with GitHub Actions when an existing workflow can run without changing its YAML, the runner can complete its protocol exchange, and GitHub-integrated checks still report the result. Use this page to choose a deployment and to identify the few behaviors that need an external runner or a workflow adjustment.

Three compatibility boundaries

Compatibility does not mean reproducing GitHub’s internal service topology. Preloop uses local control, results, cache, and artifact stores behind the same runner-facing contracts. Signed URLs, service hosts, token bytes, timestamps, and other volatile values are normalized or intentionally local.

Protocol target

The current protocol target is actions/runner v2.337.0, pinned by runner_version in versions.toml. The bundled preloop-runner follows the official Listener/Worker split; the control plane can also accept an official runner in supported external-runner configurations. A GitHub App can trigger the compatible REST surface with:
  • POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches for workflow_dispatch. Invalid inputs return 422; a workflow without that trigger returns 409.
  • POST /repos/{owner}/{repo}/dispatches for repository_dispatch. Matching workflows are broadcast the event and the endpoint returns 204.
  • GET /repos/{owner}/{repo}/actions/workflows and GET /repos/{owner}/{repo}/actions/runs for polling.
Workflow dispatch requires actions: write. Repository dispatch requires contents: write. The supported credential forms are system bearer credentials, PATs, App JWTs, and installation tokens. Workflow and run IDs are filename-based or deterministic local IDs, not GitHub’s numeric database IDs.

How compatibility is verified

The five conformance layers are summarized below. The maintainer runbook contains the capture formats, setup, and exact commands in the conformance guide.
  • Captured wire: a MITM proxy records the exact HTTP exchange between the official runner and GitHub, then records the corresponding exchange with Preloop.
  • Replayed wire: 39 v2.336.0 capture definitions are retained; 36 are in the gated set and three are quarantined by corpus-integrity checks. Replay compares status codes, request/response schemas, job and step conclusions, timelines, annotations, and service exchanges.
  • Invariant properties: randomized server tests exercise queue modes, cancellation, lease expiry, stale-runner cleanup, assignment binding, and matrix/concurrency interactions.
  • Formal model checking: the scheduling and gate model is checked with the Specula/TLA+ artifacts retained in the repository. Findings are reconciled against the current implementation; one recorded model finding is withdrawn as a model artifact.
  • Whole-repo behavior: the same workflows are run through Preloop and comparison systems. The checked-in benchmark manifests contain 39 recorded entries, while the broader scenario corpus contains 66 directories; results compare job and step names, order, conclusions, and failure behavior.
To replay the configured golden set locally, use just conform. A runner-watch replay can target the pinned version explicitly:
The gate treats volatile values such as timestamps, GUIDs, session IDs, tokens, and random URL segments as non-semantic. A passing replay therefore means the observable contract matches where the runner and workflows depend on it, not that Preloop has GitHub’s private hostnames or token service.

Known limitations

These are current behaviors users can encounter on public/main. They are separate from historical campaign findings in the contributor tracker. For alternatives and the measured local benchmark snapshot, see Comparison. For deployment-specific host and storage requirements, see Control plane deployment.