RESOURCES / FAQ

Frequently Asked
Questions

Everything you need to know about WarpBuild, CI runners, build performance, infrastructure, integrations, pricing, and more.

462 FAQs across 20 topics

Find your next answer.

Getting Started with WarpBuild

Your first build, account setup, and the basics.

10
What is WarpBuild?

WarpBuild provides managed runners for GitHub Actions, with ephemeral virtual machines, fast compute, caching, and tools for understanding build performance. Use hosted runners or run supported configurations inside your own cloud account with BYOC.

Does WarpBuild replace GitHub Actions?

WarpBuild supplies the compute that runs your GitHub Actions jobs. You continue to use GitHub workflows and choose a WarpBuild runner through the job’s runs-on label. GitHub remains the workflow orchestration system.

How do I get started with WarpBuild?

Create a WarpBuild account, install the GitHub app through the dashboard, and grant access to the repositories you want to use. Change a job’s runs-on label to a supported WarpBuild label, then run the workflow.

Do I need a GitHub organization?

Yes. WarpBuild requires a GitHub organization and cannot be installed on a personal account. Choose an existing organization or create one, then install the app from the WarpBuild dashboard.

Can I install WarpBuild directly from GitHub Marketplace?

Start in the WarpBuild dashboard after signing up. The quick-start guide specifies that the WarpBuild GitHub app must be installed through that setup flow, rather than directly from GitHub Marketplace.

Can one GitHub organization connect to multiple WarpBuild workspaces?

A GitHub organization can connect to only one WarpBuild workspace. If it is already connected, use that workspace or disconnect the existing connection before connecting it to another workspace.

Why is my GitHub app installation waiting for approval?

If you are not an organization owner, GitHub sends the installation request to an owner for approval. Ask an owner to approve it. For agent-assisted setup, tell the agent once approval is complete.

Where can I copy a runner label?

Copy a label from Ready-to-use runners on the dashboard Overview page or the Label column on the Runners page. Use that exact label as the job’s runs-on value in your workflow.

Can an AI agent help me set up WarpBuild?

Yes. The quick-start guide supports agent-assisted setup through the WarpBuild MCP server. The agent helps install the app and opens a pull request changing runner labels. Review the pull request and its checks before merging.

What should I do while my workspace is under review?

Some new workspaces require review before jobs can run. Submit the requested details on the review page. If using agent-assisted setup, run the setup prompt again after the review is complete.

CI Runners

Choose the right environment for your workflows.

31
How Much Disk Space Do GitHub Actions Runners Have?

Standard WarpBuild Linux runners have 150GB SSD storage, Windows runners have 256GB, and macOS runners have 120GB or 270GB. Linux ARM64 on Apple Silicon has separate 150GB and 300GB configurations. Check the catalog for the specific runner label.

Do GitHub Actions Runners Keep State Between Jobs?

Ordinary WarpBuild runner VMs are ephemeral and their disks are discarded after the job. Use caches or artifacts for selected files. Cloud Ubuntu snapshot runners can explicitly restore a previously saved disk state.

Do GitHub Actions Runners Store My Source Code?

Code checked out during a job lives on the runner disk, which is destroyed with an ordinary ephemeral runner. Files you deliberately save to caches, artifacts, or snapshots have separate retention rules; clean sensitive files before persisting them.

Is Visual Studio Preinstalled on Windows Runners?

WarpBuild Windows images include the standard Windows development toolchain. Windows Server 2025 labels with vs2026 select Visual Studio 2026; ordinary Windows Server 2025 labels currently carry Visual Studio 2022. Check the image manifest for installed components.

Which platforms does WarpBuild support?

The runner catalog covers Linux x86-64 and ARM64, macOS ARM64, and Windows x86-64. Feature availability varies between hosted runners and each BYOC cloud; check the feature matrix before choosing a deployment.

Can I use GPU runners on WarpBuild?

The published feature matrix does not mark GPU support as available on WarpBuild Cloud or BYOC. Contact the team about your requirements rather than assuming a GPU runner label is supported.

Can I use spot instances on WarpBuild Cloud?

Hosted cloud spot runners were removed. Spot instances are supported through BYOC on AWS, GCP, and Azure. Use a supported BYOC configuration when your workload can tolerate instance interruptions.

How do I make a self-hosted runner ephemeral?

Configure the runner agent with the --ephemeral flag, so the agent accepts one job and then deregisters and exits. The second half is up to whatever created the machine: a controller or provisioning script has to delete the virtual machine or container after the agent exits, otherwise the disk survives for the next agent that starts on that host.

Do ephemeral runners lose my dependency cache?

The machine's disk goes away with the machine, so anything warm has to be restored on purpose. The usual mechanisms are actions/cache for dependency directories, artifacts for files a later job needs, a prebuilt image that already contains the toolchain, or a runner that boots from saved disk state captured on an earlier run.

Why does every job repeat the same setup steps on ephemeral runners?

Because every job starts from the same base image with an empty workspace. A workflow of five jobs runs its package install, its checkout, and its container pulls five times unless caching, a prebuilt image, or restored disk state shortens the start of each job.

What is ephemeral storage?

Ephemeral storage is disk space whose contents are bound to the lifetime of the compute that owns it. When the instance, container, or pod goes away, the data on that disk goes with it. AWS documents instance store volumes this way, Docker documents the writable container layer this way, and Kubernetes documents emptyDir volumes this way.

Is ephemeral storage the same as a temporary directory?

A temporary directory such as /tmp is a path convention inside one filesystem, and the operating system or a cleanup job decides when its contents are removed. Ephemeral storage describes the durability of the whole volume, so a file in a home directory on an ephemeral disk disappears at the same moment as a file in /tmp on that disk.

What does a GitHub Actions runner actually do?

A runner is a machine plus the open source runner agent installed on it. The agent registers with GitHub, advertises a set of labels, holds an outbound long poll waiting for work, then runs the steps of one job and streams logs and the final conclusion back to GitHub.

What is a runner image in GitHub Actions?

It is the prepared disk image a runner machine boots from before it accepts a job. The image carries the operating system, the system packages, and the language runtimes and SDKs that steps use, so anything the image lacks has to be installed by a step inside the job.

How is a runner image different from a Docker image?

A runner image boots a whole machine and supplies the kernel, the init system, and the container runtime. A Docker image supplies a filesystem for a process that runs on top of that machine, so a job using a container still depends on the runner image underneath it.

Why did a tool version change without any workflow edit?

Runner images are versioned and republished on a cadence, and a job runs on whichever build is current when it starts. A workflow that requests a runtime by major version inherits the patch version the image happens to carry, so an image rollout can move it between two runs of the same commit.

What is a runner label in GitHub Actions?

A runner label is a string attached to a runner when it registers with GitHub. A workflow job lists labels in its runs-on key, and GitHub gives the job to an online runner that advertises every label the job asked for.

Does a runner label change what a machine can do?

No. Labels are opaque routing strings. GitHub does not check that a runner labeled x64 is an x86-64 machine or that a runner labeled large has more cores. Whoever registers the runner picks the strings, so the accuracy of a label is a convention held by the registrar.

Can one job request more than one runner label?

Yes. The array form of runs-on lists several labels and a runner must carry all of them to be eligible. Labels the runner carries beyond that set are ignored, so a request is a subset test against each runner's label set.

What is a runner pool in GitHub Actions?

A runner pool is the set of machines that can accept a job carrying a given label, together with the policy that decides when machines are created and when they are retired. Workflow YAML never names a pool. A job names labels, and the pool is whatever set of online runners advertises those labels when the job is queued.

Is a runner pool the same as a runner group?

They answer different questions. A runner group is a GitHub access control object that decides which repositories and workflows may queue work onto a set of runners. A pool describes capacity: which machines exist, how many can exist at once, and how they are created and retired.

What is a self-hosted runner in GitHub Actions?

A self-hosted runner is a machine you supply and operate, with GitHub's open source runner agent installed on it and registered against a repository, an organization, or an enterprise.

How does a self-hosted runner connect to GitHub?

The agent opens an outbound HTTPS long poll to GitHub and waits for a job message on that connection. Nothing dials the machine from the internet, so a runner works inside a private subnet behind a firewall that allows outbound traffic only, and it can reach private services that a machine outside your network cannot.

What do I have to operate myself when I run self-hosted runners?

Provisioning the machines, building and patching the image the jobs run on, scaling the fleet up and down against queue depth, deciding the isolation boundary between jobs, and decommissioning machines so a deregistered runner leaves nothing running. GitHub operates none of that for a self-hosted runner.

Can self-hosted runners run jobs from public repositories?

Yes, subject to GitHub settings and runner-group access policies. Public pull requests can introduce untrusted code, so review the trust boundary carefully. For WarpBuild, follow the public-repository setup guide and keep sensitive credentials out of persisted state.

What is a vCPU?

A vCPU is one virtual processor a cloud instance exposes to the guest operating system, appearing as a single entry in the processor list the guest schedules work onto. On most x86 instances one vCPU is one hardware thread of a physical core, so a 4 vCPU machine is commonly 2 cores running 2 threads each.

Is a vCPU the same as a physical CPU core?

Usually not on x86. AWS documents each thread of an SMT-capable core as a vCPU, so an m5.xlarge with 2 cores and 2 threads per core reports 4 vCPUs. On Arm hardware the mapping is one to one: AWS Graviton instance types default to 1 thread per core, and Compute Engine documents one thread per core for Arm processors.

Why does my build tool spawn more workers than the runner has vCPUs?

Most tools size their worker pool from the processor list they read at startup. A cgroup CPU quota limits how much CPU time the process receives without shortening that list, so a tool can read the host's processors and start one worker per entry while the job holds a much smaller share. Pin the worker count with a flag instead.

How Do I Detect an Undersized Runner?

Look for sustained CPU pressure, memory exhaustion, filesystem saturation, or high disk I/O in representative runs. Correlate those measurements with slow or failed steps, then test a larger configuration to determine whether it improves time and cost.

How Do I Forecast Runner Spend?

Forecast runner spend by taking the billed minutes on each runner label from the last full month, applying that label's per-minute rate, and multiplying by a growth factor drawn from planned job count. Scale by job count rather than by headcount, because the bill has no seat term to grow.

What Happens to Runner Disks After a Job?

The disk is destroyed with the job. Each WarpBuild runner has its own encrypted storage volume that is created on demand and destroyed after each build, and the virtual machine that carried it is destroyed on the same schedule and never handed to a second job, both stated in the runner security documentation.

GitHub Actions

Workflow syntax, triggers, permissions, and job orchestration.

63
How Do I Export GitHub Actions Job Data to CSV?

On a report page, open More actions and select Export CSV. The export includes all rows matching the current filters and sort order. It runs in the background; download it from Export history or use the email sent when it is ready.

What is artifact retention?

Artifact retention is the period a CI platform keeps uploaded build artifacts before deleting them. The window is set per repository and can be narrowed per upload. On GitHub Actions the default is 90 days, and when the window closes the artifact is deleted and its download link stops resolving.

What is a build matrix in GitHub Actions?

A build matrix is the strategy.matrix block on a job. Each key names a variable and holds a list of values, and the workflow expands that one job definition into a separate job for every combination of those values. Nine combinations become nine independent jobs, each with its own runner, its own workspace, and its own log.

How many jobs does a matrix create?

Start with the product of the value counts in each matrix dimension, then account for include and exclude rules. Exclusions can match several combinations, and includes can extend existing combinations or create new ones. Check GitHub’s current matrix limits for large expansions.

Why do matrix jobs queue instead of all starting at once?

Expansion and execution are separate steps. The matrix creates every job immediately, then each job waits for an online runner that advertises every label in its runs-on key. A matrix wider than the number of eligible runners runs in waves, so wall clock time tracks available capacity instead of matrix width.

What makes an action composite rather than JavaScript or Docker?

The runs.using value in action.yml. A composite action sets runs.using to composite and supplies runs.steps, a list of workflow steps. A JavaScript action sets runs.using to a Node.js runtime such as node20 or node24 and points runs.main at a script file. A Docker container action sets runs.using to docker and points runs.image at a Dockerfile or a registry image.

Do composite action steps need a shell key?

Yes, whenever the step uses run. GitHub documents runs.steps[*].shell as required if run is set, so a composite step that omits it fails to parse. Steps that use uses instead of run do not need a shell key.

What does the concurrency group name control?

The group name is the identity of the lane. Any workflow run or job in the same repository that resolves to the same string shares that lane and waits for it. GitHub treats the name as case insensitive, so prod and Prod are one group.

Does a concurrency group make jobs start sooner?

No. A concurrency group only holds work back or cancels it. One run occupies the lane, the next becomes pending, and later arrivals are cancelled or lined up depending on the queue setting. Waiting caused by a shortage of runners is a separate problem.

What does the environment key do in a job?

It binds one job to a named environment configured in repository settings. The job waits until every protection rule on that environment passes, then runs with that environment's secrets and variables in scope, and GitHub records a deployment object for the run.

Does an environment secret override a repository secret with the same name?

Yes. For a job referencing an environment, an environment secret takes precedence over a repository or organization secret with the same name. Review each level when a job receives an unexpected credential.

What happens if a workflow names an environment that does not exist?

GitHub creates it during the run with no protection rules and no secrets configured. Anyone who can edit a workflow file can create an environment this way, while configuring reviewers, timers, and branch rules on it requires repository admin access.

What is fail-fast in a GitHub Actions matrix?

It is the key under a job's strategy block that decides what happens to the rest of a matrix when one combination fails. With fail-fast set to true, the default, GitHub cancels every in-progress and queued job in that matrix as soon as the first one fails.

Does fail-fast default to true or false?

True. A matrix with no fail-fast key behaves as if fail-fast were set to true, so the first failing combination cancels its siblings. Writing fail-fast false is the only way to keep every leg running.

When should a matrix set fail-fast to false?

When the value of the run is the full list of failures rather than the earliest one. Cross platform matrices, version compatibility matrices, and sharded test suites all fit, because a single leg cancelling the others hides how many combinations are broken and forces one run per fix.

What is the GITHUB_TOKEN in GitHub Actions?

GitHub creates a GITHUB_TOKEN secret at the start of each workflow job. It is a GitHub App installation access token for the GitHub Actions app installed on the repository, its permissions are limited to the repository that contains the workflow, and steps read it as secrets.GITHUB_TOKEN or through the github.token context.

When does the GITHUB_TOKEN expire?

The token expires when the job finishes, or at its effective maximum lifetime if the job is still running. On GitHub-hosted runners the maximum job execution time is 6 hours, so the token lives 6 hours at most.

