|
| 1 | +name: sync winredirect driver |
| 2 | + |
| 3 | +on: |
| 4 | + pull_request: |
| 5 | + branches: |
| 6 | + - main |
| 7 | + - dev |
| 8 | + paths: |
| 9 | + - '.github/scripts/compare_signed_pe.py' |
| 10 | + - '.github/workflows/winredirect-driver-sync.yml' |
| 11 | + - 'internal/winredirect/driver/**' |
| 12 | + |
| 13 | +permissions: |
| 14 | + contents: write |
| 15 | + |
| 16 | +concurrency: |
| 17 | + group: winredirect-driver-${{ github.event.pull_request.head.repo.full_name }}-${{ github.event.pull_request.head.ref }} |
| 18 | + cancel-in-progress: true |
| 19 | + |
| 20 | +jobs: |
| 21 | + sync: |
| 22 | + name: Refresh bundled drivers |
| 23 | + if: github.event.pull_request.head.repo.full_name == github.repository |
| 24 | + runs-on: windows-2025 |
| 25 | + env: |
| 26 | + REPO_DIR: C:\Users\sekai\Projects\sing-tun |
| 27 | + steps: |
| 28 | + - name: Checkout PR head |
| 29 | + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 |
| 30 | + with: |
| 31 | + fetch-depth: 0 |
| 32 | + ref: ${{ github.event.pull_request.head.ref }} |
| 33 | + |
| 34 | + - name: Install Windows SDK and WDK |
| 35 | + shell: pwsh |
| 36 | + run: | |
| 37 | + $sdkHeader = 'C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um\Windows.h' |
| 38 | + $wdkHeader = 'C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\km\ntddk.h' |
| 39 | +
|
| 40 | + if (-not (Test-Path $sdkHeader)) { |
| 41 | + winget install --source winget --exact --id Microsoft.WindowsSDK.10.0.26100 --accept-source-agreements --accept-package-agreements --disable-interactivity --log "$env:RUNNER_TEMP\sdk-install.log" |
| 42 | + Write-Host "Windows SDK install exit code: $LASTEXITCODE" |
| 43 | + } |
| 44 | +
|
| 45 | + if (-not (Test-Path $wdkHeader)) { |
| 46 | + winget install --source winget --exact --id Microsoft.WindowsWDK.10.0.26100 --accept-source-agreements --accept-package-agreements --disable-interactivity --log "$env:RUNNER_TEMP\wdk-install.log" |
| 47 | + Write-Host "WDK install exit code: $LASTEXITCODE" |
| 48 | + } |
| 49 | +
|
| 50 | + if (-not (Test-Path $sdkHeader)) { |
| 51 | + throw "Windows SDK header not found after installation: $sdkHeader" |
| 52 | + } |
| 53 | + if (-not (Test-Path $wdkHeader)) { |
| 54 | + throw "WDK header not found after installation: $wdkHeader" |
| 55 | + } |
| 56 | +
|
| 57 | + - name: Mirror repository to stable Windows path |
| 58 | + shell: pwsh |
| 59 | + run: | |
| 60 | + if (Test-Path $env:REPO_DIR) { |
| 61 | + Remove-Item -LiteralPath $env:REPO_DIR -Recurse -Force |
| 62 | + } |
| 63 | + New-Item -ItemType Directory -Path (Split-Path -Parent $env:REPO_DIR) -Force | Out-Null |
| 64 | + robocopy $env:GITHUB_WORKSPACE $env:REPO_DIR /MIR /NFL /NDL /NJH /NJS /NP |
| 65 | + $robocopyExitCode = $LASTEXITCODE |
| 66 | + if ($robocopyExitCode -gt 7) { |
| 67 | + throw "robocopy failed with exit code $robocopyExitCode" |
| 68 | + } |
| 69 | + Write-Host "robocopy completed with exit code $robocopyExitCode" |
| 70 | + exit 0 |
| 71 | +
|
| 72 | + - name: Build, verify reproducibility, and refresh tracked drivers |
| 73 | + id: sync |
| 74 | + shell: pwsh |
| 75 | + working-directory: ${{ env.REPO_DIR }} |
| 76 | + run: | |
| 77 | + git config --global --add safe.directory $env:REPO_DIR |
| 78 | +
|
| 79 | + $vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe' |
| 80 | + $msbuild = & $vswhere -latest -products * -requires Microsoft.Component.MSBuild -find 'MSBuild\**\Bin\MSBuild.exe' | Select-Object -First 1 |
| 81 | + if (-not $msbuild) { |
| 82 | + throw 'MSBuild.exe not found' |
| 83 | + } |
| 84 | +
|
| 85 | + $env:CL = '/Brepro' |
| 86 | + $env:LINK = '/Brepro' |
| 87 | + $artifactDir = Join-Path $env:RUNNER_TEMP 'winredirect-driver-sync' |
| 88 | + $failureDir = Join-Path $artifactDir 'failure' |
| 89 | + Remove-Item -LiteralPath $artifactDir -Recurse -Force -ErrorAction SilentlyContinue |
| 90 | + New-Item -ItemType Directory -Path $artifactDir -Force | Out-Null |
| 91 | +
|
| 92 | + function Invoke-DriverBuild([string] $platform) { |
| 93 | + Remove-Item -LiteralPath "internal/winredirect/driver/build/$platform" -Recurse -Force -ErrorAction SilentlyContinue |
| 94 | + Remove-Item -LiteralPath "internal/winredirect/driver/intermediate/$platform" -Recurse -Force -ErrorAction SilentlyContinue |
| 95 | + & $msbuild 'internal/winredirect/driver/winredirect.vcxproj' '/t:Rebuild' '/p:Configuration=Release' "/p:Platform=$platform" '/p:SpectreMitigation=false' '/v:minimal' |
| 96 | + if ($LASTEXITCODE -ne 0) { |
| 97 | + throw "MSBuild failed for $platform with exit code $LASTEXITCODE" |
| 98 | + } |
| 99 | + } |
| 100 | +
|
| 101 | + $targets = @( |
| 102 | + @{ platform = 'x64'; repo = 'internal/winredirect/amd64/winredirect.sys' }, |
| 103 | + @{ platform = 'ARM64'; repo = 'internal/winredirect/arm64/winredirect.sys' } |
| 104 | + ) |
| 105 | +
|
| 106 | + Write-Host 'ARM and x86 are intentionally skipped here: WDK 10.0.26100 on GitHub-hosted CI does not support them.' |
| 107 | +
|
| 108 | + $changed = $false |
| 109 | + foreach ($target in $targets) { |
| 110 | + $platform = $target.platform |
| 111 | + $tracked = $target.repo |
| 112 | + $buildOutput = "internal/winredirect/driver/build/$platform/Release/winredirect.sys" |
| 113 | + $run1 = Join-Path $artifactDir "$platform-run1.sys" |
| 114 | + $run2 = Join-Path $artifactDir "$platform-run2.sys" |
| 115 | +
|
| 116 | + Invoke-DriverBuild $platform |
| 117 | + Copy-Item -LiteralPath $buildOutput -Destination $run1 -Force |
| 118 | +
|
| 119 | + Invoke-DriverBuild $platform |
| 120 | + Copy-Item -LiteralPath $buildOutput -Destination $run2 -Force |
| 121 | +
|
| 122 | + & python '.github/scripts/compare_signed_pe.py' $run1 $run2 |
| 123 | + switch ($LASTEXITCODE) { |
| 124 | + 0 { |
| 125 | + Write-Host "$platform reproduced after stripping Authenticode data." |
| 126 | + } |
| 127 | + 1 { |
| 128 | + New-Item -ItemType Directory -Path $failureDir -Force | Out-Null |
| 129 | + Copy-Item -LiteralPath $run1 -Destination (Join-Path $failureDir "$platform-run1.sys") -Force |
| 130 | + Copy-Item -LiteralPath $run2 -Destination (Join-Path $failureDir "$platform-run2.sys") -Force |
| 131 | + throw "$platform build is not reproducible beyond signing metadata." |
| 132 | + } |
| 133 | + default { |
| 134 | + throw "reproducibility comparison failed for $platform with exit code $LASTEXITCODE" |
| 135 | + } |
| 136 | + } |
| 137 | +
|
| 138 | + & python '.github/scripts/compare_signed_pe.py' $run2 $tracked |
| 139 | + switch ($LASTEXITCODE) { |
| 140 | + 0 { |
| 141 | + Write-Host "$platform matches the tracked driver after stripping Authenticode data." |
| 142 | + } |
| 143 | + 1 { |
| 144 | + Write-Host "$platform differs beyond signing metadata; replacing tracked driver." |
| 145 | + Copy-Item -LiteralPath $run2 -Destination $tracked -Force |
| 146 | + git add -- $tracked |
| 147 | + $changed = $true |
| 148 | + } |
| 149 | + default { |
| 150 | + throw "comparison failed for $platform with exit code $LASTEXITCODE" |
| 151 | + } |
| 152 | + } |
| 153 | + } |
| 154 | +
|
| 155 | + if ($changed) { |
| 156 | + "changed=true" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append |
| 157 | + } else { |
| 158 | + "changed=false" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append |
| 159 | + } |
| 160 | +
|
| 161 | + - name: Upload failed reproducibility artifacts |
| 162 | + if: failure() |
| 163 | + uses: actions/upload-artifact@v4 |
| 164 | + with: |
| 165 | + name: winredirect-repro-failure-${{ github.run_id }}-${{ github.run_attempt }} |
| 166 | + path: ${{ runner.temp }}\winredirect-driver-sync\failure\*.sys |
| 167 | + if-no-files-found: warn |
| 168 | + |
| 169 | + - name: Commit and push refreshed drivers |
| 170 | + if: steps.sync.outputs.changed == 'true' |
| 171 | + shell: pwsh |
| 172 | + working-directory: ${{ env.REPO_DIR }} |
| 173 | + run: | |
| 174 | + git config user.name 'github-actions[bot]' |
| 175 | + git config user.email '41898282+github-actions[bot]@users.noreply.github.com' |
| 176 | +
|
| 177 | + git diff --cached --quiet |
| 178 | + if ($LASTEXITCODE -eq 0) { |
| 179 | + exit 0 |
| 180 | + } |
| 181 | +
|
| 182 | + git commit -m 'winredirect: update bundled drivers' |
| 183 | + git push origin "HEAD:${{ github.event.pull_request.head.ref }}" |
0 commit comments