JsonSerializerOptions Options { get; }
Source
Gets indented camel-case JSON options.
Mutable YAML sidecar metadata for release-note documentation pages.
Sidecars are dictionary-backed so unknown fields are preserved. The committed release artifact remains in the prepared state; only a tag-bound resolver creates the transient tagged projection used by docs and publishing.
Task<ReleaseSidecar> LoadAsync(string path, CancellationToken cancellationToken)
Source
Loads sidecar metadata from YAML.
pathSidecar path. Expected content is a YAML mapping at the document root.cancellationTokenCancellation token honored during file I/O.Loaded sidecar whose unknown keys are preserved for later serialization.
The current release flow expects the unreleased sidecar to contain documentation keys such as title, summary, page_type, nav_group, order, breadcrumbs, and trust. Missing keys are tolerated because ToPreparedRelease writes the release-owned fields. Malformed YAML is wrapped in ReleaseToolException with release-sidecar-invalid; I/O and cancellation failures bubble to the shared command diagnostic layer.
string ToPreparedRelease(SemVer version, DateOnly date)
Source
Converts unreleased metadata into a committed prepared-release sidecar.
versionPrepared release version.datePreparation date.Prepared release sidecar YAML using underscored key naming for generated CLR-backed values.
This method mutates the loaded dictionary before serializing. It replaces release-owned metadata with provisional prepared-release values and preserves unrelated keys from the source sidecar. The result deliberately makes no tag-derived or GitHub Release existence claim.
ReleaseSidecar Parse(string content, string source)
Source
Parses a sidecar YAML payload that was read from a tag or another explicit source.
contentYAML document content.sourceHuman-readable source identifier used in diagnostics.Parsed release sidecar with unknown fields preserved.
void EnsurePrepared(SemVer version, string source)
Source
Ensures that this sidecar is an explicit prepared artifact for the requested version.
versionRelease version that owns the sidecar.sourceHuman-readable source identifier used in diagnostics.Missing state is treated as a legacy artifact rather than being silently interpreted as prepared. This keeps new release publication deterministic while leaving historical docs and archive reads independent of the new resolver.
string ToTaggedProjection(SemVer version, DateTimeOffset taggerTimestamp, string source)
Source
Creates the transient tagged sidecar projection after a resolver has verified the annotated tag.
versionRelease version that owns the sidecar.taggerTimestampTimestamp recorded in the annotated tag object.sourceHuman-readable source identifier used for prepared-state validation.Rendered tagged sidecar YAML. The caller owns any temporary output path.
This method mutates and consumes the loaded metadata. After projection, the instance declares release.state: tagged and final trust wording, so it no longer passes EnsurePrepared. Parse a fresh ReleaseSidecar for each projection.
string UnreleasedTemplate()
Source
Creates reset unreleased metadata for the next release cycle.
Canonical unreleased sidecar YAML with title, navigation, trust metadata, and source guidance.
The template is complete enough for docs harvesting without requiring the previous sidecar. It intentionally resets release-specific trust metadata back to provisional language.
JSON serializer configuration for release artifacts.
JsonSerializerOptions Options { get; }
Source
Gets indented camel-case JSON options.
Canonical annotated-tag binding for one prepared AppSurface release.
The binding repeats the prepared sidecar and manifest digests alongside the release evidence subject so a maintainer can identify the mismatched artifact directly. It is not a replacement for the checked-in evidence bundle; the resolver validates both sources and uses the tag object as the immutable state-transition record.
string Render()
Source
Renders the exact trailing message block accepted by the resolver.
Canonical four-line trailer block with a trailing newline.
void ParseAndValidate(string tag, string tagObject, ReleaseTagBinding expected)
Source
Parses a Git tag object and validates its final AppSurface release trailer block.
tagAnnotated tag name used in diagnostics.tagObjectRaw output from git cat-file -p.expectedExpected binding computed from tagged artifact bytes.DateTimeOffset ParseTaggerTimestamp(string tag, string tagObject)
Source
Reads the tagger timestamp from a raw annotated Git tag object.
tagAnnotated tag name used in diagnostics.tagObjectRaw output from git cat-file -p.Timestamp and offset recorded by the annotated tagger.
int RequiredKeyCount { get; }
Source
Gets the number of canonical trailers required to bind a tagged release.
Validates release readiness without mutating repository files.
bool FailOnWarningsOption { get; set; }
Source
Gets a value indicating whether check should fail on warning diagnostics.
bool AllowExistingTargetsOption { get; set; }
Source
Gets a value indicating whether check may review already-generated release artifacts.
string? DocsCatalogPath { get; set; }
Source
Gets the AppSurface Docs version catalog used to verify stable release evidence.
check may omit this value to use dist/docs/versions.json when that local review fallback exists. Stable checks that review prepared artifacts should pass the staged catalog explicitly when possible. Relative paths are resolved from the repository root, and invalid or missing catalogs surface release diagnostics rather than mutating release files.
string? DocsTrustedReleaseRootPath { get; set; }
Source
Gets the trusted release root used to resolve catalog exactTreePath values.
When omitted, the verifier uses the catalog directory as the trusted release root. Pass this option when the catalog is staged outside the directory that contains the exact tree paths. The root must be an ordinary directory, and catalog exactTreePath values must stay relative to it without hidden or parent segments.
Generates the coordinated release pull request payload.
Renders canonical annotated-tag trailers from the prepared release artifacts at HEAD.
Inspects a local annotated release tag and renders the validated tagged projection.
string? Tag { get; set; }
Source
Gets the annotated release tag to inspect.
string? BaseRef { get; set; }
Source
Gets the branch that must contain the tag commit.
string? OutputPath { get; set; }
Source
Gets an optional explicit output path for the tagged sidecar projection.
The command validates all tag-bound inputs before writing this path, then opens each parent directory without following links and atomically replaces the output through that retained directory object. The release-publish docs job uses a runner-temporary file and explicitly overlays it only in its disposable detached checkout. The path must resolve outside the repository source tree so inspection cannot overwrite a prepared release artifact.
Validates tag state and emits GitHub Release workflow outputs.
string? Tag { get; set; }
Source
Gets the annotated release tag to publish.
string? GitHubOutputPath { get; set; }
Source
Gets an optional GitHub Actions output file.
string? BaseRef { get; set; }
Source
Gets the branch that must contain the annotated tag commit.
Publish defaults to main. Use this option when a maintained release branch, such as release/0.1.0, owns the tag provenance for a release. The command accepts branch names and branch refs shaped as origin/<branch>, refs/heads/<branch>, or refs/remotes/origin/<branch>, then normalizes them before validation fetches and checks origin/<branch>. Tags, SHAs, empty branch names, and unsupported refs such as refs/tags/v1.2.3 are invalid because publish validation must prove protected branch reachability.
string? DocsCatalogPath { get; set; }
Source
Gets the staged AppSurface Docs version catalog used to verify stable release evidence.
Stable publish accepts this path for local diagnostics, but the public release workflow creates its staged docs artifact through docs-publication. Relative paths are resolved from the repository root. Prerelease publish accepts the option but does not require docs archive proof.
string? DocsTrustedReleaseRootPath { get; set; }
Source
Gets the trusted release root used to resolve catalog exactTreePath values.
When omitted, stable publish resolves exact trees relative to the staged catalog directory. Supply this option when the artifact layout stores versions.json separately from the exact release trees; the path must resolve under the repository root when relative and must point at the ordinary directory that owns the catalog exact-tree paths.
Creates AppSurface Docs publication artifacts for the release publish workflow.
This command is the maintainer-facing CLI seam for the public release docs trust path. It expects docs to have already been exported for the annotated tag commit and produces the deterministic archive, digest ledger, Pages staging payload, catalog entry, publication plan, and recovery summary consumed by release-publish.yml. Use it when the release workflow needs a durable GitHub Release asset and a Pages catalog update from the same tag-bound exact tree. Do not use it to publish arbitrary local docs: the tag must match --version, --docs-exact-tree must be an ordinary exported tree with the release manifest, and --pages-staging-root is deleted before the merged payload is written. Disable --promote-recommended only for a documented recovery or prerelease-style staging run where the current stable recommendation must remain unchanged.
string? Tag { get; set; }
Source
Gets the annotated release tag that owns the docs publication.
This option is required and must be the canonical v{version} tag. A mismatch fails before any staging directory is reset.
string? DocsExactTreePath { get; set; }
Source
Gets the exported docs exact tree for the tag.
The exact tree must be a completed AppSurface Docs export for the tag commit and must contain .appsurface-docs-release-manifest.json. The planner rejects hidden repository-relative paths, generated output paths under this tree, and reparse-point entries so archive bytes come only from ordinary exported files.
string? ExistingPagesRootPath { get; set; }
Source
Gets the optional current Pages payload to copy before adding the immutable release tree.
When supplied, this directory must exist. Use it to preserve existing versions.json, /docs, and prior releases/* content before the new release exact tree is copied into the staging root.
string? ArchiveOutputPath { get; set; }
Source
Gets the tar.gz archive output path.
The command writes this file and a sibling .sha256 file. The path and its temporary .tar sibling must be outside the exact tree so the archive cannot include its own generated bytes.
string? PagesStagingRootPath { get; set; }
Source
Gets the Pages staging root output path.
This directory is destructive scratch space: it is deleted and recreated before existing Pages content and the new releases/{version}/ tree are copied. It must not overlap the repository, exact tree, existing Pages root, archive, publication plan, or recovery summary paths.
string? PlanOutputPath { get; set; }
Source
Gets the publication plan JSON output path.
The plan is the machine-readable artifact handoff between docs archive creation, Pages deployment, public verification, and release promotion. Store it outside the exact tree and staging root.
string? SummaryOutputPath { get; set; }
Source
Gets the optional recovery summary output path.
The summary contains exact resume, publish, and abort commands for partial failures. Store it outside the exact tree and staging root so it cannot be served as release docs content.
string? ExpectedReleaseManifestSha256 { get; set; }
Source
Gets the optional release evidence docs manifest digest that the exact tree must match.
Stable release workflows pass this from tag-bound release evidence. A mismatch means the exported docs tree does not match the reviewed evidence and must be regenerated from the annotated tag commit.
string PromoteRecommendedText { get; set; }
Source
Gets whether stable docs publication should promote the version to recommendedVersion.
Defaults to true. The command rejects values other than true or false. Passing false keeps the existing recommendation and is intended for prereleases or explicit recovery where maintainers do not want to change the stable docs pointer.
string? GitHubOutputPath { get; set; }
Source
Gets an optional GitHub Actions output file.
When supplied, the command appends scalar outputs such as archive name, digest, catalog path, exact tree path, and recovery summary path using GitHub Actions output-file syntax. The option must name a file, not a root directory.
Repository path helper for release-owned files.
Paths are rooted under RepositoryRoot and accept slash-separated repository-relative inputs. PathFor rejects rooted paths and traversal that would escape the repository. Use IsUnderPath when checking paths that come from command-line input, temporary files, or other untrusted sources.
string ReleaseNotePath(SemVer version)
Source
Gets the absolute path for a release note file.
versionRelease version.Absolute release note path.
string ReleaseSidecarPath(SemVer version)
Source
Gets the absolute path for a release note sidecar file.
versionRelease version.Absolute sidecar path.
string ReleaseManifestPath(SemVer version)
Source
Gets the absolute path for a release manifest file.
versionRelease version.Absolute manifest path.
string ReleaseEvidencePath(SemVer version)
Source
Gets the absolute path for a release evidence bundle file.
versionRelease version.Absolute release evidence bundle path.
string PathFor(string relativePath)
Source
Resolves a repository-relative path and verifies that the result stays inside the repository root.
relativePathRepository-relative path using slash separators and no leading root.Absolute path under RepositoryRoot.
ArgumentExceptionThrown when relativePath is rooted or traverses outside the repository.string DisplayPath(string path)
Source
Formats an absolute path as a slash-normalized repository-relative path.
pathAbsolute path.Repository-relative path when possible.
bool IsUnderPath(string root, string path)
Source
Determines whether a path is under the supplied root.
rootRoot path.pathCandidate path.true when the path is equal to or below the root.
string RepositoryRoot { get; }
Source
Gets the absolute repository root.
string ChangelogPath { get; }
Source
Gets the absolute changelog path.
string UnreleasedPath { get; }
Source
Gets the absolute unreleased note path.
string UnreleasedSidecarPath { get; }
Source
Gets the absolute unreleased sidecar path.
string CurrentReleasePath { get; }
Source
Gets the absolute current coordinated release pointer path.
This pointer is overwritten only by release preparation. Once docs are exported, its bytes live inside that exact tree, so the same releases/current.md route stays frozen to the release represented by the tree.
string CurrentReleaseSidecarPath { get; }
Source
Gets the absolute permanent current coordinated release pointer metadata sidecar path.
string PackageIndexPath { get; }
Source
Gets the absolute package index manifest path.
string TemplatePath { get; }
Source
Gets the absolute tagged-release template path.
Creates release artifacts from the living unreleased note.
Task<ReleasePreparationResult> PrepareAsync(ReleaseOptions options, CancellationToken cancellationToken)
Source
Generates release files or, in dry-run mode, returns the planned edits.
optionsRelease command options. Date defaults to the injected clock when omitted.cancellationTokenCancellation token.Preparation result containing readiness diagnostics and planned or written repository-relative paths.
Preparation is a deterministic repository-file rewrite: it runs readiness checks, reads the unreleased note and sidecar, builds versioned release artifacts, refreshes the frozen tree-local current pointer, rolls CHANGELOG.md, resets unreleased files, and records diagnostics in the release manifest. Coordinated package rows are intentionally not rewritten: each docs export freezes the current pointer that was generated for its release. Dry-run mode performs all reads and rendering but does not write files. The method does not create git branches, tags, commits, package artifacts, or GitHub Releases; workflows own those operations. Callers should treat any readiness errors as blocking and should avoid running against a dirty or concurrently modified tree. Writes are sequential rather than transactional. The current pointer is written last, so a partial write cannot advance the visible coordinated alias before the matching versioned artifacts and living-note roll-forward exist. If the local process fails, rerun git status and remove or revert the partial generated artifacts before retrying so create-only target checks do not stop the next run.
Schema-v2 release evidence implementation for frozen coordinated release pointers.
This type deliberately has its own JSON shape and reader. A v2 bundle must never be deserialized as the v1 shape: v1 could silently omit the current-pointer fields that make a versioned documentation tree historically honest.
ReleaseEvidenceBundleV2 RefreshSubject(ReleaseEvidenceBundleV2 bundle)
Source
Recomputes the v2 subject after a maintainer or workflow supplies catalog-bound docs archive fields.
The release-preparation draft intentionally leaves stable docs archive proof unconfigured until the staged exact tree exists. Callers that add that proof must refresh the subject rather than hand-editing its digest.
ReleaseEvidenceBundle ToCompatibilityBundle()
Source
Adapts already-parsed v2 docs archive fields for the existing archive gate; this is not JSON deserialization.
The immutable commit identity included in the V2 evidence subject digest.
The reviewed preparation source is stable release evidence. Later preparation, tag, and workflow identities are intentionally excluded because they are supplied after the preparation artifact set is generated.
string RollForward(string changelog, SemVer version, DateOnly date, string releasePath)
Source
Resets the compact Unreleased ledger and inserts a tagged changelog section after it.
changelogExisting changelog content. Canonical input contains a single ## Unreleased heading.versionRelease version inserted as ## {version} - yyyy-MM-dd.dateRelease date rendered with invariant yyyy-MM-dd formatting.releasePathRepository-relative release note path linked from the new section.Updated changelog content with a reset Unreleased section and the tagged section inserted or appended.
The algorithm is intentionally text-based to preserve surrounding Markdown. The detailed release narrative lives in releases/unreleased.md before preparation and releases/v{version}.md after preparation; the changelog keeps only the durable compact ledger. If ## Unreleased is missing, the canonical compact section is appended before the new tagged section. If the first-release placeholder follows ## Unreleased, that placeholder block is replaced. Duplicate release sections are not de-duplicated; callers should run readiness checks before calling this method. Malformed heading hierarchies and concurrent changelog edits can therefore produce surprising placement, so this helper should only be used on the repository's canonical changelog shape.
Verifies stable release evidence against a staged AppSurface Docs version catalog and exact archive tree.
Runtime docs catalog loading is deliberately lenient so one bad version cannot break unrelated docs. Stable release publishing is the opposite boundary: the selected release version must be present, public, catalog-pinned, and byte verified before the release tool allows the stable GitHub Release path to continue.
Task<ReleaseDocsArchiveGateResult> ValidateStableAsync(ReleaseWorkspace workspace, ReleaseOptions options, ReleaseEvidenceBundle bundle, CancellationToken cancellationToken)
Source
Validates the stable release docs archive contract using command-supplied catalog inputs.
bool TryValidateNoReparseSegments(string rootPath, string candidatePath, out string? detail)
Source
Validates that a physical directory candidate stays below an ordinary trusted root without crossing reparse segments.
rootPathTrusted exact-tree root or trusted release root to contain candidatePath.candidatePathPhysical directory path to validate after canonicalization.detailReceives diagnostic detail when the candidate escapes the root or crosses a symlink, junction, or reparse point.true when the candidate equals or descends from the root and every directory segment is ordinary.
This test seam validates directory ancestors. File leaves still need a separate FileInfo check before hashing or reading bytes so a manifest entry cannot point at a symlinked file inside an otherwise ordinary directory.
bool TryResolveExactTreePath(string trustedReleaseRoot, string exactTreePath, out string? physicalExactTreePath, out string? issue)
Source
Resolves a catalog exactTreePath into a physical path beneath the trusted release root.
trustedReleaseRootCanonical trusted release root that contains staged exact-tree archives.exactTreePathCatalog-authored exact-tree path. It must be relative and must avoid parent or hidden segments.physicalExactTreePathReceives the canonical physical exact-tree path when resolution succeeds; otherwise null unless containment fails after normalization.issueReceives a maintainer-facing reason when the catalog path is empty, rooted, unsafe, escaping, or invalid.true when the authored path can be safely resolved under trustedReleaseRoot.
The trusted root is supplied by release operators or defaults from the catalog directory. Callers should validate the returned directory exists and has no reparse segments before reading archive content.
IReadOnlySet<string> CreatePhysicalManifestPathSet(IEnumerable<string> manifestPaths, StringComparer pathComparer)
Source
Creates the physical-path coverage set for a release manifest under the filesystem's casing rules.
manifestPathsLogical paths recorded by the release manifest.pathComparerComparer matching the physical filesystem's case behavior.A set used to match paths returned by physical archive enumeration.
StringComparer ResolvePhysicalPathComparer(string rootPath, Func<string, bool> fileExists, Func<string, IEnumerable<string>> enumerateFileSystemEntries)
Source
Resolves physical filesystem casing behavior without writing probe files into an immutable archive.
rootPathExisting exact release tree.fileExistsFile existence operation used for the read-only case-variant probe.enumerateFileSystemEntriesFilesystem enumeration used to reject ambiguous case-variant siblings.An ordinal comparer matching the archive root's case behavior.
IDisposable UseFileSystemInspectorForTesting(IFileSystemInspector inspector)
Source
Overrides release docs archive filesystem inspection for the current async test flow.
inspectorInspector used to read filesystem metadata until the returned scope is disposed.A disposable scope that restores the previous inspector.
Production code uses the default physical inspector. Tests use this seam to force deterministic metadata and enumeration failures that operating systems otherwise expose only through race-prone permission or reparse-point behavior.
Reads filesystem metadata used by stable docs archive validation.
The interface is intentionally narrow and internal: callers should not use it to virtualize archive bytes, only metadata operations whose real filesystem failures are difficult to trigger deterministically in tests.
bool DirectoryExists(DirectoryInfo directory)
Source
Returns whether the directory currently exists.
FileAttributes GetDirectoryAttributes(DirectoryInfo directory)
Source
Reads directory attributes, throwing the same filesystem exceptions as FileSystemInfo.Attributes.
FileSystemInfo[] EnumerateFileSystemInfos(DirectoryInfo directory)
Source
Enumerates immediate entries in a directory.
FileAttributes GetFileSystemInfoAttributes(FileSystemInfo entry)
Source
Reads attributes for a file or directory entry discovered during archive traversal.
bool FileExists(FileInfo file)
Source
Returns whether the file currently exists.
FileAttributes GetFileAttributes(FileInfo file)
Source
Reads file attributes, throwing the same filesystem exceptions as FileSystemInfo.Attributes.
Result of stable docs archive verification.
ProofVerification proof when the catalog entry, exact tree, manifest, and serveable files matched; otherwise null.DiagnosticsBlocking diagnostics explaining why stable docs archive verification could not produce proof.Successful results have a non-null proof and no diagnostics. Failure results keep proof null so check and publish callers cannot accidentally treat a partially inspected archive as verified.
Immutable proof that the stable release docs catalog entry and staged exact tree were verified.
StateVerification state written into release reports. Successful verification uses ReleaseDocsArchiveGate.VerifiedState.CatalogPathPhysical path to the staged AppSurface Docs versions.json that supplied the selected catalog entry.TrustedReleaseRootPathCanonical trusted release root used to resolve the catalog exact tree path.CatalogExactTreePathCatalog-authored exact tree path reviewed by maintainers.CatalogReleaseManifestSha256Catalog-pinned release manifest digest that matched the staged manifest bytes.PhysicalExactTreePathCanonical physical exact tree path that was inspected for ordinary directories and verified content.VerifiedFileCountNumber of release manifest entries that were byte-verified.The proof intentionally carries both authored catalog values and resolved physical paths. Maintainers should review the authored values for release identity and the physical values for staging provenance.
Command runner abstraction for git and GitHub CLI calls.
Task<CommandResult> RunAsync(CommandInvocation invocation, CancellationToken cancellationToken)
Source
Runs a process and captures stdout and stderr.
invocationCommand invocation.cancellationTokenCancellation token.Command result.
Process command runner used by the default CLI.
Clock abstraction used by tests to make generated release dates deterministic.
DateOnly TodayUtc()
Source
Gets today's UTC date.
UTC date.
System clock used by the default CLI.
AppSurface Console root module for the release cockpit.
Per-invocation execution context supplied by the CLI entry point.
CurrentDirectoryDirectory used to resolve default repository-relative paths.Diagnostic envelope with a stable code and reader-actionable context.
ReleaseDiagnostic Error(string code, string problem, string cause, string fix, string docs)
Source
Creates an error diagnostic.
ReleaseDiagnostic Warning(string code, string problem, string cause, string fix, string docs)
Source
Creates a warning diagnostic.
string Render()
Source
Renders the diagnostic envelope for CLI stderr.
Human-readable diagnostic envelope.
Exception that carries a structured release diagnostic.
ReleaseDiagnostic Diagnostic { get; }
Source
Gets the structured diagnostic.
Validates release inputs and computes release readiness diagnostics.
Task<ReleaseCheckResult> CheckAsync(ReleaseOptions options, CancellationToken cancellationToken)
Source
Runs local release readiness checks.
optionsRelease command options.cancellationTokenCancellation token.Readiness result with errors, warnings, and generated paths.
DI-backed execution runtime for release CliFx commands.
Task RunAsync(string[] args, Action<ConsoleOptions>? configureOptions = null)
Source
Runs release commands through the shared AppSurface command-service primitive.
argsCommand-line arguments.configureOptionsOptional console configuration.A task that completes when command execution finishes.
CLI entry point for AppSurface release preparation and publishing validation.
Task<int> Main(string[] args)
Source
Launches the release CLI with process IO streams.
argsCommand-line arguments supplied to the process.Process exit code where 0 indicates success.
Task<int> RunAsync(string[] args, TextWriter standardOut, TextWriter standardError, string currentDirectory, CancellationToken cancellationToken = default, ICommandRunner? commandRunner = null, IReleaseClock? clock = null)
Source
Runs the release CLI against supplied IO streams and an explicit working directory.
argsCommand-line arguments, including command and options.standardOutWriter that receives reports, structured output, and help.standardErrorWriter that receives diagnostic envelopes and invalid usage.currentDirectoryDirectory used to resolve repository-relative defaults.cancellationTokenCancellation token for file and process work.commandRunnerOptional command runner seam used by tests.clockOptional clock seam used by tests.0 for success; otherwise a non-zero exit code.
Creates and validates checked-in release evidence bundles.
Release evidence is repository consistency evidence, not a signature or hosted-build attestation. The bundle ties together release-owned files, package release-note paths, optional docs archive catalog fields, and split commit identities so release preparation can be reviewed in a pull request and publishing can validate the same bundle at the annotated tag commit.
ReleaseEvidenceBundle BuildDraft(ReleaseWorkspace workspace, SemVer version, string releaseClassification, DateOnly date, string? contentSourceCommit, string releaseNoteContent, string releaseSidecarContent, string releaseManifestContent, IReadOnlyList<PackagePathUpdate> packagePathUpdates)
Source
Builds a draft release evidence bundle for release preparation.
ReleaseEvidenceBundleV2 BuildDraftV2(ReleaseWorkspace workspace, SemVer version, string releaseClassification, DateOnly date, string? contentSourceCommit, string releaseNoteContent, string releaseSidecarContent, string releaseManifestContent, string currentReleaseContent, string currentReleaseSidecarContent, IReadOnlyList<CoordinatedPackageReleaseNoteResolution> coordinatedPackageReleaseNoteResolutions)
Source
Builds schema-v2 evidence for a release whose package links use the frozen coordinated current pointer.
workspaceRepository workspace that supplies the canonical artifact paths.versionVersion represented by the generated evidence.releaseClassificationRelease channel, either prerelease or stable.dateRelease date recorded in the manifest and evidence.contentSourceCommitPreparation base commit, when it is available.releaseNoteContentVersioned release-note bytes included in the evidence digest set.releaseSidecarContentVersioned release-note metadata bytes included in the evidence digest set.releaseManifestContentVersioned V2 manifest bytes included in the evidence digest set.currentReleaseContentFrozen tree-local current pointer bytes. Required for schema V2; schema V1 does not use this artifact.currentReleaseSidecarContentFrozen tree-local current pointer metadata bytes. Required for schema V2; schema V1 does not use this artifact.coordinatedPackageReleaseNoteResolutionsCoordinated package links resolved through the frozen current pointer.Task<ReleaseEvidenceValidationResult> ValidatePreparedAsync(ReleaseWorkspace workspace, SemVer version, string releaseClassification, string? contentSourceCommit, CancellationToken cancellationToken)
Source
Validates a checked-in release evidence bundle in the current worktree.
ReleaseEvidenceValidationResult ValidateTag(SemVer version, string releaseClassification, string tag, string tagCommit, string releaseNoteJson, string releaseSidecarJson, string releaseManifestJson, string evidenceJson, string? currentReleaseContent = null, string? currentReleaseSidecarContent = null)
Source
Validates release evidence read from an annotated tag.
versionVersion claimed by the annotated tag.releaseClassificationRelease channel expected for the tagged evidence.tagAnnotated tag name.tagCommitCommit resolved from the annotated tag.releaseNoteJsonTagged release-note content.releaseSidecarJsonTagged release-note metadata content.releaseManifestJsonTagged release-manifest content.evidenceJsonTagged release-evidence content.currentReleaseContentOptional frozen current-pointer content for schema V1; required with the sidecar for schema V2.currentReleaseSidecarContentOptional frozen current-pointer metadata for schema V1; required with the pointer for schema V2.string Serialize(ReleaseEvidenceBundleV2 bundle)
Source
Serializes a schema-v2 coordinated release evidence bundle.
bool IsV2(string evidenceJson)
Source
Determines whether a raw evidence document declares schema v2 without deserializing it as a v1 object.
Describes the outcome of release evidence validation.
SummaryStructured summary when the evidence shape was readable enough to summarize; otherwise null.DiagnosticsErrors or warnings discovered while validating the release evidence bundle.BundleDeserialized evidence bundle when parsing and top-level shape validation reached the bundle. This can be null for unreadable evidence and can be non-null while Diagnostics contains errors.Stable docs archive verification depends on Bundle only after callers have checked diagnostics. Do not treat a non-null bundle as proof that the evidence is publishable.
Parsed release CLI options shared by every command.
CommandRelease command name controlling command-specific validation.RepositoryRootCanonical repository root used to resolve relative paths.VersionSemVer release identity without a leading v.TagOptional annotated tag used by publish.DateOptional release date used by prepare.DryRunWhether the command should validate without mutating repository or GitHub state.ReportPathOptional Markdown report output path.GitHubOutputPathOptional GitHub Actions output file used by publish.FailOnWarningsWhether check should fail when warning diagnostics are present.AllowExistingTargetsWhether check may review already-generated release artifacts.BaseRefPublish branch that must contain the release tag commit.DocsCatalogPathOptional staged AppSurface Docs versions.json used for stable docs evidence verification. check may leave this null to use the local dist/docs/versions.json fallback; release publication should use the docs-publication command for the public archive/catalog path.DocsTrustedReleaseRootPathOptional trusted release root for catalog exact-tree paths. When null, verification defaults to the catalog directory; callers should pass it when the staged exact trees live elsewhere.Minimal SemVer 2.0 model used by release automation.
SemVer Parse(string value)
Source
Parses a release version and rejects leading-v tags, build metadata, and invalid SemVer shapes.
valueVersion string supplied by the user.The parsed version.
bool TryParse(string value, out SemVer? version)
Source
Tries to parse a SemVer value without producing a command-line diagnostic.
valueVersion text without the tag prefix.versionParsed version when the input is valid.true when the input is a supported SemVer value.
int CompareTo(SemVer? other)
Source
Compares two versions with SemVer 2.0 precedence.
otherThe version to compare.A negative value, zero, or a positive value according to SemVer precedence.
bool IsStable { get; }
Source
Gets whether the version is a stable SemVer identity.
bool IsProtectedPrereleaseWorkflowCompatible { get; }
Source
Gets whether this prerelease version can trigger the protected prerelease package workflow.
string TagName { get; }
Source
Gets the annotated git tag expected for this version.
Creates deterministic AppSurface Docs release archives, version catalogs, Pages staging payloads, and maintainer recovery summaries.
This planner is the release-tool owned boundary between a tag-local AppSurface Docs export and the public publication workflow. It does not deploy Pages or mutate GitHub Releases directly; instead it emits deterministic local artifacts that GitHub Actions uploads, deploys, verifies, and promotes in separate jobs. Callers must provide an already-exported exact tree for the tag, a disposable Pages staging root, and output paths that do not overlap the exact tree. Supplying DocsPublicationRequest.ExistingPagesRoot means prior Pages content is required and will be copied before the new immutable releases/{version}/ tree is staged. The staging root is deleted and recreated during planning, so it must never point at the repository, an exact tree, or any durable artifact directory.
Task<DocsPublicationPlan> CreateAsync(DocsPublicationRequest request, CancellationToken cancellationToken)
Source
Produces the release docs publication plan and all local artifacts the publish workflow transports.
requestPublication request from the release workflow, including exact-tree input, output paths, optional existing Pages content, and promotion policy.cancellationTokenCancellation token for file reads, writes, and hash computation.The completed publication plan that names every generated artifact and the recovery summary path.
The method validates the tag/version pairing, verifies the exact-tree release manifest digest against release evidence when supplied, writes a deterministic .tar.gz plus .sha256, resets the Pages staging directory, copies existing Pages content when requested, writes the merged catalog, and emits a recovery summary. It rejects missing existing Pages roots, output paths under the exact tree, and reparse-point entries so a release archive cannot accidentally include generated output or follow a symlink outside the trusted tree.
Task WriteOutputsAsync(DocsPublicationPlan plan, string? githubOutputPath, CancellationToken cancellationToken)
Source
Writes GitHub Actions outputs for the generated publication plan.
planCompleted docs publication plan.githubOutputPathOptional GitHub Actions output path.cancellationTokenCancellation token.Request for creating docs publication artifacts.
VersionRelease version without a leading v. Stable versions may become recommendedVersion.TagAnnotated tag name that must equal v{Version}.ExactTreePathExported AppSurface Docs exact tree for this tag. It must already contain the release manifest.ExistingPagesRootOptional existing Pages payload to preserve. When supplied, the directory must exist.ArchivePathOutput path for the deterministic docs archive. The sibling temporary .tar path must also be outside the exact tree.PagesStagingRootDisposable output directory for the merged Pages payload. It is deleted and recreated.PlanPathOutput path for the machine-readable publication plan.SummaryPathOptional output path for the maintainer recovery summary.ExpectedReleaseManifestSha256Optional release evidence digest that the exact-tree manifest must match.PromoteRecommendedWhether stable publication should update the public recommended docs pointer.Machine-readable release docs publication plan.
SchemaPlan schema identifier.VersionRelease version described by the plan.TagAnnotated release tag.PlanPathPath where this plan was written.ArchiveAssetNameGitHub Release asset name for the docs archive.ArchivePathLocal docs archive path.ArchiveSha256SHA-256 digest of the archive bytes.Sha256PathLocal path of the paired digest ledger file.ExactTreePathCatalog exact-tree path, relative to the Pages release root.ReleaseManifestSha256SHA-256 digest of the exact-tree release manifest.PagesStagingRootLocal staged Pages payload root.CatalogPathLocal staged versions.json path.RecommendedVersionRecommended public docs version after catalog generation, if any.CatalogEntryCatalog entry generated for this release.RetryPolicyPolicy for draft/public asset replacement during recovery.RecoveryRecovery summary metadata.Version catalog entry produced for the released docs tree.
VersionCatalog version value.LabelHuman-readable catalog label.SummaryShort release summary for docs navigation.SupportStateSupport state, usually Current for promoted stable releases or Maintained.VisibilityCatalog visibility. Release publication emits public entries.AdvisoryStateAdvisory state for the docs version.ExactTreePathRelease-root-relative exact tree path.ReleaseManifestSha256Pinned release manifest digest for the exact tree.Draft/public asset retry policy emitted with the publication plan.
DraftAssetReplaceAllowedWhether recovery may replace assets while the GitHub Release is still a draft.PublicAssetReplaceAllowedWhether recovery may replace assets after the GitHub Release is public.Maintainer recovery summary metadata.
SummaryPathPath to the human-readable recovery summary with resume, publish, and abort commands.string Build(SemVer version, DateOnly date, string unreleased)
Source
Converts the living unreleased note into a tagged release note.
versionRelease version rendered in the heading and generated comment.dateRelease date rendered with invariant yyyy-MM-dd formatting.unreleasedUnreleased Markdown content. Canonical input starts with an exact # Unreleased heading.Tagged release Markdown with a generated comment header and a trailing newline.
The method first parses Markdown to catch syntax problems, but it does not use the returned syntax tree to rewrite content. It then replaces only the exact top-level # Unreleased heading without consuming its following blank line, and two known narrative phrases using ordinal matching. Variants in casing or wording are left unchanged. Output is deterministic apart from the supplied version and date, uses Environment.NewLine for generated sections, and trims trailing whitespace from the source body. Callers should run release readiness checks first because duplicate headings, missing phrases, or concurrently edited Markdown are not treated as errors.
string ResetUnreleased(SemVer previousVersion)
Source
Creates the next-cycle unreleased proof artifact.
previousVersionVersion that just moved into tagged release files.Canonical unreleased Markdown for the next cycle, including the previous version reference and a trailing newline.
This reset intentionally discards the prior living-release body after it has been copied into a tagged release note. It preserves the expected section order for future checks: overview, shaping work, included changes, and migration watch.
string BuildCurrentReleasePointer(SemVer version)
Source
Builds the tree-local pointer used by coordinated package and documentation links.
versionThe immutable tagged release selected by this pointer.Deterministic Markdown that links to the exact release note.
Do not replace this link with a global release lookup. Release archives copy this file into their immutable exact trees; a historical current route must therefore point to the release that was current when that tree was published.
Task<PackageIndexSummary> LoadAsync(string path, CancellationToken cancellationToken)
Source
Loads a package index summary from YAML.
pathPackage index path.cancellationTokenCancellation token.Package index summary.
PackageIndexSummary Load(string content)
Source
Parses a package-index document into the release-owned public package summary.
contentThe YAML document to parse.The public publish package rows and their release-link contracts.
IReadOnlyList<PackageIndexEntry> PublicPublishedPackages { get; }
Source
Gets public package rows whose publish decision is publish.
Package manifest root shape used by the release tool.
List<PackageIndexYamlEntry> Packages { get; init; }
Source
Gets the package rows.
Package manifest row shape used by the release tool.
string Project { get; init; }
Source
Gets the project path.
string Classification { get; init; }
Source
Gets the classification string.
string? PublishDecision { get; init; }
Source
Gets the publish decision string.
string? ReleaseTrack { get; init; }
Source
Gets the release-link policy.
string? ReleaseNotesPath { get; init; }
Source
Gets the explicit release notes path when the package uses an explicit link.
string? ReadinessBlocker { get; init; }
Source
Gets the same-repository issue or pull request that blocks publication, when one remains unresolved.
Package row included in a release manifest.
ProjectRepository-relative package project path. The package index supplies a non-empty path for every row.ReleaseLinkResolved package release-link policy.ReadinessBlockerOptional same-repository issue or pull-request reference. A non-empty value blocks publication until the package is held or the blocker is cleared.string ReleaseNotesPath { get; }
Source
Gets the repository-relative release note path after applying the package release-link policy.
A single entry from git diff --name-status.
StatusThe Git status code, such as A, M, D, or R100.PathThe current path reported by Git.OriginalPathThe original path for a rename, when Git reported one.Result of validating the exact release-preparation change set.
bool IsValid { get; }
Source
Gets whether the diff is exactly the generated release artifacts and next-cycle rollover files for the requested version.
Enforces the narrow change contract for a release-preparation pull request.
The policy applies to the complete Git diff between the pull request base and head. It intentionally excludes releases/current.md.yml: that sidecar is permanent, version-independent metadata and must never be regenerated or changed by release preparation.
ReleasePreparationChangePolicyResult Validate(string version, IEnumerable<ReleasePreparationChange> changes)
Source
Validates that the diff contains the versioned release artifacts, frozen current pointer, changelog, and next-cycle files for version.
versionRelease version without a leading v.changesComplete Git name-status diff.Validation errors, or an empty result when the diff is valid.
IReadOnlyList<ReleasePreparationChange> ParseNameStatus(string nameStatusOutput)
Source
Parses tab-delimited output from git diff --name-status --find-renames.
nameStatusOutputGit name-status output.Parsed change entries.
Shared CliFx option surface and diagnostic handling for release commands.
ValueTask ExecuteWithDiagnosticsAsync(IConsole console, Func<ReleaseOptions, CancellationToken, Task<int>> executeAsync)
Source
Runs command logic with release diagnostic rendering.
consoleCliFx console.executeAsyncCommand implementation.A task that completes after command execution.
ReleaseServices CreateServices(ReleaseOptions options)
Source
Creates service objects for the resolved repository root.
optionsResolved command options.Workspace, checker, preparation, tagged projection resolver, and publishing services.
string? ResolveTag(SemVer version)
Source
Resolves the command tag, when relevant.
versionParsed release version.The tag value, or null for commands that do not use a tag.
string? ResolveGitHubOutputPath(string repoRoot)
Source
Resolves the GitHub Actions output path, when relevant.
repoRootResolved repository root.The output path, or null for commands that do not write workflow outputs.
string? ResolveDocsCatalogPath(string repoRoot)
Source
Resolves the AppSurface Docs version catalog path, when the command supports stable docs evidence verification.
repoRootResolved repository root.The catalog path, or null when the command does not accept docs catalog input.
Overrides should resolve relative option values from repoRoot instead of the process working directory so local shells, CI jobs, and generated reports all describe the same artifact. Return null for commands that do not verify stable docs evidence, and for check when callers want the local dist/docs/versions.json fallback. Stable publish callers should prefer an explicit staged catalog path because checkout-local docs may not be the artifact being published.
string? ResolveDocsTrustedReleaseRootPath(string repoRoot)
Source
Resolves the trusted release root path used to interpret docs catalog exact-tree paths.
repoRootResolved repository root.The trusted release root, or null to default to the catalog directory.
Overrides should resolve relative option values from repoRoot. Returning null tells the verifier to derive the trusted root from the catalog directory, which is the right default for colocated review artifacts. Pass an explicit root when the catalog is staged beside, but not above, the exact release trees; otherwise catalog exactTreePath values may resolve as missing or unsafe.
string ResolveBaseRef()
Source
Resolves the branch name used for publish-time reachability and source workflow checks.
The base branch name for release validation. Commands default to main; publish accepts branch-ish inputs such as release/0.1.0, origin/release/0.1.0, refs/heads/release/0.1.0, or refs/remotes/origin/release/0.1.0 and normalizes them before validators query origin/<branch>. Tags and commit SHAs are not valid base refs because publish validation must prove protected branch reachability.
Task WriteReportAsync(ReleaseOptions options, string rendered, TextWriter standardOut, CancellationToken cancellationToken)
Source
Writes the rendered command report to stdout and to the optional report path.
optionsResolved command options.renderedRendered Markdown report.standardOutStandard output writer.cancellationTokenCancellation token.A task that completes after the report is written.
string? VersionText { get; set; }
Source
Gets the SemVer 2.0 release version without a leading v.
string? DateText { get; set; }
Source
Gets the release date for prepare, formatted as YYYY-MM-DD.
bool DryRun { get; set; }
Source
Gets a value indicating whether the command should avoid repository mutations or publishing.
string? RepositoryRoot { get; set; }
Source
Gets the repository root. Defaults to the current directory.
string? ReportPath { get; set; }
Source
Gets an optional readiness report output path.
string CommandName { get; }
Source
Gets the command name used by release validation logic.
bool FailOnWarnings { get; }
Source
Gets whether this command should turn warning diagnostics into a failing exit code.
bool AllowExistingTargets { get; }
Source
Gets whether this command may review already-generated release artifacts.
Command services bound to a resolved workspace.
WorkspaceWorkspace path helper.CheckerReadiness checker.PreparationRelease preparation workflow.TaggedProjectionResolverPrepared-to-tagged projection resolver.PublishingRelease publishing workflow.Validates tag state and produces GitHub Release workflow outputs.
Task<PublishOutputs> PublishAsync(ReleaseOptions options, CancellationToken cancellationToken)
Source
Validates an existing annotated tag and extracts release notes from the tag commit.
optionsPublish command options. The version and tag must match, and stable versions require protected stable package publishing proof.cancellationTokenCancellation token.Structured workflow outputs for GitHub Release creation.
PublishAsync verifies annotated tag shape, reachability from the configured base ref, package publication, draft-safe GitHub Release state, and presence of releases/v{version}.md in the tag commit. The tag commit must also contain the release sidecar, release manifest, and release evidence bundle; missing or invalid tag-bound artifacts fail fast before a GitHub Release is created or promoted. The method writes the tag's release note to a temporary file so workflows can pass a stable notes path to GitHub's release action.
Task WriteOutputsAsync(PublishOutputs outputs, ReleaseOptions options, CancellationToken cancellationToken)
Source
Writes publish outputs to a GitHub Actions output file when requested.
outputsPublish outputs.optionsRelease command options. ReleaseOptions.GitHubOutputPath must be a file path, not a root directory.cancellationTokenCancellation token.Scalar outputs use name=value. Multiline outputs use GitHub's delimiter form. Existing files are appended to match GITHUB_OUTPUT behavior.
Immutable command invocation for release-owned external processes.
ExecutableExecutable name or absolute path.ArgumentsArgument list passed without shell evaluation.WorkingDirectoryWorking directory used for the process.TimeoutOptional wall-clock timeout. When omitted, release commands use the default bounded timeout.Captured command result.
Release readiness result.
bool HasErrors { get; }
Source
Gets whether the report contains errors.
Release preparation result.
Machine-readable release manifest.
Machine-readable schema-v2 release manifest for frozen coordinated release links.
V2 deliberately retains V1 as a separate type so checked-in historical manifests are never deserialized through a newer contract. Its package resolutions record the tree-local alias and the immutable tagged note it resolves to at preparation time.
Records how a public package's coordinated release alias resolves in the prepared documentation tree.
ProjectRepository-relative project path for the public package.SourceResolution source. Schema V2 accepts only coordinated.AliasPathTree-local alias path used by coordinated package documentation.ResolvedPathImmutable versioned release-note path selected by the alias in this documentation tree.ReleaseTagAnnotated release tag for the immutable note.PreparationBaseCommitPreparation base commit; null only while a draft has not yet been bound to a concrete repository commit.Package release note path update recorded in the release manifest.
Serializable diagnostic record for release manifests.
ReleaseDiagnosticRecord FromDiagnostic(ReleaseDiagnostic diagnostic)
Source
Creates a serializable diagnostic record.
diagnosticSource diagnostic.Serializable record.
Structured publish outputs for GitHub Actions.
Maintainer-facing release evidence summary rendered in command reports and workflow outputs.
PathRepository-relative evidence bundle path.SchemaEvidence bundle schema.StatusDraft or tag-bound validation status.SubjectSha256Stable subject digest for the evidence bundle.DocsReleaseManifestSha256Optional AppSurface Docs archive manifest digest referenced by the evidence bundle.CatalogExactTreePathOptional catalog exact tree path referenced by the evidence bundle.DocsArchiveVerificationStateStable docs archive verification state from the checked catalog/archive inputs.DocsCatalogPathPhysical catalog input used to verify stable docs evidence.DocsTrustedReleaseRootPathPhysical trusted release root used to resolve catalog exact-tree paths.DocsPhysicalExactTreePathPhysical exact-tree path verified against the catalog pin.DocsVerifiedFileCountNumber of archive files verified from the release manifest.TagCommitOptional tag commit validated at publish time.AttestationAttestation requirement state.Parses and renders the frozen tree-local coordinated release pointer.
The current pointer deliberately has a very small, byte-stable surface. Exact documentation trees copy this file, so accepting free-form prose would allow a historical current route to silently stop identifying the release represented by its tree.
string BuildNone()
Source
Builds the initial pointer used before the repository has a reachable coordinated tag.
string Build(SemVer version)
Source
Builds the canonical pointer for a tagged coordinated release.
bool TryParse(string content, out SemVer? version)
Source
Validates canonical pointer bytes and returns its optional referenced tag version.
Finds annotated, reachable coordinated release tags and enforces the current-pointer advancement rule.
Writes tagged release projections through retained directory handles.
Every directory component is opened without following links and remains open until the temporary file is atomically renamed. Unix uses openat and renameat relative to the retained descriptor. Windows retains non-delete-sharing directory handles, which pins the traversed path while the temporary file is created, and uses a relative FILE_RENAME_INFO target for replacement.
Task WriteAsync(string outputPath, string yaml, CancellationToken cancellationToken)
Source
Creates the output directory securely and atomically replaces the target projection.
outputPathAbsolute logical path to the output file.yamlUTF-8 YAML content to write.cancellationTokenToken that cancels before the replacement is committed.IDisposable UseDirectoryOpenedHookForTesting(Action<string> callback)
Source
Runs a callback after the target directory is safely opened and before the temporary file is created.
callbackCallback used by tests to simulate a parent-directory replacement race.A scope that restores the previous callback.
The callback is async-flow-local so concurrent tests cannot alter another write. Production code leaves the callback unset.
IDisposable UseTemporaryFileOpenedHookForTesting(Action callback)
Source
Runs a callback after the temporary output file is created and before its content is written.
callbackCallback used by tests to deterministically cancel a write after temporary-file creation.A scope that restores the previous callback.
The callback is async-flow-local so concurrent tests cannot alter another write. Production code leaves the callback unset.
IDisposable UseUnixFChmodFailureForTesting(int error)
Source
Forces Unix temporary-file permission hardening to fail with a specified native error code.
errorNon-zero native error code returned by the test-only failure seam.A scope that restores the previous failure seam.
The seam is async-flow-local so tests can verify cleanup after a permission-hardening failure without depending on host filesystem behavior. Production code leaves the seam unset and calls fchmod directly.
string NormalizePlatformPath(string path, bool? isMacOs = null)
Source
Canonicalizes fixed macOS temporary-directory aliases before no-follow traversal.
pathAbsolute path to canonicalize.isMacOsOptional platform override used by focused tests.The physical macOS temporary path or the original path on other platforms.
string RenderCheck(ReleaseCheckResult result)
Source
Renders a check report.
resultCheck result.Markdown report.
The report shape is stable for workflow comments and maintainer review: # Release readiness report, a summary bullet list, ## Generated files, optional ## Release evidence bundle, ## Errors, then ## Warnings. Empty diagnostics render as - None. Each diagnostic renders its complete severity/code/problem/cause/fix/docs envelope. Generated file paths and diagnostic codes are wrapped in inline code; diagnostic text is not escaped beyond normal Markdown rendering. Consumers should key off headings and diagnostic codes rather than line numbers.
string RenderPreparation(ReleasePreparationResult result)
Source
Renders a prepare report.
resultPreparation result.Markdown report.
Preparation reports begin with the check report contract, then append a manual review gate, optional evidence summary, either ## Dry-run plan or ## Files written based on ReleasePreparationResult.DryRun, and structured recovery guidance. Paths are repository-relative bullets. This distinction is the only dry-run marker in the report, so callers that publish the report should preserve that heading.
Dispatches and validates the schema-v2 release-manifest contract before evidence consumes it.
This deliberately performs raw JSON validation before typed deserialization. System.Text.Json otherwise ignores unknown fields, which would make an accidental V1/V2 hybrid look valid even though the checked-in JSON schemas forbid it.
bool TryValidatePackageSet(ReleaseManifestV2 manifest, IReadOnlyList<PackageIndexEntry> packages, out string issue)
Source
Confirms that a V2 manifest attests to exactly the release surface declared by the package index.
manifestThe already validated V2 manifest.packagesPublic publish package rows from the same release tree.issueThe mismatch explanation when validation fails.true when the manifest and package index describe the same release surface.
Prevents trimming coverage from depending on generated process-start wiring.
Resolves prepared release artifacts into a tagged projection bound to an annotated Git tag.
This is the single authority for the prepared-to-tagged transition. It reads tag objects and artifact blobs through Git, validates the checked-in evidence bundle and canonical tag trailers, then returns an in-memory sidecar projection. It never mutates repository files, creates tags, or calls GitHub.
Task<string> GenerateTagMessageAsync(SemVer version, CancellationToken cancellationToken)
Source
Generates canonical annotated-tag trailers from the prepared artifacts at HEAD.
versionRelease version whose prepared artifacts are read from HEAD.cancellationTokenCancellation token.Canonical trailer block with a trailing newline.
Task<ReleaseTaggedProjection> ResolveAsync(ReleaseOptions options, CancellationToken cancellationToken)
Source
Resolves and validates the tag-bound tagged projection for inspect and publish.
optionsRelease command options containing the canonical version, tag, and base ref.cancellationTokenCancellation token.Validated immutable tag details and transient tagged sidecar YAML.
Exact release artifacts read from one Git revision.
Result of a successful prepared-to-tagged projection resolution.