Build discover_printers for Windows on the Gitea runner

SSDP can only be tried on a machine that shares the printers' network
segment, and the development container is a router hop away. This builds
the existing discover_printers example as a Windows .exe and uploads it as
a CI artifact, with a README for whoever runs it and a SHA-256 file.

Uses the windows-latest self-hosted runner continuum-cad already uses
(Windows PowerShell 5.1, MSVC present, upload-artifact@v3 only). The proxy
links OpenSSL directly and Windows has none, so the job builds it with
vcpkg (x64-windows-static-md, linked into the .exe) in a directory of its
own, away from the CAD pipeline's. The job smoke-runs the exe, then runs
the discovery tests on Windows after the upload, so a Windows-only test
failure turns the job red without withholding the executable.

Not run anywhere yet: this container cannot build for Windows (no MSVC or
mingw). The first CI run is the first real build.
This commit is contained in:
2026-10-29 10:54:07 +00:00
parent e0a6ccd2c1
commit 815131b951
2 changed files with 176 additions and 0 deletions
+145
View File
@@ -0,0 +1,145 @@
# Builds `discover_printers` as a Windows executable, for trying SSDP
# discovery on a machine that shares the printers' network segment (multicast
# does not cross a router, so the development container cannot hear them).
#
# Runs on the `windows-latest` self-hosted runner that continuum-cad's
# pipeline also uses: a host executor running as SYSTEM, Windows PowerShell
# 5.1 (no pwsh), MSVC build tools present. The notes in
# continuum-cad/.gitea/workflows/ci.yml on that machine apply here too.
# Its artifact UPLOAD works (`upload-artifact@v3`); DOWNLOAD does not, which
# is why nothing here downloads one.
#
# A job whose label matches no registered runner is skipped silently, not
# failed - if this never runs, check that the runner is online.
#
# Cargo.lock is not committed in this repo, so this resolves dependencies
# fresh; the artifact is built from whatever versions that picks today.
name: Windows discovery tool
on:
push:
paths:
- "src/**"
- "examples/discover_printers.rs"
- "Cargo.toml"
- ".gitea/workflows/discover-windows.yml"
workflow_dispatch:
env:
CARGO_TERM_COLOR: never
# Outside the runner's deep work directory, and short, for the same MAX_PATH
# reason continuum-cad gives. A directory of its own - not C:\vcpkg or
# C:\ccad-target - so the two pipelines cannot step on each other's state
# on the one machine.
CARGO_TARGET_DIR: 'C:\continuum-proxy-target'
VCPKG_ROOT: 'C:\continuum-vcpkg'
# The same release tag continuum-cad pins, known to exist.
VCPKG_REF: "2026.07.29"
jobs:
windows:
runs-on: windows-latest
defaults:
run:
shell: powershell
timeout-minutes: 90
steps:
- uses: actions/checkout@v4
- name: Install the Rust MSVC toolchain
shell: powershell
run: |
# Genuine no-BOM UTF-8: Windows PowerShell 5.1's `-Encoding utf8`
# writes a BOM, which corrupts the first entry of GITHUB_PATH.
$NoBom = New-Object System.Text.UTF8Encoding $false
function Add-CiPath([string] $Value) {
[System.IO.File]::AppendAllText($env:GITHUB_PATH, "$Value`r`n", $NoBom)
}
if (-not (Get-Command rustup -ErrorAction SilentlyContinue)) {
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -UseBasicParsing -Uri https://win.rustup.rs/x86_64 -OutFile rustup-init.exe
.\rustup-init.exe -y --default-toolchain stable-x86_64-pc-windows-msvc
if ($LASTEXITCODE -ne 0) { throw "rustup-init failed" }
$cargoBin = Join-Path $env:USERPROFILE ".cargo\bin"
if (-not (Test-Path (Join-Path $cargoBin "rustup.exe"))) {
throw "rustup-init reported success but rustup.exe is not in $cargoBin"
}
# GITHUB_PATH only takes effect for later steps; the in-process
# PATH is what the calls just below need.
$env:PATH = "$cargoBin;$env:PATH"
Add-CiPath $cargoBin
}
rustup default stable-x86_64-pc-windows-msvc
if ($LASTEXITCODE -ne 0) { throw "could not select the MSVC toolchain" }
rustc -vV
# The proxy links OpenSSL directly (Ed25519 verification, SHA-256, and
# reading a printer's certificate), and Windows has none. vcpkg builds
# it, fetching its own Perl and NASM. `x64-windows-static-md` links it
# into the .exe, so the tool needs no DLL beside it; openssl-sys finds
# it through VCPKG_ROOT with no further settings.
- name: Build OpenSSL with vcpkg
shell: powershell
run: |
git config --global core.longpaths true
if (-not (Test-Path "$env:VCPKG_ROOT\.git")) {
git clone --depth 1 --branch $env:VCPKG_REF https://github.com/microsoft/vcpkg $env:VCPKG_ROOT
if ($LASTEXITCODE -ne 0) { throw "could not clone vcpkg at $env:VCPKG_REF" }
}
Push-Location $env:VCPKG_ROOT
try {
if (-not (Test-Path .\vcpkg.exe)) {
.\bootstrap-vcpkg.bat -disableMetrics
if ($LASTEXITCODE -ne 0) { throw "bootstrap-vcpkg failed" }
}
.\vcpkg.exe install openssl:x64-windows-static-md
if ($LASTEXITCODE -ne 0) { throw "vcpkg failed to build OpenSSL" }
} finally {
Pop-Location
}
- name: Build discover_printers
shell: powershell
run: |
$env:VCPKGRS_TRIPLET = "x64-windows-static-md"
cargo build --release --example discover_printers
if ($LASTEXITCODE -ne 0) { throw "cargo build failed" }
New-Item -ItemType Directory -Force -Path dist | Out-Null
Copy-Item "$env:CARGO_TARGET_DIR\release\examples\discover_printers.exe" dist\
Copy-Item scripts\discover-windows-README.txt dist\README.txt
# It must run on a machine with nothing installed. No arguments
# prints the usage and exits non-zero, which proves the binary
# loads (no missing DLL) without touching the network.
$ErrorActionPreference = "Continue"
$out = cmd /c "dist\discover_printers.exe 2>&1" | Out-String
if ($out -notmatch "identify") { throw "discover_printers.exe did not print its usage: $out" }
Write-Host "usage text looks right"
# Imports of the .exe, so a DLL that a clean machine lacks shows up
# in the log (the VC++ runtime is the one that commonly does).
if (Get-Command dumpbin -ErrorAction SilentlyContinue) {
& dumpbin /dependents dist\discover_printers.exe | Select-String "\.dll" |
ForEach-Object { Write-Host $_.Line.Trim() }
}
$hash = (Get-FileHash dist\discover_printers.exe -Algorithm SHA256).Hash.ToLower()
Set-Content -Path dist\SHA256.txt -Value "$hash discover_printers.exe" -Encoding ASCII
Write-Host "sha256 $hash"
- name: Upload the executable
uses: actions/upload-artifact@v3
with:
name: continuum-discover-printers-windows
path: dist/*
if-no-files-found: error
# After the upload on purpose: the executable is useful even if a test
# that only breaks on Windows fails, and a red job still says so.
- name: Run the discovery tests on Windows
shell: powershell
run: |
$env:VCPKGRS_TRIPLET = "x64-windows-static-md"
cargo test --lib discovery
if ($LASTEXITCODE -ne 0) { throw "discovery tests failed on Windows" }
+31
View File
@@ -0,0 +1,31 @@
discover_printers.exe - finds Continuum-compatible 3D printers on this network
=============================================================================
Run it from PowerShell, in the folder it is in. It only LISTENS and asks
printers who they are. It sends no passwords or access codes and changes
nothing on any printer.
The test we need (Bambu printers announce themselves over SSDP multicast,
which only works if this PC is on the SAME network segment as the printers -
same Wi-Fi/Ethernet, not through a VPN, not a guest network):
.\discover_printers.exe raw 120 2>&1 | Tee-Object ssdp.txt
That listens for 2 minutes and prints EVERY datagram it hears, then what it
understood. Send back ssdp.txt. "listening for SSDP ... interfaces=[...]"
near the top lists the adapters it joined; the one on the printers' network
should be there.
Other commands:
.\discover_printers.exe listen 30 SSDP only, Bambu printers
.\discover_printers.exe sweep 192.168.0.0/24 probe every address on a subnet
.\discover_printers.exe all 192.168.0.0/24 both, merged
.\discover_printers.exe identify 192.168.0.21 one known address
Windows Firewall will ask whether to allow it on first run. Allow it on
PRIVATE networks; without that, Windows drops the multicast and the result is
"No printers found" even when printers are there.
Check the file is intact: Get-FileHash .\discover_printers.exe -Algorithm SHA256
(compare with SHA256.txt)