Skip to content

Commit

Permalink
Fully automate the setup of the GitHub Action Runner
Browse files Browse the repository at this point in the history
  • Loading branch information
PSchmiedmayer committed Jul 17, 2023
1 parent af360cb commit 29b8da3
Show file tree
Hide file tree
Showing 4 changed files with 268 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Installation/.env
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ XCODES_PASSWORD=""
GITHUB_ACTION_SCOPE=""
## Name of the GitHub Runner
GITHUB_ACTION_NAME=""
## Personal Access topen with permissions to modify the runner configuration
## Fine-grained Personal Access Token (PAT) with Read and Write access to organization self hosted runners
GITHUB_ACTION_RUNNER_PAT=""
233 changes: 233 additions & 0 deletions Installation/create-latest-svc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
#/bin/bash
#
# This source file is part of the Stanford BDGH VirtualMachine project
# Based on https://github.com/actions/runner/blob/main/scripts/create-latest-svc.sh
#
# SPDX-FileCopyrightText: 2023 Stanford University
#
# SPDX-License-Identifier: MIT
#

set -e


# Notes:
# PATS over envvars are more secure
# Downloads latest runner release (not pre-release)
# Configures it as a service more secure
# Should be used on VMs and not containers
# Works on OSX and Linux
# Assumes arm64 arch
# See EXAMPLES below


flags_found=false


while getopts 's:g:n:r:u:l:df' opt; do
flags_found=true


case $opt in
s)
runner_scope=$OPTARG
;;
g)
ghe_hostname=$OPTARG
;;
n)
runner_name=$OPTARG
;;
r)
runner_group=$OPTARG
;;
u)
svc_user=$OPTARG
;;
l)
labels=$OPTARG
;;
f)
replace='true'
;;
d)
disableupdate='true'
;;
*)
echo "
Runner Service Installer
Examples:
RUNNER_CFG_PAT=<yourPAT> ./create-latest-svc.sh myuser/myrepo my.ghe.deployment.net
RUNNER_CFG_PAT=<yourPAT> ./create-latest-svc.sh -s myorg -u user_name -l label1,label2
Usage:
export RUNNER_CFG_PAT=<yourPAT>
./create-latest-svc scope [ghe_domain] [name] [user] [labels]
-s required scope: repo (:owner/:repo) or org (:organization)
-g optional ghe_hostname: the fully qualified domain name of your GitHub Enterprise Server deployment
-n optional name of the runner, defaults to hostname
-r optional name of the runner group to add the runner to, defaults to the Default group
-u optional user svc will run as, defaults to current
-l optional list of labels (split by comma) applied on the runner
-d optional allow runner to remain on the current version for one month after the release of a newer version
-f optional replace any existing runner with the same name"
exit 0
;;
esac
done


shift "$((OPTIND - 1))"


if ! "$flags_found"; then
runner_scope=${1}
ghe_hostname=${2}
runner_name=${3:-$(hostname)}
svc_user=${4:-$USER}
labels=${5}
runner_group=${6}
fi


# apply defaults
runner_name=${runner_name:-$(hostname)}
svc_user=${svc_user:-$USER}


echo "Configuring runner @ ${runner_scope}"
sudo echo


#---------------------------------------
# Validate Environment
#---------------------------------------
runner_plat=linux
[ ! -z "$(which sw_vers)" ] && runner_plat=osx;


function fatal()
{
echo "error: $1" >&2
exit 1
}


if [ -z "${runner_scope}" ]; then fatal "supply scope as argument 1"; fi
if [ -z "${RUNNER_CFG_PAT}" ]; then fatal "RUNNER_CFG_PAT must be set before calling"; fi


which curl || fatal "curl required. Please install in PATH with apt-get, brew, etc"
which jq || fatal "jq required. Please install in PATH with apt-get, brew, etc"


# bail early if there's already a runner there. also sudo early
if [ -d ./runner ]; then
fatal "Runner already exists. Use a different directory or delete ./runner"
fi


sudo -u ${svc_user} mkdir runner


# TODO: validate not in a container
# TODO: validate systemd or osx svc installer


#--------------------------------------
# Get a config token
#--------------------------------------
echo
echo "Generating a registration token..."


base_api_url="https://api.github.com"
if [ -n "${ghe_hostname}" ]; then
base_api_url="https://${ghe_hostname}/api/v3"
fi