Do several steps in one job overwrite each other's summaries?

No. GITHUB_STEP_SUMMARY is unique for each step, so two steps write to two different files, and steps are isolated so malformed markdown in one cannot break rendering for the next. When the job finishes, the summaries for all its steps are grouped into a single job summary.

What is the default timeout for a GitHub Actions job?

360 minutes. GitHub's workflow syntax reference documents 360 as the default for jobs.<job_id>.timeout-minutes, so a job with no timeout-minutes key runs for up to six hours before the platform cancels it.

Does a job timeout include the time a job spends waiting for a runner?

No. timeout-minutes measures execution, which starts when a runner picks the job up. Waiting for a free runner is governed separately, and GitHub cancels a job that has been queued for a self-hosted runner for 24 hours.

Can a step have a shorter timeout than the job that contains it?

Yes, and that is the useful pattern. A step level timeout-minutes kills the step process at its own limit while the job level value stays as a backstop for everything else. The step maximum is 360 minutes on both GitHub-hosted and self-hosted runners, and both keys take positive integers only.

Why does a one line change trigger the whole pipeline in a monorepo?

Because a workflow trigger fires on a repository event and carries no opinion about which directory moved. A workflow with a bare on push key runs the same jobs whether the commit edited a README or a shared library.

What is the difference between a reusable workflow and a composite action?

A reusable workflow is a whole workflow file with its own jobs, and each of those jobs declares its own runs-on and gets its own machine. A composite action is a bundle of steps that runs inside a job the caller already started, on the caller's machine.

Can a reusable workflow live in a different repository?

Yes. Reference it as owner/repo/.github/workflows/file.yml@ref, subject to GitHub access policies. Reusable workflow files must be directly inside .github/workflows. Pin a trusted ref, and pass required inputs and secrets explicitly.

Why are the caller's environment variables missing inside the reusable workflow?

GitHub does not propagate variables set in an env context at the workflow level of the caller into the called workflow. Pass the values you need as typed inputs under with, and send values back out through outputs declared on on.workflow_call.

What is a runner group in GitHub Actions?

A runner group is a container defined on the GitHub side that holds a set of runners and carries an access policy. The policy decides which repositories may send jobs to those runners, and optionally which workflow files, branches, tags, and commit SHAs may claim them. Every runner registered at the organization or enterprise level belongs to exactly one group.

Do runner groups apply to repository-level runners?

Groups are an organization and enterprise concept. A runner registered against a single repository is already scoped to that repository, so there is no group policy to apply. Once a runner is registered at the organization or enterprise level, it lands in a group, and the group's access policy decides which repositories can reach it.

How does a workflow target a specific runner group?

Use the object form of runs-on with a group key, for example runs-on with group set to production-runners and labels set to [linux, x64]. GitHub first narrows the candidate runners to that group, then applies the usual label subset match inside it. A job that names no group is eligible for any group the repository can reach.

Why does a job stay queued when a runner group excludes the repository?

No runner is eligible, so nothing claims the job and nothing writes to the log. The run sits at the waiting state with an empty log view for as long as you let it. GitHub cancels a job that has been queued for 24 hours, so the failure surfaces a day later rather than immediately.

What does runs-on mean in GitHub Actions?

runs-on is the key inside a job that selects which runner executes that job. It holds a label, a list of labels the runner must all carry, or an object naming a runner group plus labels to filter inside it. GitHub routes the queued job to an online runner that advertises everything the key asked for.

What does workflow_dispatch do?

workflow_dispatch marks a workflow as startable on demand. Once the trigger is declared, a person can start a run from the Actions tab or the GitHub CLI, and a program can start one through the REST API, passing values for the inputs the workflow file declares.

Why is the Run workflow button missing from my workflow?

GitHub's documentation states that to trigger the workflow_dispatch event, your workflow must be in the default branch. A workflow that declares the trigger on a feature branch shows no button until that branch merges, even though the file is syntactically correct.

What is a workflow event in GitHub Actions?

A workflow event is the repository activity that starts a workflow run. Common events are a push to a branch or tag, activity on a pull request, a schedule tick from a cron expression, and a manual workflow_dispatch.

Can one workflow respond to more than one event?

Yes. The on key accepts a list or a mapping of several events, and each one can carry its own filters. A workflow can declare push, pull_request, schedule, and workflow_dispatch together. Every run still has exactly one triggering event, so steps that need to behave differently branch on github.event_name.

Where do I see which event started a run?

The run summary page names the event, and inside a job the value is available as github.event_name. The full webhook payload for that event sits in the github.event object, so a step can read github.event.pull_request.number or github.event.head_commit.message without calling the API.

Where does a permissions block go in a workflow file?

At the top level of the file, inside a single job, or both. A top level block sets the grants for every job in the run. A job level block replaces that set for one job. The common shape is a read only default at the top and one job widened to the scopes it actually calls.

What happens when a workflow has no permissions block?

The run uses the default configured for the repository, or the organization value when an administrator has pinned it. GitHub documents two choices for that default: permissive, which grants write access on most scopes, and restricted, which grants read access on contents and packages.

How Do I Attach Build Provenance to an Image?

Enable provenance output on the build itself: set provenance: mode=max on the build and push step and push the image straight to a registry, and the builder produces a SLSA provenance attestation and pushes it into the same image index.

How Do I Authenticate to a Private Registry?

Add one login step to the job before any step pulls or pushes an image, and give that step either a registry token stored as a repository secret or short lived credentials obtained from an OpenID Connect exchange with your cloud provider.

How Do I Authenticate to AWS With OIDC?

Request an identity token inside the job, exchange it with AWS STS for temporary credentials, and let an IAM role trust policy decide which repository and which ref are allowed to make that exchange.

How Do I Build a Rust Binary for Multiple Targets?

Build one job per target in a GitHub Actions matrix, pairing every Rust target triple with a runner label of the same architecture and operating system, and pass that triple to cargo build --target.

How Do I Build and Push in One GitHub Actions Step?

Use a build and push action with push: true and hand it the tags a metadata step computed earlier in the same job, so BuildKit exports each layer to the registry as the build finishes it and the image is never produced twice.

How Do I Cancel In-Progress Runs on a New Push?

Declare a concurrency group keyed on the ref and set cancel-in-progress: true, so the newest push takes the lane and the run already going is cancelled. The two keys live at the top level of the workflow file and are documented in GitHub's concurrency syntax reference, checked on 2026-08-13.

How Do I Generate an SBOM During a Build?

Generate the SBOM from the image build itself: set sbom: true on the build step so BuildKit scans the build result and attaches an SPDX document to the image as an attestation (Docker SBOM attestations).

How Do I Limit a Workflow to One Run at a Time?

Declare a concurrency block at the workflow level with a fixed group name and leave cancel-in-progress off, which is its default. Runs in that group then serialize: the run already in progress finishes, and a run that arrives while it is going parks in a pending state instead of starting alongside it, per GitHub's workflow syntax reference.

How Do I Publish a Package From a Workflow?

Publish from a job that runs only on a release event, authenticate with a credential scoped to the target registry, and ship the artifact the test job already built. The publish job downloads that artifact instead of rebuilding it, so the bytes that passed the test suite are the bytes that reach the registry.

How Do I Push a Manifest List from GitHub Actions?

Build each architecture on a runner of that architecture, push both images by digest with no tag attached, then run docker buildx imagetools create in a final job to publish one manifest list that points at both digests.

How Do I Reuse a Workflow Across Repositories?

Publish the shared logic once as a reusable workflow: a file in .github/workflows on the host repository with on: workflow_call, declaring the inputs and secrets it needs. Every other repository then calls it from a job with uses: OWNER/REPO/.github/workflows/FILE.yml@REF, passing those inputs and secrets explicitly and pinning REF to a tag.

How Do I Run a Job Only When Files Change?

Two mechanisms cover this, and the right one depends on how many projects a single workflow serves. Put a paths filter on the trigger when the workflow belongs to one project, and run a short change detection job whose outputs feed if conditions on the other jobs when one workflow serves several.

How Do I Run a Workflow Manually?

Add a workflow_dispatch trigger to the workflow file, declare the inputs it needs with types, and the run starts either from the Run workflow button on the Actions tab or from a single API call.

How Do I Run Browser Tests Headless in GitHub Actions?

Run browser tests headless in GitHub Actions by launching the browser in its headless mode with the system libraries it links against already installed, then giving the job enough memory for the worker count you set.

How Do I Run Database Services in GitHub Actions?

Run a database in GitHub Actions by declaring it as a service container under the job's services key, gating the first step on the container health check, and sizing the runner so the database engine and the test workers both fit in memory.

How Do I Run Go Race Detector Tests in GitHub Actions?

Run go test -race ./... on a supported platform with the required toolchain. Race instrumentation adds runtime and memory overhead, so measure representative runs and size the job accordingly rather than reusing an undersized test configuration.

How Do I Run Jobs on a Schedule?

Add a schedule trigger with a cron expression to the workflow file, and put workflow_dispatch next to it so the same jobs can start by hand.

How Do I Run PowerShell Scripts in GitHub Actions?

Set the shell on the step with shell: pwsh and let the script exit non-zero when the work fails. GitHub Actions runs pwsh by default on Windows runners and bash -e by default on Linux and macOS runners, and the pwsh and powershell keywords start two different interpreters, so a run block that leaves the shell unset behaves differently depending on which runner picked the job up.

How Do I Set a Timeout on a Job?

Set timeout-minutes on the job as a backstop, then set a tighter timeout-minutes on any step that can block: a service wait, a network fetch, an integration suite. With neither key present GitHub applies a default of 360 minutes, so one hung step holds a runner for six hours and bills every minute of it.

How Do I Skip a Workflow for a Commit?

GitHub supports skip markers such as [skip ci] for workflows triggered by push and pull_request. They do not skip every event type, and skipped required checks can remain pending. Check branch protection before using a marker.

How Do I Stop a Workflow From Blocking Deploys?

Use a separate concurrency group for each deployment target so unrelated CI workflows do not contend for the same group. Choose cancellation behavior deliberately: cancel-in-progress: false protects a running deployment but does not create a durable FIFO deployment queue.

How Do I Use include and exclude in a Matrix?

In a GitHub Actions matrix, exclude removes combinations from the product and include either merges extra keys into combinations that already exist or appends combinations the product never produced. GitHub applies every exclude entry first and every include entry afterwards, which is why an include entry can add back a combination that exclude just dropped.

How Do I Write a Composite Action?

Create an action.yml file that sets runs.using to composite and lists your steps under runs.steps, then call it from a job with uses pointing at either a path inside the repository or an owner/repo@ref reference.

How Do I Write a GitHub Actions Job Summary?

Write a job summary by appending GitHub flavored markdown to the file whose path GitHub puts in the GITHUB_STEP_SUMMARY environment variable, and the workflow run page renders that markdown as a panel under the job.

How Many GitHub Actions Jobs Can Run at Once?

There is no single number, because three separate ceilings sit between a queued job and a running one: the concurrency key you wrote in workflow YAML, the concurrent job limit attached to your GitHub plan, and the capacity of the runner pool behind your runs-on labels.

How Many Jobs Can a Matrix Fan Out To?

A single matrix generates at most 256 jobs per workflow run, and a definition whose product lands above that fails the run before any job starts. Two other numbers usually bind first: how many matching runners are available behind your runs-on label, and what the fan-out bills in runner minutes.

Linux Runners

Ubuntu, x86-64, ARM64, and native builds.

24
Which Ubuntu releases can I select on WarpBuild?

The catalog lists Ubuntu 22.04, 24.04, and 26.04 for x86-64, and Ubuntu 24.04 and 26.04 for ARM64. Select an explicit version label when your build depends on a particular Ubuntu release.

Does WarpBuild offer Linux on Apple Silicon?

Yes. The Ubuntu 26.04 ARM64 labels ending in -xfast run Linux VMs on Apple M4 Pro hardware. They complement the standard ARM64 fleet and have their own 6-vCPU and 12-vCPU configurations.

Why is the working directory different on Ubuntu ARM64?

WarpBuild documents /runner/_work for Ubuntu 24.04 ARM64, rather than GitHub’s /home/runner/work layout. Use GitHub-provided workspace paths in scripts instead of assuming an absolute checkout directory.

Can I still select Ubuntu 22.04 ARM64 runners?

Ubuntu 22.04 ARM64 images were deprecated on March 31, 2025. Migrate to a supported ARM64 Ubuntu image and validate native binaries, package availability, and working-directory assumptions during the change.

How do I tell whether an EC2 instance type uses Graviton?

Read the letters between the generation number and the size. A g there means the instance runs on an AWS Graviton processor, so m7g, c8g, and r8gd are all ARM64 shapes.

Is Graviton the same thing as ARM64?

Graviton is one implementation of the ARM64 architecture. ARM64, which the Linux kernel reports as aarch64, is the instruction set, and Graviton is the processor family AWS builds to run it. A binary or container image produced for linux/arm64 runs on a Graviton instance and on other ARM64 machines as well.

Do I have to rebuild container images to run on Graviton?

Yes, when the current image contains only a linux/amd64 manifest. A Graviton instance has no x86-64 translation layer, so an amd64-only image fails at startup with an exec format error. The fix is a linux/arm64 build, published either as an arm64 image or as one entry in a manifest list that also carries the amd64 image.

What does /dev/kvm actually do?

It is the entry point to the kernel's virtualization interface. A process opens the device, issues KVM_CREATE_VM and KVM_CREATE_VCPU to get file descriptors for a virtual machine and its virtual CPUs, then calls KVM_RUN to execute guest instructions on the physical CPU through the hardware virtualization extensions.

Why is /dev/kvm missing inside a GitHub Actions job?

A hosted runner is itself a virtual machine, so the device appears in the guest only when the layer underneath exposes the CPU virtualization extensions to that guest. That is nested virtualization. Without it the kvm modules have no hardware to program, the device node is never created, and an open call returns ENOENT.

What is the difference between KVM and QEMU?

KVM is a kernel interface that runs same architecture guest code directly on the host CPU. QEMU is a user space program that emulates machines and devices, and it can either translate foreign architecture instructions in software or hand same architecture guest code to KVM for hardware acceleration.

What is a local SSD on a cloud instance?

A local SSD is a solid state device attached to the physical host that runs the instance, reached over the host bus rather than over the storage network. Cloud providers call it an instance store on AWS, Local SSD on GCP, and local NVMe on Azure VM families that carry it.

How do I get a local SSD on a GitHub Actions runner?

