Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
9d73470
Allow specifying a specific output dir for the tests
denisonbarbosa Nov 13, 2025
ab073da
Fix timeout command
denisonbarbosa Jan 7, 2026
ba3cd29
Allow overriding the dir used to store artifacts
denisonbarbosa Jan 7, 2026
8290957
Fix image naming logic
denisonbarbosa Jan 7, 2026
d6e25e8
Rework logic to wait for domain shutdown
denisonbarbosa Jan 7, 2026
e4daf99
Fix scripts for installing dependencies
denisonbarbosa Jan 19, 2026
1143d7a
Add workflow to provision and cache VM for the E2E tests
denisonbarbosa Oct 22, 2025
9c55134
create wrapper for running virsh commands as sudo
denisonbarbosa Jan 15, 2026
c09034f
Add job to run the e2e tests for authd-msentraid
denisonbarbosa Jan 15, 2026
bad35b4
Fix snapshot name being set to empty
denisonbarbosa Jan 15, 2026
1cce429
Fix bug with TOTP generator
denisonbarbosa Jan 19, 2026
0959cca
Add a safety timewindow to TOTP code generator
denisonbarbosa Jan 19, 2026
049a2ed
Increase timeouts on resource files
denisonbarbosa Jan 20, 2026
11ccdca
e2e-tests/vm: Disable AppArmor confinement for e2e-test VM
adombeck Jan 20, 2026
e745b9d
Disable exit-on-failure tag
denisonbarbosa Jan 20, 2026
176bc33
Add job to run e2e tests for authd-google
denisonbarbosa Jan 21, 2026
c07e38f
Use stdlib's subprocess instead of robot's Process
denisonbarbosa Jan 21, 2026
09b6a3d
Update error check when provider is invalid
denisonbarbosa Jan 21, 2026
2a47a14
Retry opening machinectl login up to three times
denisonbarbosa Jan 21, 2026
5568f98
e2e-tests: Make ffmpeg less noisy
adombeck Jan 22, 2026
b26401f
e2e-tests: Make browser_window.py less noisy
adombeck Jan 22, 2026
446ae62
Add 2FA support for Google in the E2E tests
denisonbarbosa Jan 22, 2026
996caba
e2e-tests: Send journal via TCP if host doesn't support VSOCK yet
adombeck Jan 23, 2026
815f4d0
ci/e2e-tests: Add keys-path output to set-ssh-keys step
denisonbarbosa Jan 27, 2026
96ee502
ci: Rename e2e-tests workflow
adombeck Jan 28, 2026
79ac418
e2e-tests: Fix journal via TCP on GitHub Runners
adombeck Jan 28, 2026
85f2fec
ci/e2e-tests: Also run on PRs which don't target main
adombeck Jan 28, 2026
f3e143a
ci/e2e-tests: Add include/exclude paths
adombeck Jan 28, 2026
d55d1e0
ci/e2e-tests: Also support exporting journal via TCP on Questing
adombeck Jan 28, 2026
25e2709
Add re-usable e2e-test workflow
adombeck Jan 28, 2026
210ff03
ci/e2e-tests: Cancel in-progress runs
adombeck Jan 28, 2026
1b61329
ci/e2e-tests: Use hash of provisioning files in cache key
adombeck Jan 28, 2026
1ccc0eb
e2e-tests: Hide wget output in CI
adombeck Jan 28, 2026
82ca969
Move e2e-tests directory to project root
adombeck Jan 28, 2026
3deb162
e2e-tests: Check if cloud-init succeeded
adombeck Jan 28, 2026
3fe76cf
ci/e2e-tests: Upload VM image as layered OCI artifact
adombeck Jan 28, 2026
7032d95
ci/e2e-tests: Remove unnecessary chmod command
adombeck Jan 29, 2026
43f64ed
.gitignore: Ignore e2e-tests/e2e-tests.env
adombeck Jan 29, 2026
3128acf
ci/e2e-tests: Update actions/checkout to v6
adombeck Jan 29, 2026
e245dba
ci/e2e-tests: Simplify run-e2e-test.yaml
adombeck Jan 29, 2026
b4bf91b
ci/e2e-tests: Only block run-tests job on required provision-vm job
adombeck Jan 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .github/actions/e2e-tests/set-up-ssh-keys/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Set up SSH keys for VM provisioning
description: "Sets up SSH keys for VM provisioning"
inputs:
E2E_VM_SSH_PRIV_KEY:
description: "Private SSH key for VM provisioning"
required: true
E2E_VM_SSH_PUB_KEY:
description: "Public SSH key for VM provisioning"
required: true
outputs:
keys-path:
description: "Path to the SSH keys"
value: "${{ steps.set-ssh-keys.outputs.keys-path }}"
runs:
using: "composite"
steps:
- name: Set GitHub Path
run: echo "$GITHUB_ACTION_PATH" >> $GITHUB_PATH
shell: bash
env:
GITHUB_ACTION_PATH: ${{ github.action_path }}

