Implement fully automated end-to-end CI testing workflow #82
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Start E2E Test | |
on: | |
pull_request: | |
jobs: | |
build-charm: | |
name: Build Charm | |
runs-on: [self-hosted, linux, x64, e2e-test] | |
steps: | |
- uses: actions/checkout@v3 | |
- name: Remove Unnecessary Components | |
run: | | |
rm -rf .git | |
rm -rf .github | |
- name: Setup LXD | |
uses: canonical/setup-lxd@main | |
- name: Write lxd-profile.yaml | |
run: | | |
cat << EOF > ./lxd-profile.yaml | |
config: | |
security.nesting: true | |
security.privileged: true | |
raw.lxc: | | |
lxc.apparmor.profile=unconfined | |
lxc.mount.auto=proc:rw sys:rw cgroup:rw | |
lxc.cgroup.devices.allow=a | |
lxc.cap.drop= | |
devices: | |
kmsg: | |
path: /dev/kmsg | |
source: /dev/kmsg | |
type: unix-char | |
EOF | |
- name: Cache github-runner Charm | |
uses: actions/cache@v3 | |
id: cache-charm | |
with: | |
path: github-runner_ubuntu-22.04-amd64.charm | |
key: github-runner-charm-${{ hashFiles('**/*') }} | |
- name: Install charmcraft | |
if: steps.cache-charm.outputs.cache-hit != 'true' | |
run: sudo snap install charmcraft --classic | |
- name: Pack github-runner Charm | |
if: steps.cache-charm.outputs.cache-hit != 'true' | |
run: charmcraft pack || ( cat ~/.local/state/charmcraft/log/* 1 && exit 1 ) | |
- name: Upload github-runner Charm | |
uses: actions/upload-artifact@v3 | |
with: | |
name: github-runner_ubuntu-22.04-amd64.charm | |
path: github-runner_ubuntu-22.04-amd64.charm | |
deploy-e2e-test-runner: | |
name: Deploy End-to-End Testing Runner | |
runs-on: ubuntu-latest | |
needs: build-charm | |
steps: | |
- name: Initialize LXD | |
run: | | |
sudo snap refresh lxd --channel=latest/stable | |
sudo lxd waitready | |
sudo lxd init --auto | |
sudo chmod a+wr /var/snap/lxd/common/lxd/unix.socket | |
sudo lxc network set lxdbr0 ipv6.address none | |
sudo iptables -F FORWARD | |
sudo iptables -P FORWARD ACCEPT | |
- name: Install Juju | |
run: sudo snap install juju --classic --channel=3.1/stable | |
- name: Bootstrap Juju LXD Controller | |
run: | | |
juju bootstrap --debug --verbose lxd \ | |
--model-default test-mode=true \ | |
--model-default automatically-retry-hooks=false \ | |
--model-default logging-config="<root>=DEBUG" \ | |
--bootstrap-constraints="cores=2 mem=4G" | |
- name: Create Testing Juju Model | |
run: juju add-model testing | |
- name: Download github-runner Charm | |
uses: actions/download-artifact@v3 | |
with: | |
name: github-runner_ubuntu-22.04-amd64.charm | |
- name: Generate Run ID | |
id: run-id | |
shell: python | |
run: | | |
import os | |
import random | |
import string | |
with open(os.environ['GITHUB_OUTPUT'], 'a') as f: | |
run_id = "".join(random.choice(string.ascii_lowercase) for _ in range(8)) | |
f.write(f"run-id=e2e-{run_id}\n") | |
- name: Deploy github-runner Charm | |
run: | | |
cp github-runner_ubuntu-22.04-amd64.charm /home/$USER/github-runner_ubuntu-22.04-amd64.charm | |
juju deploy /home/$USER/github-runner_ubuntu-22.04-amd64.charm \ | |
${{ steps.run-id.outputs.run-id }} \ | |
--base [email protected] \ | |
--config path=${{ secrets.E2E_TESTING_REPO }} \ | |
--config token=${{ secrets.E2E_TESTING_TOKEN }} \ | |
--config virtual-machines=1 \ | |
--force | |
- name: Install GitHub Cli | |
run: which gh || sudo apt install gh -y | |
# - name: Setup tmate session | |
# uses: mxschmitt/action-tmate@v3 | |
- name: Dispatch Workflow on Testing Runner | |
env: | |
GH_TOKEN: ${{ secrets.E2E_TESTING_TOKEN }} | |
run: | | |
MAIN_SHA=$(gh api \ | |
-H "Accept: application/vnd.github+json" \ | |
-H "X-GitHub-Api-Version: 2022-11-28" \ | |
/repos/${{ secrets.E2E_TESTING_REPO }}/git/ref/heads/main --jq .object.sha) | |
gh api \ | |
--method POST \ | |
-H "Accept: application/vnd.github+json" \ | |
-H "X-GitHub-Api-Version: 2022-11-28" \ | |
/repos/${{ secrets.E2E_TESTING_REPO }}/git/refs \ | |
-f ref='refs/heads/${{ steps.run-id.outputs.run-id }}' \ | |
-f sha=$MAIN_SHA | |
gh workflow run test.yaml \ | |
-R ${{ secrets.E2E_TESTING_REPO }} \ | |
--ref ${{ steps.run-id.outputs.run-id }} \ | |
-f runner=${{ steps.run-id.outputs.run-id }} | |
sleep 5 | |
- name: Watch github-runner | |
env: | |
GH_TOKEN: ${{ secrets.E2E_TESTING_TOKEN }} | |
run: | | |
gh run list \ | |
-R ${{ secrets.E2E_TESTING_REPO }} \ | |
-L 100 \ | |
--json headBranch,status,workflowDatabaseId,conclusion \ | |
| jq '.[] | select(.headBranch=="${{ steps.run-id.outputs.run-id }}")' | |
get-workflow-status() { | |
output=$(gh run list \ | |
-R ${{ secrets.E2E_TESTING_REPO }} \ | |
-L 100 \ | |
--json headBranch,status \ | |
| jq '[.[] | select(.headBranch=="${{ steps.run-id.outputs.run-id }}")]') | |
if [ $(echo "$output" | jq 'length') -eq 0 ] | |
then | |
echo "not_started" | |
else | |
# Parse output with jq to get the status field of the first object | |
status=$(echo "$output" | jq -r '.[0].status') | |
echo "$status" | |
fi | |
} | |
juju debug-log --replay --tail & | |
for i in {1..360} | |
do | |
status=$(get-workflow-status) | |
echo "workflow status: $status" | |
if [[ $status != "not-started" && $status != "queued" && $status != "in_progress" ]]; then | |
break | |
fi | |
sleep 10 | |
done | |
kill $(jobs -p) | |
conclusion=$(gh run list \ | |
-R ${{ secrets.E2E_TESTING_REPO }} \ | |
-L 100 \ | |
--json headBranch,conclusion \ | |
| jq '.[] | select(.headBranch=="${{ steps.run-id.outputs.run-id }}") | .conclusion') | |
if [[ $status != "completed" || $conclusion != "success" ]]; then | |
echo "test workflow failed with status: $status, conclusion: $conclusion" | |
exit 1 | |
fi |