By launching the runner on an instance type that includes one, then mounting it at the runner work directory. Local devices cannot be attached after launch, so the shape chosen for the runner set decides whether the job has one at all.

What is nested virtualization?

Nested virtualization is running a virtual machine inside a machine that is already a virtual machine. The outer hypervisor has to expose the host CPU's hardware virtualization extensions to its guest, so that the guest kernel can act as a hypervisor for a second layer of virtual machines.

How do I tell whether a GitHub Actions runner supports nested virtualization?

Run ls -l /dev/kvm in a step on a Linux runner. A missing device means the outer hypervisor kept the virtualization extensions to itself. A device that exists with crw-rw---- root:kvm permissions means the extensions are exposed and the job user still needs group access before it can open the device.

Why does an Android emulator job get slow instead of failing?

The android-emulator-runner action probes /dev/kvm before it launches. When the probe fails it logs a ProbeKVM line, disables Linux hardware acceleration, and starts the emulator with -accel off, so the job keeps running under software emulation and finishes much later than usual.

What is QEMU emulation in a Docker build?

It is user mode emulation of a foreign processor architecture. QEMU translates the guest instructions of every binary inside the target rootfs into host instructions and forwards the guest syscalls to the host kernel, so an x64 machine can execute the aarch64 binaries in an arm64 base image.

How does the kernel know to hand a binary to QEMU?

Through binfmt_misc, a Linux kernel feature that maps the magic bytes at the start of a file to an interpreter. Registering an aarch64 entry writes a file under /proc/sys/fs/binfmt_misc naming the aarch64 ELF magic and the qemu-aarch64 binary, and the kernel routes matching binaries there instead of failing with exec format error.

Which build steps get slower under QEMU emulation?

The steps that execute guest binaries and burn CPU: compilers, linkers, minifiers, package managers that build from source, and tests run during the image build. Docker's multi-platform documentation states that emulation with QEMU can be much slower than native builds, especially for compute heavy tasks like compilation and compression or decompression.

Can GitHub Actions Run an Android Emulator?

Yes. GitHub Actions runs an Android emulator on Linux x86-64 runners, and the emulator runs with hardware acceleration whenever the runner exposes /dev/kvm to the job. On WarpBuild cloud runners you enable that by appending ;nested-virtualization.enabled=true to the runs-on label, then adding the documented KVM udev permission step before the emulator action.

Can GitHub Actions Run on ARM64?

Yes. GitHub Actions runs jobs on ARM64 hardware natively, and the switch is a one line change to runs-on: point the job at an ARM64 runner label such as warp-ubuntu-latest-arm64-4x and the steps execute on an aarch64 machine with no translation layer in between.

Can I Build 32-bit ARM Targets on ARM64 Runners?

Yes. A 32-bit ARM artifact is produced on an ARM64 runner by cross compiling with a toolchain that targets the 32-bit ABI, which keeps the compiler running as native aarch64 code and avoids standing up an emulated 32-bit environment for the build.

Can ARM64 and x64 Jobs Run in One Workflow?

Yes. runs-on is a per-job field, so one workflow file can place a job on an ARM64 label and another job on an x64 label in the same run, and a matrix is the normal way to write that.

How Do I Run ARM64 Integration Tests?

Run the integration test job on a native ARM64 runner so the service under test, its service containers, and the test harness all execute on aarch64. Point runs-on at a Linux ARM64 label such as warp-ubuntu-latest-arm64-8x, which carries 8 vCPU and 32 GB at $0.012 per minute.

Which ARM64 Runner Sizes Are Available?

Standard WarpBuild Linux ARM64 runners range from 2 to 32 vCPU, with 8GB to 128GB memory and 150GB SSD storage. Separate Ubuntu ARM64 on Apple Silicon configurations use 6 or 12 vCPU and different memory/storage sizes.

macOS Runners

Apple Silicon, Xcode, signing, and simulator workflows.

20
Which macOS versions are available on WarpBuild?

The catalog lists macOS 14, 15, and 26 on Apple Silicon. macOS 13 has been removed. Use an explicit version label when release builds need a predictable operating-system family.

What hardware powers WarpBuild macOS runners?

WarpBuild macOS runners use Apple M4 Pro hardware with ARM64 architecture. The catalog provides 6-vCPU and 12-vCPU configurations; available sizes depend on the selected macOS image.

How much memory do WarpBuild macOS runners have?

The 6-vCPU macOS configuration has 14GB memory and the 12-vCPU configuration has 28GB. These memory sizes took effect on October 1, 2026. Check the selected label in the current catalog before sizing a build.

Can macOS use region-specific cloud infrastructure?

The documented enterprise region-specific infrastructure option explicitly excludes macOS instances. Discuss macOS placement requirements with the team before relying on a regional deployment for Apple builds.

Does macOS have the same concurrency policy as Linux?

High-concurrency macOS requirements should be discussed with WarpBuild support. The documented unlimited concurrency statement applies to generally available Linux and Windows runners and should not be extended to macOS.

Where can I check installed Xcode and simulator versions?

Use the preinstalled-software documentation and the image manifest for your selected macOS label. Tooling changes with image updates, so verify the installed Xcode and simulator runtimes when pinning a release workflow.

Why does a signature need a timestamp?

A trusted timestamp provides evidence that signing occurred while the signing certificate was valid. Whether an older signature remains acceptable depends on the platform’s verification policy, certificate chain, revocation status, and timestamp validity.

Is code signing the same as notarization?

No. Signing is a local operation that attaches a signature using a key you hold. Notarization on Apple platforms is a separate submission to Apple's service, which scans the already signed build and returns a ticket. A build can be signed and still be refused by Gatekeeper if it was never notarized.

What is a provisioning profile?

A provisioning profile is a property list wrapped in a Cryptographic Message Syntax signature and signed by Apple. It binds an application identifier to the certificates allowed to sign that application, to a device list or a distribution method, and to an expiration date, and it carries the allowlist of entitlements the signed code may claim.

What is the difference between a signing certificate and a provisioning profile?

A signing certificate binds an identity to a public key; the corresponding private key creates signatures. An Apple provisioning profile authorizes particular app identifiers, signing identities, entitlements, and distribution conditions. Building a signed app requires compatible signing material and profiles.

Where does a GitHub Actions job install a provisioning profile?

Into the profile directory of the Xcode the job selects. Xcode 16 and later read ~/Library/Developer/Xcode/UserData/Provisioning Profiles, and earlier toolchains read ~/Library/MobileDevice/Provisioning Profiles. The profile is stored base64 encoded in a repository or environment secret and decoded into that directory before xcodebuild archive runs.

What is a simulator runtime?

It is the guest operating system image a simulator boots: the OS build, frameworks, and system apps for iOS, tvOS, watchOS, or visionOS, packaged so a Mac can run them. It is downloaded and versioned separately from the developer tools that create and drive simulated devices.

Why did my simulator tests change behavior with no code change?

A destination written with OS=latest resolves to the newest runtime installed on the machine at the moment the job runs. When an image update adds a newer runtime, the same commit starts testing against a different operating system build, which moves API behavior, permission prompts, and locale defaults.

Can GitHub Actions Build iOS Apps Without a Mac?

No. An iOS archive is produced by Xcode, Apple publishes Xcode for macOS only (Xcode minimum requirements), and no supported cross-platform path produces a signed .ipa, so the job that builds one has to land on a macOS runner.

Can Android and iOS Builds Share One Workflow?

Yes. runs-on is declared on each job rather than on the workflow, so one file can hold an Android job on a Linux runner and an iOS job on a macOS runner. WarpBuild provides Linux x64, Linux ARM64, macOS, and Windows runners, so both legs select a warp- label and the pair runs in parallel from the same trigger.

Can You Run Docker on macOS GitHub Actions Runners?

WarpBuild macOS runners do not support nested virtualization or a local Docker daemon for Linux containers. Put container work in a Linux job or use a supported remote builder while the macOS job handles Apple tooling.

Do GitHub Actions Runners Support macOS?

Yes. GitHub Actions runs macOS jobs on ARM64 macOS runners, and moving a job onto one is a single runs-on change to a label such as warp-macos-15-arm64-6x, which provisions 6 vCPU with 14GB of memory and a 120GB SSD at $0.08 per minute. WarpBuild provides Linux x64, Linux ARM64, macOS, and Windows runners, and the macOS line is ARM64 only.

Is Xcode Preinstalled on macOS Runners?

Yes. Xcode is baked into the macOS runner image, so a job that calls xcodebuild in its first step compiles right away with no toolchain download at job start.

How Do I Select an Xcode Version in GitHub Actions?

Selecting an Xcode version in GitHub Actions is two decisions. Pick the runner image that carries the Xcode version you want, because the image decides which toolchains exist on disk, then point the job at that toolchain by setting DEVELOPER_DIR at job level or running sudo xcode-select -s on the bundle path, and print xcodebuild -version as the first step so the log records which toolchain compiled the build.

How Much Disk Do macOS Runners Have?

A WarpBuild macOS runner carries a 120GB SSD on the 6 vCPU labels and a 270GB SSD on the 12 vCPU labels, and the figure comes from the runner row you name in runs-on.

Windows Runners

Windows Server images, tooling, and .NET builds.

10
Does WarpBuild Cache support Windows runners?

WarpBuild Cache is not supported on Windows runners. This limitation applies to the WarpBuild cache service; it does not mean all GitHub Actions caching mechanisms are unavailable on Windows.

Which Windows versions are available on WarpBuild?

The catalog lists Windows Server 2022 and Windows Server 2025 on x86-64. Windows Server 2025 also has separate labels selecting Visual Studio 2026. Choose the label matching your toolchain requirements.

What does the Windows latest label select?

The documented warp-windows-latest-x64 labels currently select Windows Server 2022. Use an explicit Windows Server 2025 label if that is required; do not assume latest points to the numerically newest release.

Can I use a 2-vCPU Windows runner?

The 2-vCPU Windows runner tier was removed on June 8, 2026. Choose a 4-vCPU or larger supported Windows label and update workflows still referencing a removed size.

Can GitHub Actions Run Windows Builds?

Yes. GitHub Actions runs Windows builds on x86-64 Windows runners, and moving a job onto one is a single line change to runs-on: point it at a Windows label such as warp-windows-latest-x64-8x and the steps execute on a Windows Server machine with MSBuild, Visual Studio, and the rest of the standard Windows toolchain already installed.

Can I Still Build on Windows Server 2022?

Yes. Windows Server 2022 is a current image in the WarpBuild catalog: warp-windows-latest-x64-<size> resolves to Windows Server 2022 today and warp-windows-2022-x64-<size> is the dated alias for the same machines. Windows Server 2025 ships beside it on its own labels, and the preinstalled software documentation publishes the Windows Server 2022 x86-64 tooling list for teams mapping a pipeline across the two.

Can I Run Unit Tests in Parallel on Windows Runners?

Yes. A Windows GitHub Actions job runs unit tests in parallel two ways: raise the test runner's worker count so one larger machine executes several tests at once, or shard the suite across several jobs that each run a slice.

Do Windows Runners Support Nested Virtualization?

No. Nested virtualization is documented for cloud Linux x86-64 runners through the nested-virtualization.enabled=true dynamic label, Windows runners are recorded as unsupported in the support matrix, and that matrix is what to read before you design a workflow around /dev/kvm, because an unsupported label is accepted and ignored rather than rejected, so the job starts and the KVM-dependent step is what breaks.

How Do I Install Windows SDK Components in a Job?

Two routes work. Run the Visual Studio installer inside a step with --add <component-id> --quiet --norestart, waiting for the process to exit, or point runs-on at a Windows runner image that already ships the SDK build your project targets so nothing is downloaded during the job.

What Is the Smallest Windows Runner Size?

The smallest Windows GitHub Actions runner size available on WarpBuild is 4 vCPU with 16GB of memory and 256GB of SSD storage, at $0.016 per minute. The 2 vCPU Windows tier was removed on June 8, 2026, so warp-windows-latest-x64-4x and its Windows Server 2025 equivalents are the entry shapes on every Windows image family (changelog).

Docker Builders

Remote builders, container images, and multi-platform builds.

48
How do I create a WarpBuild Docker builder profile?

Open Docker builders in the WarpBuild dashboard and select New Docker builder. Configure the profile, then pass its name to the WarpBuild build-push, bake, or docker-configure action in your workflow.

Can I use WarpBuild Docker builders from another CI provider?

Yes. The Docker builder documentation supports non-WarpBuild runners and API integration, including local development and other CI systems. Authenticate with an API key when the caller is not a WarpBuild runner.

Do Docker builders require an API key on WarpBuild runners?

The documented build actions do not require an API key when running on WarpBuild runners. On other runners, pass the required API key securely through your CI secret store.

Do I need cache-to and cache-from with WarpBuild Docker builders?

A cached WarpBuild Docker builder automatically retains and reuses layers, so those explicit cache export and import options are not required for its built-in cache. Remove obsolete settings when moving from the older cache backend.

How long does a Docker builder keep its cache?

Builder cache and data have a 10-day inactivity TTL. If a profile is unused for more than 10 days, it is reset automatically. Expect a cold build after that reset.

Will concurrent Docker builds immediately see each other’s new layers?

Builder cache sharing is eventually consistent. A layer produced by one concurrent build may not immediately be available to another, but it becomes available for later builds after synchronization.

Does my CI runner size determine the remote builder size?

No. The builder profile determines the Docker build machine’s size independently of the GitHub Actions runner. Size the runner for orchestration and other job steps, and the builder for the container workload.

Are auto-scaling Docker builders generally available?

The Docker builder documentation currently labels automatic scale-out as private beta. The standard profile uses a dedicated builder VM; do not assume extra builder machines are automatically provisioned for every account.

How should I size a builder for parallel builds?

The documentation recommends approximately 8 vCPU and 16GB memory per concurrent build job. Shared profiles have no hard build-count limit, but CPU, memory, and disk capacity still constrain practical throughput.

Why is my WarpBuild Docker builder timing out?

Builders have idle timeouts to limit charges. Invoke the docker-configure action immediately before the step that performs the build, rather than leaving a long gap between builder setup and use.

Why does a multi-platform build report exec format error?

Check that the builder profile has the required architectures enabled. A multi-platform build requesting amd64 and arm64 needs a profile configured for both, rather than a profile limited to one architecture.

What is a base image in a Dockerfile?

The base image is the image named in a FROM instruction. It supplies the root filesystem and the image configuration that the instructions after it build on, so the tools, libraries, default user, and PATH available to the first RUN line all come from it.

Does every Dockerfile have exactly one base image?

