Table of Contents

Stable Release Validation

This article documents the reusable release-blocking validation path for stable release lines. The stable package family maintained on main is 7.x, and the current stable release is 7.1.0.

The binary assembly identity for the 7.x line is 7.0.0.0.

Release validation should confirm that the package family remains practical governance infrastructure and that implementation claims stay within the documented software boundary. See Release Cadence and Readiness for the release-stream and stabilization guidance that complements this checklist.

The 7.1.0 Release Readiness Record and the 7.1.0 Consumer Verification Guide record the current release-control evidence. The 7.1.0 Release Notes record the current 7.x minor-release boundary. The Upgrade from 6.x to 7.0 guide is authoritative for consumers moving from the previous stable line. Earlier readiness records are retained for traceability.

Required checks before tagging a stable release

Before cutting a stable release tag, confirm the following checks have passed on the release-candidate commit:

Check Where it runs Release purpose
Release stream classification Release PR, release readiness record Confirms the release is correctly classified as patch, minor, major, or preview.
Version metadata validation stable release validation, package publish Confirms MSBuild version metadata, citation metadata, Zenodo metadata, optional tag metadata, and generated package filenames align.
Debug solution build coverage validation CI, stable release validation, developer checklist Confirms first-party package and test projects remain enabled for default Debug solution builds and that any remaining Debug exclusions are reviewed.
Locked restore CI, stable release validation, package publish Confirms committed lock files match the current package and project dependency graph.
Build CI, stable release validation, package publish Confirms release projects compile in Release configuration.
Public API XML documentation inventory CI, release readiness record Inventories CS1591 gaps for selected public package projects while staged enforcement is phased in.
Stable public API baseline CI, stable release validation, package publish Compares DocFX-derived stable managed package APIs with committed eng/api-baseline files and fails on unreviewed additions, removals, enum-value changes, or signature changes.
Formatting CI, stable release validation, package publish Confirms source formatting is stable before release.
Tests CI, stable release validation, package publish Confirms the solution test suite passes before packaging or publishing.
Dependency vulnerability analysis dependency review, OWASP Dependency-Check Blocks newly introduced dependencies at moderate severity or higher and fails OWASP scans for findings with CVSS 7 or higher unless a reviewed suppression applies.
Package creation CI, stable release validation, package publish Confirms every package project under src, excluding template-content projects, can be packed.
Package version validation stable release validation, package publish Confirms generated package versions and tag identity align with repository version metadata.
NuGet metadata validation stable release validation, package publish Confirms generated .nupkg metadata, README files, IDs, descriptions, tags, license metadata, project URL, repository URL, and repository commit metadata align before publication.
Package metadata asset checklist release readiness record, generated package inspection Confirms package icons, packaged README rendering, NuGet metadata, Source Link metadata, SBOM/provenance artifacts, and documentation links are reviewed.
Package SBOM generation CI, stable release validation, package publish Generates SPDX JSON SBOM files and an SBOM manifest for generated .nupkg artifacts.
Package provenance attestation CI on non-PR events, stable release validation on non-PR events, package publish Attests generated package and SBOM artifacts where supported.
Durable release evidence package publish on stable tags Attaches the attested build packages, package SBOMs, package/hash mappings, exact release notes, and the release-evidence manifest to the public GitHub release, then fails if any required asset or package attestation is absent.
Consumer verification guide README, release notes, release readiness record, docs navigation Confirms consumers have a copy/paste verification path for package source, package IDs, package version, repository metadata, Source Link, SBOM/provenance, and deferred package signing.
NuGet package signing readiness signing decision record, release readiness record, SECURITY.md, release notes Confirms package signing is either governed by a current dated deferral with review criteria or, when available, documented with signing process, verification guidance, and updated public wording before release.
Template package smoke validation CI, stable release validation Confirms the packed AsiBackbone.Templates package can be installed, generate supported host styles, restore, and build.
Documentation build publish docs, stable release validation, package publish Confirms DocFX can build the documentation included in the release posture.
Documentation link review release readiness record, manual docs review Confirms README links, DocFX navigation, release notes, migration guides, package documentation links, and GitHub Pages links point to current pages.
External consumer smoke tests external consumer smoke workflow, stable release validation Confirms clean consumer-style projects can reference and wire the package family.
Source Link metadata validation manual post-publish validation Confirms published NuGet packages include expected repository type, repository URL, and non-empty repository commit metadata.
Security advisory distribution manual post-publish validation Confirms published repository advisories reach the global GitHub Advisory Database or remain explicitly tracked during GitHub's documented review window.

Canonical local release-hardening commands

Use these commands before treating local validation as release evidence:

dotnet restore AsiBackbone.slnx --locked-mode -p:Configuration=Release
dotnet build AsiBackbone.slnx --configuration Release --no-restore
dotnet test --solution AsiBackbone.slnx --configuration Release --no-build --no-restore

The default Debug solution build should include all first-party package and test projects:

dotnet build AsiBackbone.slnx

The reviewed Debug exclusion allowlist is enforced by:

