10b898305f
S-1: replace the hand-maintained 5-project unit-tests matrix (which silently dropped Client's 388 tests, Analyzers' 31, and every driver + most Core suite) with ONE whole-solution leg — dotnet test ZB.MOM.WW.OtOpcUa.slnx --filter "Category!=E2E&Category!=LiveIntegration". Self-maintaining: a new *.Tests project is covered automatically, matching CLAUDE.md's own guidance. S-2: emit trx + add scripts/ci/assert-not-all-skipped.sh, a fail-on-skip gate that turns 'green CI == everything skipped' into a red build. Wired strict (MIN_EXECUTED=1) on the unit leg; report-only (MIN_EXECUTED=0) on the fixtureless integration leg so its skip tally is VISIBLE without a false red — with a documented follow-up to start the one public-image fixture (opc-plc) as a service and flip it strict. S-4 (paired): the newly-CI'd Client.CLI.Tests had fixed-sleep startup races (await Task.Delay(100/150) before cancelling a background command) that would flake under CI load. Added SubscribeInvoked / SubscribeAlarmsInvoked readiness signals (TaskCompletionSource) to FakeOpcUaClientService and replaced the 11 sleeps across AlarmsCommandTests / SubscribeCommandTests / EventHandlerLifecycleTests with a deterministic await-the-signal (10s timeout guard). Verified: workflow YAML parses; skip-gate proven locally on a real trx (executed=31 => OK), a synthetic all-skipped trx (executed=0 => exit 1 with diagnostic), report-only mode (never fails), multi-file sum, and missing-file (exit 2); Client.CLI.Tests 104/104 green after the deflake. (CI job execution itself is verifiable only on push — nothing pushed.)
107 lines
4.4 KiB
YAML
107 lines
4.4 KiB
YAML
# CI for the v2 branch — runs on every push + PR to the v2-akka-fuse / master
|
|
# branches. Layered into three jobs:
|
|
# build dotnet restore + build (fast feedback on compile errors)
|
|
# unit-tests the WHOLE solution minus the env-gated tiers (self-maintaining)
|
|
# integration 2-node Host.IntegrationTests harness + OpcUaServer.IntegrationTests
|
|
#
|
|
# Skips E2E (Category=E2E) — that runs nightly via v2-e2e.yml against the full
|
|
# four-node docker-dev stack — and LiveIntegration (needs a real gateway/PLC/VPN).
|
|
#
|
|
# Compatible with both GitHub Actions and Gitea Actions (act_runner). The .NET 10
|
|
# SDK is pinned via global.json at the repo root; if no global.json exists, the
|
|
# setup-dotnet step falls back to dotnet-version below.
|
|
|
|
name: v2-ci
|
|
|
|
on:
|
|
push:
|
|
branches: [v2-akka-fuse, master]
|
|
pull_request:
|
|
branches: [v2-akka-fuse, master]
|
|
workflow_dispatch: {}
|
|
|
|
env:
|
|
DOTNET_NOLOGO: "1"
|
|
DOTNET_CLI_TELEMETRY_OPTOUT: "1"
|
|
|
|
jobs:
|
|
|
|
build:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-dotnet@v4
|
|
with:
|
|
dotnet-version: 10.0.x
|
|
- name: dotnet restore
|
|
run: dotnet restore ZB.MOM.WW.OtOpcUa.slnx
|
|
- name: dotnet build
|
|
run: dotnet build ZB.MOM.WW.OtOpcUa.slnx --no-restore --configuration Release
|
|
|
|
unit-tests:
|
|
needs: build
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-dotnet@v4
|
|
with:
|
|
dotnet-version: 10.0.x
|
|
- name: dotnet restore
|
|
run: dotnet restore ZB.MOM.WW.OtOpcUa.slnx
|
|
# 07/S-1: ONE whole-solution leg instead of a hand-maintained 5-project matrix that
|
|
# silently dropped Client (388 tests), Analyzers (31), and every driver + most Core suite.
|
|
# Self-maintaining — a new *.Tests project is covered automatically, no matrix to widen —
|
|
# and matches CLAUDE.md's own `dotnet test ZB.MOM.WW.OtOpcUa.slnx` guidance. Excludes only
|
|
# the env-gated tiers: E2E (nightly, needs the docker-dev fleet) and LiveIntegration (needs
|
|
# a real gateway/PLC/VPN). The skip-gated *.IntegrationTests Assert.Skip when their fixtures
|
|
# are unreachable, so they run harmlessly here (and are counted by the skip-gate below).
|
|
- name: dotnet test (whole solution, minus E2E + LiveIntegration)
|
|
run: >
|
|
dotnet test ZB.MOM.WW.OtOpcUa.slnx --configuration Release --no-restore
|
|
--filter "Category!=E2E&Category!=LiveIntegration"
|
|
--logger "trx" --results-directory artifacts/trx
|
|
# 07/S-2 fail-on-skip: a whole-solution run that executed ZERO tests is a masked outage
|
|
# (bad filter, broken discovery), not a pass — fail loudly. Runs even on test failure so
|
|
# the diagnostic is always emitted.
|
|
- name: assert not-all-skipped
|
|
if: always()
|
|
run: bash scripts/ci/assert-not-all-skipped.sh artifacts/trx/*.trx
|
|
- name: upload trx
|
|
if: always()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: unit-trx
|
|
path: artifacts/trx/*.trx
|
|
if-no-files-found: warn
|
|
|
|
integration:
|
|
needs: build
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
project:
|
|
- tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests
|
|
- tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-dotnet@v4
|
|
with:
|
|
dotnet-version: 10.0.x
|
|
- name: dotnet test ${{ matrix.project }}
|
|
run: >
|
|
dotnet test ${{ matrix.project }} --configuration Release
|
|
--filter "Category!=E2E&Category!=LiveIntegration"
|
|
--logger "trx" --results-directory artifacts/trx
|
|
# 07/S-2: this leg has NO fixtures on a hosted runner, so its tests legitimately Assert.Skip.
|
|
# Report-only (MIN_EXECUTED=0 never fails) so the skip tally is VISIBLE in the log instead of
|
|
# a silent green. FOLLOW-UP (S-2 option #2): start the one public-image fixture as a workflow
|
|
# `services:` block (mcr.microsoft.com/iotedge/opc-plc; the modbus/S7/AB/FOCAS sims are
|
|
# locally-built `otopcua-*` images not pullable here) + set OPCUA_SIM_ENDPOINT, then flip this
|
|
# leg to MIN_EXECUTED=1 so a fixture outage turns the job red.
|
|
- name: report skips (integration has no hosted fixtures yet)
|
|
if: always()
|
|
env:
|
|
MIN_EXECUTED: "0"
|
|
run: bash scripts/ci/assert-not-all-skipped.sh artifacts/trx/*.trx
|