A Dockerfile has one base image per stage, and each FROM instruction starts a stage. A two stage Dockerfile that compiles in one image and copies the result into a smaller runtime image names two base images, and only the last stage decides what the published image contains.

Why does a base image update invalidate the rest of the build cache?

A changed base-image digest changes an input for dependent build steps, so BuildKit may need to rebuild those steps. Independent stages can still reuse their caches. Inspect the build output to identify which dependencies caused invalidation.

What is the difference between BuildKit and Buildx?

BuildKit is the engine that executes a build: it turns the Dockerfile into a graph, schedules the steps, and owns the cache. Buildx is the client-side CLI that decides which BuildKit instance receives the build, creates and lists builders, and passes flags such as platforms and cache backends to the engine.

How do I tell whether a build used BuildKit?

Docker Engine 23.0 and later run docker build through BuildKit by default, and the giveaway is the grouped step output with per-step timings instead of a flat stream of intermediate container IDs. On older engines the legacy builder ran unless DOCKER_BUILDKIT=1 was set in the environment.

Do I need to install Docker Buildx separately?

Usually no. Buildx ships with Docker Desktop and with current Docker Engine packages as the docker-buildx-plugin, and the GitHub-hosted runner images include it. Run docker buildx version to confirm the plugin is on the path before adding a setup step.

What is the difference between docker build and docker buildx build?

Modern Docker installations use BuildKit for builds. Buildx provides builder management and access to different drivers and remote builders. Use docker buildx commands when you need to select or configure a specific builder and inspect its capabilities.

Why does a multi-platform build fail on the default builder?

The default builder uses the docker driver, which builds for one platform per invocation unless the daemon runs the containerd image store. Create a builder on the docker-container, kubernetes, or remote driver, then pass --platform with the architecture list.

What does a container registry actually store?

Two kinds of object. Blobs are opaque byte streams named by their sha256 digest, and they hold the layer tarballs and the image config JSON. Manifests are small JSON documents that list the config blob and the layer blobs belonging to one image, in order, with a media type and a size for each.

What is the difference between a tag and a digest?

A digest is the sha256 hash of the manifest bytes, so a digest reference always resolves to the same image. A tag is a name the registry lets a push reassign, so the same tag can point at different content in two runs.

Why does a workflow have to log in to a registry on every run?

Registry credentials live in the client's config.json or in a credential helper on the machine running the pull. A workflow job that starts on a fresh machine has an empty config, so the login step runs again to exchange credentials for a short lived bearer token scoped to the repository and the action requested.

Which file does docker buildx bake read?

By default bake looks in the working directory for docker-bake.hcl, docker-bake.json, their.override variants, and Compose files such as compose.yaml or docker-compose.yml, since a Compose file is a valid bake definition. Passing -f names the file explicitly, and repeating -f merges several files into one definition.

How is bake different from running docker build twice?

Two docker build commands carry their context, Dockerfile, tags, build args, and cache flags on the command line, and each one is a separate invocation. Bake keeps those fields in a file as named targets, and one invocation resolves the file, expands the requested targets or group, and sends them to the same builder together.

How do I override a bake value without editing the file?

A variable block reads its value from the environment, so exporting TAG=abc123 before the command changes every expression that references it. The --set flag overrides target attributes directly with a target pattern, as in --set *.platform=linux/amd64, and --print renders the resolved definition as JSON without building anything.

Is the IMAGE ID from docker images the same as the digest?

No. The IMAGE ID column shows the digest of the image config blob, which is computed locally when the image is built. The registry digest is computed over the manifest document that lists the config and the layers. The two values are different hashes of different documents, and only the manifest digest works in a pull reference.

Does a digest still work for a multi-platform image?

Yes. A multi-platform build publishes an image index that lists one manifest per platform, and the index itself has a digest. A client pulling that index digest reads the platform entries and fetches the manifest matching its own architecture, so one digest covers every platform in the build.

What is the difference between a manifest list and an image index?

They are the same idea in two formats. A Docker manifest list carries the media type application/vnd.docker.distribution.manifest.list.v2+json and an OCI image index carries application/vnd.oci.image.index.v1+json. Both hold a list of per architecture manifests with a platform block on each entry, and registries and clients accept either.

How does a client know which architecture to pull?

The client requests the tag with an Accept header listing the manifest media types it understands. When the registry returns an index, the client compares its own operating system and CPU architecture against the platform block of each entry and fetches the matching manifest by digest. Passing --platform to docker pull or docker run overrides that choice.

Why does my manifest list contain unknown/unknown entries?

BuildKit can attach provenance and SBOM attestations as additional manifests with unknown/unknown platform metadata. These are not runnable platform images. Inspect the manifest annotations before treating them as a broken architecture build.

Which stage becomes the image when no target is passed?

The last stage in the file. Passing a target ends the build at the named stage instead, which is how one Dockerfile produces a test image and a runtime image from the same set of earlier stages.

Can COPY --from read from an image instead of a stage in the file?

Yes. COPY --from accepts an image reference as well as a stage name, so a stage can lift one file out of a published image without inheriting that image's layers. Copying a certificate bundle into a minimal base image is the common case.

What is the difference between provenance and an SBOM?

Provenance describes how an artifact was produced: the source repository and commit, the builder identity, the workflow file, and the parameters that run was given. An SBOM describes what is inside the artifact: the packages and versions assembled into it. They are separate documents with separate predicate types, and a build can publish both against the same digest.

Does a provenance attestation prove the build is safe?

No. The statement records what the build system observed, and verification answers who signed it and whether the subject digest matches the artifact in hand. Whether the recorded source, builder, and parameters are acceptable is a policy decision the verifier makes after the signature checks out.

Where is the attestation stored if it is not inside the image?

The signed statement is a separate document referenced by the artifact digest. It can be pushed to the same OCI registry as a referrer of the image manifest, kept in the build platform's own attestation store and fetched by digest at verification time, or written next to a released binary as a file.

Can GitHub Actions Build Multi Architecture Images?

Yes. GitHub Actions builds multi architecture images two ways: one job per architecture on a runner of that architecture, joined afterwards by a manifest list, or a single job that hands the build to a remote Docker builder profile with both architectures enabled.

Can I Build ARM64 Images on an x64 Runner?

Yes, an x64 runner builds linux/arm64 Docker images through QEMU emulation: docker/setup-qemu-action registers binfmt_misc handlers on the host, and BuildKit then executes every RUN layer as translated aarch64 instructions on x86-64 hardware.

Can I Run Docker Compose in GitHub Actions?

Docker Compose is available on the documented Ubuntu runner images. Check the selected image’s tooling manifest, then run your Compose services with health checks and enough memory for both the containers and test processes.

Can I Use Podman Instead of Docker in GitHub Actions?

Yes, Podman builds and runs OCI images on Linux GitHub Actions runners, it is already present on the Ubuntu runner images, and swapping docker build for podman build in a workflow is a change to the run steps rather than to the job.

Can Two Jobs Share One Docker Builder?

Yes. Overlapping jobs using the same standard builder profile share its builder VM and persistent cache. The overlapping usage is billed as one session per architecture. Automatic scale-out is separately documented as private beta.

Do ARM64 Runners Support Docker Buildx?

Yes. Docker Buildx runs on ARM64 GitHub Actions runners, so docker buildx build --platform linux/arm64 on a label such as warp-ubuntu-latest-arm64-4x produces arm64 layers on aarch64 hardware with no emulation in the path.

Do Remote Docker Builders Support Multi Platform Builds?

Yes. The documented shape is one builder instance per platform, joined into a single Buildx instance, so the amd64 layers compile on an amd64 machine and the arm64 layers compile on an arm64 machine with no instruction translation anywhere in the build.

Does Caching Work Inside a Container Job?

Yes, a container job restores and saves a WarpBuild cache once the image carries wget and zstd and the job passes WARPBUILD_RUNNER_VERIFICATION_TOKEN into the container environment, which is the setup written down in the WarpBuild caching documentation.

How Do I Cache Docker Layers in GitHub Actions?

To cache Docker layers in GitHub Actions, either point the build at a remote Docker builder whose layer cache lives on the builder's own disk and outlives the job, or, if the build stays on the runner, configure a Buildx cache backend that exports layers to a registry or cache service and imports them on the next run.

How Do I Keep a Docker Layer Cache Across Pull Requests?

Use a persistent remote builder or a supported registry cache backend to reuse layers across builds. Configure access deliberately so untrusted pull requests cannot replace cache outputs that trusted release jobs will consume.

How Do I Reduce Docker Image Pull Time in GitHub Actions?

Three changes reduce Docker image pull time in GitHub Actions: shrink what you pull, keep the registry in the same Region as the runners, and stop re-pulling what a builder or a snapshot already holds.

How Do I Use Docker Bake in GitHub Actions?

Define each image as a target in a docker-bake.hcl file, commit it, and call the bake action once from the workflow: one invocation resolves the file, expands the targets or the group you name, and builds all of them against one builder.

What Is a Remote Docker Builder?

A remote Docker builder is a dedicated build virtual machine that runs docker build outside the GitHub Actions runner and keeps a layer cache on its own disk between jobs.

Build Caching

Cache keys, dependencies, layers, and faster repeat builds.

55
How Do I Cache Go Modules in GitHub Actions?

Use the documented WarpBuild Go setup action to cache Go modules and build outputs. For manual caching, determine paths with go env GOMODCACHE GOCACHE and include the Go version, platform, and go.sum hash in cache keys.

How Do I Cache Gradle Builds in GitHub Actions?

The WarpBuild Gradle setup action provides dependency and build caching through WarpBuild Cache. Use the action version and inputs in the setup-actions documentation, and avoid overlapping cache steps that independently save the same Gradle directories.

How Do I Cache Maven Dependencies?

Use the Java setup action’s Maven cache support, or cache ~/.m2/repository with a key that includes your platform and POM hashes. Run Maven dependency resolution after restoration; a cache hit alone does not guarantee every required artifact exists.

How Do I Cache node_modules in GitHub Actions?

Use the WarpBuild Node setup action with the appropriate package-manager cache input and lockfile path. This caches package downloads rather than assuming a restored node_modules tree is valid. Run your normal reproducible install command afterward.

How Do I Clear a GitHub Actions Cache?

Delete a WarpBuild cache entry from the console or use the cache action’s delete-cache input. Changing a key starts a new entry but does not delete the old one; broad restore keys can still restore older content.

How do I switch from actions/cache to WarpBuild Cache?

Replace the upstream cache action with WarpBuilds/cache using the version documented in the setup guide. Keep the key, paths, and restore-key strategy, then validate a cold save and a subsequent restore.

What does lookup-only do in the WarpBuild cache action?

The lookup-only input checks whether a cache entry exists without downloading it. It does not change save behavior. Use the resulting cache status when you need to check availability before choosing work.

Can a missing WarpBuild cache fail the workflow?

Yes. The fail-on-cache-miss input makes a missing entry fail the cache step. It defaults to false, so normal builds can proceed from a cold cache and recreate dependencies.

Can I save and restore a cache in separate steps?

Yes. WarpBuild provides separate restore and save actions as well as the combined cache action. Separate steps let you choose the restore point and the point where successfully produced files should be saved.

Why does a cache restore report zstd version: null?

The execution environment may lack zstd, especially inside a custom container. Different compression tools can produce different cache versions. Install the compression tools used when the cache was saved and inspect debug logs.

What is an artifact cache?

An artifact cache is a store of dependencies or build outputs written under a key, so that a later run can restore those files instead of producing them again. A run computes the key, asks the store for a matching entry, and either restores the files or does the work and writes a new entry.

What is the difference between a cache and an artifact?

A cache entry is an optimization that the store may remove at any time, so a build has to succeed when the store is empty. An artifact is an output kept for a stated period so that people or later jobs can download it.

What is the difference between an exact cache hit and a partial restore?

An exact hit means an entry existed under the primary key and the restored files match what the key describes. A partial restore means no entry matched the primary key, so the store fell back to the newest entry matching a restore-keys prefix.

Why did a cache key that hit yesterday miss today?

Either the key changed or the entry is gone. Keys built from a lockfile hash change whenever a dependency moves, and entries disappear when they age past the disuse window or when the store evicts them to stay under a size cap.

What is cache eviction?

Cache eviction is the removal of entries from a cache store so the store stays inside its budget. Two triggers cover most implementations: capacity pressure, where a new write does not fit under the size ceiling, and age, where an entry that has gone unread for a set window is deleted. The usual removal order is least recently used first.

What is the difference between eviction and expiration?

Expiration removes an entry according to an age or inactivity policy. Eviction removes entries to satisfy a storage or resource budget. A cache can implement both, so a stable key does not guarantee that an entry remains available.

Why did my GitHub Actions cache disappear without the key changing?

An entry can expire or be evicted even if its key stays unchanged. Inspect the cache’s last-access time, storage usage, and the repository’s current retention and capacity settings before changing the workflow key.

What counts as a cache hit?

Define the metric explicitly. An exact hit matches the primary key; a partial restore retrieves an entry through a fallback prefix. Track them separately because a partial restore may still require dependency installation or compilation.

What makes a good cache key?

A key that changes exactly when the cached contents should change. The common shape puts the runner platform first, then the ecosystem and its version, then a hash of the lockfile that determines what gets installed. Shorter prefixes of the same string go in restore-keys as fallbacks.

Does changing the cache key delete the old entry?

No. The previous entry stays in storage under its own key until it ages out or is evicted to make room. A new key writes a new entry, so a lockfile that changes every day leaves a trail of superseded entries behind it.

Can two jobs share one cache key?

Yes, when both jobs resolve the same key string, request the same path list, and sit inside a scope that allows the read. Two jobs with matching key text but different path values compute a different cache version and address different entries.

What decides the scope of a GitHub Actions cache entry?

The Git ref of the run that wrote it, inside the repository that owns it. A push run records refs/heads/<branch>, a pull request run records refs/pull/<number>/merge, and a tag run records refs/tags/<tag>. That ref is the boundary every later restore request is checked against.

Can one feature branch read a cache written by another feature branch?

No. Two feature branches are two separate scopes, so an entry written on feature-a is invisible to feature-b even when the keys match exactly. Both branches can read entries written on the default branch, which is why shared dependencies are usually seeded by a run on main.

What is a compiler cache?

A store of compiler output from earlier builds, addressed by a hash of the compilation inputs. When a later build presents the same source content, the same compiler, and the same options, the stored object file is copied into place and the compiler is skipped.

How is a compiler cache different from an incremental build?