- name: Set up SSH keys for the VM provisioning
id: set-ssh-keys
shell: bash
run: |
set -eu

mkdir -p "${HOME}/.ssh"
chmod 700 "${HOME}/.ssh"

echo "${{ inputs.E2E_VM_SSH_PRIV_KEY }}" > "${HOME}/.ssh/id_rsa"
chmod 600 "${HOME}/.ssh/id_rsa"

echo "${{ inputs.E2E_VM_SSH_PUB_KEY }}" > "${HOME}/.ssh/id_rsa.pub"
chmod 644 "${HOME}/.ssh/id_rsa.pub"

eval "$(ssh-agent -s)"

ssh-add "${HOME}/.ssh/id_rsa"

echo "keys-path=${HOME}/.ssh" >> "$GITHUB_OUTPUT"
42 changes: 42 additions & 0 deletions .github/workflows/e2e-tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: e2e-tests

on:
workflow_dispatch:
schedule:
- cron: '0 0 * * 1' # Runs every Monday at midnight
pull_request:
paths:
- '**'
- '!.github/workflows/**'
- '.github/workflows/run-e2e-tests.yaml'
- '.github/workflows/provision-and-run-e2e-tests.yaml'
- '.github/workflows/e2e-tests.yaml'
- '!.gitignore'
- '!.golangci.yaml'
- '!AGENTS.md'
- '!CODE_OF_CONDUCT.md'
- '!CONTRIBUTING.md'
- '!COPYING'
- '!COPYING.LESSER'
- '!README.md'
- '!SECURITY.md'
- "!authd-oidc-brokers/po/**"
- "!authd-oidc-brokers/.gitignore"
- '!docs/**'
- '!examplebroker/**'
- '!gotestcov'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
provision-and-run-e2e-tests:
strategy:
matrix:
release: [noble, questing]
fail-fast: false
uses: ./.github/workflows/provision-and-run-e2e-tests.yaml
with:
release: ${{ matrix.release }}
secrets: inherit
127 changes: 127 additions & 0 deletions .github/workflows/provision-and-run-e2e-tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
name: provision-e2e-test (reusable)

on:
workflow_call:
inputs:
release:
required: true
type: string
secrets:
E2E_VM_SSH_PRIV_KEY:
required: true
E2E_VM_SSH_PUB_KEY:
required: true

env:
DEBIAN_FRONTEND: noninteractive
VM_NAME_BASE: e2e-runner
ARTIFACTS_DIR: /tmp/e2e-artifacts
E2E_TESTS_DIR: e2e-tests

jobs:
provision-vm:
name: Provision VM
runs-on: ubuntu-latest
permissions:
contents: read
actions: write
packages: write
steps:
- name: Checkout repo
uses: actions/checkout@v6

- name: Restore cached VM image (if available)
id: restore-cache
uses: actions/cache/restore@v4
with:
path: ${{ env.ARTIFACTS_DIR }}/${{ env.VM_NAME_BASE }}-${{ inputs.release }}.qcow2
key: >-
e2e-runner-vm-${{ inputs.release }}-${{ hashFiles(
'e2e-tests/vm/**',
'.github/actions/e2e-tests/set-up-ssh-keys/**',
'.github/workflows/provision-and-run-e2e-tests.yaml'
) }}
fail-on-cache-miss: false

- uses: canonical/desktop-engineering/gh-actions/common/dpkg-install-speedup@main
if: steps.restore-cache.outputs.cache-hit != 'true'

- name: Install APT dependencies for VM provisioning
if: steps.restore-cache.outputs.cache-hit != 'true'
run: ./${{ env.E2E_TESTS_DIR }}/vm/install-provision-deps.sh

- name: Set up SSH keys for the VM provisioning
id: set-ssh-keys
if: steps.restore-cache.outputs.cache-hit != 'true'
uses: ./.github/actions/e2e-tests/set-up-ssh-keys
with:
E2E_VM_SSH_PRIV_KEY: ${{ secrets.E2E_VM_SSH_PRIV_KEY }}
E2E_VM_SSH_PUB_KEY: ${{ secrets.E2E_VM_SSH_PUB_KEY }}

- name: Provision the VM
id: provision-vm
if: steps.restore-cache.outputs.cache-hit != 'true'
run: |
set -eu
export PATH="$(realpath "${{ env.E2E_TESTS_DIR }}/vm/helpers"):${PATH}"
mkdir -p ${{ env.ARTIFACTS_DIR }}
env VM_NAME_BASE="${{ env.VM_NAME_BASE }}" \
RELEASE="${{ inputs.release }}" \
ARTIFACTS_DIR="${{ env.ARTIFACTS_DIR }}" \
SSH_PUBLIC_KEY_FILE="${{ steps.set-ssh-keys.outputs.keys-path }}/id_rsa.pub" \
./${{ env.E2E_TESTS_DIR }}/vm/provision-ubuntu.sh

