name: Run tests on: [push, pull_request] permissions: contents: read jobs: build-linux-km: name: Linux kernel module strategy: fail-fast: false matrix: distro: - {name: "alpine", tag: "3.23", variant: "-lts", image_prefix: "docker.io/library/"} - {name: "alpine", tag: "3.22", variant: "-lts", image_prefix: "docker.io/library/"} - {name: "alpine", tag: "3.21", variant: "-lts", image_prefix: "docker.io/library/"} - {name: "alpine", tag: "3.20", variant: "-lts", image_prefix: "docker.io/library/"} # - {name: "archlinux", tag: "latest", image_prefix: "docker.io/library/"} - {name: "archlinux", tag: "latest", variant: "-lts", image_prefix: "docker.io/library/"} # - {name: "archlinux", tag: "latest", variant: "-zen", image_prefix: "docker.io/library/"} # - {name: "archlinux", tag: "base", image_prefix: "docker.io/library/"} - {name: "centos", tag: "stream9", image_prefix: "quay.io/centos/"} - {name: "debian", tag: "12", image_prefix: "docker.io/library/"} - {name: "debian", tag: "12-slim", image_prefix: "docker.io/library/"} - {name: "debian", tag: "11", image_prefix: "docker.io/library/"} - {name: "ubuntu", tag: "24.04", image_prefix: "docker.io/library/"} - {name: "ubuntu", tag: "22.04", image_prefix: "docker.io/library/"} runs-on: ubuntu-22.04 container: image: docker://${{ matrix.distro.image_prefix }}${{ matrix.distro.name }}:${{ matrix.distro.tag }} steps: - name: Harden Runner uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false - name: Install Alpine dependencies if: matrix.distro.name == 'alpine' run: | apk --no-cache --update add linux${{ matrix.distro.variant }} linux${{ matrix.distro.variant }}-dev nasm # DKMS is not yet packaged in Alpine apk --no-cache --update add bash gcc git make git clone --depth=1 --branch=v3.0.5 https://github.com/dell/dkms /opt/dkms make -C /opt/dkms install - name: Install Arch Linux dependencies if: matrix.distro.name == 'archlinux' run: | pacman -Syu --noconfirm dkms linux${{ matrix.distro.variant }}-headers nasm - name: Install CentOS dependencies if: matrix.distro.name == 'centos' run: | if [ "${{ matrix.distro.tag }}" = stream9 ] ; then dnf install -y --enablerepo=crb kernel kernel-devel nasm dnf install -y elfutils-libelf-devel gcc git make fi # DKMS is not longer packaged in CentOS Stream if ! command -v dkms > /dev/null 2>&1 ; then git clone --depth=1 --branch=v3.0.5 https://github.com/dell/dkms /opt/dkms make -C /opt/dkms install fi - name: Install Debian dependencies if: matrix.distro.name == 'debian' run: | apt-get update -q apt-get install -qqy dkms nasm - name: Install Ubuntu dependencies if: matrix.distro.name == 'ubuntu' run: | apt-get update -q apt-get install -qqy dkms linux-headers-generic nasm - name: Compute packaged kernel version id: versions run: | KERNEL_VER='' if [ "${{ matrix.distro.name }}" = alpine ] ; then # Parse "lib/modules/5.15.53-0-lts/build" KERNEL_VER="$(apk info --contents "linux${{ matrix.distro.variant }}-dev" | sed -n 's:^lib/modules/\([^/][^/]*\)/.*:\1:p' | head -n 1)" elif [ "${{ matrix.distro.name }}" = archlinux ] ; then # Parse "/usr/lib/modules/5.18.0-arch1-1/build/" KERNEL_VER="$(pacman -Qql "linux${{ matrix.distro.variant }}-headers" | sed -n 's:^/usr/lib/modules/\([^/]\+\)/.*:\1:p' | head -n 1)" elif [ "${{ matrix.distro.name }}" = centos ] ; then # Parse "Source RPM : kernel-3.10.0-1160.71.1.el7.src.rpm" KERNEL_VER="$(LANG=C rpm -qi kernel-devel | sed -n 's/^Source RPM *: kernel-\(.*\).src.rpm$/\1.x86_64/p' | tail -n 1)" elif [ "${{ matrix.distro.name }}" = debian ] ; then # Parse "Depends: linux-headers-5.10.0-15-amd64 (= 5.10.120-1)" KERNEL_VER="$(LANG=C dpkg --status linux-headers-amd64 | sed -n 's/^Depends: linux-headers-\(\S*\)\( .*\)\?$/\1/p' | head -n 1)" elif [ "${{ matrix.distro.name }}" = ubuntu ] ; then # Parse "Depends: linux-headers-5.15.0-40-generic" KERNEL_VER="$(LANG=C dpkg --status linux-headers-generic | sed -n 's/^Depends: linux-headers-\(\S*\)\( .*\)\?$/\1/p' | head -n 1)" fi if [ -z "${KERNEL_VER}" ] ; then echo >&2 "Error: no kernel package found" exit 1 fi echo "Found packaged kernel ${KERNEL_VER}" echo "KERNEL_VER=${KERNEL_VER}" >> "$GITHUB_ENV" CHIPSEC_MODULE_VER="$(cat chipsec/VERSION)" echo "CHIPSEC_MODULE_VER=${CHIPSEC_MODULE_VER}" >> "$GITHUB_ENV" echo "kernel=${KERNEL_VER}" >> "$GITHUB_OUTPUT" echo "chipsec=${CHIPSEC_MODULE_VER}" >> "$GITHUB_OUTPUT" echo "uname_m=$(uname -m)" >> "$GITHUB_OUTPUT" - name: Build Linux driver with DKMS for ${{ steps.versions.outputs.kernel }} run: | echo "Building chipsec ${CHIPSEC_MODULE_VER} for Linux kernel ${KERNEL_VER}" dkms add drivers/linux dkms install -m chipsec -v "${CHIPSEC_MODULE_VER}" -k "${KERNEL_VER}" - name: Show dkms status run: dkms status - name: Print log if failure if: failure() run: | KERNEL_VER="$(uname -r)" CHIPSEC_MODULE_VER="$(cat chipsec/VERSION)" echo "Printing log for chipsec ${CHIPSEC_MODULE_VER} on Linux kernel ${KERNEL_VER}" cat "/var/lib/dkms/chipsec/${CHIPSEC_MODULE_VER}/build/make.log" dkms status dkms status -m chipsec -v "${CHIPSEC_MODULE_VER}" -k "${KERNEL_VER}" sudo dkms status -m chipsec -v "${CHIPSEC_MODULE_VER}" -k "${KERNEL_VER}" --logfile - name: Show modinfo on the kernel module id: modinfo run: | MODULE="$(ls -1 "/var/lib/dkms/chipsec/${CHIPSEC_MODULE_VER}/${KERNEL_VER}/$(uname -m)/module/chipsec.ko"* | head -n1)" echo "module_path=${MODULE}" >> "$GITHUB_OUTPUT" modinfo "${MODULE}" - name: Upload Linux driver from ${{ steps.modinfo.outputs.module_path }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: chipsec-${{ steps.versions.outputs.chipsec }}.${{ matrix.distro.name }}-${{ matrix.distro.tag }}${{ matrix.distro.variant }}-${{ steps.versions.outputs.kernel }}.${{ steps.versions.outputs.uname_m }} path: ${{ steps.modinfo.outputs.module_path }} if-no-files-found: error windows_driver: name: Windows driver matrix strategy: fail-fast: false matrix: versions: # - {window: "2025", python: "3.13"} # - {window: "2025", python: "3.11"} # - {window: "2025", python: "3.10"} # - {window: "2025", python: "3.9"} # - {window: "2025", python: "3.8"} - {window: "2022", python: "3.13"} - {window: "2022", python: "3.11"} - {window: "2022", python: "3.10"} - {window: "2022", python: "3.9"} - {window: "2022", python: "3.8"} runs-on: windows-${{ matrix.versions.window }} steps: - name: Harden Runner uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false - name: Set up Python ${{ matrix.versions.python }} uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: ${{ matrix.versions.python }} - name: Install dependencies shell: bash run: | pip install -r windows_requirements.txt pip install pytest - name: Build Windows driver shell: bash run: python setup.py build_ext -i - name: Upload Windows Main driver uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: chipsec_drivers_windows_x64_py${{ matrix.versions.python }}_win${{ matrix.versions.window }} path: drivers/windows/chipsec/x64 if-no-files-found: error - name: Upload Windows PCI Filter driver uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: pcifilter_drivers_windows_x64_py${{ matrix.versions.python }}_win${{ matrix.versions.window }} path: drivers/windows/pcifilter/x64 if-no-files-found: error - name: Run Python unit tests shell: bash run: python -m unittest - name: Run Python pytest shell: bash run: python -m pytest tests - name: Run xml cfg checker shell: bash run: | python tests/cfg_checker.py ubuntu-test: name: Test on Ubuntu matrix strategy: fail-fast: false matrix: versions: - {ubuntu: "24.04", python: "3.13"} - {ubuntu: "24.04", python: "3.11"} - {ubuntu: "24.04", python: "3.10"} - {ubuntu: "24.04", python: "3.9"} - {ubuntu: "24.04", python: "3.8"} - {ubuntu: "22.04", python: "3.13"} - {ubuntu: "22.04", python: "3.11"} - {ubuntu: "22.04", python: "3.10"} - {ubuntu: "22.04", python: "3.9"} - {ubuntu: "22.04", python: "3.8"} runs-on: ubuntu-${{ matrix.versions.ubuntu }} steps: - name: Harden Runner uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - name: Set up Python ${{ matrix.versions.python }} uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: ${{ matrix.versions.python }} - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false - name: Patch chipsec_main to return true even when some module failed run: | sed 's/^ return modules_failed$/ return 0/' -i chipsec_main.py - name: Install dependencies run: | sudo apt-get update -qy sudo apt-get install -qqy dkms nasm python3-setuptools pip install distro pytest pytest-cov pip install --upgrade packaging pip install -r linux_requirements.txt pip uninstall -y importlib_metadata pip install importlib_metadata --force-reinstall - name: Show Python version run: | python -m pip list python --version - name: Build the driver with Python run: python setup.py build_ext -i - name: Build the driver with DKMS run: | KERNEL_VER="$(uname -r)" CHIPSEC_MODULE_VER="$(cat chipsec/VERSION)" echo "Building chipsec ${CHIPSEC_MODULE_VER} for Linux kernel ${KERNEL_VER}" sudo dkms add drivers/linux sudo dkms install -m chipsec -v "${CHIPSEC_MODULE_VER}" -k "${KERNEL_VER}" - name: Run Python unit tests run: python -m unittest - name: Get coverage requirement run: | CODE_COVERAGE_REQ=$(curl https://raw.githubusercontent.com/chipsec/chipsec/refs/heads/main-cfg/codeCoverageRequirement2.cfg) #if var is not a number, set it to 100 if ! [[ "$CODE_COVERAGE_REQ" =~ ^[0-9]{1,3}\.?[0-9]{0,2}$ ]]; then CODE_COVERAGE_REQ=100 echo "Retrieved CODE_COVERAGE_REQ is not a number, setting to 100." fi echo "CODE_COVERAGE_REQ=${CODE_COVERAGE_REQ}" echo "CODE_COVERAGE_REQ=$CODE_COVERAGE_REQ" >> $GITHUB_ENV - name: Run Python pytest run: | python -m pytest --cov . --cov-report=term-missing --cov-fail-under="${COV_REQ}" env: COV_REQ: ${{ env.CODE_COVERAGE_REQ }} - name: Run xml cfg checker run: | python tests/cfg_checker.py python tests/xml_validator.py - name: pylint pilot for modules folder run: | pylint chipsec/modules - name: Install chipsec run: | python setup.py install - name: Run chipsec_main test run: | PYTHONEXE="$(which python)" CHIPSECEXIT="$($(sudo ${PYTHONEXE} chipsec_main.py -p PMC_I440FX 1>&2); echo $?)" if echo "0 1 2 4 8" | grep -qw $CHIPSECEXIT; then $(exit 0); else $(exit $CHIPSECEXIT); fi