1#!/usr/bin/env bash 2 3# This simple script can be used to set up a CI node running MacOS. 4# An additional requirement that is *not* handled by this script is the 5# installation of Xcode, which requires manual intervention. 6# 7# This script should first be run from an administrator account to install 8# the dependencies necessary for running CI. It can be run without having 9# to clone the LLVM repository with: 10# 11# $ /bin/bash -c "$(curl -fsSl https://raw.githubusercontent.com/llvm/llvm-project/main/libcxx/utils/ci/macos-ci-setup)" 12# 13# If you perform system updates, you should re-run the script from the 14# administrator account -- this allows updating the packages used for 15# CI and the BuildKite agent tags. 16# 17# Once the necessary dependencies have been installed, you can switch 18# to a non-administrator account and run the script again, passing the 19# --setup-launchd argument. That will install a Launchd agent to run the 20# BuildKite agent whenever the current user is logged in. You should enable 21# automatic login for that user, so that if the CI node goes down, the user 22# is logged back in automatically when the node goes up again, and the 23# BuildKite agent starts automatically. 24# 25# Alternatively, you can simply run the BuildKite agent by hand using: 26# 27# $ caffeinate -s buildkite-agent start --build-path /tmp/buildkite-builds 28 29set -e 30 31# Install a Launchd agent that will automatically start the BuildKite agent at login 32if [[ ${1} == "--setup-launchd" ]]; then 33 HOMEBREW_PREFIX="$(brew --prefix)" 34 mkdir -p ~/Library/LaunchAgents 35 cat <<EOF > ~/Library/LaunchAgents/libcxx.buildkite-agent.plist 36<?xml version="1.0" encoding="UTF-8"?> 37<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 38<plist version="1.0"> 39<dict> 40 <key>Label</key> 41 <string>libcxx.buildkite-agent</string> 42 43 <key>ProgramArguments</key> 44 <array> 45 <string>${HOMEBREW_PREFIX}/bin/buildkite-agent</string> 46 <string>start</string> 47 <string>--build-path</string> 48 <string>${HOME}/libcxx.buildkite-agent/builds</string> 49 </array> 50 51 <key>EnvironmentVariables</key> 52 <dict> 53 <key>PATH</key> 54 <string>${HOMEBREW_PREFIX}/bin:/usr/bin:/bin:/usr/sbin:/sbin</string> 55 </dict> 56 57 <key>RunAtLoad</key> 58 <true/> 59 60 <key>KeepAlive</key> 61 <dict> 62 <key>SuccessfulExit</key> 63 <false/> 64 </dict> 65 66 <key>ProcessType</key> 67 <string>Interactive</string> 68 69 <key>ThrottleInterval</key> 70 <integer>30</integer> 71 72 <key>StandardOutPath</key> 73 <string>${HOME}/libcxx.buildkite-agent/stdout.log</string> 74 75 <key>StandardErrorPath</key> 76 <string>${HOME}/libcxx.buildkite-agent/stderr.log</string> 77</dict> 78</plist> 79EOF 80 81 echo "Starting BuildKite agent" 82 launchctl load ~/Library/LaunchAgents/libcxx.buildkite-agent.plist 83 84else 85 echo "Installing CI dependencies for macOS" 86 87 if [[ -z "${BUILDKITE_AGENT_TOKEN}" ]]; then 88 echo "The BUILDKITE_AGENT_TOKEN environment variable must be set to a BuildKite Agent token when calling this script." 89 exit 1 90 fi 91 92 # Install Homebrew 93 if ! which -s brew; then 94 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" 95 fi 96 97 # Install the required tools to run CI 98 brew update 99 for package in sphinx-doc python3 ninja cmake clang-format buildkite/buildkite/buildkite-agent; do 100 if brew ls --versions "${package}" >/dev/null; then 101 brew upgrade "${package}" 102 else 103 brew install "${package}" 104 fi 105 done 106 python3 -m pip install --upgrade psutil 107 108 echo "Setting up BuildKite Agent config" 109 version="$(sw_vers -productVersion | sed -E 's/([0-9]+).([0-9]+).[0-9]+/\1.\2/')" 110 arch="$(uname -m)" 111 cat <<EOF > "$(brew --prefix)/etc/buildkite-agent/buildkite-agent.cfg" 112token="${BUILDKITE_AGENT_TOKEN}" 113tags="queue=libcxx-builders,arch=${arch},os=macos,os=macos${version}" 114build-path=/tmp/buildkite-builds # Note that this is actually overwritten when starting the agent with launchd 115EOF 116fi 117