An incremental build compares timestamps and a dependency graph inside one build tree, so it needs that tree to survive. A compiler cache hashes the inputs of each compilation, so it produces hits on a clean checkout and on a machine that has never built the project before.

Does a compiler cache work in GitHub Actions?

Yes, once the cache directory outlives the job. Every hosted job starts on a fresh machine, so the cache directory has to be restored at the start of the job and saved at the end, or held on a runner whose disk persists between jobs.

What invalidates a Docker layer cache?

A cache miss can result from changed instructions, base-image digests, copied files, or other declared inputs. Steps depending on a changed result may need rebuilding. Independent stages and special cache mechanisms can behave differently.

Where is the Docker layer cache stored?

In one of three places, and a single build can read from more than one. Layers can sit in the local store on the build machine, in a container registry as cache manifests and blobs written by a cache export, or on a dedicated builder that keeps its own layer store between builds and serves every client that connects to it.

Is a Docker layer cache the same as a dependency cache?

No. A layer cache stores built image layers keyed by the inputs of each Dockerfile instruction. A dependency or artifact cache stores files, such as a package manager directory, under a key the workflow computes itself. They have different keys, different lifetimes, and different restore paths.

What is the difference between an incremental build and a cached build?

An incremental build reuses valid outputs from an existing build tree and executes affected work. A cache retrieves outputs by a key describing their inputs. Build systems often combine both techniques to avoid repeated work.

Is an incremental build safe for a release artifact?

It depends on the build system’s correctness and how completely it tracks inputs. Validate release reproducibility with clean builds, and ensure stale outputs or undeclared inputs cannot affect the artifact. Incremental execution alone does not establish or disprove safety.

What is the difference between inline cache and a registry cache export?

Inline cache writes the cache manifest into the configuration of the image you push, so the image is the cache. A registry cache export writes a separate manifest to its own reference, which can describe every step of the build including stages that never reach the final image.

Why does my multi-stage build still rebuild with inline cache?

Inline cache supports min mode only, and min mode records the layers of the resulting image. A builder stage that compiles a binary and hands one file to a slim runtime stage leaves no record behind, so the compile step runs again on the next build while the runtime layers match.

How do I turn inline cache on in a Docker build?

With Buildx, pass cache-to type=inline on a build that pushes an image, then import it on the next build with cache-from type=registry pointed at that image reference. With docker build on an engine running BuildKit, the equivalent is the build argument BUILDKIT_INLINE_CACHE set to 1.

Where does a registry cache actually live?

In a container registry, as its own tag next to the application image. The cache tag holds the exported layer blobs plus a BuildKit cache config blob that records which build step produced which layer, so it is pulled like any other artifact and never runs as a container.

Why does my registry cache export fail with the default builder?

Cache backend support depends on the builder driver and image-store configuration. Check your builder’s capabilities; a docker-container or supported remote builder is commonly used for registry cache export. Configure both the export and subsequent import.

What does mode=max change?

The default mode=min exports only the layers of the final stage of the resulting image. mode=max exports the layers of every stage, including build stages whose output is copied forward, so a multi-stage Dockerfile can reuse its compile stage on the next run.

What is the difference between a remote build cache and a dependency cache?

A dependency cache holds third party packages downloaded from a registry, keyed by a lockfile hash or by the coordinate and checksum of each artifact. A remote build cache holds the outputs your own build produced, keyed by a hash of the inputs to each task or action.

Does a remote build cache work across branches and machines?

Yes, that is the property the word remote carries. The key is derived from the inputs of a unit of work rather than from a branch name or a machine identity, so a branch that touches one package hits the cache for every package it did not touch, and a laptop can reuse an entry a build server wrote.

What is a warm cache?

A warm cache is a cache that already holds the entries a run needs, so the run restores them and skips the work that produced them. Warmth is measured per lookup: a cache is warm for a run when the key that run computes finds a matching entry in a store the run is allowed to read.

What makes a cache cold?

A lookup is cold when the required entry is missing or inaccessible. Common causes are a changed key, incompatible paths or compression version, a branch scope that cannot read the entry, or expiration and eviction from the cache store.

How do you keep a cache warm across runs?

Keep the key stable, keep the scope shared, and keep the entry in use. Derive the key from inputs that change when the cached content changes, such as a lockfile hash, rather than from a commit SHA or a timestamp. Write the entry on the default branch so every branch created from it can fall back to that copy.

Can I Share a Cache Between GitHub Actions Workflows?

Yes. A cache entry is addressed by three things, its key, its version, and the branch that wrote it, and the name of the workflow that created it is absent from that address, so any workflow in the same repository can restore an entry that another workflow saved.

Do Caches Carry Across Branches?

Cache reads depend on branch scope as well as the key and version. Default-branch entries can be reused by other branches, and pull-request runs can access eligible base-branch caches. Sibling feature-branch caches are generally isolated from one another.

Do GitHub Actions Caches Work Across Architectures?

Separate caches containing compiled objects or native modules by CPU architecture. Source downloads may be reusable, but binaries built for x64 generally cannot run on ARM64. Include the architecture in keys for platform-dependent outputs.

How Do I Cache Bundler Gems?

Cache vendor/bundle and key the entry on a hash of Gemfile.lock plus the Ruby version and the runner platform. Point bundler at that same directory first with bundle config set --local path vendor/bundle, so the cache path and the install path are one directory, and run bundle install in deployment mode so a Gemfile.lock that no longer matches the Gemfile fails the job instead of resolving new versions on the runner.

How Do I Cache Cargo Dependencies?

Cache the two directories under Cargo home that hold downloaded dependencies, ~/.cargo/registry and ~/.cargo/git, plus the workspace target directory, and key the entry on a hash of Cargo.lock and the Rust toolchain version.

How Do I Cache CocoaPods in GitHub Actions?

Cache three paths and derive the key from Podfile.lock: the Pods directory in the checkout, ~/Library/Caches/CocoaPods, and ~/.cocoapods/repos. Then run pod install --deployment so a lockfile that no longer matches the Podfile stops the job instead of resolving new versions in the background.

How Do I Cache Composer Dependencies?

Cache the directory that composer config cache-files-dir prints, and key the entry on a hash of composer.lock. With that entry restored, composer install --prefer-dist --no-interaction copies distribution archives off the runner disk instead of fetching one archive per package from Packagist and the git hosts behind it, which turns the install step into a local copy rather than a set of downloads.

How Do I Cache pip Dependencies in GitHub Actions?

Caching pip dependencies in GitHub Actions takes one input, because caching is off by default on the Python setup action and a workflow that never sets it re-downloads every package on every run. Set cache to pip, pipenv, or poetry, and point cache-dependency-path at the requirements or lock file whose contents should invalidate the entry.

How Do I Cache uv or Poetry Environments?

Cache the tool's own cache directory, key it on the lockfile, and let uv sync or poetry install rebuild the virtual environment from that cache on every job.

How Do I Cache Yarn Berry Installs?

Cache the folder that yarn config get cacheFolder prints, key it on the hash of yarn.lock, and run yarn install --immutable so a lockfile that drifts fails the job rather than rewriting itself. A zero-install repository needs no cache step at all, because its package archives are committed to .yarn/cache and arrive with actions/checkout.

How Long Do GitHub Actions Caches Last?

A WarpBuild cache entry expires 7 days after its last use, and it can be deleted manually at any time from the action or the console.

What Are restore-keys in GitHub Actions?

restore-keys is an ordered list of key prefixes the cache action falls back to when the primary key finds no entry. The action walks the list top to bottom, and the first prefix that matches at least one stored entry restores the most recently created of those entries, so a job whose lockfile just changed still starts from the previous run's dependency tree instead of an empty directory.

What Is the Difference Between cache-from and cache-to?

cache-from is the import side of a Docker build and cache-to is the export side: the first tells BuildKit where to read an existing layer cache, the second tells it where to write the cache the build produces.

Snapshots

Save prepared environments and reuse their disk state.

15
Which WarpBuild runners support snapshots?

Snapshots are supported only on WarpBuild Cloud Ubuntu runners. BYOC, Windows, and macOS runners do not support them. Snapshot labels on unsupported runner types are silently ignored rather than causing a configuration error.

What is the difference between snapshot.enabled and snapshot.key?

snapshot.enabled=true starts from the base image and allows a later save. snapshot.key=<alias> restores the named snapshot when available; if the alias has no saved snapshot, the runner starts from the base image.

Does the /tmp directory survive a runner snapshot?

No. The snapshot documentation states that /tmp is cleaned on reboot. Store files you intend to persist in an appropriate disk location and recreate temporary runtime state when a job starts.

How can a job detect that it booted from a snapshot?

A runner created from a snapshot has WARPBUILD_SNAPSHOT_KEY set to the snapshot alias. Use that environment variable to inspect the restored state, while ensuring your workflow still works when no snapshot is available.

Should I remove credentials before saving a snapshot?

Yes. Remove cloud credentials, SSH material, and other sensitive files before capturing the disk. In public repositories, pull-request jobs may access snapshots by alias; within an organization, other jobs may also receive restored runners.

What are the default snapshot save timeout and failure behavior?

The snapshot-save action documents a 30-minute wait timeout and fail-on-error=true by default. Set these inputs explicitly if your workflow needs different behavior, and check the save result before relying on a new snapshot.

Does a VM snapshot include the contents of memory?

Only when the implementation captures machine state as well as disk. Block storage snapshots from cloud providers record the virtual disk alone, so a machine that boots from one comes up as though it had been powered off and started again.

Why does a job still reinstall dependencies after booting from a snapshot?

The snapshot holds the filesystem as it was at capture time, so an install step still runs and still checks its inputs. What changes is where the bytes come from: a populated package manager cache on the restored disk answers the request locally instead of over the network.

Can I Keep a Database Warm Between Jobs?

Yes, on WarpBuild Cloud Ubuntu runners. Seed the database once, capture the machine with the WarpBuilds/snapshot-save action after the data is loaded, and later jobs that request the same snapshot alias boot with the data directory already on disk, so they start the database process and run tests instead of importing the dump again.

Can I Snapshot a Runner on a Feature Branch?

Yes. Snapshot behavior is requested by a label on the job, so any branch can boot from a snapshot or write one, and the two documented shapes are a clean snapshot published on the default branch that feature branches read with snapshot.key=<alias>, or an incremental alias that the branch refreshes on every push.

Do Snapshot Runners Replace the Cache?

No. A cache action and a snapshot runner solve different problems: a cache moves selected directories in and out of a clean machine over the network, while a snapshot runner boots the job from a disk image an earlier run left behind.

Do Snapshot Runners Work on macOS?

No. Snapshot runners are documented for Linux x64 and Linux ARM64 runners, and macOS runners are listed as an unsupported platform, so an Xcode job cannot boot from a saved machine image. A macOS job keeps warm state the other way, by caching the directories that hold compiled output and resolved packages.

How Are Snapshot Storage Costs Billed?

Snapshot storage bills at $0.025 per snapshot-hour for every hour a snapshot exists, which makes it a wall-clock charge rather than a per-job one, so the monthly figure is the number of live snapshots multiplied by the hours they stay alive.

How Long Do Runner Snapshots Last?

Runner snapshots are temporary and are deleted after 15 days, per the snapshot runners documentation. An alias that no workflow rewrites inside that window stops resolving, and the next job that requests it boots from the base image and runs normally, so an expiry costs a slow job rather than a failed one.

What Are Snapshot Runners?

A snapshot runner is a GitHub Actions runner that boots from a saved image of a previous run's virtual machine instead of from a clean base image, so the packages, dependency directories, container images, and build outputs an earlier run left on disk are already present when the first step executes.

Bring Your Own Cloud (BYOC)

Managed runners in your AWS, GCP, or Azure account.

39
Can BYOC Runners Reach Internal Services?

BYOC places runner VMs inside your cloud infrastructure. Private services are reachable when routes, firewalls or security groups, DNS, and service access policies allow the connection. Follow your cloud provider’s BYOC configuration guide.

Does BYOC Support Windows Runners?

The feature matrix lists Windows x86-64 support for AWS and Azure BYOC. GCP Windows support is not currently marked available. Check the cloud-specific setup requirements before selecting a Windows custom runner.

How Do I Tag Runner Resources for Cost Allocation?

AWS BYOC supports custom resource tags. Add the tags in the AWS stack configuration and use your cloud’s billing tools to track costs. The feature matrix does not currently mark custom resource tags available for GCP or Azure.

What are the three steps to configure BYOC?

Connect your cloud account, create a WarpBuild stack for the required region and network, then create a custom runner. Install the WarpBuild GitHub app and grant repository access before starting the cloud setup.

What is a WarpBuild stack?

A stack groups the cloud infrastructure needed by runners in a particular region, including networking and object storage. Custom runner configurations reference a stack and define instance, disk, and networking choices for jobs.

Can I import existing infrastructure on every BYOC cloud?

The feature matrix lists importing stack resources for AWS only. GCP and Azure support creating stack resources, but should not be assumed to offer the same import workflow as AWS.

Can I run macOS inside my BYOC account?

The feature matrix lists macOS runners on WarpBuild Cloud, with no BYOC support on AWS, GCP, or Azure. Keep Apple builds on a supported hosted macOS runner when using BYOC for other jobs.

Where do I configure the BYOC standby pool?

Set the Standby pool field on a BYOC custom runner. Choose a pool size based on expected simultaneous jobs for that runner type, balancing startup readiness against your cloud’s storage charges.

Can standby disks use spot instances?

No. The standby-disk documentation excludes spot instances because they can be reclaimed. Use a supported non-spot configuration when you need a maintained standby pool for predictable availability.

What happens when no standby disk is available?

WarpBuild creates a new VM for the job when the standby pool is empty. The control plane replenishes the pool asynchronously, so a burst beyond the pool size can have a different startup profile.

What does BYOC stand for?

BYOC stands for bring your own cloud. It describes a deployment model where a vendor operates the control plane for a service while the compute, storage, and network resources that do the work are created inside the customer's own cloud account, under the customer's ownership and on the customer's cloud invoice.

How is BYOC different from self-hosted?

Both place the workload in infrastructure the customer owns. They differ in who operates it. Under self-hosted, the customer runs the orchestration, the scaling policy, the image builds, and the upgrades. Under BYOC, the vendor's control plane performs those operations remotely through a scoped role the customer grants.

Who pays the cloud bill under BYOC?

The customer does, directly to the cloud provider. Instance hours, disks, object storage, and data transfer are metered against the customer's own account at whatever rates and commitments that account carries. The vendor bills separately for its own service.

Does BYOC give the vendor access to my cloud account?

