#!/usr/bin/env bash # # Provisioning script for a self-hosted GitHub Actions runner # for GrakovNe/lissen-android on an Ubuntu 22.04 (x86_64) box. # # Idempotent: safe to re-run. Run as root. # # sudo ./provision-runner.sh # # A fresh registration token is required to (re)register the runner. # Get one at: Settings -> Actions -> Runners -> New self-hosted runner # and export it: export RUNNER_TOKEN=XXXX (token lives ~1h) # set -euo pipefail # ---- config ------------------------------------------------------------------ RUNNER_USER="actions-runner" RUNNER_HOME="/home/${RUNNER_USER}" RUNNER_DIR="${RUNNER_HOME}/actions-runner" RUNNER_VERSION="2.335.1" REPO_URL="https://github.com/GrakovNe/lissen-android" RUNNER_NAME="${RUNNER_NAME:-lissen-local}" RUNNER_LABELS="self-hosted,linux,x64" ANDROID_HOME="/opt/android-sdk" CMDLINE_TOOLS_ZIP="commandlinetools-linux-13114758_latest.zip" # Keep these in sync with app/build.gradle.kts (compileSdk / buildToolsVersion) SDK_PACKAGES=("platform-tools" "platforms;android-37.0" "build-tools;36.0.0" "cmdline-tools;latest") # ---- 0. must be root --------------------------------------------------------- [ "$(id -u)" -eq 0 ] || { echo "run as root"; exit 1; } # ---- 1. OS dependencies (build + Android emulator) --------------------------- export DEBIAN_FRONTEND=noninteractive apt-get update -qq apt-get install -y -qq \ curl wget unzip ca-certificates \ libpulse0 libgl1 libnss3 libxcursor1 libxcomposite1 libasound2 # ---- 2. runner user, with KVM access for the emulator ------------------------ id "${RUNNER_USER}" &>/dev/null || useradd -m -s /bin/bash "${RUNNER_USER}" usermod -aG kvm "${RUNNER_USER}" # emulator needs /dev/kvm (crw-rw---- root:kvm) # ---- 3. Android SDK (system-wide, owned by runner user) ---------------------- # The bootstrap zip must never be unpacked into cmdline-tools/latest: that path # belongs to the sdkmanager-managed "cmdline-tools;latest" package. Otherwise the # managed copy lands in latest-2 while PATH keeps using the stale bootstrap, which # cannot parse newer SDK XML metadata (v4) and breaks package installs on CI. export ANDROID_HOME ANDROID_SDK_ROOT="${ANDROID_HOME}" SDKMANAGER="${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" if [ -d "${ANDROID_HOME}/cmdline-tools/latest-2" ]; then rm -rf "${ANDROID_HOME}/cmdline-tools/latest" mv "${ANDROID_HOME}/cmdline-tools/latest-2" "${ANDROID_HOME}/cmdline-tools/latest" fi if [ ! -x "${SDKMANAGER}" ]; then tmp="$(mktemp -d)" wget -q "https://dl.google.com/android/repository/${CMDLINE_TOOLS_ZIP}" -O "${tmp}/cmdt.zip" unzip -q -o "${tmp}/cmdt.zip" -d "${tmp}/unz" BOOTSTRAP_SDKMANAGER="${tmp}/unz/cmdline-tools/bin/sdkmanager" yes | "${BOOTSTRAP_SDKMANAGER}" --sdk_root="${ANDROID_HOME}" --licenses >/dev/null 2>&1 || true "${BOOTSTRAP_SDKMANAGER}" --sdk_root="${ANDROID_HOME}" "cmdline-tools;latest" rm -rf "${tmp}" fi yes | "${SDKMANAGER}" --licenses >/dev/null 2>&1 || true "${SDKMANAGER}" --update "${SDKMANAGER}" "${SDK_PACKAGES[@]}" chown -R "${RUNNER_USER}:${RUNNER_USER}" "${ANDROID_HOME}" # ---- 4. download & extract the runner agent --------------------------------- if [ ! -x "${RUNNER_DIR}/config.sh" ]; then sudo -u "${RUNNER_USER}" bash -c " mkdir -p '${RUNNER_DIR}' && cd '${RUNNER_DIR}' curl -sL -o rn.tgz 'https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz' tar xzf rn.tgz && rm rn.tgz " fi # ---- 5. inject ANDROID_HOME into every job ---------------------------------- cat > "${RUNNER_DIR}/.env" <> RUNNER_TOKEN not set — skipped registration." echo ">> Get a token and run: cd ${RUNNER_DIR} && sudo -u ${RUNNER_USER} ./config.sh --url ${REPO_URL} --token --labels ${RUNNER_LABELS} --unattended --replace" echo ">> then: cd ${RUNNER_DIR} && ./svc.sh install ${RUNNER_USER} && ./svc.sh start" fi echo "DONE."