Skip to content

Commit 8bf68c6

Browse files
author
ml2pr
committed
ci: add CI infrastructure [ml2pr]
1 parent 1f318b9 commit 8bf68c6

29 files changed

Lines changed: 1141 additions & 0 deletions

.github/scripts/matrix.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/usr/bin/env python3
2+
"""Generate CI build and test matrices for vfs-test.
3+
Outputs JSON matrices to GITHUB_OUTPUT for consumption by test.yml.
4+
"""
5+
6+
import json
7+
import os
8+
9+
# Base build configurations (arch/toolchain/distro/runner).
10+
BASE_CONFIGS = [
11+
{
12+
"arch": "x86_64",
13+
"toolchain": "gcc",
14+
"distro": "fedora",
15+
"runs_on": '["ubuntu-24.04"]',
16+
},
17+
{
18+
"arch": "x86_64",
19+
"toolchain": "gcc",
20+
"distro": "debian",
21+
"runs_on": '["ubuntu-24.04"]',
22+
},
23+
# TODO: re-enable aarch64 once we have self-hosted ARM runners.
24+
# QEMU TCG emulation on GitHub-hosted x86_64 runners is too slow
25+
# and lacks KVM.
26+
]
27+
28+
# Each test suite becomes its own matrix entry with its own timeout.
29+
TEST_SUITES = [
30+
{"test_suite": "selftests", "timeout_minutes": 120},
31+
{"test_suite": "xfstests", "timeout_minutes": 1440},
32+
{"test_suite": "ovl-fstests", "timeout_minutes": 1440},
33+
]
34+
35+
36+
def generate_matrix():
37+
"""Generate the matrix consumed by test.yml.
38+
39+
Produces the cross-product of BASE_CONFIGS × TEST_SUITES.
40+
"""
41+
include = []
42+
for base in BASE_CONFIGS:
43+
for suite in TEST_SUITES:
44+
include.append({**base, **suite})
45+
return {"include": include}
46+
47+
48+
def main():
49+
matrix = generate_matrix()
50+
51+
github_output = os.environ.get("GITHUB_OUTPUT", "")
52+
if github_output:
53+
with open(github_output, "a") as f:
54+
f.write(f"matrix={json.dumps(matrix)}\n")
55+
56+
# Debug output
57+
print(json.dumps(matrix, indent=2))
58+
59+
60+
if __name__ == "__main__":
61+
main()
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
name: kernel-build-test
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
arch:
7+
type: string
8+
required: true
9+
toolchain:
10+
type: string
11+
default: gcc
12+
distro:
13+
type: string
14+
required: true
15+
runs_on:
16+
description: 'JSON-encoded runner label array, e.g. ["ubuntu-24.04"]'
17+
type: string
18+
default: '["ubuntu-24.04"]'
19+
timeout_minutes:
20+
type: number
21+
default: 90
22+
test_suite:
23+
type: string
24+
required: true
25+
26+
jobs:
27+
build-and-test:
28+
runs-on: ${{ fromJSON(inputs.runs_on) }}
29+
timeout-minutes: ${{ inputs.timeout_minutes }}
30+
env:
31+
MKOSI_KERNEL: "${{ github.workspace }}/../mkosi-kernel"
32+
MKOSI_FSTESTS: "${{ github.workspace }}/../fstests"
33+
steps:
34+
- uses: actions/checkout@v6
35+
36+
- uses: systemd/mkosi@56d5ed4247deb3d0b11f7a6aec5a1a9f580ccde5
37+
38+
- name: Clone mkosi-kernel
39+
run: git clone --depth=1 https://github.com/DaanDeMeyer/mkosi-kernel.git "$MKOSI_KERNEL"
40+
41+
- name: Clone fstests
42+
if: inputs.test_suite != 'selftests'
43+
run: |
44+
git clone --depth=1 https://github.com/kdave/xfstests.git "$MKOSI_FSTESTS"
45+
if [ "${{ inputs.test_suite }}" = "ovl-fstests" ]; then
46+
git clone --depth=1 https://github.com/amir73il/unionmount-testsuite.git "$MKOSI_FSTESTS/src/unionmount-testsuite"
47+
fi
48+
49+
- name: Configure mkosi
50+
run: |
51+
set -euo pipefail
52+
cp -av ci/mkosi/mkosi.kernel.config "${MKOSI_KERNEL}/"
53+
cp -avr ci/mkosi/mkosi.extra/. "${MKOSI_KERNEL}/mkosi.extra/"
54+
cp -avr ci/mkosi/mkosi.repart "${MKOSI_KERNEL}/"
55+
mkdir -p "${MKOSI_KERNEL}/mkosi.conf.d"
56+
cp -av ci/mkosi/mkosi.conf.d/99-vfs.conf "${MKOSI_KERNEL}/mkosi.conf.d/"
57+
if [ "${{ inputs.test_suite }}" != "selftests" ]; then
58+
cp -av ci/mkosi/mkosi.conf.d/99-vfs-fstests.conf "${MKOSI_KERNEL}/mkosi.conf.d/"
59+
fi
60+
61+
if [ "${{ inputs.test_suite }}" = "ovl-fstests" ]; then
62+
cp -av ci/mkosi/mkosi.conf.d/99-vfs-ovl.conf "${MKOSI_KERNEL}/mkosi.conf.d/"
63+
fi
64+
65+
cat > "${MKOSI_KERNEL}/mkosi.local.conf" <<EOF
66+
[Distribution]
67+
Distribution=${{ inputs.distro }}
68+
EOF
69+
mkosi --directory="${MKOSI_KERNEL}" genkey
70+
71+
- name: Run mkosi summary
72+
run: mkosi --directory="${MKOSI_KERNEL}" summary
73+
74+
- name: Build image and kernel
75+
run: mkosi --directory="${MKOSI_KERNEL}" build
76+
77+
- name: Run ${{ inputs.test_suite }}
78+
run: |
79+
set -euo pipefail
80+
81+
case "${{ inputs.test_suite }}" in
82+
selftests) unit=vfs-selftests.service ;;
83+
xfstests) unit=xfs-fstests.service ;;
84+
ovl-fstests) unit=ovl-fstests.service ;;
85+
esac
86+
87+
rc=0
88+
mkosi --directory="${MKOSI_KERNEL}" box -- mkosi --directory="${MKOSI_KERNEL}" --kernel-command-line-extra=systemd.unit="$unit" qemu || rc=$?
89+
90+
if [ "$rc" -ne 123 ]; then
91+
echo "::error::Tests failed (exit code $rc)"
92+
exit 1
93+
fi

