Syncs pipeline files from a git repository into the job's workspace after the checkout phase, so it composes with a plugin that has already replaced Buildkite's built-in git checkout.
It exists for pipelines that check out Perforce instead of git: those pipelines get no git checkout at all, so any pipeline definitions, scripts or config living in a git repo are whatever happens to be on the agent's disk. This plugin makes that content a deterministic, per-build revision again.
Buildkite runs at most one checkout hook. runreal/perforce supplies one, so a
second plugin providing checkout would fight it. post-checkout runs after the
checkout phase on every job, which is what makes the pipeline files
consistent across a fan-out that lands on several machines.
The workspaces this runs in hold a Perforce tree that can take hours to repopulate, so the hook is deliberately narrow:
- It never runs a checkout into the workspace root. It keeps its own git dir
in a cache directory outside the workspace and drives the work tree with
--work-tree, so no.gitis created at the workspace root. git checkout -fonly ever writes tracked paths and removes paths this cache previously wrote. Untracked content — the Perforce tree, build output, agent scratch — is never considered, andgit cleanis never run.- It refuses to start if the cache directory resolves inside the workspace.
- It refuses to run if the source repo tracks anything under the Perforce client
root (
subdir_root), which is the one way a checkout here could clobber depot files. - It refuses a ref it cannot resolve, and refuses a revision that is not a 40-character commit sha, before touching the work tree.
- Credentials are never persisted: no remote is configured in the cache repo, the authenticated URL is passed per invocation, and only a redacted form is logged.
steps:
- command: ./scripts/build.sh
plugins:
- runreal/perforce:
stream: //Workspace/Main
subdir_root: p4
- runreal/runreal-checkout:
repository: https://github.com/runreal/runreal-pipeline.git
ref: mainPlugin order does not matter — post-checkout runs after every checkout hook
regardless of where this plugin appears in the list.
Git URL of the pipeline files repository.
Default: main. A branch, tag, or 40-character commit sha. A sha is used as-is
and skips remote resolution.
Sparse-checkout patterns limiting what is materialised. Deletions are still applied within the sparse set. Omit to materialise the whole repository.
paths:
- .runreal
- runreal.config.json
- deno.jsonc
- deno.lockDefault: true. The first job of a build resolves the ref and records it in
build meta-data; later jobs reuse that revision so every job in the build runs
the same pipeline files even if the branch moves mid-build.
This is reliable when a build starts with a single step — the pin is established
before any fan-out. If several jobs start simultaneously as a build's first
steps, they can race to set the pin; they converge on whichever value landed.
Set ref to a sha for an absolute guarantee.
Default: runreal-checkout-revision. The meta-data key used to pin the revision.
Default: GITHUB_ACCESS_TOKEN. Name of the environment variable holding a token
used for HTTPS auth. Ignored when empty or when the URL is not HTTPS.
Default: ${BUILDKITE_BUILD_CHECKOUT_PATH}/../.runreal-checkout-cache. Must be
outside the workspace. One git dir is kept per (repository, checkout path)
pair, so agents running several pipelines never share an index, and concurrent
jobs sharing a cache are serialised with a lock.
bash tests/post-checkout.test.shThe suite builds a throwaway upstream repo and a workspace containing a stand-in Perforce tree, then asserts the depot files survive first sync, re-sync, upstream deletions, rollback to an older commit, sparse checkout, and each refusal path.