Self-hosted runners
Run Actions jobs on machines you manage: Linux, macOS or
Windows computers, build servers, or hardware-in-the-loop rigs with boards
attached. A self-hosted runner is GitHub's official runner,
actions/runner, unmodified: you
download it from GitHub, configure it against GitCafe instead of github.com,
and run it. GitCafe presents itself to the runner as a GitHub Enterprise
Server.
A runner belongs to an organization (personal accounts too) and serves the repositories its runner group allows, or it belongs to one repository. Organization owners and admins manage organization runners; repository admins manage a repository's runners.
Add a runner
- Open your organization's Settings → Runners and choose New runner (or, for a runner that serves one repository, the repository's Settings → CI and Add runner).
- In the dialog, choose the machine's operating system and architecture.
- Choose Create registration token and run the commands shown on the machine, as the user the runner should run as.
On Linux or macOS the commands are:
| 1 | mkdir actions-runner && cd actions-runner |
| 2 | curl -o actions-runner-linux-x64-2.338.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.338.0/actions-runner-linux-x64-2.338.0.tar.gz |
| 3 | tar xzf ./actions-runner-linux-x64-2.338.0.tar.gz |
| 4 | ./config.sh --url https://git.cafe/acme --token GCR... |
| 5 | ./run.sh |
macOS packages are named actions-runner-osx-<arch>-<version>.tar.gz. On
Windows, in PowerShell, download actions-runner-win-x64-2.338.0.zip,
extract it and run ./config.cmd and ./run.cmd with the same arguments.
--url is your organization's address on GitCafe, such as
https://git.cafe/acme, or a repository's, such as
https://git.cafe/acme/firmware, for a runner that serves only that
repository. config.sh asks for the runner's name, group, labels and work
folder; press Enter to accept the defaults.
From the CLI:
| 1 | cafe runner token create --org acme --name rig-1 # prints the config.sh command |
| 2 | cafe runner token create --repo acme/firmware # a repository runner |
A registration token starts with GCR and works for one hour; it can
register any number of runners until then. It is shown once. Scripts that
create tokens with GitHub's REST API ("create a registration token for an
organization" or "for a repository") can do the same against GitCafe: use
https://git.cafe/api/v3 as the API URL and a GitCafe API token of an
organization or repository admin.
The runner needs HTTPS access to your GitCafe server and, for the actions
your workflows use, to api.github.com and codeload.github.com. It keeps
the release you installed: GitCafe doesn't update runners.
Labels
Each runner has these labels, which it reports itself:
self-hosted;- its operating system:
Linux,macOSorWindows; - its architecture:
X64orARM64; - any labels you add with
--labelswhen you configure it, or at theconfig.shprompt, such as--labels gpu,cuda-12.
A job runs on a runner that has every label in its runs-on; letter case
doesn't matter. To change a runner's labels, configure it again with
./config.sh --url … --token … --replace and the new --labels.
Settings → Runners lists each runner with its status (Idle, Busy running a job, or Offline when it hasn't polled GitCafe for two minutes), its labels (the ones it added itself, then yours), group, architecture, version and when it was last seen.
Runner groups
Groups decide which repositories may use an organization's runners. Every
organization has a Default group that all its repositories may use; new
runners join it unless you choose another group with --runnergroup NAME
(or at the prompt).
In Settings → Runners → Runner groups, choose New group to create one for all repositories or only selected ones, and a group's edit (pencil) button to rename it or change its repositories. You can delete a group that has no runners; Default can be neither renamed nor deleted.
| 1 | cafe runner groups create --org acme --name "HIL rigs" --repos firmware,drivers |
| 2 | cafe runner groups update "HIL rigs" --org acme --visibility all |
| 3 | cafe runner groups list --org acme |
| 4 | cafe runner groups delete "HIL rigs" --org acme --yes |
To move a runner to another group, configure it again with --replace and
--runnergroup. A repository's Settings → CI lists the groups and
runners it can use.
Hardware-in-the-loop rigs
Give each rig labels that say what is attached to it, and target them in
runs-on:
| 1 | ./config.sh --url https://git.cafe/acme --token GCR... --name rig-stm32 --labels hil,stm32 --runnergroup "HIL rigs" |
| 1 | jobs: |
| 2 | flash-and-test: |
| 3 | runs-on: [self-hosted, hil, stm32] |
| 4 | concurrency: hil-stm32 |
| 5 | steps: |
| 6 | - uses: actions/checkout@v4 |
| 7 | - run: ./flash.sh && ./hil-test.sh |
A runner takes one job at a time. Use a concurrency group per rig when
several workflows target it, so a queued run waits instead of interleaving
with another, and a runner group to keep the rig to the repositories that
should use it.
Run the runner as a service
./run.sh runs in the foreground until you stop it. To start the runner at
boot, install it as a service after configuring it:
- Linux (systemd):
sudo ./svc.sh install, thensudo ./svc.sh start.sudo ./svc.sh statusandsudo ./svc.sh stopshow and stop it. - macOS (launchd):
./svc.sh install, then./svc.sh start, as the user the runner runs as; the service starts when that user logs in. - Windows: answer Y when
config.cmdasks whether to run the runner as a service, or pass--runasservice.
Ephemeral and just-in-time runners
./config.sh … --ephemeral registers a runner that takes one job and then
unregisters itself, for machines you reset between jobs.
A just-in-time (JIT) runner is created by an API call instead of
config.sh, for scripts that start a fresh machine per job:
| 1 | curl -X POST https://git.cafe/api/v3/orgs/acme/actions/runners/generate-jitconfig \ |
| 2 | -H "Authorization: Bearer $GITCAFE_TOKEN" -H "Content-Type: application/json" \ |
| 3 | -d '{"name": "vm-42", "runner_group_id": 1, "labels": ["hil"]}' |
The answer's encoded_jit_config starts the runner without configuring it:
./run.sh --jitconfig <encoded_jit_config>. It is a credential: pass it to
the machine privately. The runner is ephemeral. runner_group_id is the
group's number, which cafe runner groups list shows. For a repository
runner, use the repository's generate-jitconfig endpoint, as on GitHub. The
API token must belong to an admin of the organization or repository.
Remove a runner
Choose the remove (trash) button next to the runner in Settings → Runners (or the repository's Settings → CI), or:
| 1 | cafe runner list --org acme |
| 2 | cafe runner remove <runner-id> --org acme --yes |
Its credential stops working at once and a job it is running fails. Then
delete the runner folder on the machine, after sudo ./svc.sh uninstall (or
./svc.sh uninstall on macOS) if it runs as a service.
You can also remove a runner from the machine itself:
./config.sh remove --token <token> removes it from GitCafe and deletes its
configuration. Get the remove token from GitHub's REST API ("create a remove
token for an organization" or "for a repository") at
https://git.cafe/api/v3, with a GitCafe API token of an admin.
Move a runner from GitHub
One runner installation is registered with one server: it can't serve GitHub and GitCafe at the same time. To move a machine:
- On the machine, stop the runner (
sudo ./svc.sh stopandsudo ./svc.sh uninstallif it runs as a service). - Remove it from GitHub:
./config.sh remove --token <remove token>, with a remove token from the runner's settings page on GitHub. - Configure the same installation against GitCafe with a GitCafe
registration token, keeping its name and labels:
./config.sh --url https://git.cafe/acme --token GCR... --labels <same labels>. - Start it again, or install the service again.
Your workflows' runs-on keeps working when the runner keeps its labels. To
try GitCafe without touching a GitHub runner, install a second copy of the
runner in another folder.
Troubleshooting
- The job waits for a runner. Check the runner is Idle and has every
label in the job's
runs-on, and that its group lets the repository use it (the repository's Settings → CI lists what it can use). config.shfails with "Http response code: NotFound". The token has expired, or--urlnames another organization or repository than the token: create a new token from the same page.- The runner shows Offline. It hasn't polled GitCafe for two minutes: check it's running and can reach your GitCafe server.
- Logs. The runner writes its own logs to the
_diagfolder in its installation directory:Runner_*.logfor registration and polling,Worker_*.logfor each job.