./scripts/Validate-DebugSolutionBuildCoverage.ps1

The stable managed public API baseline is validated from DocFX output:

dotnet tool restore
dotnet tool run docfx -- docs/docfx.json
./scripts/Validate-PublicApiBaseline.ps1

Release-blocking workflows

The following workflows form the reusable gate for stable release candidates:

  • CI validates dependency review for pull requests, Debug solution build coverage, solution restore/build/test, public API XML documentation inventory, the stable public API baseline, formatting, package creation, package SBOM generation, template package smoke validation, coverage output, and CodeQL analysis.
  • External Consumer Smoke Test validates package-consumer wiring through the external consumer and stable package integration smoke scripts.
  • OWASP Dependency-Check software composition analysis restores with the SDK selected by global.json, publishes its reports, and fails when an unsuppressed dependency finding has CVSS 7 or higher.
  • Publish Documentation validates the DocFX build used for the documentation site.
  • Stable Release Validation provides a single release-candidate gate for version metadata, documentation release claims and publication state, Debug solution build coverage, locked restore, build, formatting, tests, DocFX, stable public API baseline validation, package creation, generated package version validation, generated NuGet metadata validation, SBOM generation, template package smoke validation, smoke checks, and provenance handling where supported.
  • Publish AsiBackbone Packages repeats release-critical validation, including the public API baseline and documentation publication state, before package publish. It publishes only from a release tag; branch dispatches are pack-only. For stable tags it then attaches durable release evidence and verifies every required GitHub release asset.

Tagging rule

Do not cut a stable release tag until the release-candidate commit has passed the release-blocking workflows above, or until any intentionally deferred check is documented in the release notes or release readiness record for that release.

If a tag is pushed and package validation fails, do not publish replacement packages by hand. Fix the release candidate, document the reason, and repeat the release process with a corrected tag or clearly documented follow-up plan.

Stable Release Validation workflow

The Stable Release Validation workflow runs on pull requests to main, pushes to main, v*.*.* tags, and manual dispatch.

The workflow validates .NET SDK setup, version metadata, Debug solution build coverage, locked restore, Release build, formatting, tests, tool restore, DocFX, package creation, package versions, NuGet metadata, package SBOM generation, template package smoke validation, external consumer smoke tests, stable package integration smoke tests, and artifact upload. On non-pull-request events, a separate dependent job receives the OIDC and attestation permissions needed to attest the validated package and SBOM artifacts; pull-request validation receives neither permission.

Package publish validation

The package publish workflow performs release-critical validation before publishing packages. It validates version metadata, restores dependencies in locked mode, builds the solution, verifies formatting, runs tests, restores .NET tools, builds DocFX documentation, packs package projects, validates generated package versions and NuGet metadata, generates SBOMs, handles provenance where supported, uploads temporary workflow artifacts, and publishes packages only after validation succeeds. For a stable tag, a dependent least-privilege job downloads the exact attested package and SBOM outputs, copies the published release notes, creates release-evidence-manifest.json, uploads the evidence to the GitHub release, and fails if any expected asset is missing or any released package fails provenance verification.

NuGet metadata validation

Validate-NuGetPackageMetadata.ps1 inspects generated .nupkg files rather than only project files. It validates package ID casing, package version, package descriptions, package tags, license metadata, project URL, repository URL metadata, repository commit metadata when available, README metadata, packaged README presence, package icon metadata, packaged icon presence, and package-specific README wording anchors.

This check catches release-blocking NuGet metadata mistakes before package publication because NuGet package metadata for a published version cannot be overwritten.

Public API XML documentation inventory

Validate-XmlDocumentation.ps1 builds selected public package projects with CS1591 unsuppressed and writes a Markdown inventory to artifacts/xml-docs/cs1591-inventory.md. CI uploads this file as the asi-backbone-cs1591-inventory artifact.

The staged policy is documented in Public API XML Documentation. Existing package projects may carry AsiBackboneSuppressMissingXmlDocs=true as a transitional, project-scoped baseline. New projects should not add that property unless the exception is documented.

Stable public API baseline validation

Validate-PublicApiBaseline.ps1 compares the DocFX-managed reference surface for the stable managed package assemblies with committed baselines under eng/api-baseline/. The gate runs in normal CI, Stable Release Validation, and the package-publish validation path.

The v5.0.0 managed-reference output is the initial 5.x baseline. AsiBackbone.Templates is excluded because it is a content-only dotnet new package without a managed consumer assembly; template smoke tests remain its compatibility guard.

An intentional baseline change must be classified under API Compatibility and SemVer before the baseline is regenerated. After reviewing the failed diff, maintainers may run ./scripts/Validate-PublicApiBaseline.ps1 -Update, inspect git diff -- eng/api-baseline, and commit that reviewable baseline update in the same pull request as the API change. Baseline regeneration by itself does not authorize an additive change in a patch release or a breaking change in a minor release.

Pre-release metadata and asset checklist

