Skip to content

refactor: sonar fixes #368

refactor: sonar fixes

refactor: sonar fixes #368

Workflow file for this run

---
name: CI
permissions: {}
on:
pull_request:
push:
branches:
- master
concurrency:
group: "${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true
env:
CMAKE_BUILD_CONFIG: Debug
DRIVER_BUILD_CONFIG: Release
OPENCPPCOVERAGE_VERSION: '0.9.9.0'
PYTHON_VERSION: '3.14'
jobs:
setup_release:
name: Setup Release
outputs:
publish_release: ${{ steps.setup_release.outputs.publish_release }}
release_body: ${{ steps.setup_release.outputs.release_body }}
release_commit: ${{ steps.setup_release.outputs.release_commit }}
release_generate_release_notes: ${{ steps.setup_release.outputs.release_generate_release_notes }}
release_tag: ${{ steps.setup_release.outputs.release_tag }}
release_version: ${{ steps.setup_release.outputs.release_version }}
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Setup Release
id: setup_release
uses: LizardByte/actions/actions/release_setup@d0ae7f82215a479fe2b74f4088c53ee6460513dd # v2026.728.214955
with:
dotnet: true
github_token: ${{ secrets.GITHUB_TOKEN }}
build:
name: Build (${{ matrix.name }})
needs:
- setup_release
- windows_driver
permissions:
contents: read
runs-on: ${{ matrix.os }}
defaults:
run:
shell: ${{ matrix.shell }}
strategy:
fail-fast: false
matrix:
include:
- name: Linux-GCC
os: ubuntu-latest
shell: bash
kind: unix
cc: gcc
cxx: g++
gcov_executable: gcov
- name: Linux-Clang
os: ubuntu-latest
shell: bash
kind: unix
cc: clang
cxx: clang++
# Clang writes LLVM coverage notes, so gcovr needs llvm-cov's gcov compatibility mode.
gcov_executable: llvm-cov gcov
- name: macOS
os: macos-latest
shell: bash
kind: unix
cc: clang
cxx: clang++
gcov_executable: gcov
- name: Windows-MinGW-UCRT64
os: windows-latest
shell: msys2 {0}
kind: msys2
cc: gcc
cxx: g++
msystem: ucrt64
toolchain: ucrt-x86_64
gcov_executable: gcov
- name: Windows-MSVC
os: windows-2022
shell: pwsh
kind: msvc
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
submodules: recursive
- name: Setup Dependencies Linux
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
clang \
cmake \
libevdev-dev \
libinput-dev \
libsdl2-dev \
libx11-dev \
libxtst-dev \
llvm \
ninja-build \
pkg-config
kernel_modules_package="linux-modules-extra-$(uname -r)"
if apt-cache show "${kernel_modules_package}" >/dev/null 2>&1; then
sudo apt-get install -y "${kernel_modules_package}"
else
echo "::warning::${kernel_modules_package} is unavailable; relying on the runner image kernel modules."
fi
sudo tee /etc/udev/rules.d/99-libvirtualhid-ci.rules >/dev/null <<'EOF'
SUBSYSTEM=="hidraw", KERNEL=="hidraw*", ENV{HID_PHYS}=="libvirtualhid/uhid/*", MODE="0666", TAG+="uaccess"
SUBSYSTEM=="hidraw", KERNEL=="hidraw*", ATTRS{name}=="(libvirtualhid)*", MODE="0666", TAG+="uaccess"
SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="(libvirtualhid)*", MODE="0666", TAG+="uaccess"
SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="libvirtualhid*", MODE="0666", TAG+="uaccess"
EOF
sudo udevadm control --reload-rules
for module in uhid uinput; do
if ! sudo modprobe "${module}"; then
message="Unable to load ${module}; tests requiring /dev/${module}"
message="${message} will fail unless the device already exists."
echo "::warning::${message}"
fi
done
if ! sudo modprobe hid_playstation; then
echo "::warning::Unable to load hid_playstation; SDL HIDAPI will exercise the native hidraw output path."
fi
for node in /dev/uhid /dev/uinput; do
if [[ -e "${node}" ]]; then
sudo chmod a+rw "${node}"
else
echo "::error::${node} does not exist after module setup."
exit 1
fi
done
- name: Setup Dependencies macOS
if: runner.os == 'macOS'
run: |
brew install \
cmake \
ninja
- name: Setup Dependencies Windows MinGW
if: matrix.kind == 'msys2'
uses: msys2/setup-msys2@66cd2cce69caa17b53920067426061ca1de3a884 # v2.32.0
with:
msystem: ${{ matrix.msystem }}
update: true
install: >-
mingw-w64-${{ matrix.toolchain }}-cmake
mingw-w64-${{ matrix.toolchain }}-ninja
mingw-w64-${{ matrix.toolchain }}-toolchain
- name: Setup Dependencies Windows MSVC
if: matrix.kind == 'msvc'
run: |
choco install opencppcoverage --version=${{ env.OPENCPPCOVERAGE_VERSION }} --yes --no-progress
$openCppCoverageDir = "${env:ProgramFiles}\OpenCppCoverage"
if (!(Test-Path (Join-Path $openCppCoverageDir "OpenCppCoverage.exe"))) {
$openCppCoverageDir = "${env:ProgramFiles(x86)}\OpenCppCoverage"
}
if (!(Test-Path (Join-Path $openCppCoverageDir "OpenCppCoverage.exe"))) {
throw "OpenCppCoverage.exe was not found after Chocolatey install."
}
$openCppCoverageDir | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Setup python
id: setup-python
if: matrix.kind != 'msvc'
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Setup uv
if: matrix.kind != 'msvc'
uses: astral-sh/setup-uv@ae62891fec2bb8e7d6c99fc78c9fec3a63790f8d # v10.0.0
with:
enable-cache: true
- name: Sync Python tools
if: matrix.kind != 'msvc'
env:
MSYS2_PATH_TYPE: inherit
UV_PYTHON: ${{ steps.setup-python.outputs.python-path }}
run: |
uv sync --project third-party/lizardbyte-common --locked --only-group test-c \
--no-python-downloads \
--no-install-project
- name: Configure
if: matrix.kind != 'msvc'
env:
BRANCH: ${{ github.head_ref || github.ref_name }}
BUILD_VERSION: ${{ needs.setup_release.outputs.release_version }}
CC: ${{ matrix.cc }}
COMMIT: ${{ needs.setup_release.outputs.release_commit }}
CXX: ${{ matrix.cxx }}
run: |
cmake \
-DBUILD_DOCS=OFF \
-DBUILD_EXAMPLES=ON \
-DBUILD_TESTS=ON \
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_CONFIG} \
-DLIBVIRTUALHID_BUILD_TOOLS=ON \
-B cmake-build-ci \
-G Ninja \
-S .
- name: Configure MSVC
if: matrix.kind == 'msvc'
env:
BRANCH: ${{ github.head_ref || github.ref_name }}
BUILD_VERSION: ${{ needs.setup_release.outputs.release_version }}
COMMIT: ${{ needs.setup_release.outputs.release_commit }}
run: |
cmake `
-DBUILD_DOCS=OFF `
-DBUILD_EXAMPLES=ON `
-DBUILD_TESTS=ON `
-DLIBVIRTUALHID_BUILD_TOOLS=ON `
-A x64 `
-B cmake-build-ci `
-G "Visual Studio 17 2022" `
-S .
- name: Build
run: cmake --build cmake-build-ci --config ${{ env.CMAKE_BUILD_CONFIG }} --parallel 2
- name: Download Windows driver installer artifact
if: runner.os == 'Windows'
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: windows-driver-installer
path: windows-driver-installer
- name: Trust Windows driver catalog signer
if: runner.os == 'Windows'
shell: pwsh
run: |
$certificate = Get-ChildItem `
-LiteralPath .\windows-driver-installer `
-Filter *.cer `
-ErrorAction SilentlyContinue |
Select-Object -First 1
if (!$certificate) {
Write-Host "No separate driver signing certificate artifact was provided."
return
}
$imported = Import-Certificate `
-FilePath $certificate.FullName `
-CertStoreLocation "Cert:\LocalMachine\TrustedPublisher"
foreach ($cert in $imported) {
Write-Host "Trusted driver publisher certificate $($cert.Subject) [$($cert.Thumbprint)]."
}
- name: Install Windows driver installer
if: runner.os == 'Windows'
shell: pwsh
timeout-minutes: 10
run: |
$installer = Get-ChildItem -LiteralPath .\windows-driver-installer -Filter *.msi | Select-Object -First 1
if (!$installer) {
throw "Windows driver installer artifact did not contain an MSI."
}
$logPath = Join-Path $env:RUNNER_TEMP "libvirtualhid-driver-install.log"
$driverLogPath = Join-Path $env:ProgramData "libvirtualhid\install-driver.log"
$setupApiLogPath = Join-Path $env:windir "inf\setupapi.dev.log"
$process = Start-Process `
-FilePath msiexec.exe `
-ArgumentList @("/i", $installer.FullName, "/qn", "/norestart", "/L*v", $logPath) `
-PassThru `
-NoNewWindow
if (!$process.WaitForExit([int] [TimeSpan]::FromMinutes(5).TotalMilliseconds)) {
Get-Content -LiteralPath $logPath -Tail 200 -ErrorAction SilentlyContinue
Get-Content -LiteralPath $driverLogPath -Tail 200 -ErrorAction SilentlyContinue
Get-Content -LiteralPath $setupApiLogPath -Tail 300 -ErrorAction SilentlyContinue
Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue
throw "Windows driver installer timed out after 5 minutes."
}
if ($process.ExitCode -notin @(0, 3010)) {
Get-Content -LiteralPath $logPath -ErrorAction SilentlyContinue
Get-Content -LiteralPath $driverLogPath -ErrorAction SilentlyContinue
Get-Content -LiteralPath $setupApiLogPath -Tail 300 -ErrorAction SilentlyContinue
throw "Windows driver installer exited with code $($process.ExitCode)."
}
- name: Enable GitHub Actions evaluation window
if: runner.os == 'Windows'
shell: pwsh
run: |
$serviceName = "libvirtualhid_broker"
$serviceRegistryPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$serviceName"
New-ItemProperty `
-LiteralPath $serviceRegistryPath `
-Name Environment `
-PropertyType MultiString `
-Value @("GITHUB_ACTIONS=true") `
-Force | Out-Null
Restart-Service -Name $serviceName -Force
(Get-Service -Name $serviceName).WaitForStatus("Running", [TimeSpan]::FromSeconds(15))
- name: Verify Windows test driver package
if: runner.os == 'Windows'
shell: pwsh
run: |
if ("${{ matrix.kind }}" -eq "msys2") {
$env:PATH = "C:\msys64\${{ matrix.msystem }}\bin;C:\msys64\usr\bin;$env:PATH"
$gamepadAdapterPath = "$env:GITHUB_WORKSPACE\cmake-build-ci\examples\gamepad_adapter.exe"
} else {
$gamepadAdapterPath = Join-Path `
"$env:GITHUB_WORKSPACE\cmake-build-ci\examples\$env:CMAKE_BUILD_CONFIG" `
"gamepad_adapter.exe"
}
$profiles = @("generic", "xone", "xseries", "ds4", "ds5", "switch")
foreach ($profile in $profiles) {
.\scripts\windows\test-installed-driver.ps1 `
-GamepadAdapterPath $gamepadAdapterPath `
-Profile $profile `
-Verbose
}
- name: Run gamepad adapter example
run: cmake --build cmake-build-ci --config ${{ env.CMAKE_BUILD_CONFIG }} --target run_gamepad_adapter_example
- name: Prepare report directory
run: cmake -E make_directory cmake-build-ci/reports
- name: Run tests
id: test
if: matrix.kind != 'msvc'
working-directory: cmake-build-ci/tests
run: ./test_libvirtualhid --gtest_color=yes --gtest_output=xml:../reports/junit.xml
- name: Run tests MSVC
id: test_msvc
if: matrix.kind == 'msvc'
run: |
$openCppCoverage = (Get-Command OpenCppCoverage.exe -ErrorAction SilentlyContinue).Source
if (!$openCppCoverage) {
$candidates = @(
"${env:ProgramFiles}\OpenCppCoverage\OpenCppCoverage.exe",
"${env:ProgramFiles(x86)}\OpenCppCoverage\OpenCppCoverage.exe"
)
$openCppCoverage = $candidates | Where-Object { Test-Path $_ } | Select-Object -First 1
}
if (!$openCppCoverage) {
throw "OpenCppCoverage.exe was not found."
}
# The broker test hook compiles a private copy only for failure injection.
& $openCppCoverage `
--sources "$env:GITHUB_WORKSPACE\examples" `
--sources "$env:GITHUB_WORKSPACE\src" `
--sources "$env:GITHUB_WORKSPACE\tools" `
--excluded_sources "$env:GITHUB_WORKSPACE\src\platform\windows\broker" `
"--export_type=cobertura:$env:GITHUB_WORKSPACE\cmake-build-ci\reports\coverage.xml" `
--working_dir "$env:GITHUB_WORKSPACE\cmake-build-ci\tests" `
-- `
"$env:GITHUB_WORKSPACE\cmake-build-ci\tests\$env:CMAKE_BUILD_CONFIG\test_libvirtualhid.exe" `
--gtest_color=yes `
"--gtest_output=xml:$env:GITHUB_WORKSPACE\cmake-build-ci\reports\junit.xml"
- name: Normalize MSVC coverage paths
if: >-
always() &&
matrix.kind == 'msvc' &&
(steps.test_msvc.outcome == 'success' || steps.test_msvc.outcome == 'failure')
run: |
$coveragePath = Join-Path $env:GITHUB_WORKSPACE "cmake-build-ci\reports\coverage.xml"
if (!(Test-Path $coveragePath)) {
return
}
[xml] $coverage = Get-Content $coveragePath
$workspace = $env:GITHUB_WORKSPACE.Replace('\', '/')
foreach ($node in $coverage.SelectNodes('//*[@filename]')) {
$filename = $node.GetAttribute('filename').Replace('\', '/')
if ($filename.StartsWith("${workspace}/")) {
$filename = $filename.Substring($workspace.Length + 1)
}
$node.SetAttribute('filename', $filename)
}
foreach ($source in $coverage.SelectNodes('//source')) {
$source.InnerText = '.'
}
$coverage.Save($coveragePath)
- name: Generate gcov report
id: test_report
if: >-
always() &&
matrix.kind != 'msvc' &&
(steps.test.outcome == 'success' || steps.test.outcome == 'failure')
working-directory: cmake-build-ci
env:
GCOV_EXECUTABLE: ${{ matrix.gcov_executable }}
MSYS2_PATH_TYPE: inherit
run: |
# The broker test hook compiles a private copy only for failure injection.
uv run --project ../third-party/lizardbyte-common --locked --no-sync gcovr . -r .. \
--filter ../examples/ \
--filter ../src/ \
--filter ../tools/ \
--gcov-executable "${GCOV_EXECUTABLE}" \
--exclude ../src/platform/windows/broker/ \
--exclude ../tests/ \
--exclude ../third-party/ \
--exclude-noncode-lines \
--exclude-throw-branches \
--exclude-unreachable-branches \
--verbose \
--xml-pretty \
-o reports/coverage.xml
- name: Uninstall Windows driver installer
if: >-
always() &&
runner.os == 'Windows'
shell: pwsh
run: |
$installer = Get-ChildItem -LiteralPath .\windows-driver-installer `
-Filter *.msi `
-ErrorAction SilentlyContinue |
Select-Object -First 1
if ($installer) {
$logPath = Join-Path $env:RUNNER_TEMP "libvirtualhid-driver-uninstall.log"
$process = Start-Process `
-FilePath msiexec.exe `
-ArgumentList @("/x", $installer.FullName, "/qn", "/norestart", "/L*v", $logPath) `
-PassThru `
-NoNewWindow
if (!$process.WaitForExit([int] [TimeSpan]::FromMinutes(5).TotalMilliseconds)) {
Get-Content -LiteralPath $logPath -Tail 200 -ErrorAction SilentlyContinue
Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue
throw "Windows driver installer uninstall timed out after 5 minutes."
}
if ($process.ExitCode -notin @(0, 3010)) {
Get-Content -LiteralPath $logPath -ErrorAction SilentlyContinue
throw "Windows driver installer uninstall exited with code $($process.ExitCode)."
}
}
- name: Install
run: cmake --install cmake-build-ci --config ${{ env.CMAKE_BUILD_CONFIG }} --prefix cmake-build-ci/install
- name: Upload report artifact
if: >-
always() &&
(
steps.test_report.outcome == 'success' ||
steps.test_msvc.outcome == 'success' ||
steps.test_msvc.outcome == 'failure'
)
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: reports-${{ matrix.name }}
path: cmake-build-ci/reports
if-no-files-found: error
package_consumer:
name: Installed Package Consumer (Linux)
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
submodules: recursive
- name: Install package dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
cmake \
libevdev-dev \
libx11-dev \
libxtst-dev \
ninja-build \
pkg-config
# This intentionally uses a separate BUILD_TESTS=OFF configuration. Test
# builds add lizardbyte-common for test support and therefore cannot prove
# that a normal installed package is independently consumable. Release also
# keeps an optimized GCC library build under warnings-as-errors without
# changing or publishing the ordinary library artifacts.
- name: Configure tests-disabled package
run: |
cmake \
-DBUILD_DOCS=OFF \
-DBUILD_EXAMPLES=OFF \
-DBUILD_TESTS=OFF \
-DCMAKE_BUILD_TYPE:STRING=Release \
-DCMAKE_INSTALL_PREFIX="${GITHUB_WORKSPACE}/cmake-build-package/install" \
-DLIBVIRTUALHID_BUILD_TOOLS=OFF \
-DLIBVIRTUALHID_ENABLE_PACKAGING=OFF \
-B cmake-build-package \
-G Ninja \
-S .
- name: Build and install package
run: |
cmake --build cmake-build-package --parallel 2
cmake --install cmake-build-package
test ! -d cmake-build-package/install/lib/cmake/lizardbyte-common
# A separate CMake project and real symbol reference force find_package,
# imported-target generation, compilation, and the final static-library link.
- name: Configure, compile, and link downstream consumer
run: |
cmake \
-DCMAKE_FIND_USE_PACKAGE_REGISTRY=OFF \
-DCMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY=OFF \
-DCMAKE_PREFIX_PATH="${GITHUB_WORKSPACE}/cmake-build-package/install" \
-B cmake-build-package-consumer \
-G Ninja \
-S tests/package-consumer
cmake --build cmake-build-package-consumer --parallel 2
windows_driver:
name: Windows Driver Installer
needs: setup_release
permissions:
contents: read
runs-on: windows-2022
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
submodules: recursive
- name: Setup dotnet
uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0
with:
dotnet-version: '10.x'
- name: Configure Windows driver package
shell: pwsh
env:
BRANCH: ${{ github.head_ref || github.ref_name }}
BUILD_VERSION: ${{ needs.setup_release.outputs.release_version }}
COMMIT: ${{ needs.setup_release.outputs.release_commit }}
run: |
$certificatePath = Join-Path $env:GITHUB_WORKSPACE "cmake-build-driver\certificates\libvirtualhid-ci-test.cer"
cmake `
-DBUILD_DOCS=OFF `
-DBUILD_EXAMPLES=ON `
-DBUILD_TESTS=OFF `
-DLIBVIRTUALHID_BUILD_WINDOWS_DRIVER=ON `
-DLIBVIRTUALHID_ENABLE_PACKAGING=ON `
"-DLIBVIRTUALHID_DRIVER_TEST_CERTIFICATE=$certificatePath" `
-A x64 `
-B cmake-build-driver `
-G "Visual Studio 17 2022" `
-S .
- name: Build Windows driver package
shell: pwsh
run: >-
cmake --build cmake-build-driver
--config ${{ env.DRIVER_BUILD_CONFIG }}
--target libvirtualhid_windows_catalog libvirtualhid_broker gamepad_adapter virtualhid_control
--parallel 2
- name: Validate Azure signing configuration
if: >-
github.event_name == 'push' &&
needs.setup_release.outputs.publish_release == 'true' &&
vars.AZURE_SIGNING_ACCOUNT == ''
shell: pwsh
run: throw "Release builds must use Azure Trusted Signing for the Windows driver package."
- name: Sign Windows driver package with local test certificate
if: >-
github.event_name == 'pull_request' ||
needs.setup_release.outputs.publish_release != 'true'
shell: pwsh
run: |
$packagePath = Join-Path `
$env:GITHUB_WORKSPACE `
"cmake-build-driver\src\platform\windows\driver\package\$env:DRIVER_BUILD_CONFIG"
$certificatePath = Join-Path `
$env:GITHUB_WORKSPACE `
"cmake-build-driver\certificates\libvirtualhid-ci-test.cer"
.\scripts\windows\sign-driver-package.ps1 `
-PackagePath $packagePath `
-CertificatePath $certificatePath
- name: Locate Windows driver catalog
id: driver_catalog
if: >-
github.event_name == 'push' &&
needs.setup_release.outputs.publish_release == 'true' &&
vars.AZURE_SIGNING_ACCOUNT != ''
shell: pwsh
run: |
$catalogPath = Join-Path `
$env:GITHUB_WORKSPACE `
"cmake-build-driver\src\platform\windows\driver\package\$env:DRIVER_BUILD_CONFIG\libvirtualhid.cat"
"path=$catalogPath" >> $env:GITHUB_OUTPUT
- name: Sign Windows driver package with Azure Trusted Signing
if: >-
github.event_name == 'push' &&
needs.setup_release.outputs.publish_release == 'true' &&
vars.AZURE_SIGNING_ACCOUNT != ''
uses: azure/trusted-signing-action@c7ab2a863ab5f9a846ddb8265964877ef296ee82 # v2.0.0
with:
azure-client-id: ${{ secrets.AZURE_CLIENT_ID }}
azure-client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }}
certificate-profile-name: ${{ vars.AZURE_SIGNING_CERT_PROFILE }}
endpoint: ${{ vars.AZURE_SIGNING_ENDPOINT }}
files: |
${{ steps.driver_catalog.outputs.path }}
signing-account-name: ${{ vars.AZURE_SIGNING_ACCOUNT }}
- name: Package Windows driver installer
shell: pwsh
run: |
Push-Location .\cmake-build-driver
cpack -G WIX -C $env:DRIVER_BUILD_CONFIG
$packageExitCode = $LASTEXITCODE
Pop-Location
if ($packageExitCode -ne 0) {
exit $packageExitCode
}
New-Item -ItemType Directory -Force -Path artifacts | Out-Null
Copy-Item `
-LiteralPath .\cmake-build-driver\cpack_artifacts\libvirtualhid.msi `
-Destination `
".\artifacts\libvirtualhid-Windows-AMD64-driver-installer.msi"
- name: Export Azure driver signing certificate
if: >-
github.event_name == 'push' &&
needs.setup_release.outputs.publish_release == 'true' &&
vars.AZURE_SIGNING_ACCOUNT != ''
shell: pwsh
run: |
$catalogPath = Join-Path `
$env:GITHUB_WORKSPACE `
"cmake-build-driver\src\platform\windows\driver\package\$env:DRIVER_BUILD_CONFIG\libvirtualhid.cat"
$signature = Get-AuthenticodeSignature -FilePath $catalogPath
if ($signature.Status -ne "Valid") {
throw "Azure signed driver catalog is not valid: $($signature.StatusMessage)"
}
if (!$signature.SignerCertificate) {
throw "Azure signed driver catalog did not expose a signer certificate."
}
$certificatePath = Join-Path $env:GITHUB_WORKSPACE "artifacts\libvirtualhid-driver-signing.cer"
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $certificatePath) | Out-Null
Export-Certificate -Cert $signature.SignerCertificate -FilePath $certificatePath -Force | Out-Null
Write-Host (
"Exported Azure driver signing certificate " +
"$($signature.SignerCertificate.Subject) [$($signature.SignerCertificate.Thumbprint)]."
)
- name: Sign Windows driver installer with Azure Trusted Signing
if: >-
github.event_name == 'push' &&
needs.setup_release.outputs.publish_release == 'true' &&
vars.AZURE_SIGNING_ACCOUNT != ''
uses: azure/trusted-signing-action@c7ab2a863ab5f9a846ddb8265964877ef296ee82 # v2.0.0
with:
azure-client-id: ${{ secrets.AZURE_CLIENT_ID }}
azure-client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }}
certificate-profile-name: ${{ vars.AZURE_SIGNING_CERT_PROFILE }}
endpoint: ${{ vars.AZURE_SIGNING_ENDPOINT }}
files-folder: artifacts
files-folder-filter: msi
files-folder-recurse: false
signing-account-name: ${{ vars.AZURE_SIGNING_ACCOUNT }}
- name: Validate release signing identities
if: >-
github.event_name == 'push' &&
needs.setup_release.outputs.publish_release == 'true' &&
vars.AZURE_SIGNING_ACCOUNT != ''
shell: pwsh
run: |
$catalogPath = Join-Path `
$env:GITHUB_WORKSPACE `
"cmake-build-driver\src\platform\windows\driver\package\$env:DRIVER_BUILD_CONFIG\libvirtualhid.cat"
$installerPath = Get-ChildItem -LiteralPath .\artifacts -Filter *.msi |
Select-Object -ExpandProperty FullName -First 1
if (!$installerPath) {
throw "The signed Windows driver installer was not found."
}
$catalogSignature = Get-AuthenticodeSignature -FilePath $catalogPath
$installerSignature = Get-AuthenticodeSignature -FilePath $installerPath
foreach ($signature in @($catalogSignature, $installerSignature)) {
if ($signature.Status -ne "Valid" -or !$signature.SignerCertificate) {
throw "A release signature is invalid: $($signature.StatusMessage)"
}
}
if ($catalogSignature.SignerCertificate.Subject -cne `
$installerSignature.SignerCertificate.Subject) {
throw "The catalog and MSI were signed with different identities."
}
Write-Host (
"Validated release signer " +
"$($installerSignature.SignerCertificate.Subject) " +
"[$($installerSignature.SignerCertificate.Thumbprint)]."
)
- name: Debug wix
if: always()
shell: pwsh
run: |
Get-Content .\cmake-build-driver\cpack_artifacts\_CPack_Packages\win64\WIX\wix.log `
-ErrorAction SilentlyContinue
- name: Upload Windows driver installer artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: windows-driver-installer
path: artifacts
if-no-files-found: error
codecov:
name: Codecov-${{ matrix.flag }}
if: >-
always() &&
(needs.build.result == 'success' || needs.build.result == 'failure') &&
startsWith(github.repository, 'LizardByte/')
needs: build
permissions:
contents: read
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- build_name: Linux-GCC
flag: Linux-GCC
has_coverage: true
- build_name: Linux-Clang
flag: Linux-Clang
has_coverage: true
- build_name: macOS
flag: macOS
has_coverage: true
- build_name: Windows-MinGW-UCRT64
flag: Windows-MinGW-UCRT64
has_coverage: true
- build_name: Windows-MSVC
flag: Windows-MSVC
has_coverage: true
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Download report artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: reports-${{ matrix.build_name }}
path: _reports
- name: Debug coverage file
if: matrix.has_coverage
run: cat _reports/coverage.xml
- name: Upload test coverage
if: matrix.has_coverage
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
with:
disable_search: true
fail_ci_if_error: true
files: ./_reports/coverage.xml
report_type: coverage
flags: ${{ matrix.flag }}
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true
- name: Upload test results
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
with:
disable_search: true
fail_ci_if_error: true
files: ./_reports/junit.xml
report_type: test_results
flags: ${{ matrix.flag }}
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true
release:
name: Release
if: >-
always() &&
needs.setup_release.outputs.publish_release == 'true' &&
needs.build.result == 'success' &&
needs.package_consumer.result == 'success' &&
needs.windows_driver.result == 'success' &&
startsWith(github.repository, 'LizardByte/')
needs:
- build
- package_consumer
- windows_driver
- setup_release
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- name: Download Windows driver installer artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: windows-driver-installer
path: windows-driver-installer
- name: Prepare release artifact
run: |
mkdir -p artifacts
cp windows-driver-installer/*.msi artifacts/
- name: Validate release metadata
env:
RELEASE_COMMIT: ${{ needs.setup_release.outputs.release_commit }}
RELEASE_TAG: ${{ needs.setup_release.outputs.release_tag }}
RELEASE_VERSION: ${{ needs.setup_release.outputs.release_version }}
run: |
test -n "${RELEASE_TAG}"
test -n "${RELEASE_VERSION}"
test "${RELEASE_COMMIT}" = "${GITHUB_SHA}"
test -s "artifacts/libvirtualhid-Windows-AMD64-driver-installer.msi"
- name: Create/Update GitHub Release
if: needs.setup_release.outputs.publish_release == 'true'
uses: LizardByte/actions/actions/release_create@d0ae7f82215a479fe2b74f4088c53ee6460513dd # v2026.728.214955
with:
allowUpdates: false
body: ${{ needs.setup_release.outputs.release_body }}
draft: true
generateReleaseNotes: ${{ needs.setup_release.outputs.release_generate_release_notes }}
name: ${{ needs.setup_release.outputs.release_tag }}
prerelease: true
tag: ${{ needs.setup_release.outputs.release_tag }}
token: ${{ secrets.GH_BOT_TOKEN }}
virustotal_api_key: ${{ secrets.VIRUSTOTAL_API_KEY }}