- name: Clean previous cache
if: always() && steps.provision-vm.outcome == 'success'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
run: |
set -eu
gh cache delete e2e-runner-${{ inputs.release }} || true
echo "Previous cache (if any) deleted"

- name: Cache the VM image
uses: actions/cache/save@v4
if: always() && steps.provision-vm.outcome == 'success'
with:
path: ${{ env.ARTIFACTS_DIR }}/${{ env.VM_NAME_BASE }}-${{ inputs.release }}.qcow2
key: >-
e2e-runner-vm-${{ inputs.release }}-${{ hashFiles(
'e2e-tests/vm/**',
'.github/actions/e2e-tests/set-up-ssh-keys/**',
'.github/workflows/provision-and-run-e2e-tests.yaml'
) }}

- uses: oras-project/setup-oras@v1
- name: Upload VM image as OCI artifact
if: steps.provision-vm.outcome == 'success' || steps.restore-cache.outputs.cache-hit == 'true'
env:
IMAGE_PATH: ${{ env.ARTIFACTS_DIR }}/${{ env.VM_NAME_BASE }}-${{ inputs.release }}.qcow2
OCI_REPO: ghcr.io/${{ github.repository }}/e2e-runner
OCI_TAG: ${{ inputs.release }}
run: |
set -euo pipefail

echo "${{ secrets.GITHUB_TOKEN }}" \
| oras login ghcr.io -u "${{ github.actor }}" --password-stdin

# Chunk qcow2 into stable fixed-size layers (64 MiB)
WORKDIR=$(mktemp -d)
split -b 64M "$IMAGE_PATH" "$WORKDIR/chunk-"

# Push as a layered OCI artifact (each chunk becomes a layer)
cd "$WORKDIR"
oras push "${OCI_REPO}:${OCI_TAG}" chunk-* --artifact-type application/vnd.qemu.qcow2

e2e-test:
needs: provision-vm
strategy:
matrix:
broker: [authd-msentraid, authd-google]
fail-fast: false
uses: ./.github/workflows/run-e2e-tests.yaml
with:
release: ${{ inputs.release }}
broker: ${{ matrix.broker }}
secrets: inherit
164 changes: 164 additions & 0 deletions .github/workflows/run-e2e-tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
name: run-e2e-test (reusable)

on:
workflow_call:
inputs:
release:
required: true
type: string
broker:
required: true
type: string
secrets:
E2E_VM_SSH_PRIV_KEY:
required: true
E2E_VM_SSH_PUB_KEY:
required: true
E2E_MSENTRA_ISSUER_ID:
required: false
E2E_MSENTRA_CLIENT_ID:
required: false
E2E_MSENTRA_USERNAME:
required: false
E2E_MSENTRA_PASSWORD:
required: false
E2E_MSENTRA_TOTP_SECRET:
required: false
E2E_GOOGLE_CLIENT_ID:
required: false
E2E_GOOGLE_CLIENT_SECRET:
required: false
E2E_GOOGLE_USERNAME:
required: false
E2E_GOOGLE_PASSWORD:
required: false
E2E_GOOGLE_TOTP_SECRET:
required: false

env:
DEBIAN_FRONTEND: noninteractive
VM_NAME_BASE: e2e-runner
ARTIFACTS_DIR: /tmp/e2e-artifacts
E2E_TESTS_DIR: e2e-tests
OUTPUT_DIR: /tmp/e2e-${{ inputs.broker }}-${{ inputs.release }}/output

jobs:
run-tests:
name: Run e2e-tests (${{ inputs.broker }})
runs-on: ubuntu-latest
permissions:
contents: read
actions: write
packages: read
steps:
- uses: oras-project/setup-oras@v1
- name: Download VM image OCI artifact
env:
OCI_REPO: ghcr.io/${{ github.repository }}/e2e-runner
OCI_TAG: ${{ inputs.release }}
IMAGE_PATH: ${{ env.ARTIFACTS_DIR }}/${{ env.VM_NAME_BASE }}-${{ inputs.release }}.qcow2
run: |
set -euo pipefail

mkdir -p "$(dirname "$IMAGE_PATH")"

echo "${{ secrets.GITHUB_TOKEN }}" \
| oras login ghcr.io -u "${{ github.actor }}" --password-stdin

oras pull "${OCI_REPO}:${OCI_TAG}"
cat chunk-* > "$IMAGE_PATH"
rm chunk-*

- name: Checkout repo
uses: actions/checkout@v6

- uses: canonical/desktop-engineering/gh-actions/common/dpkg-install-speedup@main