.github/workflows/test.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: fsdevel-selftests
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- '**'
8+
- '!vfs.all'
9+
- '!vfs.base'
10+
- '!vfs.fixes'
11+
- '!pw/**'
12+
13+
concurrency:
14+
group: ci-test-${{ github.ref_name }}
15+
cancel-in-progress: true
16+
17+
jobs:
18+
set-matrix:
19+
runs-on: ubuntu-latest
20+
timeout-minutes: 5
21+
outputs:
22+
matrix: ${{ steps.matrix.outputs.matrix }}
23+
steps:
24+
- uses: actions/checkout@v6
25+
with:
26+
sparse-checkout: .github/scripts
27+
28+
- name: Generate matrix
29+
id: matrix
30+
run: python3 .github/scripts/matrix.py
31+
32+
build-and-test:
33+
name: ${{ matrix.arch }} (${{ matrix.toolchain }}, ${{ matrix.distro }}, ${{ matrix.test_suite }})
34+
if: ${{ github.repository != 'linux-fsdevel/vfs-test' }}
35+
needs: set-matrix
36+
strategy:
37+
fail-fast: false
38+
matrix: ${{ fromJSON(needs.set-matrix.outputs.matrix) }}
39+
uses: ./.github/workflows/kernel-build-test.yml
40+
with:
41+
arch: ${{ matrix.arch }}
42+
toolchain: ${{ matrix.toolchain }}
43+
distro: ${{ matrix.distro }}
44+
runs_on: ${{ matrix.runs_on }}
45+
timeout_minutes: ${{ matrix.timeout_minutes }}
46+
test_suite: ${{ matrix.test_suite }}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[Config]
2+
Profiles=fstests
3+
4+
[Build]
5+
BuildSources=$MKOSI_FSTESTS:fstests
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[Content]
2+
ExtraTrees=$MKOSI_FSTESTS/src/unionmount-testsuite:/var/lib/xfstests/src/unionmount-testsuite

ci/mkosi/mkosi.conf.d/99-vfs.conf

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[Content]
2+
Autologin=yes
3+
Ssh=yes
4+
Bootable=no
5+
Bootloader=none
6+
Packages=e2fsprogs
7+
file
8+
9+
[Config]
10+
Profiles=kernel
11+
12+
[Build]
13+
BuildSources=$GITHUB_WORKSPACE:kernel
14+
Environment=SELFTESTS=1
15+
SELFTESTS_TARGETS="mount mount_setattr filelock tmpfs pidfd pid_namespace cachestat"
16+
17+
[Output]
18+
Format=disk
19+
20+
[Runtime]
21+
Firmware=linux
22+
RAM=8G
23+
CPUs=4
24+
KernelCommandLineExtra=enforcing=0 rw systemd.mask=var-lib-nfs-rpc_pipefs.mount debug no_console_suspend systemd.firstboot=no

ci/mkosi/mkosi.extra/etc/fstab

Whitespace-only changes.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[Journal]
2+
SystemMaxUse=256M
3+
SystemMaxFileSize=32M
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[Match]
2+
Name=en*
3+
4+
[Network]
5+
DHCP=yes
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
d /home/user1 0755 1000 1000
2+
d /mnt/test 0755 0 0
3+
d /mnt/scratch 0755 0 0
4+
Z /home/user1/src - 1000 1000
5+
w+ /etc/nsswitch.conf - - - - shadow: files systemd\n
6+
w+ /etc/nsswitch.conf - - - - group: files [SUCCESS=merge] systemd\n
7+
f+ /etc/sudoers.d/user1 - - - - user1 ALL=(ALL) NOPASSWD:ALL\n

0 commit comments

Comments
 (0)