#!/usr/bin/env bash # servers/gcp/runners/startup.sh # # Boot script for the Gitea Actions runner GCE VM. # - Installs docker + git + jq + the Forgejo/Gitea act_runner binary. # - Pulls the runner registration token from GCP Secret Manager # (the VM's attached service account has secretmanager.secretAccessor on it). # - Registers against https://git.neuralplatform.ai with labels matching # the workflows that target ubuntu-latest hosts. # - Starts act_runner under systemd so it auto-recovers on reboot. # # Logs land at /var/log/runner-bootstrap.log for debugging from IAP SSH. set -euxo pipefail exec > >(tee /var/log/runner-bootstrap.log) 2>&1 apt-get update # Core system tools and C build dependencies required by CI jobs. # libcurl4-openssl-dev + build-essential are needed by the El compiler C build; # libssl-dev/libsqlite3-dev/libpq-dev for downstream projects. # python3 is for the inline label-rewrite step below. apt-get install -y --no-install-recommends \ curl \ ca-certificates \ docker.io \ git \ jq \ python3 \ wget \ unzip \ zip \ xz-utils \ rsync \ file \ sudo \ make \ build-essential \ pkg-config \ gcc \ libcurl4-openssl-dev \ libssl-dev \ libsqlite3-dev \ libpq-dev \ libffi-dev \ zlib1g-dev # Node.js 20 LTS via NodeSource — Ubuntu 24.04's bundled nodejs is 18.x # which works but 20 LTS matches what our other CI images use. curl -fsSL https://deb.nodesource.com/setup_20.x | bash - apt-get install -y --no-install-recommends nodejs npm install -g yarn # Make docker usable by the unprivileged runner user systemctl enable --now docker useradd -m -s /bin/bash runner || true usermod -aG docker runner # Allow the runner user to install packages and run system commands # in CI workflow steps without a password prompt. echo "runner ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers # act_runner — pinned to a known-good release. Bump RUNNER_VERSION when # upgrading. The project moved from gitea/act_runner to gitea/runner around # the 0.6.x series; the binary inside the asset is still called act_runner. # Latest releases at: https://gitea.com/gitea/runner/releases RUNNER_VERSION="0.6.1" curl -fsSL \ "https://gitea.com/gitea/runner/releases/download/v${RUNNER_VERSION}/act_runner-${RUNNER_VERSION}-linux-amd64" \ -o /usr/local/bin/act_runner chmod +x /usr/local/bin/act_runner mkdir -p /opt/runner chown -R runner:runner /opt/runner # Pull registration token. Fail fast if the secret is missing — the runner # is useless without it, and a silent fallback would leave us debugging an # unregistered VM later. GITEA_RUNNER_TOKEN="$(gcloud secrets versions access latest \ --secret=gitea-runner-token \ --project=neuron-785695)" # Generate a baseline config so the daemon has a sane starting point. The # register step writes the .runner state file into /opt/runner. sudo -u runner /usr/local/bin/act_runner generate-config > /opt/runner/config.yaml chown runner:runner /opt/runner/config.yaml cd /opt/runner sudo -u runner /usr/local/bin/act_runner register \ --no-interactive \ --instance https://git.neuralplatform.ai \ --token "${GITEA_RUNNER_TOKEN}" \ --name "gcp-us-central1-runner-1" \ --labels "ubuntu-latest,ubuntu-22.04,ubuntu-24.04" # Belt-and-braces: act_runner v0.6 has a habit of wrapping bare labels with # the default `:docker://docker.gitea.com/runner-images: