GitHub Actions Tutorial — Runner Groups & Labels
Runner Groups & Labels
As your runner fleet grows, you need a way to organize runners and route jobs to the right machines. Labels identify runner capabilities, and groups control access at the organization level.
Labels
Default Labels
Every self-hosted runner automatically receives:
| Label | Values |
|---|---|
self-hosted |
Always present |
| OS | linux, macOS, windows |
| Architecture | X64, ARM64 |
Custom Labels
Add labels during configuration:
./config.sh --url https://github.com/my-org \
--token TOKEN \
--labels gpu,docker,production
Or add labels later in Settings → Actions → Runners → (select runner) → Edit labels.
Using Labels in Workflows
jobs:
train-model:
runs-on: [self-hosted, linux, gpu] # must match ALL labels
steps:
- run: nvidia-smi
deploy:
runs-on: [self-hosted, production]
steps:
- run: echo "Deploying to production..."
Important: runs-on: with multiple labels requires ALL labels to match. The runner must have every listed label.
Runner Groups
Runner groups are an organization-level feature (Team and Enterprise plans) that control which repositories can use which runners.
Creating a Group
Organization Settings → Actions → Runner groups → New group:
Group: production-runners
├── Runner: prod-server-1
├── Runner: prod-server-2
└── Runner: prod-server-3
Repositories: my-org/api, my-org/web (selected repos only)
Group Settings
| Setting | Options |
|---|---|
| Name | Descriptive group name |
| Repository access | All repos, or selected repos |
| Workflow access | All workflows, or selected workflows |
| Allow public repos | Enable/disable for public repositories |
Routing Strategies
By Environment
jobs:
deploy-staging:
runs-on: [self-hosted, staging]
steps:
- run: echo "Staging deploy"
deploy-production:
runs-on: [self-hosted, production]
steps:
- run: echo "Production deploy"
By Hardware
jobs:
build:
runs-on: [self-hosted, linux, x64] # standard build
steps:
- run: make build
train:
runs-on: [self-hosted, linux, gpu] # GPU workload
steps:
- run: python train.py
ios-build:
runs-on: [self-hosted, macOS, ARM64] # Apple Silicon
steps:
- run: xcodebuild
By Team
Group: frontend-runners → repos: web, mobile
Group: backend-runners → repos: api, worker
Group: ml-runners → repos: ml-pipeline
Common Mistakes
| Mistake | Fix |
|---|---|
| Job stuck in queue | Labels in runs-on: don’t match any runner |
| Wrong runner picks up job | Add more specific labels |
| Can’t create groups | Runner groups require Team or Enterprise plan |
| Public repo can’t use runners | Enable “Allow public repositories” in group settings |
Quick Reference
| Concept | Detail |
|---|---|
| Default labels | self-hosted, OS name, architecture |
| Custom labels | --labels gpu,docker during config |
| Label matching | ALL labels in runs-on: must match |
| Groups | Org-level; control repo access |
| Group access | All repos or selected repos |
← Previous: Setup Runners
Next: Autoscaling (ARC) →