Repository navigation
v2.5.0 — Runner Groups
Runner Groups
Runners can now be grouped into named, many-to-many pools — by region, by proximity to the resources they automate, or any other grouping that makes sense for your fleet — so a script or scheduled job can target "whichever eligible runner in this group is available" instead of pinning to one specific runner.
Why
Routing was previously single-runner only: pin to one exact runner, or auto-pick the least-busy runner fleet-wide by tags and language. There was no way to say "run this against whichever of these particular runners is free" for a set of runners that don't necessarily have identical capabilities individually but collectively cover what a job needs.
What's new
- Runner Groups — create named groups from Settings → Runner Groups and assign runners to them; a runner can belong to more than one group (e.g. a host that's both
us-eastandshared-terraform). - Aggregate eligibility — a group is eligible for a language or a set of required tags if any member runner qualifies, not all of them — since an execution always ends up running on one concrete runner,
RunnerAssignmentServicepicks the least-busy eligible member of the targeted group at assignment time. The Settings tab shows this as aggregate language badges per group. - Group-aware pickers — the Run Script and Scheduled Jobs runner dropdowns now list both runner groups and individual runners (in separate sections), and scheduled jobs can be pinned to a group via
preferred_runner_group_id, mutually exclusive with pinning to a single runner. - Cross-navigation — each runner's expandable detail row in Settings → Runners now shows which groups it belongs to.
- Purely a management-plane concept — the Go runner binary is unchanged; groups are never sent to or evaluated by the runner itself.
Upgrading
Two new tables (runner_groups, runner_group_runner) and one new column
(preferred_runner_group_id on scheduled_jobs) — run php artisan migrate --force as usual.
No existing behavior changes until you create a group and start targeting it.