Overview
Azure SDK for .NET is a large multi-service repository. Its contributor, test, API-compatibility,
code-generation, live-resource, and release paths are not one runnable surface.
The Ota contract therefore owns one useful contributor slice and names it plainly:
- restore the dependencies for
sdk/core/Azure.Corethrough the repository'sNuGet.Config; - build that library with
--no-restore; - execute the same sequence in native mode and in a fresh .NET SDK container.
That is enough to pressure a real boundary without pretending that a green build means the Azure
SDK repository, its services, or its releases are ready.
The Contract
The repository owns package-source policy. Ota owns the typed restore operation that consumes it:
tasks:
setup:
prepare:
kind: dependency_hydration
medium: package_dependencies
source:
kind: dotnet_restore
cwd: sdk/core/Azure.Core/src
config_file: ../../../../NuGet.Config
The later build is deliberately no-restore:
tasks:
build:
depends_on: [setup]
command:
exe: dotnet
args: [build, --no-restore, --framework, net10.0]
cwd: sdk/core/Azure.Core/src
This makes the boundary testable. If restore state does not reach the build, --no-restore fails
instead of silently going back to the network.
Ephemeral Container Cache Ownership
The selected container context is ephemeral, so restore and build do not share a long-lived
container. The contract declares the NuGet cache as Ota-managed attachment state:
execution:
contexts:
dotnet:container:
backend: container
lifecycle: ephemeral
container:
image: mcr.microsoft.com/dotnet/sdk:10.0.103
attachments:
isolated_paths:
- .nuget/packages
Ota derives NUGET_PACKAGES for the selected context and carries that cache across the restore and
later no-restore build containers. The repo does not need to duplicate a host cache path or a
Docker volume name in a helper script.
Azure SDK exposed two Ota corrections while this was pressure-tested:
- command tasks must mount the contract root, then apply
command.cwdinside it, because restore writes shared intermediates under the repositoryartifacts/tree; - typed
dotnet_restoremust carry the resolved NuGet package cache into later ephemeral tasks, not merely report that restore exited successfully.
Those are runner ownership fixes. They are not Azure-specific workflow glue.
.NET Version Truth
The contract follows global.json, which requests 10.0.103 with rollForward: feature:
toolchains:
dotnet:
version: ">=10.0.103, <10.1.0"
That admits valid servicing releases in the same feature band. An exact patch equality would turn
the repository's declared roll-forward policy into a false readiness failure.
Released Matrix
The requalification matrix installs Ota from the contract as released v1.6.25, verifies the
binary version before any Ota command runs, and pins all GitHub Actions by immutable revision.
The released four-lane matrix
is green. Every lane recorded ota v1.6.25 (source, commit a3e9f98f3) before running Ota.
It covers:
-
validate, Doctor, task/workflow discovery, and safe/unsafe task-surface discovery; - task and workflow dry-runs on Ubuntu, macOS, Windows, and Ubuntu container mode;
- real restore, no-restore build, and declared workflow execution in each advertised mode;
- retained version, diagnosis, contract snapshot, and archived workflow receipt artifacts on every result.
The receipts agree on one contract snapshot:
sha256:f7a96703141dc4e6cbb9626e0f893f4692d781db48113ac639c18770d972134b.
The Ubuntu container receipt records dotnet:container with ephemeral lifecycle; the other three
receipts record the native context. A historical matrix that installed an implementation branch is
not evidence for this release claim.
What It Does Not Prove
This is selected-lane evidence only. It does not prove:
- every Azure SDK client library, test suite, API-compatibility check, generator, or release build;
- Azure credentials, live-resource tests, external package-feed availability, or service behavior;
- application correctness, package publication, or repository-wide readiness;
- container execution on macOS or Windows, where those lanes exercise native contract execution;
- hermetic replay or a contract-pinned expected identity for the SDK image tag.
The last point is an intentional limitation to keep visible: this contract records the configured
SDK image tag, not an immutable image digest. A mutable tag is not a maintainer-declared immutable
input, so this is not a claim of a pinned container base.
Why This Matters
The useful result is not that Ota can invoke dotnet restore.
It is that the contract declares dependency intent once, while the runner owns the workspace and
cache continuity needed to make a later no-restore build meaningful across fresh containers. The
result remains narrow, inspectable, and honest about the much larger Azure SDK surface it does not
govern.
Links
- Upstream repository: Azure/azure-sdk-for-net
- Pressure contract: Azure SDK
ota.yaml - Pressure matrix: Azure SDK Ota contract matrix
- Released Ota evidence: green Azure SDK matrix run
Originally Posted: https://ota.run/blog/pressure-testing-ota-on-azure-sdk-for-net-3v9q
Top comments (0)