name: build-windows on: push: branches: [main, master] workflow_dispatch: inputs: version_suffix: description: "Version suffix (e.g. 'cst', 'beta1'). Empty = vanilla." type: string default: "" env: RUST_VERSION: "1.75" LLVM_VERSION: "15.0.6" # bindgen (pulled in via scrap → libvpx-sys) reads LIBCLANG_PATH; the runner # provisioner installs LLVM here. LLVM_HOME: 'C:\tools\llvm-15.0.6' VCPKG_COMMIT_ID: "120deac3062162151622ca4860575a33844ba10b" jobs: build-x64: name: build-hello-agent-x64 runs-on: [self-hosted, windows-10] timeout-minutes: 90 env: VCPKG_ROOT: C:\vcpkg VCPKG_BINARY_SOURCES: "clear;files,C:\\vcpkg-cache,readwrite" LIBCLANG_PATH: 'C:\tools\llvm-15.0.6\bin' steps: - name: Checkout hello-agent (with vendored rustdesk) uses: actions/checkout@v4 # We vendor the rustdesk source under vendor/rustdesk/ so this # checkout is fully self-contained — no sibling repo, no submodules. - name: Verify host toolchain shell: pwsh run: | $required = 'pwsh','git','bash','python','rustc','cargo','rustup','clang' $missing = @() foreach ($tool in $required) { $cmd = Get-Command $tool -ErrorAction SilentlyContinue if (-not $cmd) { $missing += $tool; continue } $ver = & $tool --version 2>&1 | Select-Object -First 1 Write-Host ("{0,-10} {1} ({2})" -f $tool, $cmd.Source, $ver) } if ($missing.Count -gt 0) { Write-Error ("Missing tools on runner: {0}" -f ($missing -join ', ')) exit 1 } if (-not $env:VCPKG_ROOT -or -not (Test-Path "$env:VCPKG_ROOT\vcpkg.exe")) { Write-Error "VCPKG_ROOT not set or vcpkg.exe missing at $env:VCPKG_ROOT" exit 1 } if (-not (Test-Path "$env:LIBCLANG_PATH\libclang.dll")) { Write-Error "libclang.dll not found at $env:LIBCLANG_PATH" exit 1 } - name: Configure Rust toolchain shell: pwsh run: | rustup toolchain install $env:RUST_VERSION --profile minimal --component rustfmt if ($LASTEXITCODE -ne 0) { throw "rustup toolchain install failed ($LASTEXITCODE)" } rustup default $env:RUST_VERSION if ($LASTEXITCODE -ne 0) { throw "rustup default failed ($LASTEXITCODE)" } rustup target add x86_64-pc-windows-msvc rustc --version cargo --version - name: Configure git safe.directory shell: pwsh run: git config --global --add safe.directory '*' - name: vcpkg install dependencies (x64-windows-static) shell: bash env: VCPKG_DEFAULT_HOST_TRIPLET: x64-windows-static # vcpkg.json sits at vendor/rustdesk/vcpkg.json (alongside the # rustdesk Cargo.toml). Run from there so manifest mode picks it up. run: | mkdir -p /c/vcpkg-cache cd vendor/rustdesk if ! "$VCPKG_ROOT/vcpkg" install \ --triplet x64-windows-static \ --x-install-root="$VCPKG_ROOT/installed"; then find "$VCPKG_ROOT/" -name "*.log" -exec sh -c 'echo "===== {} ====="; cat "{}"' \; exit 1 fi # Build hello-agent. We do NOT pre-build vendor/rustdesk/libs/virtual_display/dylib # the way the upstream rustdesk workflow does. That dylib produces a # standalone `dylib_virtual_display.dll` runtime artifact that the # rustdesk Flutter exe ships side-by-side; hello-agent doesn't bundle # it (no virtual-display feature in v0), and the `virtual_display` # crate that librustdesk *does* link against has no compile-time dep # on the dylib — it loads it by name at runtime if present. # # Pre-building it would also force a second cargo invocation inside # the vendor/rustdesk/ workspace, which has no Cargo.lock of its own # and would re-resolve git deps from HEAD (breaking the tray-icon # 0.21.3 pin we keep at the hello-agent root). - name: Cargo build hello-agent shell: pwsh run: | cargo build --release --bin hello-agent --locked if ($LASTEXITCODE -ne 0) { throw "hello-agent build failed" } if (-not (Test-Path target\release\hello-agent.exe)) { throw "target\release\hello-agent.exe missing after cargo build" } - name: Compute version suffix and stage artifact shell: pwsh run: | $suffix = "${env:VERSION_SUFFIX}" if ($suffix) { $tag = "0.1.0-$suffix" } else { $tag = "0.1.0" } New-Item -ItemType Directory -Force -Path .\SignOutput | Out-Null Copy-Item -Force ` target\release\hello-agent.exe ` ".\SignOutput\hello-agent-$tag-x86_64.exe" Write-Host "staged: SignOutput\hello-agent-$tag-x86_64.exe" env: VERSION_SUFFIX: ${{ inputs.version_suffix }} - name: Report signing status of build artifacts shell: pwsh run: | $artifacts = Get-ChildItem .\SignOutput -Include *.exe -File if (-not $artifacts) { Write-Warning "No artifacts found in SignOutput\" return } $unsigned = @() foreach ($f in $artifacts) { $sig = Get-AuthenticodeSignature -FilePath $f.FullName $size = '{0,8:N0}' -f $f.Length switch ($sig.Status) { 'Valid' { Write-Host ("[ SIGNED ] {0} ({1} bytes) signed by: {2}" -f $f.Name, $size, $sig.SignerCertificate.Subject) } 'NotSigned' { Write-Host ("[UNSIGNED] {0} ({1} bytes)" -f $f.Name, $size) $unsigned += $f.Name } default { Write-Host ("[ {0,-7} ] {1} ({2} bytes) -- {3}" -f $sig.Status, $f.Name, $size, $sig.StatusMessage) $unsigned += $f.Name } } } if ($unsigned.Count -gt 0) { $list = $unsigned -join ', ' Write-Host "::warning title=Unsigned artifacts::$list -- SmartScreen will warn end users. Wire up signing before distributing." } - name: Upload artifacts uses: actions/upload-artifact@v3 with: name: hello-agent-windows-x64-${{ github.sha }} path: SignOutput/hello-agent-*.exe if-no-files-found: error retention-days: 14