diff --git a/README.md b/README.md new file mode 100644 index 0000000..e4c1157 --- /dev/null +++ b/README.md @@ -0,0 +1,80 @@ +# GitHub Actions Runner Scale Set Client (Private Preview) + +> Status: **Private Preview** – While the API is stable, interfaces and examples in this repository may change. + +This repository provides a standalone Go client for the GitHub Actions **Runner Scale Set** APIs. It is extracted from the `actions-runner-controller` project so that platform teams, integrators, and infrastructure providers can build **their own custom autoscaling solutions** for GitHub Actions runners. + +You do *not* need to adopt the full controller (and Kubernetes) to take advantage of scale sets. This package contains all the primitives you need: create/update/delete scale sets, generate just‑in‑time (JIT) runner configs, manage message sessions, and react to job lifecycle events. + +--- + +## High-Level Flow + +1. Create a `Client` with either a GitHub App credential (recommended) or a PAT. +2. Create a Runner Scale Set specifying name & settings. +3. Start a message session to receive scale / job events: the `listener` package in this repo can give you a headstart with this. +4. What you need to bring is what it means **to your infrastructure** to provision/tear down a runner: + - Call `GenerateJitRunnerConfig` to obtain an encoded JIT config for a new runner belonging to your scale set. + - Start a fresh runner process/container/VM passing the JIT config. + - 🎉 You have a new runner! + +You can find a complete example of a Docker-based scale set in [`examples/dockerscaleset`](./examples/dockerscaleset). + +> [!NOTE] +> It's important to let the API know about your scale set maximum capacity using the `X-ScaleSetMaxCapacity` header when starting a message session so that job assignment can be as accurate as possible. + +--- + +## Getting Started + +```bash +go get github.com/actions/scaleset@latest +``` + +Import: + +```go +import "github.com/actions/scaleset" +``` + +### Using Without Go Experience + +If you are not a Go developer, you can still: + +- Treat this repo as reference documentation to design an API integration in another language. +- Vendor the code and compile a minimal binary that exposes a simpler CLI. +- Use the example CLI (`examples/dockerscaleset`) as inspiration—its flags show required inputs. +- Copilot can also help you translate this Go code into your language of choice. + +--- + +## Authentication + +Two options: + +1. **GitHub App (preferred):** Stronger scoping & rotation. Provide: `ClientID`, `InstallationID`, `PrivateKey`. +2. **PAT (personal access token):** Simpler but broader scoped. + +The client automatically exchanges credentials for a registration token + admin token behind the scenes and refreshes them before expiry. + +You can find more details on required permissions in the [GitHub Docs](https://docs.github.com/en/actions/tutorials/use-actions-runner-controller/authenticate-to-the-api). + +--- + +## Working With Messages + +- Call `CreateMessageSession` to obtain `messageQueueUrl` and `messageQueueAccessToken`. +- Poll with `GetMessage(lastMessageID, maxCapacity)`; you get scaling / job events. +- After processing a message, call `DeleteMessage(messageId)`. +- Refresh or delete the session as needed (`RefreshMessageSession`, `DeleteMessageSession`). + +Scaling logic uses the statistics & job events to decide how many new JIT configs to generate. + +--- + +## Security Notes + +- Always prefer GitHub App credentials; rotate PATs if you must use them. +- Treat JIT configs as secrets until consumed. + +--- diff --git a/examples/dockerscaleset/README.md b/examples/dockerscaleset/README.md new file mode 100644 index 0000000..9efe515 --- /dev/null +++ b/examples/dockerscaleset/README.md @@ -0,0 +1,47 @@ +# Docker Runner Scale Set Example + +This example showcases a Docker implementation of GitHub Actions runner scale sets, using the `github.com/actions/scaleset` client to provision ephemeral GitHub Actions runners as Docker containers. + +The goal of this example is to show how simple and powerful it is when you only need to focus on the core logic of scaling runners up and down, while the client handles all the API interactions. + +> [!WARNING] +> This is a simplified example meant for demonstration and learning purposes. It is not intended for production use. + +> [!NOTE] +> When exiting normally all runners and the scale set itself are cleaned up automatically. + +## Getting started + +You can install the example with: + +```bash +go install github.com/actions/scaleset/examples/dockerscaleset@latest +``` + +You'll then need: + +- Docker installed and running on your machine. +- A URL for the target repository, organization, or enterprise where you want to register your scale set. +- [Credentials that have access to the above target](https://docs.github.com/en/actions/tutorials/use-actions-runner-controller/authenticate-to-the-api): you can use either a GitHub App (recommended) or a Personal Access Token (PAT). +- A name for your scale set (this must be unique within the runner group the scale set is created in). + +--- + +## Flags + +| Flag | Required | Description | +|------|----------|-------------| +| `--url` | Yes | Registration target (org, repo, or enterprise URL, e.g. `https://github.com/org/repo`). | +| `--name` | Yes | Runner scale set name (must be unique within the runner group). | +| `--max-runners` | No | Upper bound of concurrently provisioned runners (default 10). | +| `--min-runners` | No | Lower bound to maintain (default 0). | +| `--runner-group` | No | Runner group name (default `default`). | +| `--app-client-id` | Cond.* | GitHub App Client (App) ID. | +| `--app-installation-id` | Cond.* | GitHub App Installation ID. | +| `--app-private-key` | Cond.* | GitHub App private key PEM contents. | +| `--token` | Cond.* | Personal Access Token (alternative to App). | +| `--log-level` | No | `debug`, `info`, `warn`, `error` (default `info`). | +| `--log-format` | No | `text`, `json`, or `none` (any invalid → no logs). | +| `--runner-image` | No | Override container image (defaults to latest official). | + +*Provide either App credentials (all three) OR a PAT.*