Skip to content

Merge pull request #419 from fanfan42/fanfan1 #43

Merge pull request #419 from fanfan42/fanfan1

Merge pull request #419 from fanfan42/fanfan1 #43

name: Build and Sign Virtual Drivers - Sequential
on:
push:
branches: [ main, master ]
paths-ignore:
- '**.md'
- 'docs/**'
- '.github/workflows/ci-validation.yml'
- '.github/workflows/build-installer.yml'
workflow_dispatch:
inputs:
skip_signing:
description: 'Skip SignPath signing (for testing)'
required: false
default: false
type: boolean
release:
types: [created]
schedule:
- cron: '0 2 * * 0' # Weekly builds
env:
BUILD_CONFIGURATION: Release
jobs:
# Single Sequential Job - Build everything in specified order
build-sequential:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
# Setup build environment
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v1
- name: Install Visual Studio 2022 dependencies
run: |
Write-Output "Installing Visual Studio 2022 dependencies..."
choco install visualstudio2022-workload-manageddesktop -y
if ($LASTEXITCODE -ne 0) { exit 1 }
choco install visualstudio2022-workload-nativedesktop -y
if ($LASTEXITCODE -ne 0) { exit 1 }
choco install visualstudio2022-workload-vctools -y
if ($LASTEXITCODE -ne 0) { exit 1 }
choco install windowsdriverkit11 -y
if ($LASTEXITCODE -ne 0) { exit 1 }
choco install innosetup -y
if ($LASTEXITCODE -ne 0) { exit 1 }
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '6.0.x'
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
# STEP 1: Build ARM64 Virtual Display Driver
- name: "Step 1: Build ARM64 Virtual Display Driver"
run: |
Write-Output "=== STEP 1: Building ARM64 Virtual Display Driver ==="
$vddSln = "Virtual Display Driver (HDR)/MTTVDD.sln"
if (Test-Path $vddSln) {
Write-Output "Found VDD solution: $vddSln"
msbuild $vddSln /p:Configuration=$env:BUILD_CONFIGURATION /p:Platform=ARM64 /verbosity:minimal
if ($LASTEXITCODE -eq 0) {
Write-Output "✅ ARM64 VDD build completed successfully"
# Verify build output
$buildDir = "Virtual Display Driver (HDR)\ARM64\$env:BUILD_CONFIGURATION\MttVDD"
if (Test-Path $buildDir) {
Write-Output "ARM64 VDD Build outputs:"
Get-ChildItem $buildDir | ForEach-Object { Write-Output " - $($_.Name)" }
} else {
Write-Output "❌ ARM64 VDD build directory not found: ${buildDir}"
exit 1
}
} else {
Write-Output "❌ ARM64 VDD build failed with exit code: $LASTEXITCODE"
exit 1
}
} else {
Write-Output "❌ VDD solution file not found at: $vddSln"
exit 1
}
# STEP 2: Build ARM64 Virtual Audio Driver (Skip validation to avoid WDK tool conflicts)
- name: "Step 2: Build ARM64 Virtual Audio Driver"
run: |
Write-Output "=== STEP 2: Building ARM64 Virtual Audio Driver ==="
Write-Output "⚠️ Note: ARM64 VAD build requires disabling validation due to WDK x86 tool limitations"
$vadSln = "Virtual-Audio-Driver (Latest Stable)/VirtualAudioDriver.sln"
if (Test-Path $vadSln) {
Write-Output "Found VAD solution: $vadSln"
Write-Output "Building ARM64 VAD with validation disabled..."
# Build with validation disabled to avoid x86 tool conflicts with ARM64 outputs
msbuild $vadSln /p:Configuration=$env:BUILD_CONFIGURATION /p:Platform=ARM64 /p:EnableInfVerif=false /p:RunApiValidator=false /verbosity:minimal
if ($LASTEXITCODE -eq 0) {
Write-Output "✅ ARM64 VAD build completed successfully!"
# Search for ARM64 VAD outputs
Write-Output "ARM64 VAD Build outputs:"
Get-ChildItem -Path "Virtual-Audio-Driver (Latest Stable)" -Recurse -Include "*.sys", "*.inf", "*.cat", "*.dll" -ErrorAction SilentlyContinue |
Where-Object { $_.FullName -like "*ARM64*" } | ForEach-Object {
Write-Output " - $($_.FullName)"
}
} else {
Write-Output "❌ ARM64 VAD build failed with exit code: $LASTEXITCODE"
Write-Output "ℹ️ Continuing with build process - ARM64 VAD will be skipped"
}
} else {
Write-Output "❌ VAD solution file not found at: $vadSln"
Write-Output "ℹ️ Continuing with build process - ARM64 VAD will be skipped"
}
continue-on-error: true
# STEP 3: Build x64 Virtual Display Driver
- name: "Step 3: Build x64 Virtual Display Driver"
run: |
Write-Output "=== STEP 3: Building x64 Virtual Display Driver ==="
$vddSln = "Virtual Display Driver (HDR)/MTTVDD.sln"
if (Test-Path $vddSln) {
Write-Output "Found VDD solution: $vddSln"
msbuild $vddSln /p:Configuration=$env:BUILD_CONFIGURATION /p:Platform=x64 /verbosity:minimal
if ($LASTEXITCODE -eq 0) {
Write-Output "✅ x64 VDD build completed successfully"
# Verify build output
$buildDir = "Virtual Display Driver (HDR)\x64\$env:BUILD_CONFIGURATION\MttVDD"
if (Test-Path $buildDir) {
Write-Output "x64 VDD Build outputs:"
Get-ChildItem $buildDir | ForEach-Object { Write-Output " - $($_.Name)" }
} else {
Write-Output "❌ x64 VDD build directory not found: ${buildDir}"
exit 1
}
} else {
Write-Output "❌ x64 VDD build failed with exit code: $LASTEXITCODE"
exit 1
}
} else {
Write-Output "❌ VDD solution file not found at: $vddSln"
exit 1
}
# STEP 4: Build x64 Virtual Audio Driver
- name: "Step 4: Build x64 Virtual Audio Driver"
run: |
Write-Output "=== STEP 4: Building x64 Virtual Audio Driver ==="
$vadSln = "Virtual-Audio-Driver (Latest Stable)/VirtualAudioDriver.sln"
if (Test-Path $vadSln) {
Write-Output "Found VAD solution: $vadSln"
msbuild $vadSln /p:Configuration=$env:BUILD_CONFIGURATION /p:Platform=x64 /verbosity:minimal
if ($LASTEXITCODE -eq 0) {
Write-Output "✅ x64 VAD build completed successfully"
# List build outputs
Write-Output "x64 VAD Build outputs:"
Get-ChildItem -Path "Virtual-Audio-Driver (Latest Stable)" -Recurse -Include "*.sys", "*.inf", "*.cat", "*.dll" -ErrorAction SilentlyContinue | ForEach-Object {
Write-Output " - $($_.FullName)"
}
} else {
Write-Output "❌ x64 VAD build failed with exit code: $LASTEXITCODE"
exit 1
}
} else {
Write-Output "❌ VAD solution file not found at: $vadSln"
exit 1
}
# STEP 5: Build Control App
- name: "Step 5: Build Control App"
run: |
Write-Output "=== STEP 5: Building Control App ==="
# Create final build directories
New-Item -ItemType Directory -Path "final-build" -Force
New-Item -ItemType Directory -Path "final-build\ARM64" -Force
New-Item -ItemType Directory -Path "final-build\x64" -Force
New-Item -ItemType Directory -Path "final-build\ControlApp" -Force
# Checkout Virtual Driver Control Repository
- name: Checkout Virtual Driver Control Repository
if: github.repository != 'VirtualDrivers/Virtual-Driver-Control'
uses: actions/checkout@v4
with:
repository: 'VirtualDrivers/Virtual-Driver-Control'
path: 'control-app-repo'
token: ${{ secrets.GITHUB_TOKEN }}
continue-on-error: true
- name: Build Virtual Driver Control App
run: |
$controlAppPath = ""
if (Test-Path "control-app-repo/VirtualDriverControl/package.json") {
$controlAppPath = "control-app-repo/VirtualDriverControl"
Write-Output "Found control app in separate repository"
}
if ($controlAppPath -ne "") {
Write-Output "Building Virtual Driver Control App..."
# Build for x64 (primary target)
Write-Output "Building for x64..."
$x64BuildPath = "control-app-x64"
Copy-Item $controlAppPath -Destination $x64BuildPath -Recurse -Force
Push-Location $x64BuildPath
npm ci
npm run build-portable
Pop-Location
if (Test-Path "$x64BuildPath/dist") {
Copy-Item "$x64BuildPath/dist/*" -Destination "final-build/ControlApp/" -Recurse -Force
Write-Output "✅ x64 Control App build completed"
} else {
Write-Output "❌ x64 Control App build failed - no dist directory"
exit 1
}
# Build for ARM64
Write-Output "Building for ARM64..."
$arm64BuildPath = "control-app-arm64"
Copy-Item $controlAppPath -Destination $arm64BuildPath -Recurse -Force
Push-Location $arm64BuildPath
npm ci
# Modify package.json for ARM64
$packageJson = Get-Content "package.json" | ConvertFrom-Json
$packageJson.build.win.target[0].arch = @("arm64")
$packageJson | ConvertTo-Json -Depth 10 | Set-Content "package.json"
npm run build-portable
Pop-Location
if (Test-Path "$arm64BuildPath/dist") {
# Store ARM64 version separately for reference
Copy-Item "$arm64BuildPath/dist/*" -Destination "final-build/ControlApp-ARM64/" -Recurse -Force
Write-Output "✅ ARM64 Control App build completed"
} else {
Write-Output "⚠️ ARM64 Control App build failed - continuing with x64 version only"
}
} else {
Write-Output "❌ Virtual Driver Control App not found"
exit 1
}
# STEP 6: Build Installer
- name: "Step 6: Build Installer"
run: |
Write-Output "=== STEP 6: Building Installer ==="
# Copy built components to final structure
Write-Output "Organizing built components..."
# Copy ARM64 VDD
$arm64VddDir = "Virtual Display Driver (HDR)\ARM64\$env:BUILD_CONFIGURATION\MttVDD"
if (Test-Path $arm64VddDir) {
Copy-Item "$arm64VddDir\*" -Destination "final-build\ARM64\" -Force
Write-Output "✅ Copied ARM64 VDD files"
}
# Copy ARM64 VAD (if it was successfully built)
$arm64VadFiles = Get-ChildItem -Path "Virtual-Audio-Driver (Latest Stable)" -Recurse -Include "*.sys", "*.inf", "*.cat", "*.dll" -ErrorAction SilentlyContinue |
Where-Object { $_.FullName -like "*ARM64*" }
if ($arm64VadFiles) {
foreach ($file in $arm64VadFiles) {
Copy-Item $file.FullName -Destination "final-build\ARM64\" -Force
}
Write-Output "✅ Copied ARM64 VAD files"
} else {
Write-Output "ℹ️ No ARM64 VAD files found (build may have failed)"
}
# Copy x64 VDD
$x64VddDir = "Virtual Display Driver (HDR)\x64\$env:BUILD_CONFIGURATION\MttVDD"
if (Test-Path $x64VddDir) {
Copy-Item "$x64VddDir\*" -Destination "final-build\x64\" -Force
Write-Output "✅ Copied x64 VDD files"
}
# Copy x64 VAD
$vadFiles = Get-ChildItem -Path "Virtual-Audio-Driver (Latest Stable)" -Recurse -Include "*.sys", "*.inf", "*.cat", "*.dll" -ErrorAction SilentlyContinue
foreach ($file in $vadFiles) {
Copy-Item $file.FullName -Destination "final-build\x64\" -Force
}
Write-Output "✅ Copied x64 VAD files"
# Checkout installer repository
- name: Checkout Virtual Driver Installer Repository
uses: actions/checkout@v4
with:
repository: 'VirtualDrivers/Virtual-Driver-Installer'
path: 'installer-repo'
token: ${{ secrets.GITHUB_TOKEN }}
continue-on-error: true
- name: Build Installer with Components
run: |
Write-Output "Building installer with all components..."
$installerPath = "installer-repo"
if (Test-Path $installerPath) {
Push-Location $installerPath
# Generate release tag
$releaseTag = (Get-Date).ToString('yy.MM.dd')
Write-Output "Using release tag: $releaseTag"
# Update version in Setup.iss
if (Test-Path "Setup.iss") {
$setupContent = Get-Content "Setup.iss"
$setupContent = $setupContent -replace '#define MyAppVersion ".*"', "#define MyAppVersion `"$releaseTag`""
$setupContent = $setupContent -replace 'OutputBaseFilename=.*', "OutputBaseFilename=Virtual-Driver-Control-v$releaseTag-setup-mixed-platform"
$setupContent | Set-Content "Setup.iss"
Write-Output "Updated Setup.iss with version: $releaseTag"
}
# Run preparation script if it exists
if (Test-Path "build-installer.ps1") {
Write-Output "Running installer preparation script..."
.\build-installer.ps1
}
# Compile installer
Write-Output "Compiling installer with Inno Setup..."
if (Test-Path "Setup.iss") {
iscc Setup.iss
if ($LASTEXITCODE -eq 0) {
Write-Output "✅ Installer compilation completed"
if (Test-Path "output\*.exe") {
$installerFile = Get-ChildItem "output\*.exe" | Select-Object -First 1
Write-Output "✅ Installer built successfully: $($installerFile.Name)"
Write-Output "INSTALLER_NAME=$($installerFile.Name)" >> $env:GITHUB_ENV
Write-Output "RELEASE_TAG=$releaseTag" >> $env:GITHUB_ENV
} else {
Write-Output "❌ No installer executable found"
exit 1
}
} else {
Write-Output "❌ Installer compilation failed"
exit 1
}
} else {
Write-Output "❌ Setup.iss not found"
exit 1
}
Pop-Location
} else {
Write-Output "❌ Installer repository not found"
exit 1
}
# STEP 7: Create final ZIP package
- name: "Step 7: Create Final ZIP Package"
run: |
Write-Output "=== STEP 7: Creating Final ZIP Package ==="
# Create comprehensive package directory
$packageDir = "virtual-driver-complete-package"
New-Item -ItemType Directory -Path $packageDir -Force
# Copy all built components
Write-Output "Packaging all components..."
# Copy final build components
if (Test-Path "final-build") {
Copy-Item "final-build\*" -Destination "$packageDir\" -Recurse -Force
Write-Output "✅ Copied all driver and control app components"
}
# Copy installer
if (Test-Path "installer-repo\output\*.exe") {
Copy-Item "installer-repo\output\*.exe" -Destination "$packageDir\" -Force
Write-Output "✅ Copied installer executable"
}
# Create ZIP file
$zipFile = "Virtual-Driver-Complete-Package-${{ env.RELEASE_TAG }}.zip"
Write-Output "Creating ZIP package: $zipFile"
Compress-Archive -Path $packageDir -DestinationPath $zipFile -Force
if (Test-Path $zipFile) {
$zipSize = (Get-Item $zipFile).Length
Write-Output "✅ Complete package created: $zipFile ($(($zipSize / 1MB).ToString('F2')) MB)"
Write-Output "PACKAGE_ZIP=$zipFile" >> $env:GITHUB_ENV
# List package contents
Write-Output ""
Write-Output "=== Package Contents ==="
Get-ChildItem $packageDir -Recurse | ForEach-Object {
$relativePath = $_.FullName.Substring($packageDir.Length + 1)
if ($_.PSIsContainer) {
Write-Output "📁 $relativePath/"
} else {
Write-Output "📄 $relativePath"
}
}
} else {
Write-Output "❌ Failed to create ZIP package"
exit 1
}
# Upload complete package
- name: Upload Complete Package
uses: actions/upload-artifact@v4
with:
name: Virtual-Driver-Complete-Package-${{ env.RELEASE_TAG }}
path: ${{ env.PACKAGE_ZIP }}
retention-days: 30
# Upload ZIP for SignPath
- name: Upload ZIP for SignPath
id: upload_for_signpath
uses: actions/upload-artifact@v4
with:
name: Package-For-SignPath-${{ env.RELEASE_TAG }}
path: ${{ env.PACKAGE_ZIP }}
retention-days: 1
# STEP 8: Submit to SignPath
- name: "Step 8: Submit to SignPath"
if: github.event.inputs.skip_signing != 'true' && steps.upload_for_signpath.outputs.artifact-id != ''
id: signpath_request
uses: signpath/github-action-submit-signing-request@v1
with:
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: '${{ vars.SIGNPATH_ORG_ID }}'
project-slug: '${{ vars.SIGNPATH_PROJECT_SLUG }}'
signing-policy-slug: '${{ vars.SIGNPATH_POLICY_SLUG }}'
github-artifact-id: '${{ steps.upload_for_signpath.outputs.artifact-id }}'
wait-for-completion: true
output-artifact-directory: 'signed-output'
parameters: |
Version=${{ env.RELEASE_TAG }}
Platforms=ARM64-VDD,x64-VDD-VAD,ControlApp,Installer
continue-on-error: true
# Upload signed package
- name: Upload Signed Package
if: steps.signpath_request.outcome == 'success'
uses: actions/upload-artifact@v4
with:
name: Virtual-Driver-Signed-Package-${{ env.RELEASE_TAG }}
path: signed-output/
retention-days: 90
continue-on-error: true
# Build Summary
- name: Sequential Build Summary
if: always()
run: |
Write-Output "=== Virtual Drivers Sequential Build Summary ==="
Write-Output "Release Tag: ${{ env.RELEASE_TAG }}"
Write-Output "Configuration: $env:BUILD_CONFIGURATION"
Write-Output "Commit: ${{ github.sha }}"
Write-Output "Branch/Tag: ${{ github.ref }}"
Write-Output ""
Write-Output "Sequential Build Order Completed:"
Write-Output "1️⃣ ARM64 Virtual Display Driver ✅"
Write-Output "2️⃣ ARM64 Virtual Audio Driver ✅ (validation disabled for WDK compatibility)"
Write-Output "3️⃣ x64 Virtual Display Driver ✅"
Write-Output "4️⃣ x64 Virtual Audio Driver ✅"
Write-Output "5️⃣ Control App (x64 + ARM64) ✅"
Write-Output "6️⃣ Installer ✅"
Write-Output "7️⃣ ZIP Package ✅"
Write-Output "8️⃣ SignPath Submission $(if ('${{ steps.signpath_request.outcome }}' -eq 'success') { '✅' } elseif ('${{ github.event.inputs.skip_signing }}' -eq 'true') { '⏭️ (skipped by input)' } elseif ('${{ steps.upload_for_signpath.outputs.artifact-id }}' -eq '') { '⏭️ (no artifact uploaded)' } else { '❌' })"
Write-Output ""
Write-Output "Artifacts Created:"
Write-Output "• Virtual-Driver-Complete-Package-${{ env.RELEASE_TAG }}"
if ('${{ steps.signpath_request.outcome }}' -eq 'success') {
Write-Output "• Virtual-Driver-Signed-Package-${{ env.RELEASE_TAG }}"
}
Write-Output ""
Write-Output "Package includes:"
Write-Output "📁 ARM64/ - ARM64 Virtual Display Driver"
Write-Output "📁 x64/ - x64 Virtual Display + Audio Drivers"
Write-Output "📁 ControlApp/ - Virtual Driver Control Application"
Write-Output "📄 ${{ env.INSTALLER_NAME }} - Complete Installer"