It gives the vendor a scoped identity, typically an IAM role, a service account, or a managed identity, with permissions limited to the resource types the service manages. The customer defines the trust relationship and the permission set, can audit every API call in the cloud provider's own audit log, and revokes access by removing the role.

What is an IAM instance profile?

An IAM instance profile is an AWS container that holds a single IAM role and can be attached to an EC2 instance.

What is the difference between an IAM role and an instance profile?

The role carries the permissions policy and the trust policy. The instance profile is the wrapper that lets EC2 pass that role to a machine. An instance profile holds at most one role, and the console creates a profile with the same name as the role, which is why the two are often confused.

Why does attaching an instance profile fail with a PassRole error?

The identity launching or modifying the instance needs iam:PassRole on the role inside the profile. Handing a role to a machine is a privilege escalation path, so AWS requires that grant separately from ec2:RunInstances, usually scoped with a condition on iam:PassedToService equal to ec2.amazonaws.com.

What is the difference between IMDSv1 and IMDSv2?

IMDSv1 answers a plain GET to the link-local address with no authentication step. IMDSv2 is session oriented: the caller first sends a PUT to /latest/api/token with a time-to-live header, receives a session token, and puts that token in a header on every later GET.

Why does a container on the instance fail to read instance metadata?

IMDSv2 token responses carry an IP time-to-live, called the response hop limit, that defaults to 1. A packet leaving the instance for a container on a bridge network crosses one hop, so the token response expires before it arrives. Raising the hop limit to 2 lets containers reach the service, and leaving it at 1 keeps metadata inside the instance.

What does the metadata service return that a build might need?

The instance identity fields (instance id, instance type, region, availability zone, private and public IPv4 addresses) and, when a role is attached to the instance, temporary credentials under /latest/meta-data/iam/security-credentials/. Cloud SDKs read that credential path automatically as the last step of their default credential chain.

What is a cloud instance type?

An instance type is a catalog entry a cloud provider publishes under a name such as m6id.2xlarge or c4a-standard-4-lssd. The name maps to a fixed shape: a vCPU count, a memory size, the storage physically attached to the machine, and a network bandwidth ceiling. Every instance launched with that name gets the same shape.

Do two instance types with the same vCPU count run a build at the same speed?

Not necessarily. Processor generation, per-core performance, memory bandwidth, storage, network, and workload parallelism can differ despite the same vCPU count. Benchmark representative jobs rather than predicting build time from core count alone.

Does the instance type decide the disk a GitHub Actions job writes to?

Partly. The instance type decides whether the machine has an instance store device at all, because only names carrying the matching suffix include one. The boot volume behind the work directory is a separate launch setting with its own size, type, and performance, so two machines of the same instance type can still present different disks to a job.

What is a spot instance?

A spot instance is spare capacity in a cloud provider's fleet, offered at a discount to that provider's standard on-demand rate on the condition that the provider can reclaim the machine when it needs the capacity back.

Which GitHub Actions jobs are safe to run on spot instances?

Prefer restartable, idempotent work such as lint or test shards that can tolerate interruption. Handle partial writes explicitly and avoid assuming every build or deployment can safely restart. Verify your cloud’s interruption behavior and retry strategy.

What is fallback instance selection and why does it matter on spot?

Fallback instance selection lets a runner configuration name several acceptable instance types instead of one, so the launcher can pick whichever type has capacity at that moment. Spot availability is per pool, meaning per instance type, per zone, so a single pinned type can leave jobs queued while a near identical type nearby has capacity.

Does a standby disk cost money while nothing is running on it?

Provisioned storage is billed continuously, and compute is billed only while a machine is running. AWS documents this split for EC2: an instance in the stopped state is not billed for usage or data transfer, while charges are incurred for the storage of any Amazon EBS volumes.

Can GitHub Actions Runners Run in My Own Cloud Account?

Yes. WarpBuild BYOC runs your GitHub Actions runners as ordinary virtual machines inside your own AWS account, GCP project, or Azure subscription, so your cloud provider bills the compute directly and WarpBuild charges $0.002 per runner minute on top.

Can I Attach an IAM Role to a BYOC Runner?

Yes. Every custom runner in an AWS BYOC stack takes an Instance Profile ARN, so the EC2 instance WarpBuild launches for a job starts with an IAM role already attached and the AWS SDK inside your build steps reads credentials from instance metadata (instance profile setup).

Can I Restrict Outbound Traffic From Runners?

Yes. Configure BYOC egress controls while preserving the destinations listed in the cloud-specific setup guide, including WarpBuild, GitHub, and required build services. Validate the full allowlist, DNS, and package-registry access before tightening rules.

Can I Run BYOC in More Than One Region?

Yes. You run BYOC in more than one region by creating one stack per region inside the same cloud connection and then defining custom runner configurations against each stack, so a GitHub Actions job picks its region through the warp-custom- label in runs-on.

Can BYOC Runners Run in a Private Subnet?

Yes. WarpBuild BYOC runners launch in private subnets when you enable static IPs on the custom runner configuration, and the placement works as long as the route tables and the security group let each instance reach the destinations the runner needs. Those destinations and the network shape around them are listed in the AWS BYOC configuration prerequisites.

Can I Use My Existing VPC With BYOC Runners?

Yes. On AWS you create the BYOC stack in import mode, which takes an existing VPC, subnets, and security group as inputs instead of having the CloudFormation template provision them, and the import works once that network meets the prerequisites in the AWS BYOC configuration guide.

Do BYOC Runners Need a NAT Gateway?

Private-subnet runners need an outbound path to required services. The AWS BYOC guide documents a NAT-based configuration for static IPs; public-subnet configurations use a different route. Follow the supported setup for your cloud and network design.

Does BYOC Support Custom VM Images?

Yes. WarpBuild BYOC accepts VM images you build in your own cloud account, provided the image meets the requirements in the custom VM images documentation, and you register the image with WarpBuild so a custom runner definition can select it.

Does BYOC on GCP Support Local SSD?

Yes. GCP BYOC runners support Local SSD, and the mount is automatic: when the Compute Engine machine types on a runner configuration ship bundled Local SSDs, such as the -lssd machine types, WarpBuild detects the NVMe devices during boot, formats them, and mounts them to the runner work directory on Linux images.

How Does BYOC Billing Work?

BYOC billing has two lines. WarpBuild charges a per-minute platform fee of $0.002 per runner minute for BYOC runners, and the compute those runners use is billed by your own cloud account at whatever rate that account pays for the instance.

What Gets Created in My Cloud Account?

BYOC creates or references a stack of cloud infrastructure for runners. On AWS this can include networking, object storage, IAM configuration, and the instances and volumes used by jobs. Exact resources depend on creation versus import mode and runner settings.

What Permissions Does BYOC Need in My AWS Account?

AWS BYOC uses an IAM role created during cloud connection. The configuration guide lists permissions for runner lifecycle, networking, storage, and stack management. Review the actual CloudFormation policy with your cloud administrators rather than granting a blanket administrator role.

Performance and Scaling

Concurrency, right-sizing, and shorter feedback loops.

27
Do I Need to Rewrite My Workflow for Faster Runners?

Change the job’s runs-on label to select a WarpBuild runner after installing the GitHub app. Keep existing workflow steps initially, then validate OS, architecture, tool versions, and any provider-specific cache or build actions.

How Do I Choose a GitHub Actions Runner Size?

Use Recommendations and Usage to compare CPU, memory, disk, and I/O pressure across representative runs. Test a different runner label and compare duration and cost. Resource thresholds identify candidates for investigation rather than guaranteeing an optimal size.

How Fast Does a Runner Start After Queueing?

Inspect queue percentiles on Insights → Jobs, or Queue time p90 in a runner’s Activity card. Startup varies with runner type and configuration. Compare actual queue timings for your workload instead of assuming a universal startup guarantee.

Which WarpBuild runners support unlimited concurrency?

Generally available Linux and Windows runners support unlimited job concurrency according to the runner documentation. Beta features may have different limits. Contact support about high-concurrency macOS workloads rather than applying the Linux policy to them.

What makes a runner an autoscaling runner?

Its capacity follows the job queue. A queue signal reports that jobs are waiting, a provisioning step boots machines and registers them with the labels the workflow asks for, and a teardown rule removes them once the work is done. GitHub's self-hosted runners reference describes autoscaling as dynamically adjusting the number of self-hosted runners based on demand.

Why does GitHub recommend ephemeral runners for autoscaling?

Because an ephemeral runner accepts exactly one job and then deregisters, so job completion and capacity release are the same event. GitHub's self-hosted runners reference recommends autoscaling with ephemeral runners and advises against autoscaling persistent runners, since a persistent runner can be assigned a job while it is shutting down.

What happens when the autoscaler is too slow?

The job waits. GitHub does not fail a job that has no matching runner online; it stays queued until a runner carrying every requested label comes online, and GitHub's Actions limits page documents a 24 hour job queue time after which the job is automatically cancelled. A scaling gap therefore reads as a slow queue rather than an error.

Is a cold start the same thing as queue time?

Queue time is one part of it. A job can wait because no machine has been supplied yet, which is allocation, or because a concurrency rule is holding it back, which is policy. Both show up as a job sitting with no logs, and they have different fixes, so measure them separately.

Do ephemeral runners always pay a cold start?

Every job on an ephemeral runner starts on a machine with no history, so the full window is there by default. What shortens it is state that arrives with the machine rather than state left behind by an earlier job: a prebuilt image, a restored cache, a disk captured on an earlier run, or a machine that was booted before the job was queued.

What is a concurrency limit in GitHub Actions?

A concurrency limit is a ceiling on how many jobs are allowed to run at the same time. Three separate ceilings carry that name: the concurrency key written into a workflow, the concurrent job allowance attached to the account plan, and the number of runners available to accept jobs for a given runs-on label.

Does the concurrency key limit how many jobs run in parallel?

A concurrency group restricts matching workflow runs or jobs within a repository. Matrix parallelism and the available runner pool are separate controls. Review both the concurrency group and matrix max-parallel setting when jobs execute in waves.

Is a concurrency limit the same thing as queue time?

Queue time is the symptom and a concurrency limit is one of its causes. Queue time is the gap between the moment a job is queued and the moment a runner starts it, and that gap grows whenever a ceiling holds the job back, whenever no runner matches the labels, or whenever the fleet is busy.

What is queue time in GitHub Actions?

Queue time is the interval between a job entering the queue and a runner claiming it and starting the first step. It measures the wait for a machine. Run time, the interval from the first step to the job conclusion, measures the work itself.

What is the difference between remote execution and remote caching?

A remote cache stores the results of actions that already ran somewhere and returns them when an action digest matches, so a miss still compiles on the machine running the build. Remote execution sends the action itself to a worker pool, so a miss compiles on a worker.

Which build tools support remote execution?

The Remote Execution API repository lists Bazel, Buck2, BuildStream, Justbuild, Pants, Please, Recc, Reclient, and Siso as clients that distribute builds to workers through it, read on 2026-08-13. Support is per tool: the tool has to model its work as discrete actions with declared inputs before it can send one anywhere.

What still runs on the local machine under remote execution?

The initiating machine generally checks out source, analyzes the build graph, hashes and uploads inputs, coordinates remote actions, and retrieves outputs. Those responsibilities can still consume substantial CPU, memory, and network resources even when compilation runs remotely.

What is a good CPU utilization number for a GitHub Actions job?

There is no single target, because the useful reading is the gap between peak and mean. A job whose peak sustained CPU sits near the ceiling is limited by the machine, and a job whose mean stays low for most of its wall clock is holding cores that no step can use.

Why is my job slow when CPU utilization is low?

Low CPU utilization means the bottleneck lives somewhere else. The usual candidates are a single-threaded step that can only occupy one core, a step waiting on network transfer such as a dependency download or an image pull, and a step waiting on disk throughput. Memory pressure produces the same shape once swapping starts.

What is a task graph in a build tool?

The directed acyclic graph a build tool computes over the tasks it was asked to run. Each node is one task bound to one package or target, and each edge says that one task must finish before another starts.

Why does a task graph skip tasks?

A build tool can skip a task when its recorded inputs are unchanged and reusable outputs exist locally or in a cache. Correctness depends on declaring all relevant source files, dependencies, configuration, and environment inputs.

What is the difference between test sharding and running tests in parallel?

Parallel workers run several test processes on one machine and share its checkout, its installed dependencies, and its vCPU budget. Sharding splits the suite across separate machines, so each shard pays its own setup cost and the ceiling is the number of jobs that can run at once rather than the size of one machine. Large suites usually use both.

What happens when one shard fails?

With fail-fast set to false the remaining shards keep running, so one run reports every failure in the suite instead of stopping at the first. The merge job needs if always() so it still collects artifacts from failed shards, otherwise the merged report is skipped whenever a shard is red.

What is a warm pool?

A warm pool is capacity prepared before anything asks for it. Machines are provisioned ahead of demand and held part way or all the way through the startup path, so an arriving job attaches to a machine that has already booted rather than waiting for one to be created, booted, and registered.

What happens when the warm pool is empty?

The request falls back to cold provisioning. A fresh machine is created, booted, and registered, and the job runs on it as usual, so the pool changes when a job starts rather than whether it starts. The visible signature is a Set up job step that takes far longer on some runs than others.

Do Runner Groups Limit Concurrency?

No. A runner group is an access boundary around a set of self-hosted runners: it decides which repositories may use them and, on GitHub Enterprise, which workflow paths, branches, tags, and commit SHAs may claim them, and no field in that access list holds a parallel job count, so adding or removing a group changes who may run while leaving the number of simultaneous jobs alone.

How Do I See CPU and Memory Usage for a Job?

CPU and memory for a GitHub Actions job come from an agent running on the runner machine: the WarpBuild agent emits system metrics in OpenTelemetry format over port 33931, and the observability Usage view draws those metrics against the same job's GitHub Actions log timeline so a spike and the step that caused it sit on one screen.

What Happens When Two Workflows Share a Concurrency Group?

They serialize against each other. A concurrency group is a lane across the repository rather than a setting scoped to one workflow file, so when two workflows resolve the same group string, GitHub allows one run in that lane at a time and parks the other as pending, per the concurrency reference in the workflow syntax docs.

Security and Compliance

Isolation, credentials, access controls, and security evidence.

20
How does WarpBuild isolate runner workloads?

Each ordinary runner runs in its own ephemeral virtual machine, created on demand and destroyed after the build. Its dedicated encrypted storage volume is destroyed too. Deliberately persisted caches and snapshots have separate lifecycle rules.

What is WarpBuild’s policy on build secrets?

