Deploy Runner
Run GitHub Actions jobs on Skippr-managed Linux runners. Keep workflow YAML in GitHub; point runs-on at a Skippr label. When GitHub queues a matching job, Skippr starts a runner for that session.
Runner is part of Deploy. Preview runners are Linux x86_64 only. macOS and Windows labels are not offered.
Status: Preview. See the API action reference for the full command list.
Before you start
- Sign in with
skippr login. See Cloud User Directory. - Ensure your policy allows the
deployactions you need. Owner and Admin already permit Deploy actions. Developer includes create, update, and list; ReadOnly includes get and list. - Install the Skippr Cloud Runners GitHub App on the GitHub organization that owns the repository. After install, copy the numeric installation id from GitHub. Do not paste a webhook secret; GitHub delivers to Skippr's platform hostname.
Steps 1–3 below show the same provisioning flow as CLI, Terraform, CDKTF TypeScript, or CDKTF Python. For provider credentials and the shared cloud provider block, see Terraform and CDKTF.
1. Record the GitHub App installation
skippr deploy runner create-github-installation --input - <<JSON
{
"installationId": "12345678",
"accountLogin": "acme",
"accountType": "Organization"
}
JSONresource "cloud_deploy_runner_github_installation" "app" {
installation_id = "12345678"
account_login = "acme"
account_type = "Organization"
}import { CloudProvider, CloudDeployRunnerGithubInstallation } from "@skippr/provider-cloud";
const cloud = new CloudProvider(this, "cloud", { region: "eu-central-1" });
const installation = new CloudDeployRunnerGithubInstallation(this, "app", {
installationId: "12345678",
accountLogin: "acme",
accountType: "Organization",
provider: cloud,
});from skippr_cdktf import CloudProvider, CloudDeployRunnerGithubInstallation
cloud = CloudProvider(self, "cloud", region="eu-central-1")
CloudDeployRunnerGithubInstallation(
self,
"app",
installation_id="12345678",
account_login="acme",
account_type="Organization",
provider=cloud,
)2. Bind a repository
Use the numeric GitHub repository id as repoId:
skippr deploy runner create-repository-binding --input - <<JSON
{
"repoId": "987654321",
"installationId": "12345678",
"owner": "acme",
"name": "app",
"defaultBranch": "main"
}
JSONresource "cloud_deploy_runner_repository_binding" "app" {
repo_id = "987654321"
installation_id = cloud_deploy_runner_github_installation.app.installation_id
owner = "acme"
name = "app"
default_branch = "main"
}import { CloudDeployRunnerRepositoryBinding } from "@skippr/provider-cloud";
const binding = new CloudDeployRunnerRepositoryBinding(this, "app", {
repoId: "987654321",
installationId: installation.installationId,
owner: "acme",
name: "app",
defaultBranch: "main",
provider: cloud,
});from skippr_cdktf import CloudDeployRunnerRepositoryBinding
CloudDeployRunnerRepositoryBinding(
self,
"app",
repo_id="987654321",
installation_id=installation.installation_id,
owner="acme",
name="app",
default_branch="main",
provider=cloud,
)Optional siteId attaches Site preview URLs for that repository. Leave it unset unless the repo publishes a Site.
3. Create a runner pool
skippr deploy runner create-runner-pool --input - <<JSON
{
"poolId": "ci",
"installationId": "12345678",
"repositoryId": "987654321",
"size": "linux_x64_2",
"labels": ["self-hosted", "linux", "x64", "skippr-linux-x64-2"]
}
JSONresource "cloud_deploy_runner_pool" "ci" {
pool_id = "ci"
installation_id = cloud_deploy_runner_github_installation.app.installation_id
repository_id = cloud_deploy_runner_repository_binding.app.repo_id
size = "linux_x64_2"
labels = ["self-hosted", "linux", "x64", "skippr-linux-x64-2"]
}import { CloudDeployRunnerPool } from "@skippr/provider-cloud";
new CloudDeployRunnerPool(this, "ci", {
poolId: "ci",
installationId: installation.installationId,
repositoryId: binding.repoId,
size: "linux_x64_2",
labels: ["self-hosted", "linux", "x64", "skippr-linux-x64-2"],
provider: cloud,
});from skippr_cdktf import CloudDeployRunnerPool
CloudDeployRunnerPool(
self,
"ci",
pool_id="ci",
installation_id=installation.installation_id,
repository_id=binding.repo_id,
size="linux_x64_2",
labels=["self-hosted", "linux", "x64", "skippr-linux-x64-2"],
provider=cloud,
)Sizes are linux_x64_1, linux_x64_2, linux_x64_4, linux_x64_8, linux_x64_16, and linux_x64_32. The public label is skippr-linux-x64-{n}. skippr-linux-x64 aliases skippr-linux-x64-2.
4. Target the pool from GitHub Actions
Keep using GitHub Actions YAML. Point runs-on at the pool labels:
jobs:
test:
runs-on: [self-hosted, skippr-linux-x64-2]
steps:
- uses: actions/checkout@v4
- run: cargo testWhen GitHub queues a matching workflow_job, Skippr starts a new runner from the managed image for that session. The previous job's disk is not reused. List sessions with skippr deploy runner list-runner-sessions. Cancel an in-flight session with skippr deploy runner cancel-runner-session. Deleting a pool stops in-flight sessions, then removes the pool.
Limits and errors
- Preview image is Linux x86_64. Other runner OSes are not available.
- Fork pull requests are denied unless the pool fork policy allows them.
- If the pool is already at
maxConcurrentin-flight sessions, Skippr rejects the job until a session finishes. RaisemaxConcurrentso the account can run many jobs at once; Skippr starts them until that ceiling or available capacity. Duplicate deliveries redrive the existing session. - Duplicate webhook deliveries are ignored.
CloudMachines.*is not available. Do not create fleets to host runners.
