Files
UA-.NETStandard/docs/ContainerReferenceServer.md
T
Marc Schier e9313ef957 Only use GitHub action for CI and nightly, establish release-branch-only package publication (#4513)
## Description

Two related changes to how the 2.0 line is built and shipped.

### 1. Release-branch-only package publication

- `master` produces development previews only.
- Stable packages can only be built from a canonical
`release/<major>.<minor>` branch and are promoted manually from the
exact signed candidate artifact.
- Core packages use explicit `major.minor.patch` versions (`2.0.0`,
`2.0.1`, then `2.1.0`); git height never changes a stable package patch.
- XRegistry, WoT Connectivity, Vision, Robotics, Redundancy,
Positioning, OpenUSD, ISA95, AI, DI, the relevant MCP extensions, and
OpenUSD connector tools remain `-preview.N` while following the core
numeric version.
- nuget.org receives only non-`.Debug` package IDs; GitHub Packages
retains the complete signed Release/Debug candidate.
- `docs/ReleaseProcess.md` is a reproducible runbook for developers and
agents, with each step stating its completion evidence.

Promotion is source-bound and byte-checked: `release.yml` checks out
nothing until the candidate SHA is known, and
`assert-published-packages-match.ps1` proves that any version already on
a feed holds *this* candidate's content before `--skip-duplicate` is
allowed to skip it. Canonical release-branch naming is matched
case-sensitively with no leading zeroes, and `version.json`'s
`publicReleaseRefSpec`, both policy helpers and the copy `release.yml`
inlines are pinned to one expression by tests.

### 2. PR CI moved to GitHub-hosted runners

- `.github/workflows/buildandtest.yml` (**CI**) now owns pull-request
validation outright, covering the Windows Debug/Release net48 + net10.0
solution builds and fast tests that only Azure Pipelines ran, alongside
the existing Linux/macOS, all-target and NativeAOT legs. `build-and-test
summary` remains the stable required check name.
- `.github/workflows/nightly.yml` is a new **manual-only**
(`workflow_dispatch`) full-scope workflow covering the Azure nightly
workload: all solutions x seven target profiles x Debug/Release, the
net472/netstandard profiles, Windows + Linux NativeAOT, and the
long-running and durable tiers.
- Shared deterministic discovery/batching lives in
`.github/scripts/get-ci-matrix.ps1` with a local composite action, so
both entry points expand the same workload manifest instead of
duplicating a large embedded script.
- `azure-pipelines.yml` is set to `pr: none`.
- The standalone pump sample image workflow is folded into the
consolidated **Images CI** workflow, which now builds all ten images and
publishes an `images summary` rollup suitable as a required check.

## Related Issues

No related issue provided.

## Checklist

- [ ] I have signed the
[CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf)
and read the
[CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md)
doc.
- [x] I have added tests that prove my fix is effective or that my
feature works and increased code coverage.
- [x] I have added all necessary documentation.
- [x] I have verified that my changes do not introduce (new) build or
analyzer warnings.
- [ ] I ran **all** tests locally using the **UA.slnx** solution against
at least .net **framework** and .net **10**, and all passed.
- [ ] I fixed **all** failing and flaky tests in the CI pipelines and
**all** CodeQL warnings.
- [x] I have addressed **all** PR feedback received.

## Validation

- `Opc.Ua.Tools.Tests` full `net10.0` suite: **959 passed, 1 skipped, 0
failed**.
- Version/package-policy regression subset
(`PackageVersionPolicyTests`): **60 passed, 0 failed**.
- GitHub Actions **CI** run 35719807620: **149/149 jobs green** on
GitHub-hosted runners.
- Canonical release-branch rule verified against the pinned nbgv 3.7.115
by building throwaway branches: `release/2.0`, `release/0.9`,
`release/10.42` -> `PublicRelease=True`; `release/02.0`, `release/2.00`,
`Release/2.0` -> `False`.
- Package identity gate verified against a live nuget.org package:
served packages carry a repository `.signature.p7s`, so equality is
decided on content excluding that part. Re-signing and zip reordering
produce an identical digest; a one-byte content change does not.
- Synthetic Release-only, Debug-only, combined, preview, duplicate,
orphaned-symbol, mismatched-root and accidental-stable-family package
sets exercise the shared validator.
- Stable-release rehearsal in an isolated `release/2.0` clone:
`Opc.Ua.Di` packed as `2.0.0-preview.6` depending on stable Core
`2.0.0`; `Opc.Ua.Di.Client` likewise against stable Client `2.0.0`.
- All workflow YAML, `version.json`, the package-policy PowerShell
scripts and the internal release-runbook anchors parse.

## Known validation limits

- Full `UA.slnx` `net48` and `net10.0` local validation remains blocked
by pre-existing `NETSDK1005` and dependency-version failures in
unmodified fuzz/sample projects; the corresponding checklist items
intentionally stay open.
- The TRX-driven test verdict added for the intermittent at-exit host
stall is proven by `CiTestVerdictTests`; the stall itself has not
recurred since.
- `nightly.yml` has not yet been run against a full-scope Azure run for
tuple-level parity — see below.

## Operational follow-up

This remains a preparation PR targeting `master`. It does **not**
authorize a release.

Release sequence:

1. Merge this PR.
2. Create canonical `release/2.0`, advance `master` to
`2.1.0-preview.{height}`, and open a separate `2.0.0` version PR against
`release/2.0`.
3. Follow
[`docs/ReleaseProcess.md`](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/ReleaseProcess.md)
for candidate dry-run, environment approval, promotion, tag/release
finalization, and next-patch preview setup.

CI migration steps still needing administrator access are tracked in
[`docs/DeveloperGuide.md#migration-status`](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/DeveloperGuide.md#migration-status):
proving `nightly.yml` parity on a trusted SHA with the private fuzz
corpus provisioned, turning off definition 14's service-side PR
override, retiring the Azure full-scope schedules and push trigger, and
retiring the duplicate `azure-pipelines-preview.yml` publisher.

> **Before cutting `release/2.0`:** the `Release` ruleset requires the
Azure context for *every* `refs/heads/release/*`, but a new 2.x branch
inherits `pr: none`, so that context would never report and would block
every PR into the new line. Exclude the new ref from that ruleset, or
add a 2.x ruleset requiring `build-and-test summary`, as part of
creating the branch.

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-09-23 15:47:43 +00:00

5.4 KiB

Container support and remote debugging for Reference Server

Overview

There are multiple options to run the reference server in a Docker container:

  • Latest and release builds from the GitHub container registry here. These builds support only Linux targets.
  • Since this commit the container image has amd64 and arm64 support. The build of the sample has been moved to containers, no more need to install the .NET SDK.
  • Local build without .NET 6.0 SDK on Linux or Windows with Docker Desktop. The target OS is chosen based on the settings in Docker Desktop for Linux or Windows containers.
  • Although with VS 2019 and greater there is built in Container support, so far issues in the UA Reference solution prevent build/startup/connection (under investigation).
  • VS2022 supports native debugging on a Linux distribution with WSL.

Other published sample images

In addition to the reference server (refserver), the Images CI workflow builds and publishes every other sample image — the sample servers, the device-integration pump server, the redundant client and both PubSub samples — to the GitHub container registry (ghcr.io/opcfoundation/uanetstandard/<image>). All are linux/amd64 + linux/arm64, and all are built by that one workflow:

Image Sample application
refserver samples/Reference/ConsoleReferenceServer
ldsserver samples/Lds/ConsoleLdsServer
boilerserver samples/MinimalApi/MinimalBoilerServer
calcserver samples/MinimalApi/MinimalCalcServer
mcpserver tools/Opc.Ua.Mcp
redundantserver samples/Redundancy/RedundantServer
redundantclient samples/Redundancy/RedundantClient
redundantpubsub samples/Redundancy/RedundantPubSub
pubsubclient samples/PubSub/ConsoleReferencePubSubClient
pumpserver samples/DI/PumpDeviceIntegrationServer

Image tags follow the release-branch-only publication model:

  • <image>:latest, :release, and the exact <major>.<minor> / <major>.<minor>.<patch> version tags are updated only from a stable commit on a canonical release/<major>.<minor> branch (see Release process). A build from that branch that is not yet stable (still -preview.N) does not move these tags.
  • <image>:latest-<branch> (for example refserver:latest-master) tracks the most recent development build on that branch. Images CI builds these from master and from release/* branches while they are pre-release.
  • <image>:<version> (for example refserver:2.0.0-preview.6 or refserver:2.0.0) always identifies the exact package version the image was built with, on every branch.

For example: docker pull ghcr.io/opcfoundation/uanetstandard/ldsserver:latest gets the most recently approved stable release; docker pull ghcr.io/opcfoundation/uanetstandard/ldsserver:latest-master gets the most recent development build. Each image has a Dockerfile under its application folder that is built from the repository root as context (for example docker build -f samples/Lds/ConsoleLdsServer/Dockerfile -t opcua-lds-server .).

Building the local containers

  1. Open a command prompt which can execute docker commands.
  2. Navigate to the folder samples/Reference/ConsoleReferenceServer.
  3. Build the docker container by executing the command dockerbuild.cmd.

On Linux,

  1. Open a shell which can execute docker commands.
  2. Navigate to the folder samples/Reference/ConsoleReferenceServer.
  3. Build the docker container by executing the command ./dockerbuild.sh.

Run the reference server container

The following samples run the server in interactive mode, hostname is the same as the host, the certificate store, the log output and the configuration file (see option -s) are mapped to a folder called ./OPC Foundation.

the following defaults are used:

  • the certificate store is mapped to './OPC Foundation/pki'
  • A log file is created in './OPC Foundation/Logs'
  • The shadow configuration file is created in './OPC Foundation/Quickstarts.ReferenceServer.Config.xml'

With the option -s the configuration file is first copied to the root of the mapped folders. In subsequent restarts the shadowed configuration file is used when the server is started and all settings can be changed from the mapped configuration file.

Run the local build of the Docker container

To run the local containers, batch files are provided called dockerrun.bat for Windows and dockerrun.sh for Linux.

Run the prebuilt Docker container hosted on Github

On Windows, open a command prompt and execute the following commands:

docker pull ghcr.io/opcfoundation/uanetstandard/refserver:latest
docker run -it -p 62541:62541 -h %COMPUTERNAME% -v "%CD%/OPC Foundation:/root/.local/share/OPC Foundation" ghcr.io/opcfoundation/uanetstandard/refserver:latest -c -s

On Linux, execute the following commands in a shell:

sudo docker pull ghcr.io/opcfoundation/uanetstandard/refserver:latest
sudo docker run -it -p 62541:62541 -h $HOSTNAME -v "$(pwd)/OPC Foundation:/root/.local/share/OPC Foundation" ghcr.io/opcfoundation/uanetstandard/refserver:latest -c -s

Known limitations and issues

  • VS integrated docker build/debug support is not working with the Solution.