Actual Host publish smoke
From an isolated candidate checkout, publish the actual Host and CLI for Linux ARM64 and Windows x64 using the install recipe's self-contained setting. Do not use a checkout that another process is building, and choose a new artifact directory.
task_output=/absolute/fresh/publish-smoke
test ! -e "$task_output" || exit 2
mkdir -p "$task_output"
for rid in linux-arm64 win-x64; do
dotnet publish src/Server/ZB.MOM.WW.OtOpcUa.Host/ZB.MOM.WW.OtOpcUa.Host.csproj \
-c Release -r "$rid" --self-contained true \
-p:PublishSingleFile=false -p:PublishTrimmed=false -m:1 \
-o "$task_output/$rid/host" || exit
dotnet publish src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/ZB.MOM.WW.OtOpcUa.Client.CLI.csproj \
-c Release -r "$rid" --self-contained true \
-p:PublishSingleFile=false -p:PublishTrimmed=false -m:1 \
-o "$task_output/$rid/cli" || exit
done
dotnet publish scripts/validation/opcua-publish-smoke/PublishProbe.csproj \
-c Release -m:1 -o "$task_output/probe" || exit
python3 scripts/validation/opcua-publish-smoke/runtime.py --artifacts "$task_output"
The cached mcr.microsoft.com/dotnet/sdk:10.0.103-noble image must be ARM64 for this
Linux artifact. The SDK image supplies the small probe's framework; the actual
Host and CLI are launched through their published self-contained apphosts. There
is no Native AOT, trimming, or single-file transformation.
The runtime script creates a fresh private state directory, ephemeral keys and
loopback ports. A temporary preparation container seeds the LocalDb cache through
public production registration/cache APIs. The artifact contains an empty driver
configuration, one raw folder, and a real HMAC API key with read/browse/subscribe
grants. No production authentication seam is replaced. The actual Host uses
Cluster:Roles=driver, ConfigSource:Mode=FetchAndCache, an unreachable loopback
central endpoint, and task-only LocalDb, secrets SQLite and GUID PKI paths. Its
single-node Akka seed is local. Every container has --network none; no fleet
endpoint, ConfigDb, existing container, volume, or PKI is used.
One task-owned container runs the actual Host as its entrypoint, stops cleanly, then starts the same executable with the same state and PKI again. Each boot must serve healthy readiness, liveness and active endpoints, admit a trusted Basic256Sha256 SignAndEncrypt API-key client, reject a wrong key, and allow an actual published CLI read of ServerStatus.State with Good quality. The first boot also rejects an untrusted server and an untrusted client. The two certificate thumbprints must match. Both stops must exit zero without an OOM kill. An explicit execution guard requires two boots and all six strict SDK probe cases.
The probe retains its public SDK ApplicationInstance throughout its session and disposes it afterward. Peer autoaccept is false. The CLI's existing configuration sets autoaccept true and has no strict-validation flag, so its successful reads are not counted as strict peer-validation coverage. Its certificate is prepared with its normal application name and URI using public SDK APIs and trusted by the server before startup. A closed-port CLI preflight is an expected nonzero setup check, not a passing connection case.
commands.json, per-case logs, health JSON and summary.json retain actual exits,
results and certificate identity. Secrets are supplied through a mode-0600 task
environment file, never written into recorded arguments, and the file is removed
at the end. Raw process output and this run's appended rolling-file output are
checked for task secrets before redacted copies are saved. Only the captured,
task-labelled container is removed; private bind-mounted state remains local for
inspection and must not be redistributed with release artifacts.
Windows cross-publish and PE/native/dependency inspection can run on macOS. Windows service installation and start/stop remain a separate operator gate on an approved Windows environment. The Wonder-box remote-execution hold still applies: no WinRM, psbridge, or replacement remote-execution channel. This smoke does not complete backend, load, failover, or two-hour soak validation.