1. Build & CI

On push to main / develop, .github/workflows/netbuild.yml builds binaries, publishes release assets + documentation, and packs + pushes NuGet packages (osisa.Mikrotik, osisa.OPNSense, and NETSetup dotnet tool) to GitHub Packages (https://nuget.pkg.github.com/osisa). Current deployment passes --skip-all-tests; run required tests separately. CLI entrypoint: src/NETSetup/CLI/NETSetup.cs (Main()), commands under src/NETSetup/CLI/Commands/<Domain>/.

Before build, check NETBASE_GHPAT has push access to Chocolatey repository. Use same token for Chocolatey checkout/push; MASKE_GHPAT remains NETBuild token. Missing cross-repository access must fail before expensive publish work.

Release byte verification remains required. Native NETBuild verifier is replaced by scripts/Verify-ReleaseAssets.ps1, immediately after NETBuild publish. Check every local output/artifacts file against published v<GitVersion_InformationalVersion> release (NOT SemVer - prerelease counter differs): unique asset name, uploaded state, byte size, and GitHub-generated SHA256 digest. Require matching tag and non-draft release. Retry missing metadata/transient API failures within workflow-configured limits; reject hash, size, tag, draft, or duplicate mismatch immediately.

After verification, publish boot assets, build Chocolatey package from same EXE, validate numeric file version against release revision, then push package source to trigger Chocolatey server publish. NixOS ISO publish follows.

Doc site: netbase-build Push --statiq-pages render this control doc with osisa-statiq (pinned in .config/dotnet-tools.json, same as NETCore / NETCommand) → one searchable site with chapters, spec, API reference over :solution: (src/NETSetup.sln) and build info (cmd/API.adoc, cmd/BuildInfo.adoc). Pushed to gh-pages → https://osisa.github.io/NETSetup/ on every deploy. Local preview: dotnet tool restore; dotnet osisa-statiq --repo-root . --control-file NETSetup.adoc --output output/pages.

1.1. Solution structure

Control-document row the serena tool (osisa.Serena via osisa.CodeManagement) read. Solution only visible when row link target = .adoc, link text = .sln. No row → Serena index whole repo, no whitelist.

Table 1. Solution Structure
# Solution Content

1

NETSetup.sln

NETSetup CLI, osisa.Mikrotik, osisa.OPNSense, osisa.OPNSense.Rest, osisa.Inventory, osisa.Virtualization + tests

1.2. Running tests & coverage

  • Prod test filter trap: src/Test.Build.props default to src/local.runsettings (TestCaseFilter: TestCategory!=Prod). Passing --filter "TestCategory=Prod" alone match NOTHING because it ANDs with discovery filter. To run a Prod test, pass --settings src/prod.runsettings --filter "FullyQualifiedName~<Class>.<Method>".

  • Coverage target: >50% line coverage per test project (osisa.OPNSense.Rest.Tests 100%, osisa.Mikrotik.Tests 81.8%, osisa.Inventory.Tests 71.6%, osisa.OPNSense.Tests 70.0%, osisa.Virtualization.Tests 50.3%). Full test sweep details: docs/test-sweep-2026-09-18.adoc.

1.3. Local repo layout (this dev machine)

Upstream osisa repos under c:\_gh\ (NETCore, NETCommand, NETBase, netbase-build, main\netsetup) are consumed via published NuGet packages pinned in src/Directory.Packages.props, never via cross-solution ProjectReference.