The security documentation states that WarpBuild does not access or store build secrets. Secrets remain in your source-code platform and are available to the runner environment for the job. Avoid persisting them into caches or snapshots.

Where can I request WarpBuild’s SOC 2 report?

Request security documentation through the WarpBuild Trust Center. The security page identifies SOC 2 Type 2 coverage for Security, Availability, and Confidentiality; review the report scope against your own requirements.

What separates an audit log from an application log?

An application log records program behavior for debugging. An audit log records attributable actions, such as who changed a setting or permission and when. Retention, access controls, and tamper resistance determine whether that record meets an organization’s audit needs.

Which GitHub Actions changes appear in an organization audit log?

Configuration and permission changes rather than job output. Adding or removing a self-hosted runner, moving a runner between runner groups, changing Actions settings for a repository, and changing who can administer those settings all produce entries. What a job printed lives in the workflow run logs instead, under a separate retention setting.

Can a workflow read the audit log through the REST API?

Yes, with a token that carries the read:audit_log scope and belongs to an organization owner. The GITHUB_TOKEN minted for a workflow run is scoped to one repository and does not carry that scope, so a scheduled export job reads the token from a secret instead.

How long does a GitHub App installation token last?

One hour. The app signs a JSON Web Token with its private key, exchanges that for an installation access token, and the installation token expires 60 minutes later. The JWT itself has to expire within 10 minutes of issue, so both credentials in the chain are short lived by design.

What permissions does a GitHub App need to manage self-hosted runners?

Read on repository Metadata, read on repository Actions so it can receive the workflow_job webhook and read run state, read and write on repository Administration to manage repository level runners, and read and write on the organization Self-hosted runners permission for organization level runners and runner groups. Repository Contents is not part of that set.

What is OIDC token exchange in GitHub Actions?

A job asks GitHub's OpenID Connect provider for a signed identity token that describes the repository, branch, and workflow it is running from. It sends that token to a cloud provider, which validates the signature and compares the claims against a trust policy, then returns temporary credentials. No long lived cloud key is stored in the repository.

How is the exchange restricted to one branch?

Configure the cloud trust policy to match the expected GitHub OIDC claims. A branch-based subject can identify a specific ref, but environments and customized subjects change the claim format. Inspect the actual subject and restrict the audience as appropriate.

What is a personal access token?

A personal access token is a credential created by an individual user that authenticates API and Git requests as that user. It is presented as a bearer credential in place of a password, and every request it makes runs under the permissions of the account that created it, narrowed by the scopes or permissions chosen at creation.

What is the difference between a classic and a fine-grained personal access token?

A classic token carries broad scopes such as repo and workflow, and those scopes apply to every repository the owner can reach. A fine-grained token names one resource owner, lists the repositories it may touch, and sets each permission to read or write individually.

Should a GitHub Actions workflow use a personal access token?

Use one when a job needs to reach a repository outside the one running the workflow, or needs a push to start another workflow run, and no application identity is available.

How long does a runner registration token last?

One hour. GitHub's REST reference for self-hosted runners states that the token expires after one hour, which applies to the repository, organization, and enterprise endpoints alike. A token minted at 09:00 is useless at 10:01, so registration scripts fetch a fresh token at the moment a machine boots.

Where does a runner registration token come from?

GitHub mints it. The web UI prints a fresh token into the setup commands under Settings, Actions, Runners, and the same token is available from the REST API at POST /repos/{owner}/{repo}/actions/runners/registration-token, POST /orgs/{org}/actions/runners/registration-token, or the enterprise equivalent. Minting one requires admin permission at that scope.

Does the runner keep using the registration token after setup?

No. The config script exchanges the registration token for credentials that the agent stores in its own directory, and every later connection to GitHub uses those stored credentials. The registration token is presented once and then expires on its own schedule.

What is the difference between an SBOM and a vulnerability scan?

An SBOM is the inventory: the components, their versions, and the identifiers that name them. A vulnerability scan is a join between that inventory and an advisory database, performed at scan time. The same SBOM produces different findings a month later, because the advisory data moved while the artifact stayed the same.

Does an SBOM need to be signed?

An unsigned SBOM is a JSON file that anyone with write access to the release can replace. Signing it, or publishing it as an attestation bound to the artifact digest, gives a consumer something to verify: that this document describes this exact artifact and was produced by the identity it claims.

Can I Restrict Which Repositories Use My Runners?

Yes. Repository access to a set of runners is decided by the GitHub runner group those runners belong to, and WarpBuild registers its runners into the Default runner group (id 1) of your organization unless you select another group in the dashboard.

How Do I Set Permissions for GITHUB_TOKEN?

Declare a permissions block at workflow level holding the minimum scopes every job needs, usually contents: read, then widen it with a job level block inside the single job that needs more. Both levels use the same map of scope name to read, write, or none, documented in GitHub's workflow syntax reference, checked on 2026-08-13.

Networking

Private services, Tailscale, subnets, and outbound access.

21
How do I enable the Tailscale networking addon?

Create a Network Addon Configuration with your Tailscale OIDC Client ID. Add network.name=<config-name> to the job’s runner label. The runner joins the tailnet when the job starts and is removed afterward.

Can different jobs use different tailnets?

Yes. Create separate network configurations for the tailnets, then select the appropriate configuration with network.name in each job’s runner label. Apply Tailscale access policies appropriate to each job.

What happens if the Tailscale addon cannot connect?

The CI job fails when Tailscale setup fails. This prevents a workflow from silently proceeding without expected private-network access. Check the configuration name, trust credential, tags, and access policy.

Does the networking addon support Windows and macOS?

Yes. The documented support table includes Ubuntu x64, Ubuntu ARM64, macOS ARM64, and Windows x64. It also supports BYOC and custom runners, subject to the documented custom-image prerequisites.

Can I combine Tailscale networking with snapshots?

Yes, on snapshot-supported Cloud Ubuntu runners. Add both network.name and the appropriate snapshot modifier to the same runner label, separated by semicolons. The networking configuration is applied for the job.

Which Tailscale arguments does WarpBuild manage?

The hostname, auth-key, client-id, id-token, and state flags are reserved and cannot be overridden. Other supported tailscale up arguments can configure tags, subnet route acceptance, or DNS behavior.

Is a Tailscale OIDC Client ID a secret?

No. The client ID is a public identifier. Authentication relies on signed, short-lived OIDC tokens from WarpBuild. Tailnet access remains controlled by your Tailscale credential configuration, tags, and policies.

What does a custom image need for the networking addon?

BYOC custom images need jq installed. The addon setup script installs Tailscale if it is absent. Follow the custom-image requirements and verify your network configuration before relying on private services.

What is a NAT gateway in simple terms?

A NAT gateway is a managed device that sits between a private subnet and the internet. Instances behind it can start outbound connections, and the gateway rewrites the private source address on each packet to its own public address so replies find their way back.

What is the difference between a NAT gateway and an internet gateway?

An internet gateway allows connections in both directions, so an instance behind one can be reached from the internet if it holds a public address and a security group permits it. A NAT gateway allows outbound connections only and carries a per gigabyte data processing charge that an internet gateway does not.

Why does a NAT gateway show up on the cloud bill?

Managed NAT gateways can incur hourly availability charges and data-processing charges, including traffic from package and image downloads. Rates depend on your provider and region. Inspect both gateway time and processed bytes when estimating BYOC network costs.

What is a security group in cloud networking?

A security group is a stateful firewall attached to the network interface of a cloud instance. It holds two lists of allow rules, one for inbound traffic and one for outbound traffic, and each rule names a protocol, a port range, and a source or destination such as a CIDR block or another security group.

What is the difference between a security group and a network ACL?

A security group attaches to a network interface, carries allow rules only, evaluates every rule as one set, and is stateful. A network ACL attaches to a subnet, carries both allow and deny rules, evaluates them in rule-number order until one matches, and is stateless, so return traffic needs its own rule covering the ephemeral port range.

Can a GitHub Actions runner work with no inbound security group rules?

Yes. The runner agent opens an outbound HTTPS connection to GitHub and holds it, so nothing needs to reach the machine from outside. Because a security group is stateful, the responses on that connection are admitted with no inbound rule present.

What is a subnet in a cloud network?

A subnet is a range of IP addresses carved out of a larger virtual network. Every machine launched into it takes an address from that range, and the routes attached to the subnet decide where traffic leaving those machines is allowed to go. AWS scopes a subnet to a single Availability Zone, while Google Cloud subnets are regional.

What is the difference between a public subnet and a private subnet?

The difference is one route. AWS documents a public subnet as one whose route table has a direct route to an internet gateway, and a private subnet as one without that route, where resources need a NAT device to reach the public internet. Nothing about the address range itself changes.

How many IP addresses does a subnet need for GitHub Actions runners?

One address per running machine, plus the addresses the provider reserves. AWS reserves the first four and the last address in every subnet CIDR block, so a /24 offers 251 usable addresses and a /28 offers 11. A fleet that scales to 250 concurrent runners does not fit in a /25.

What is a VPC in plain terms?

A virtual private cloud is an isolated virtual network in your cloud account. Subnets, routes, and access controls determine where resources are placed and how they communicate. Provider-specific details determine addressing, regional scope, and available gateways.

What is the difference between a VPC and a subnet?

The VPC holds the whole address range and the routing configuration. A subnet is one block of that range with its own route table, and on AWS a subnet lives in exactly one Availability Zone. Machines are placed in subnets rather than in the VPC directly, so subnet choice decides the zone and the default route a machine gets.

Why would build machines run inside a VPC?

Because the services a build step needs often have no public address. A machine in the same VPC reaches an internal package registry or a database endpoint directly over the private range, which leaves both services unpublished and removes the proxy that would otherwise sit in front of them.

Can GitHub Actions Runners Reach My Private Network?

Yes. WarpBuild runners reach private services through the networking addon, which joins the runner to your Tailscale tailnet at job start as an ephemeral node and removes that node when the job finishes.

Observability and Debugging

Metrics, logs, reports, and investigating a running job.

16
Where can I see runner right-sizing recommendations?

Open Insights → Recommendations. The page lists jobs, their current and suggested runner labels, run counts, and CPU and memory p90 usage. Apply a chosen recommendation by changing runs-on in the workflow.

Why is telemetry missing for a short job?

The observability documentation notes that metrics and logs are collected only for jobs longer than approximately one minute. Short jobs may therefore have no telemetry even when observability is enabled.

Can I export telemetry to my own monitoring backend?

Yes. Configure Your OTLP backend under Settings → Telemetry export. The documentation includes provider presets and custom OTLP endpoints. Save the configuration and use Test to check connectivity.

Can I export telemetry without storing it in WarpBuild?

Yes. WarpBuild Observability storage and export to your own OTLP backend are independent settings. Either destination can be enabled separately; disabling WarpBuild storage does not disable the external export.

When does a telemetry export configuration change take effect?

Runners pick up telemetry configuration changes on their next job. Jobs already running are unaffected. Save edits before using Test, which sends a sample payload from the backend to your configured endpoint.

Which resource measurements are available for runner diagnostics?

Observability includes CPU, memory, filesystem, disk I/O, and network measurements, alongside system and GitHub Actions logs. Use a job’s Usage view to correlate resource pressure with the workflow’s execution.

Where are WarpBuild’s cost and performance reports?

Open Insights → Spend for costs and Insights → Jobs for aggregated job performance. Reports provide date ranges, sorting, filtering, and CSV export; supported tables also include search.

Why are CPU and memory columns blank in Jobs reports?

CPU and memory metrics require observability to be enabled. Jobs without telemetry show a dash for these columns. Check telemetry settings and the job duration before interpreting missing values as low resource usage.

Which percentiles can I compare in Jobs reports?

The Jobs page provides a p75/p90 switch for duration, queue time, CPU, and memory. Compare the same job and percentile across equivalent periods to understand changes in performance.

What does p95 build duration mean?

It means 95 percent of the builds in the window finished at or below that time and 5 percent took longer. It is a property of a set of runs over a stated window, so a p95 quoted without the window, the job, and the run count cannot be compared against another p95.

How is a flaky test different from a broken test?

A broken test fails on every execution against the same commit and points at a defect in the code or in the assertion. A flaky test produces both outcomes on that same commit, so it is described by a rate rather than by a state.

How many times should I re-run a test to confirm it is flaky?

Enough repetitions that the expected number of failures is at least a few, which is repetitions multiplied by the estimated flake rate. Thirty repetitions of a test that fails 5 percent of the time come back all green only about 21 percent of the time, so thirty attempts catch that test roughly four times in five.

What is OpenTelemetry in one sentence?

OpenTelemetry is an open standard, together with the APIs, SDKs, and tools that implement it, for generating and exporting traces, metrics, and logs in a single vendor-neutral format that any compatible backend can read.

What is the difference between OpenTelemetry and a monitoring backend?

OpenTelemetry covers production and transport: how a process records a span or a measurement, what the attributes are called, and how the data reaches a receiver over OTLP. Storage, indexing, querying, dashboards, and alerting belong to whichever backend accepts the data, and swapping that backend is an endpoint change rather than a reinstrumentation project.

Can GitHub Actions jobs emit OpenTelemetry data?

Yes. A job is a normal process tree on a machine, so anything that can run on the runner can export OpenTelemetry data: a collector scraping host metrics, an SDK inside a test harness emitting spans, or a step that ships the run structure after the job finishes.

Can I SSH Into a GitHub Actions Runner?

Yes. You add the open-source Action Debugger step to the job, and the workflow pauses at that step while an SSH session opens on the runner machine.

Pricing and Billing

Understand usage, infrastructure costs, and your bill.

16
How Do I See Cost per Runner Label?

Open Insights → Spend and select the CI tab. Group the daily cost chart by runner label, or filter the job-execution table by label to compare runner and snapshot costs over the selected period.

Can I pay for WarpBuild through AWS Marketplace?

Yes. Subscribe to WarpBuild CI through AWS Marketplace, complete the account setup flow, and connect the subscription to a WarpBuild organization. You must be an organization admin to complete that connection.

Are free credits available with AWS Marketplace billing?

No. The AWS Marketplace billing guide states that this billing path does not support free credits. Review the Marketplace offer and account billing status before beginning your evaluation.

Why can AWS Marketplace costs differ from the WarpBuild dashboard?

Marketplace billing is submitted daily for the previous day, so its displayed costs can lag live usage in WarpBuild. Compare aligned billing periods when reconciling the Marketplace bill and dashboard.

What are egress costs?

Charges a cloud provider applies to data that leaves its network, or that crosses a boundary inside it such as an availability zone or a region. They are metered per gigabyte moved, and they land on the cloud bill rather than on a source control or build service invoice.