For every stable release, the release readiness record should explicitly confirm:

  • package icon source, generated PNG, package inclusion, and small-size rendering are acceptable;
  • packaged README files are present and render acceptably in generated packages;
  • NuGet metadata is correct for package ID, version, description, tags, license, project URL, repository URL, repository type, and repository commit where available;
  • Source Link repository commit metadata is generated and has a post-publish validation plan when NuGet download is required to confirm it;
  • security releases include a post-publication plan to verify repository-advisory ingestion into the global GitHub Advisory Database and to track any advisories still pending curation;
  • package SBOM files and sbom-manifest.json are generated for produced .nupkg artifacts;
  • package and SBOM provenance artifacts are uploaded and attested where the workflow event supports attestation;
  • stable tags expose the package SBOMs, SBOM manifest, release notes, and release-evidence manifest as durable public GitHub release assets rather than only retention-limited workflow artifacts;
  • consumer verification guidance explains package-source, package ID, version, repository metadata, Source Link, SBOM/provenance, and deferred-signing checks without overstating signing or tamper-evidence;
  • public API XML documentation inventory is reviewed, and staged enforcement changes or intentional exceptions are documented;
  • the stable public API baseline matches, or an intentional baseline change is reviewed and classified for its SemVer impact;
  • Debug solution build coverage is reviewed so first-party package/test projects stay enabled for default local solution builds;
  • NuGet package signing status is checked against SECURITY.md and the NuGet Package Signing Decision Record, and release notes/readiness records state whether the dated decision remains current or signing has an adopted process;
  • README, DocFX navigation, release notes, migration notes, package README links, and GitHub Pages links are current;
  • any intentionally deferred metadata, asset, Source Link, SBOM, provenance, package-signing, public API XML documentation, Debug solution build coverage, or documentation-link check is recorded with risk and follow-up.

The Publish Quality Reports workflow runs this check automatically on release: published, resolving the version from the release tag and waiting up to 20 minutes for nuget.org to serve the newly pushed packages. A release whose packages lack the expected Source Link metadata therefore fails a workflow rather than waiting on a manual step.

To validate a version by hand — for example when re-checking an older release — run:

./scripts/Validate-Source-Link-commit-metadata.ps1 -Version 4.0.0

This post-publish check downloads the published packages and confirms the expected repository type, repository URL, and non-empty repository commit metadata are present. Omitting -Version validates the version declared by Directory.Build.props. The same workflow can be dispatched manually with a package_version input to re-run the check against any published version; leaving that input empty skips it.

Security advisory distribution validation

For a security release, repository-advisory publication is followed by a separate post-publication distribution check. GitHub reviews published repository advisories for the global GitHub Advisory Database and documents that curation can take up to 72 hours.

Use the read-only audit first:

./scripts/Manage-SecurityAdvisoryDistribution.ps1

The script enumerates every published repository advisory, checks whether each GHSA resolves through the global advisory endpoint, and reports whether a CVE request has already been submitted. Missing entries inside the default 72-hour window are warnings. Missing entries after that window fail the audit so the release has a durable follow-up signal instead of silently losing downstream Dependabot or package-feed notification.

If an advisory is still absent after the review window, preview the CVE request path before making a mutation:

./scripts/Manage-SecurityAdvisoryDistribution.ps1 -RequestMissingCves -WhatIf

Then, when a CVE request is appropriate:

./scripts/Manage-SecurityAdvisoryDistribution.ps1 -RequestMissingCves

Requesting a CVE requires an authenticated repository administrator or security manager, or a token with "Repository security advisories" write permission. The script intentionally uses the maintainer's existing gh authentication context instead of introducing a privileged advisory-management token into GitHub Actions. A submitted CVE request is not treated as completed global distribution; rerun the audit until the global advisory endpoint resolves every published GHSA.

NuGet deprecation is a separate notification control. When affected versions need a direct package-registry warning, track and perform that work independently rather than treating global advisory ingestion as a substitute.

Branch retention audit

After a release is tagged and published, confirm that the branch list still matches the committed retention policy:

./scripts/Manage-BranchRetention.ps1

The audit is read-only. It classifies every branch as active, disposable, or unclassified, and it will not report a branch as removable unless the branch is reachable from main or from a release tag that has a published release. A branch holding unique commits is reported as retained with its commit count, so release cleanup cannot silently discard work.

Automatic deletion on merge covers branches that reach main through a pull request, so this audit exists for the remainder: abandoned branches and anything created outside the pull-request path. See Branch Retention Policy for the retention classes, the deletion preconditions, and the apply path.

Deferred checks

If a release-critical check is intentionally deferred, document the deferred check, the reason, the accepted risk, the follow-up issue or milestone, and whether release notes need to mention it.

Deferred checks should be rare for a stable release.

NuGet package signing is currently a known open supply-chain readiness item. Until a reviewed signing process is adopted, release candidates should record the deferral instead of describing artifacts as signed. If package signing is introduced, update SECURITY.md, this validation guide, the release readiness record, release notes, and consumer verification guidance in the same release-preparation PR.