- name: Install APT dependencies for provisioning
run: ${{ env.E2E_TESTS_DIR }}/vm/install-provision-deps.sh

- name: Set up SSH keys for the VM provisioning
id: set-ssh-keys
uses: ./.github/actions/e2e-tests/set-up-ssh-keys
with:
E2E_VM_SSH_PRIV_KEY: ${{ secrets.E2E_VM_SSH_PRIV_KEY }}
E2E_VM_SSH_PUB_KEY: ${{ secrets.E2E_VM_SSH_PUB_KEY }}

- name: Provision authd and the broker
run: |
set -eux
export PATH="$(realpath "${{ env.E2E_TESTS_DIR }}/vm/helpers"):${PATH}"

# Generate the libvirt domain XML file
template="${{ env.E2E_TESTS_DIR }}/vm/e2e-runner-template.xml"
env \
IMAGE_FILE=${{ env.ARTIFACTS_DIR }}/${{ env.VM_NAME_BASE }}-${{ inputs.release }}.qcow2 \
VM_NAME=${{ env.VM_NAME_BASE }}-${{ inputs.release }} \
envsubst \
< "${template}" \
> "${{ env.ARTIFACTS_DIR }}/${{ env.VM_NAME_BASE }}.xml"

# Create the provisioning config file
cat > "${{ env.E2E_TESTS_DIR }}/vm/config.sh" <<-EOF
export SSH_PUBLIC_KEY_FILE=${{ steps.set-ssh-keys.outputs.keys-path }}/id_rsa.pub
export VM_NAME_BASE=${{ env.VM_NAME_BASE }}
export RELEASE=${{ inputs.release }}
export BROKERS=${{ inputs.broker }}

export AUTHD_MSENTRAID_ISSUER_ID=${{ secrets.E2E_MSENTRA_ISSUER_ID }}
export AUTHD_MSENTRAID_CLIENT_ID=${{ secrets.E2E_MSENTRA_CLIENT_ID }}
export AUTHD_MSENTRAID_USER=${{ secrets.E2E_MSENTRA_USERNAME }}

export AUTHD_GOOGLE_CLIENT_ID=${{ secrets.E2E_GOOGLE_CLIENT_ID }}
export AUTHD_GOOGLE_CLIENT_SECRET=${{ secrets.E2E_GOOGLE_CLIENT_SECRET }}
export AUTHD_GOOGLE_USER=${{ secrets.E2E_GOOGLE_USERNAME }}
EOF

# Provision the VM
${{ env.E2E_TESTS_DIR }}/vm/provision-authd.sh

- name: Checkout YARF repo
uses: actions/checkout@v6
with:
repository: adombeck/yarf
path: ${{ env.E2E_TESTS_DIR }}/.yarf

- name: Install APT dependencies for running the E2E tests
run: ${{ env.E2E_TESTS_DIR }}/install-deps.sh

- name: Configure YARF
run: ${{ env.E2E_TESTS_DIR }}/setup-yarf.sh

- name: Run tests
id: run-tests
run: |
set -eux
export PATH="$(realpath "${{ env.E2E_TESTS_DIR }}/vm/helpers"):${PATH}"

# Set the credentials for the broker
if [ "${{ inputs.broker }}" = "authd-msentraid" ]; then
E2E_USER=${{ secrets.E2E_MSENTRA_USERNAME }}
E2E_PASSWORD=${{ secrets.E2E_MSENTRA_PASSWORD }}
TOTP_SECRET=${{ secrets.E2E_MSENTRA_TOTP_SECRET }}
elif [ "${{ inputs.broker }}" = "authd-google" ]; then
E2E_USER=${{ secrets.E2E_GOOGLE_USERNAME }}
E2E_PASSWORD=${{ secrets.E2E_GOOGLE_PASSWORD }}
TOTP_SECRET=${{ secrets.E2E_GOOGLE_TOTP_SECRET }}
fi

# Run the tests
${{ env.E2E_TESTS_DIR }}/run-tests.sh \
--user "${E2E_USER}" \
--password "${E2E_PASSWORD}" \
--totp-secret "${TOTP_SECRET}" \
--release "${{ inputs.release }}" \
--broker "${{ inputs.broker }}" \
--output-dir "${{ env.OUTPUT_DIR }}"

- name: Upload test results
id: upload-results
if: always()
uses: actions/upload-artifact@v6
with:
name: e2e-${{ inputs.broker }}-output-${{ inputs.release }}-${{ github.run_id }}
path: ${{ env.OUTPUT_DIR }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ snap/icon.svg
snap/snapcraft.yaml
authd-oidc-brokers/conf/authd.conf
authd-oidc-brokers/conf/broker.conf

# Useful for running e2e-tests locally
e2e-tests/e2e-tests.env
Loading
Loading