# if the scope has a slash, it's a repo runner
orgs_or_repos="orgs"
if [[ "$runner_scope" == *\/* ]]; then
orgs_or_repos="repos"
fi


export RUNNER_TOKEN=$(curl -s -X POST ${base_api_url}/${orgs_or_repos}/${runner_scope}/actions/runners/registration-token -H "accept: application/vnd.github.everest-preview+json" -H "authorization: token ${RUNNER_CFG_PAT}" | jq -r '.token')


if [ "null" == "$RUNNER_TOKEN" -o -z "$RUNNER_TOKEN" ]; then fatal "Failed to get a token"; fi


#---------------------------------------
# Download latest released and extract
#---------------------------------------
echo
echo "Downloading latest runner ..."


# For the GHES Alpha, download the runner from github.com
latest_version_label=$(curl -s -X GET 'https://api.github.com/repos/actions/runner/releases/latest' | jq -r '.tag_name')
latest_version=$(echo ${latest_version_label:1})
runner_file="actions-runner-${runner_plat}-arm64-${latest_version}.tar.gz"


if [ -f "${runner_file}" ]; then
echo "${runner_file} exists. skipping download."
else
runner_url="https://github.com/actions/runner/releases/download/${latest_version_label}/${runner_file}"


echo "Downloading ${latest_version_label} for ${runner_plat} ..."
echo $runner_url


curl -O -L ${runner_url}
fi


ls -la *.tar.gz


#---------------------------------------------------
# extract to runner directory in this directory
#---------------------------------------------------
echo
echo "Extracting ${runner_file}"


tar xzf "./${runner_file}" -C .


# export of pass
sudo chown -R $svc_user .


#---------------------------------------
# Unattend config
#---------------------------------------
runner_url="https://github.com/${runner_scope}"
if [ -n "${ghe_hostname}" ]; then
runner_url="https://${ghe_hostname}/${runner_scope}"
fi


echo
echo "Configuring ${runner_name} @ $runner_url"
echo "./config.sh --unattended --url $runner_url --token *** --name $runner_name ${labels:+--labels $labels} ${runner_group:+--runnergroup \"$runner_group\"} ${disableupdate:+--disableupdate}"
sudo -E -u ${svc_user} ./config.sh --unattended --url $runner_url --token $RUNNER_TOKEN ${replace:+--replace} --name $runner_name ${labels:+--labels $labels} ${runner_group:+--runnergroup "$runner_group"} ${disableupdate:+--disableupdate}


#---------------------------------------
# Configuring as a service
#---------------------------------------
echo
echo "Configuring as a service ..."
prefix=""
if [ "${runner_plat}" == "linux" ]; then
prefix="sudo "
fi


${prefix}./svc.sh install ${svc_user}
${prefix}./svc.sh start
27 changes: 22 additions & 5 deletions Installation/install.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
#!/bin/sh
#!/bin/s
#
# This source file is part of the Stanford BDGH VirtualMachine project
#
# SPDX-FileCopyrightText: 2023 Stanford University
#
# SPDX-License-Identifier: MIT
#

# Script to document and automate the installation of software for the GitHub Runner environment.
#

# Initial Setup
# Ensure that you have set all the correct credentials in the .env file.
Expand Down Expand Up @@ -48,11 +56,11 @@ brew upgrade

# Download Xcode Releases
xcodes install --update --experimental-unxip --no-superuser --empty-trash 14.3.1
sudo xcode-select -s /Applications/Xcode-14.3.1
sudo xcode-select -s /Applications/Xcode-14.3.1.app
xcodebuild -runFirstLaunch
xcodebuild -downloadAllPlatforms
xcodes install --update --experimental-unxip --no-superuser --empty-trash 15.0 Beta 4
sudo xcode-select -s /Applications/Xcode-15.0.0-Beta.4
sudo xcode-select -s /Applications/Xcode-15.0.0-Beta.4.app
xcodebuild -runFirstLaunch
xcodebuild -downloadAllPlatforms
xcodes signout
Expand All @@ -61,14 +69,23 @@ xcodes signout
# Swiftlint can only be installed after Xcode is installed
brew install swiftlint


# 6. Install GitHub Action Runners - https://github.com/actions/runner/blob/main/docs/automate.md

# Setup the GitHub Action Runner tools to connect to GitHub
export RUNNER_CFG_PAT=$GITHUB_ACTION_RUNNER_PAT
curl -s https://raw.githubusercontent.com/actions/runner/main/scripts/create-latest-svc.sh | bash -s $GITHUB_ACTION_SCOPE -n $GITHUB_ACTION_NAME
mkdir ~/actions-runner

# Move the cleanup scripts and the `.env` file in the GitHub Actions Folder to enable an automatic reset of the simulators & cleaning of the working directory.
cp -rf ./GitHubActions/ ~/actions-runner/
cp -f ./create-latest-svc.sh ~/actions-runner/
chmod 755 ~/actions-runner/create-latest-svc.sh

# Install the GitHub Runner
cd ~/actions-runner
export RUNNER_CFG_PAT=$GITHUB_ACTION_RUNNER_PAT
./create-latest-svc.sh -s $GITHUB_ACTION_SCOPE -n $GITHUB_ACTION_NAME
rm -f ~/actions-runner/create-latest-svc.sh


# 6. Cleanup
echo "The installation is complete. Ensure that you remove the .env credentials file to avoid leaking information!"
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ Small project based on the [Running macOS in a virtual machine on Apple silicon]

The repository also consists of scripts and additional setups used for maintaining the build agents.

## Stanford BDHG CI Setup

The CI setup for GitHub Actions runners uses the Virtual Machine app to host a virtual machine that we use as a GitHub Action runner.
The repository contains the nescessary steps, tools, and scripts to setup the environment.
1. Setup a macOS machine on conformance to the Stanford device setup requirements: https://uit.stanford.edu/service/StanfordJamf/Install.
2. Install the Virtual Machine App. Setup the application to "Open on Login" using the macOS dock context menu of the app.
3. Either generate new virtual machine bundle using the app or use a prexisting bundle. If you use a prexisting bundle that has done all the following steps you can skip the setup steps.
4. Start the VM using the app, go through the setup process with the minimal possible setup, e.g. **no** location services, **no** Apple ID, and more ...
5. Setup that the user of the VM automatically logged in when the VM starts: https://support.apple.com/en-au/HT201476.
6. Disable automatic screen saves, turning off the display, and requiering a passcode when the screen is locked (https://support.apple.com/guide/mac-help/set-sleep-and-wake-settings-mchle41a6ccd/mac) and enable the perserve automatic sleeping when the display if off setting in the System Settings > Displays > Advanced settings.
6. Download this repository from GitHub to the VM and run the installation steps by adapting the `.env` file in the `Installation` folder and runnig `$ sh install.sh` in the `Installation` folder. Optionally change the installed Xcode versions in the script.
7. Ensure that the GitHub runner apprears on your GitHub organization or repo.

## Build and Run the Application

Expand Down

0 comments on commit 29b8da3

Please sign in to comment.