Skip to content

Implement build-and-test Github Actions CI using AWS spot instances #1

Implement build-and-test Github Actions CI using AWS spot instances

Implement build-and-test Github Actions CI using AWS spot instances #1

Workflow file for this run

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
exit 1
fi
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 <<EOF
# Install GitHub Actions runner
mkdir /home/ubuntu/actions-runner && cd /home/ubuntu/actions-runner
curl -o actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz -L https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz
echo \"Github Runner Installed\"
# Extract the installer
tar xzf ./actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz
echo \"Github Runner Installer Extracted\"
# Run GitHub Actions runner configuration
yes '' | ./config.sh --url https://github.com/rr-debugger --token $RUNNER_REG_TOKEN --labels ${{ inputs.architecture }}_${{github.sha}}
# Run GitHub Actions runner
yes '' | ./run.sh
EOF
"
IMAGE_ID=$(aws ec2 describe-images --owners 099720109477 --filters 'Name=architecture,Values=${{ inputs.architecture }}' 'Name=name,Values=ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-*' | jq --raw-output .Images[0].ImageId)
echo "IMAGE_ID :: $IMAGE_ID"
ENCODED_USER_DATA=$(echo -n "$USER_DATA" | sed 's/^[[:space:]]*//' | base64 -w 0)
echo "ENCODED_USER_DATA :: $ENCODED_USER_DATA"
INSTANCE_ID=$(aws ec2 run-instances --image-id $IMAGE_ID --instance-type ${{ inputs.instance_type }} --user-data $ENCODED_USER_DATA --security-group-ids ${{ env.EC2_SECURITY_GROUP_ID }} --instance-market-options MarketType=spot --instance-initiated-shutdown-behavior terminate --query 'Instances[0].InstanceId' --key-name rr-testing --output text)
echo "INSTANCE_ID :: $INSTANCE_ID"
aws ec2 wait instance-running --instance-ids $INSTANCE_ID
HOSTNAME=$(aws ec2 describe-instances --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].PublicDnsName' --output text)
echo "HOSTNAME :: $HOSTNAME"
echo Runner label :: ${{ inputs.architecture }}_${{github.sha}}
echo "EC2_HOST=$HOSTNAME" >> $GITHUB_ENV
echo "EC2_INSTANCE_ID=$INSTANCE_ID" >> $GITHUB_ENV
build-and-test:
name: Build And Test
permissions:
contents: read

Check failure on line 99 in .github/workflows/build-and-test.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/build-and-test.yml

Invalid workflow file

You have an error in your yaml syntax on line 99
runs-on: [self-hosted, ${{ 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