GitHub Actions Tutorial — Runner Groups & Labels

1 minute read

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) →

Updated: