diff --git a/.gitea/workflows/discover-windows.yml b/.gitea/workflows/discover-windows.yml new file mode 100644 index 0000000..349802e --- /dev/null +++ b/.gitea/workflows/discover-windows.yml @@ -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" } diff --git a/scripts/discover-windows-README.txt b/scripts/discover-windows-README.txt new file mode 100644 index 0000000..577606c --- /dev/null +++ b/scripts/discover-windows-README.txt @@ -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)