Ephemeral GitHub runners on Hetzner Cloud

August 7, 2023 · View on GitHub

Utilize standard GitHub runners to easily deploy and terminate self-hosted runners on Hetzner Cloud. This comes in handy especially when building for arm64, as Hetzner Cloud offers native arm64 servers.

Inputs

NameRequiredDescriptionDefault
actionAction to perform, either create or remove
github-tokenFine-grained GitHub Personal Access Token
hetzner-tokenHetzner Cloud API token
server-typeHetzner Cloud server type to createcx11
server-locationServer location, note that not all locations have all server types availablefsn1
server-imageOS image to runubuntu-22.04
server-namefor removeName of the server to remove, should be passed from the create step

Outputs

NameDescription
server-nameThe generated name for the runner

Usage

  1. Create a fine-grained GitHub personal access token with 'Read and write' access to 'Administration'
  2. Create an API token in the Hetzner Cloud Console with 'Read & Write' permissions
  3. Add these two tokens as repository secrets
  4. Create/adapt your workflow by following this example:
on: [push]

jobs:
  create-runner:
    name: Create runner
    runs-on: ubuntu-latest
    outputs:
      server-name: ${{ steps.create-runner.outputs.server-name }}
    steps:
      - name: Create runner
        id: create-runner
        uses: Kwarf/hetzner-ephemeral-runner@v1
        with:
          action: create
          github-token: ${{ secrets.GH_TOKEN }}
          hetzner-token: ${{ secrets.HC_TOKEN }}

  build:
    name: Your build action
    needs: create-runner
    runs-on: ${{ needs.create-runner.outputs.server-name }}
    steps:
      - name: Hello World
        run: echo 'Hello World!'

  remove-runner:
    name: Remove runner
    needs:
      - create-runner
      - build
    runs-on: ubuntu-latest
    if: ${{ always() }}
    steps:
      - name: Remove runner
        uses: Kwarf/hetzner-ephemeral-runner@v1
        with:
          action: remove
          github-token: ${{ secrets.GH_TOKEN }}
          hetzner-token: ${{ secrets.HC_TOKEN }}
          server-name: ${{ needs.create-runner.outputs.server-name }}