Skip to content

CI Test

CI Test #9

name: Build, lint & test
on:
workflow_dispatch:
pull_request:
merge_group:
types: [checks_requested]
push:
branches:
- main
- release-*
permissions:
contents: read
pull-requests: write
env:
TZ: "Europe/Amsterdam"
concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
backend:
name: Backend
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./backend
env:
CARGO_TERM_COLOR: always
SQLX_OFFLINE: "true"
steps:
# Free up runner disk space, so that our job has enough space to run
# https://dev.to/mathio/squeezing-disk-space-from-github-actions-runners-an-engineers-guide-3pjg
- name: Free up runner disk space
working-directory: /
run: >
df -h
&&
echo "Freeing up disk space..."
&&
sudo rm -rf
/usr/local/.ghcup
/usr/share/dotnet
/usr/share/swift
&&
df -h
- uses: actions/checkout@v6
# Build frontend so that it can be included in the backend build
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 22
package-manager-cache: false
- name: Install pnpm
run: >
npm install --global corepack@latest &&
corepack enable &&
corepack prepare pnpm@latest-10 --activate
- name: Install frontend dependencies
run: pnpm install
working-directory: ./frontend
- name: Build frontend
run: pnpm build
working-directory: ./frontend
env:
INCLUDE_STORYBOOK_LINK: true
- name: Build Storybook
run: pnpm build:storybook
working-directory: ./frontend
# Compile and test backend
- name: Install musl
run: sudo apt-get update && sudo apt-get install -y musl-tools
- name: Setup Rust
shell: bash
run: >
rustup update stable &&
rustup default stable &&
rustup target add x86_64-unknown-linux-musl &&
rustup component add --toolchain stable clippy rustfmt
- name: Cargo cache
uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2
with:
workspaces: "backend -> target"
- name: Check rustfmt
run: cargo --verbose --locked fmt --all -- --check
- name: Check Clippy with all features
run: cargo --verbose --locked clippy --target=x86_64-unknown-linux-musl --all-targets --all-features -- -D warnings
- name: Check Clippy without default features
run: cargo --verbose --locked clippy --target=x86_64-unknown-linux-musl --all-targets --no-default-features -- -D warnings
- name: Run tests
run: cargo --verbose --locked test --target=x86_64-unknown-linux-musl --features embed-typst -- --nocapture
- name: Build
run: cargo --verbose --locked build --target=x86_64-unknown-linux-musl --features memory-serve,embed-typst,storybook
- uses: actions/upload-artifact@v6
with:
name: abacus
path: backend/target/x86_64-unknown-linux-musl/debug/abacus
frontend:
name: Frontend
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend
steps:
- uses: actions/checkout@v6
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 22
package-manager-cache: false
- name: Install pnpm
run: >
npm install --global corepack@latest &&
corepack enable &&
corepack prepare pnpm@latest-10 --activate
- name: Install dependencies
run: pnpm install
- name: Run Biome
run: pnpm biome ci
- name: Run TypeScript compiler
run: pnpm lint:tsc
- name: Run ESLint
run: pnpm lint:eslint
- name: Install Playwright Chromium Browser
run: pnpm playwright install --with-deps chromium
- name: Test
run: pnpm test
- name: Build
run: pnpm build
- uses: actions/upload-artifact@v6
with:
name: frontend-build
path: frontend/dist
playwright-e2e:
name: Playwright e2e tests (${{ matrix.shardIndex }}/${{ matrix.shardTotal }})
needs:
- backend
strategy:
matrix:
shardIndex: [1, 2, 3]
shardTotal: [3]
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend
steps:
- uses: actions/checkout@v6
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 22
package-manager-cache: false
- name: Install pnpm
run: >
npm install --global corepack@latest &&
corepack enable &&
corepack prepare pnpm@latest-10 --activate
- name: Install dependencies
run: pnpm install
- name: Install Playwright Browsers
run: pnpm playwright install --with-deps --no-shell
- name: Download Abacus
uses: actions/download-artifact@v7
with:
name: abacus
path: builds/backend
- name: Make Abacus executable
run: chmod a+x ../builds/backend/abacus
- name: Run e2e playwright tests
run: pnpm test:e2e --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
- name: Upload Playwright report
uses: actions/upload-artifact@v6
if: ${{ !cancelled() }}
with:
name: playwright-report-ubuntu-latest-${{ matrix.shardIndex }}
path: frontend/playwright-report/
retention-days: 30
- name: Upload test results to Codecov
if: ${{ !cancelled() }}
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
name: "Playwright e2e"
files: frontend/playwright.e2e.junit.xml
disable_search: true
fail_ci_if_error: true
deploy:
if: "github.repository == 'kiesraad/abacus' && !github.event.pull_request.head.repo.fork"
name: Deploy to abacus-test.nl
needs:
- backend
environment:
name: test
url: https://${{ github.sha }}.abacus-test.nl
permissions:
contents: read
deployments: write
runs-on: ubuntu-latest
continue-on-error: true
steps:
- name: Download Abacus
uses: actions/download-artifact@v7
with:
name: abacus
- name: Strip debug symbols
run: strip abacus
- name: Upload binary to test server
run: |
curl -s -v \
--fail \
-H "Authorization: Bearer ${{ secrets.ABACUS_TEST_API_KEY }}" \
-T ./abacus \
https://abacus-test.nl/etes/api/v1/executable/${{ github.event.pull_request.head.sha || github.sha }}/${{ github.sha }}
fuzz:
name: Backend fuzzer
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./backend
env:
CARGO_TERM_COLOR: always
SQLX_OFFLINE: "true"
steps:
- uses: actions/checkout@v6
- name: Setup Rust Nightly
shell: bash
run: >
rustup update nightly &&
rustup default nightly
- name: Cargo cache
uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2
with:
workspaces: "backend/fuzz -> target"
shared-key: "fuzzer"
- name: Install cargo fuzz
run: cargo install cargo-fuzz
- name: Run the fuzzer
run: cargo fuzz run data_entry_status -- -max_total_time=60