From 2da30d5901f155fcd830600e673ab2e6212dd03e Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Thu, 23 May 2024 21:27:55 +1200 Subject: [PATCH] Implement build-and-test Github Actions CI using AWS spot instances --- .github/workflows/build-and-test-x86_64.yml | 11 ++ .github/workflows/build-and-test.yml | 149 ++++++++++++++++++++ scripts/github-actions-build.sh | 13 ++ scripts/github-actions-test.sh | 13 ++ 4 files changed, 186 insertions(+) create mode 100644 .github/workflows/build-and-test-x86_64.yml create mode 100644 .github/workflows/build-and-test.yml create mode 100755 scripts/github-actions-build.sh create mode 100755 scripts/github-actions-test.sh diff --git a/.github/workflows/build-and-test-x86_64.yml b/.github/workflows/build-and-test-x86_64.yml new file mode 100644 index 00000000000..569eb43672f --- /dev/null +++ b/.github/workflows/build-and-test-x86_64.yml @@ -0,0 +1,11 @@ +name: Build And Test (x86-64) + +on: [push, pull_request] + +jobs: + build-and-test-x86-64: + uses: ./.github/workflows/build-and-test.yml + with: + architecture: x86_64 + instance_type: c5.9xlarge + secrets: inherit diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml new file mode 100644 index 00000000000..4aed733e9dd --- /dev/null +++ b/.github/workflows/build-and-test.yml @@ -0,0 +1,149 @@ +name: Build And Test + +# Based on +# https://blog.devgenius.io/create-register-and-terminate-ec2-spot-instances-via-github-actions-aef473b8a00f + +on: + workflow_call: + inputs: + architecture: + required: true + type: string + instance_type: + required: true + type: string + secrets: + ACTIONS_TOKEN: + required: true + +env: + EC2_SECURITY_GROUP_ID: sg-072c6deccd49e89c8 # rr-testing + AWS_ROLE_ARN: arn:aws:iam::019859450731:role/SpotInstanceManager + AWS_REGION: us-east-2 + RUNNER_VERSION: "2.316.1" + +jobs: + start-runner: + name: Start Runner + permissions: write-all + runs-on: ubuntu-latest + outputs: + EC2_HOST: ${{ env.EC2_HOST }} + EC2_INSTANCE_ID: ${{ env.EC2_INSTANCE_ID }} + steps: + - name: "Run :: Configure AWS credentials" + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.AWS_ROLE_ARN }} + role-session-name: pipeline-assume-role-session + aws-region: ${{ env.AWS_REGION }} + + - name: "Run :: Create and register AWS spot instance" + run: |2- + # Get GitHub Actions runner registration token + response=$(curl -s -X POST -H 'Accept: application/vnd.github+json' -H 'Authorization: Bearer ${{ secrets.ACTIONS_TOKEN }}' -H 'X-GitHub-Api-Version: 2022-11-28' https://api.github.com/orgs/rr-debugger/actions/runners/registration-token) + echo "response :: $response" + RUNNER_REG_TOKEN=$(echo "$response" | jq -r .token) + echo "RUNNER_REG_TOKEN :: $RUNNER_REG_TOKEN" + + if [ $RUNNER_REG_TOKEN != "null" ]; then + USER_DATA="#!/bin/bash + + # Make sure the VM doesn't run for more than an hour + shutdown +60 + + apt-get update -y + apt-get dist-upgrade -f -y + + sudo -u ubuntu --login <> $GITHUB_ENV + echo "EC2_INSTANCE_ID=$INSTANCE_ID" >> $GITHUB_ENV + else + echo "$response" + exit 1 + fi + + build-and-test: + name: Build And Test + permissions: + contents: read + runs-on: + labels: ${{ inputs.architecture }}_${{github.sha}} + needs: + - start-runner + steps: + - name: Start + run: |2- + echo " Starting GitHub Action!" && + echo "STEPS_CAN_PROCEED=true" >> $GITHUB_ENV + + - name: "Run :: Checkout repository" + uses: actions/checkout@v2 + + - name: "Run :: Build" + run: ./scripts/github-actions-build.sh + + - name: "Run :: Test" + run: ./scripts/github-actions-test.sh + + stop-runner: + name: Stop Runner + permissions: write-all + runs-on: ubuntu-latest + needs: + - start-runner + - build-and-test + if: ${{ always() }} + steps: + - name: "Run :: Configure AWS credentials" + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.AWS_ROLE_ARN }} + role-session-name: pipeline-assume-role-session + aws-region: ${{ env.AWS_REGION }} + + - name: "Run :: Terminate and unregister AWS spot instance" + run: |2- + aws ec2 terminate-instances --instance-ids ${{ needs.start-runner.outputs.EC2_INSTANCE_ID }} + gh_runner_label=${{ needs.start-runner.outputs.EC2_RUNNER }} + response=$(curl -X GET https://api.github.com/orgs/rr-debugger/actions/runners -H 'Authorization: Bearer ${{ secrets.ACTIONS_TOKEN }}' + ) + offline_runners=$(echo "$response" | jq '.runners | map(select((.labels? | any(.name == "${{ inputs.architecture }}_${{github.sha}}"))))') + echo "Offline Runners :: $offline_runners" + + echo "Attempting to remove offline runners..." + for runner in $(echo "$offline_runners" | jq -r '.[].id'); do + echo "Triggering action for runner ID: $runner" + curl -X DELETE https://api.github.com/orgs/rr-debugger/actions/runners/$runner -H 'Authorization: Bearer ${{ secrets.ACTIONS_TOKEN }}' + done diff --git a/scripts/github-actions-build.sh b/scripts/github-actions-build.sh new file mode 100755 index 00000000000..118201ceb81 --- /dev/null +++ b/scripts/github-actions-build.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set +x # echo commands +set -e # default to exiting on error" + +uname -a + +sudo apt-get install -y rpm ccache cmake g++ pkg-config zlib1g-dev git python-dev-is-python3 libacl1-dev ninja-build manpages-dev capnproto libcapnp-dev gdb lldb python3-pexpect + +mkdir obj +cd obj +cmake -G Ninja -DCMAKE_BUILD_TYPE=DEBUG -Dstaticlibs=FALSE .. +ninja diff --git a/scripts/github-actions-test.sh b/scripts/github-actions-test.sh new file mode 100755 index 00000000000..5e480b3e02a --- /dev/null +++ b/scripts/github-actions-test.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set +x # echo commands +set -e # default to exiting on error" + +# Enable perf events for rr +echo 0 | sudo tee /proc/sys/kernel/perf_event_paranoid +# Enable ptrace-attach to any process. This lets us get more data when tests fail. +echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope +# Disable AppArmor restrictions on user namespaces, which our tests need to use +(echo 0 | sudo tee /proc/sys/kernel/apparmor_restrict_unprivileged_userns) || true +let halfproc=`nproc`/2 +ctest -j$halfproc --verbose