Is inbound data charged as well?

Usually no. Most providers accept inbound data at no charge and meter the outbound direction. Managed NAT is the common exception, because the per-gigabyte data processing fee applies to traffic in both directions.

Do I Pay a Seat Fee for GitHub Actions Runners?

WarpBuild’s published runner pricing is usage-based rather than per developer seat. Estimate costs from runner minutes and applicable add-ons; BYOC also has a per-minute service charge and your own cloud-infrastructure costs.

Do I Pay for Both the Runner and the Builder?

Yes. A GitHub Actions job that uses a remote Docker builder holds two machines, and each one bills on its own line: the runner bills per minute for as long as the job runs, and the builder bills per session at the rate of its profile size.

Do Public Repositories Pay for Runners?

A public repository pays nothing for minutes on standard GitHub-hosted runners, and it pays the machine supplier for everything else. WarpBuild runners can be enabled for public repositories with the documented setup, and the security considerations for pull requests from forks are documented alongside it on the same page.

How Do I Estimate My GitHub Actions Bill?

Estimate a GitHub Actions bill by multiplying the billed minutes on each runner label by the per-minute rate for that label, then summing the labels and adding the usage add-ons that sit next to runner minutes.

How Is a Remote Docker Builder Billed?

A remote Docker builder is billed per minute for the session it stays up, at the rate attached to the builder profile size you picked, from $0.06 per minute for a 16 vCPU profile to $0.88 per minute for a 192 vCPU profile with 2TB of disk.

How Much Do GitHub Actions Runners Cost?

WarpBuild publishes per-minute runner rates by OS, architecture, and size. Estimate billed minutes for each selected label, then add applicable cache, snapshot, builder, and cloud-infrastructure charges. Use the current pricing page for your estimate.

Are ARM64 GitHub Actions Runners Cheaper Than x64?

In WarpBuild’s standard Linux catalog, ARM64 rates are lower than x64 at equivalent vCPU and memory sizes. Actual job cost also depends on runtime and compatibility. The separate Apple Silicon Linux configurations have different rates.

Is It Cheaper to Run Fewer, Larger Runners?

It depends on how much runtime falls relative to the higher minute rate. Larger machines help parallel work and memory-bound workloads, but may not accelerate serial steps. Compare billed cost per successful build using representative jobs.

What Does GitHub Actions Cache Storage Cost?

Cache for GitHub Actions has two price components on WarpBuild hosted runners: $0.20 per GB-month of storage and $0.0001 per cache write, restore, or list operation. Both components are free on BYOC runners, where add-ons are included and the compute is billed by your own cloud account.

What Is the Cheapest Runner Size?

The cheapest runner size is the 2 vCPU, 8 GB Linux ARM64 label warp-ubuntu-latest-arm64-2x at $0.003 per minute, the lowest rate in the catalog.

Integrations and APIs

API access, MCP, automation, and infrastructure as code.

8
How do I create a WarpBuild API key?

Open Settings → API keys and choose Create API key. Select the product scopes needed by your integration, then save the displayed key securely; the full key is shown only once.

Which product scopes can an API key have?

The API-key documentation lists CI, Cache, and Helios scopes. Choose only the products your integration needs. You can edit the key’s name and scopes later from its menu in Settings.

How do I authenticate a WarpBuild API request?

Send the API key in an Authorization header using the Bearer scheme. Keep the key in a secret store or environment variable, and choose scopes appropriate for the endpoint you are calling.

What does the WarpBuild Terraform provider support?

The documented Terraform provider is in beta and supports AWS BYOC runner images and custom runner sets. Authenticate with a CI-scoped WarpBuild API key. Do not assume the provider covers GCP or Azure.

Do I need an API key for agent-assisted onboarding?

The current quick-start flow uses browser sign-in and authorization for the remote MCP server, without an API key. Connected agents appear under Settings → API keys → Connected apps. Follow that guide for onboarding.

What is an MCP server?

An MCP server is a program that implements the Model Context Protocol and offers three kinds of capability to an AI application: tools the model can call, resources the application can read, and prompt templates a user can pick. The application discovers what a server offers by asking it, so no integration code is written for that one pairing.

Does the language model connect to the server itself?

No. The host application holds the connection through a client, sends the tools/call request, and returns the result to the model. Credentials stay with the host and the server, and the specification says implementations should keep a human able to deny a tool invocation.

Can AI Agents Run GitHub Actions Jobs?

Yes. A GitHub Actions workflow run starts from an event, and an AI agent holding a token produces those events the same way a person does: it dispatches a workflow, pushes a branch, opens a pull request, or posts a comment that a trigger matches.

Enterprise Infrastructure

Deployment choices, data residency, and enterprise requirements.

14
Can I Keep Builds in the EU Only?

Use a BYOC stack in an EU region, or discuss enterprise region-specific infrastructure with WarpBuild. Confirm the residency scope for compute, caches, logs, and other data separately. The region-specific cloud option excludes macOS instances.

Does the standard github.com app work on my GitHub Enterprise host?

GitHub Enterprise Cloud with data residency and GitHub Enterprise Server use a separate setup path. Follow the GitHub Enterprise guide rather than trying to install the github.com app on your enterprise host.

What is a control plane in simple terms?

A control plane is the part of a system that decides what should exist and issues the instructions that make it exist. It holds a description of desired state, watches actual state, and calls an API to close the gap.

What is the difference between a control plane and a data plane?

The control plane decides and instructs. The data plane executes and carries. In a router the control plane computes routing tables while the forwarding path moves packets. In Kubernetes the scheduler decides which node runs a pod while the kubelet and container runtime run it.

Where is the data plane in a GitHub Actions workflow?

The runner is the data plane. GitHub queues the job and matches the labels in runs-on, and the runner machine performs the checkout, compiles the code, holds the secrets in the step environment, and writes the artifacts. The runs-on line is where the boundary between the two planes appears in the workflow file.

What is data residency in plain terms?

Data residency is the requirement that a named set of data is stored and processed inside a defined geography, such as a country, an economic area, or a single cloud region. A complete requirement names three things: the data in scope, the geography, and the operations covered, which usually means storage at rest, processing, and backups.

Is data residency the same as data sovereignty?

No. Residency is about physical location: where the bytes sit and where the machines that process them run. Sovereignty is about legal reach: whose law applies to the data and who can be compelled to hand it over.

What data does a GitHub Actions run actually produce?

Seven classes show up in most reviews: the source checkout on the runner disk, dependency and build caches, uploaded artifacts, container images pushed to a registry, job logs, the secret values delivered into the job environment, and run metadata such as queue records and timings.

Does encryption satisfy a data residency requirement?

Usually no. Encryption is a confidentiality control that limits who can read data; residency is a location control that limits where data sits and where it is processed. Encrypted data stored outside the required geography is still stored outside it. Encryption and key custody matter to the neighboring sovereignty question, because whoever holds the keys can produce plaintext.

What is single sign-on?

Single sign-on is an arrangement where one system, the identity provider, authenticates a user once and then asserts that identity to other applications. Each application trusts a signed statement from the identity provider instead of storing a password for that person, and it still applies its own authorization rules once it knows who the user is.

What is the difference between SAML 2.0 and OIDC?

Both let an application trust an identity provider. SAML commonly carries XML assertions, while OpenID Connect builds on OAuth 2.0 and uses ID tokens. The identity provider and application must support the same protocol and configuration.

Does single sign-on remove access everywhere when someone leaves?

It removes the sign-in path. A disabled account in the identity provider can no longer complete a challenge, so no new session starts in any connected application. Sessions already open and credentials issued outside the browser flow, such as personal access tokens, survive until a provisioning protocol such as SCIM or a manual step revokes them.

Where Do GitHub Actions Runners Run?

WarpBuild runs every GitHub Actions job on an ephemeral virtual machine, created for that job either in WarpBuild-operated infrastructure or inside your own cloud account on BYOC.

How do I discuss region-specific infrastructure with WarpBuild?

Region-specific infrastructure is an enterprise deployment option. Contact the team with your residency and network requirements, including which data must stay in a region, and confirm supported platforms before planning the rollout.

Migration and Setup

Move workflows, validate results, and roll back safely.

3
Can I migrate a single job first?

Yes. Runner labels are selected per job. Start with one representative job, confirm the app’s repository access, update its runs-on label, and compare results before moving additional workflows.

How do I roll back a runner migration?

Restore the previous runs-on label and any provider-specific action configuration changed during migration. Keep the prior runner infrastructure available until validation is complete so the old labels can still receive jobs.

What Changes When a Workflow Moves to ARM64?

Select an ARM64 runs-on label, then check every architecture-specific binary, native dependency, and container image. Validate working-directory assumptions and separate compiled-output caches by architecture. A label change selects hardware but does not make x64-only tools ARM64-compatible.

Troubleshooting

Find the cause of queued jobs, cache misses, and build failures.

16
Why is an installed WarpBuild app not picking up my repository’s jobs?

Check that the app has access to the repository and that the selected runner group allows it. Workflow restrictions on path, branch, tag, or commit can also prevent a matching runner from accepting the job.

Why does a custom-image job receive a shutdown signal?

The troubleshooting guide identifies unattended-upgrades restarting services, including warpbuild-agentd, as one cause on custom Linux images. Disable that behavior in the image as documented, then retry on the rebuilt image.

How do I enable Dependabot on a custom runner?

Open Runners → Custom, edit the runner, and enable Allow Dependabot under GitHub jobs. The documentation notes that Dependabot updates on self-hosted runners are not supported for public repositories.

Why is my GitHub Actions job stuck in the queue with no logs?

Check the requested labels, repository access, runner-group restrictions, and available runner capacity. GitHub concurrency settings can also hold work pending. A missing log usually means the job has not started, rather than identifying one specific cause.

How Do I Debug a Failed GitHub Actions Job?

Add Action Debugger to a rerun, with an appropriate failure condition, to inspect the runner before it terminates. Compare logs and telemetry for the same job. A runner from an already completed ordinary job is not retained for later SSH access.

How Do I Reproduce a CI Failure Locally?

Record the runner image, toolchain versions, environment, and failing command, then recreate those conditions locally. If the failure depends on runner-only state, use Action Debugger during a rerun to inspect the environment before the ephemeral machine is destroyed.

How Do I Retry a Failed Step in GitHub Actions?

Retry a failed step in GitHub Actions by wrapping the command in a shell retry loop with backoff inside the run block, or by putting a retry action around the command, and scope that retry to the classes of failure that are genuinely transient.

Why Are My GitHub Actions Builds Slow?

Common causes include queued jobs, repeated dependency downloads, insufficient compute or memory, and architecture emulation. Separate queue time from execution time, inspect slow steps and cache behavior, then benchmark a targeted change against representative runs.

Why Do Python Tests Run Slower in CI?

Compare CPU, memory, dependency setup, test worker count, and external-service latency between CI and your laptop. A cold cache or serial test execution can dominate a run even when the runner itself is healthy.

Why Does Cargo Rebuild Everything in GitHub Actions?

A fresh runner starts without Cargo’s target directory unless it is restored. Even after restoration, changed toolchains, features, compiler flags, or other inputs can invalidate fingerprints. Inspect Cargo’s rebuild diagnostics and key the cache for the relevant toolchain and platform.

Why Does Docker Build Run Out of Disk?

A Docker build runs out of disk because one runner volume holds the repository checkout, every base image pulled by the Dockerfile, every intermediate stage of a multi-stage build, the final image, and the exported build cache at the same time.

Why Does My GitHub Actions Cache Miss Every Run?

A GitHub Actions cache misses on every run for one of three reasons: the key string is different on every run, the version hash is different because the compression tool or the cached paths changed, or the entry you want was written on a branch this run cannot read.

Why Does My Job Show High IO Wait?

A GitHub Actions job shows high IO wait when the processor sits idle while the kernel waits for a storage device to answer, so the job spends wall clock without spending cores.

Why Is My Cache Restore Slow?

A cache restore is a network transfer followed by a decompression, so its duration tracks two things: the size of the compressed archive and the speed of the link between the runner and the cache store.

Why Is My Docker Build Slow in GitHub Actions?

Check for cold layer caches, large build contexts, architecture emulation, expensive Dockerfile steps, and resource pressure. Persistent remote builders and native architectures can help, but compare timings to identify which bottleneck actually affects your build.

Why Is My GitHub Actions Bill So High?

Inspect billed minutes by runner label and workflow. Large runners, macOS jobs, repeated failed runs, and cache misses can all increase cost. Compare each job’s total cost and useful throughput before changing machine size or caching strategy.

Comparisons and Alternatives

Evaluate runner options against your team's requirements.

6
What does Actions Runner Controller actually do?

It runs inside a Kubernetes cluster, watches custom resources in the actions.github.com API group, and keeps a set of self-hosted GitHub Actions runners registered as pods. A listener pod per runner scale set holds an outbound long poll to the GitHub Actions Service, and each assigned job gets one ephemeral runner pod that is deleted when the job finishes.

How does a workflow target an ARC runner scale set?

By the name the scale set was installed under. The Helm installation name becomes the label the scale set registers with, so a release installed as arc-runner-set is reached by runs-on: arc-runner-set. Setting runnerScaleSetLabels adds further labels, and a job then names them the way it names any other self-hosted runner labels.

How does ARC decide how many runners to run?

The listener creates one ephemeral runner per assigned job, bounded by the minRunners and maxRunners values in the scale set chart. Both are static Helm values, so changing them is a redeploy, and GitHub's documentation states that ARC does not support scheduled maximum and minimum configurations and suggests a cron job to update the configuration on a schedule.

Can I Mix GitHub-Hosted and Managed Runners?

Yes. runs-on is evaluated per job, so a single workflow file can send one job to a GitHub-hosted runner and the next job to a self-hosted or managed pool. Nothing at the workflow, repository, or organization level forces every job in a run onto one runner type.

GitHub-Hosted vs Self-Hosted Runners

GitHub operates GitHub-hosted runners. With self-hosted runners, you or a managed provider supply the machines registered with GitHub. WarpBuild uses this integration while managing the runner fleet, so workflows remain on GitHub Actions.

What should I compare when choosing a runner provider?

Compare equivalent CPU and memory configurations, measured job duration, concurrency, platform support, and infrastructure placement. Include cache, storage, and other usage charges in a workload-based estimate rather than comparing only headline minute rates.

LET’S TALK

Still have questions?

Talk to the WarpBuild team about your CI infrastructure, runner requirements, or implementation questions.

Schedule Demo