Skip to main content

release-readiness

Assesses ship-readiness for .NET MAUI release branches — Servicing Releases (SR) and Previews — and produces public-safe, copy-ready release handoffs or Loop-page drafts from the resulting evidence. Use for readiness verdicts, release blockers, Preview/SR status, release handoff pages, manual validation instructions, or "make the SR10/Preview N release page." Surveys CI and release delta, classifies regressions, and keeps Preview and servicing semantics distinct.

Ir para a instalação

Informações da origem

Repositório
dotnet/maui
Última atividade na origem
4 de setembro de 2026 às 17:59
Idioma detectado do SKILL.md
inglês
Estrelas
23.320
Forks
1.984

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Explorador de arquivos
15 arquivos

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
release-readiness
description
Assesses ship-readiness for .NET MAUI release branches — Servicing Releases (SR) and Previews — and produces public-safe, copy-ready release handoffs or Loop-page drafts from the resulting evidence. Use for readiness verdicts, release blockers, Preview/SR status, release handoff pages, manual validation instructions, or "make the SR10/Preview N release page." Surveys CI and release delta, classifies regressions, and keeps Preview and servicing semantics distinct.
metadata
{"author":"dotnet-maui","version":"2.0"}
compatibility
Requires `gh` CLI authenticated with `repo` + `read:org` scopes. Local net11 enrichment also uses `az` CLI with access to dnceng/internal; it fails open when unavailable and is always skipped in GitHub Actions. Preview installability uses NuGet v3 feeds; an optional short-lived Azure DevOps PAT with Packaging Read scope may be needed for an authenticated shipping feed. Run from a checkout of `dotnet/maui`.
# Release Readiness This skill produces deterministic, evidence-backed answers to **"Is `<release branch>` ready to ship?"** for .NET MAUI release branches — both **Servicing Releases (SR)** and **Previews**, in both **in-flight** and **candidate** (pre-cut) modes. ## 🚨 Report-only This skill **reports**. It does **not** execute release operations against dotnet/maui — no branch cuts, no SR merges, no tags, no pushes to `release/*` refs. If you (the agent/user invoking this skill) are asked to perform a release operation, refuse and emit the recommended commands as a copy-pasteable block for the human release captain to run. ## When to Use - "How does SR8 look?" / "Is SR8 ready to ship?" - "What's blocking SR9 candidate?" / "What would ship if we cut SR9 today?" - "How does net11 preview6 look?" / "Are we ready to cut preview6 from net11.0?" - "Are there any regression fixes I should backport to SR8?" - "What's new in SR8 since the last sync?" - "Give me a status on all releases" / "release status overview" / "what needs attention across releases" (**portfolio** — read the open `[Release Readiness]` tracker issues first; see [Reading trackers directly](#reading-trackers-directly-ad-hoc-status) below) - Scheduled and event-driven release tracking across all active majors > **For per-PR regression risk** (deletions reverting prior bug-fix lines), use [`find-regression-risk`](../find-regression-risk/SKILL.md) instead — it answers a different question. ## Architecture This skill has **four** PowerShell entry points, one Preview helper, and one workflow: | Script | Branch type | Purpose | |--------|-------------|---------| | [`Find-ReleaseReadinessTrackers.ps1`](scripts/Find-ReleaseReadinessTrackers.ps1) | all | Detects active in-flight & candidate trackers (SR, Preview, and RC) across all active majors using a five-lane algorithm and the **tag-existence rule** ("a release is in flight unless its tag already exists"). Emits a single tracker JSON consumed by the workflow. | | [`Get-ReleaseReadiness.ps1`](scripts/Get-ReleaseReadiness.ps1) | SR | Full readiness report for a single SR branch (in-flight, `-Candidate`, or `-Shipped`). `-Shipped` surveys the same branch with post-ship verdict, carry-forward, and hotfix-vs-next-SR guidance semantics. | | [`Get-PreviewReadiness.ps1`](scripts/Get-PreviewReadiness.ps1) | Preview / RC | Full readiness report for a single prerelease branch (in-flight or candidate via `-Mode candidate -SurveyRef net<major>.0`). Preview reports include consumer-installability evidence; RC reports retain that check as `UNKNOWN` until RC workload-set package resolution is supported. | | [`PreviewInstallability.ps1`](scripts/PreviewInstallability.ps1) | Preview helper | Resolves the workload-set package, validates branch-pin coherence, probes manifest and representative pack availability, extracts platform prerequisites, and emits an isolated NuGet configuration for local validation. | | [`New-ReleaseHandoff.ps1`](scripts/New-ReleaseHandoff.ps1) | all | Projects existing readiness JSON plus separately verified public release evidence into copy-ready Markdown and normalized JSON. Missing facts remain `TBD`; it never selects builds or mutates release state. | | [`release-readiness.yml`](../../workflows/release-readiness.yml) | both | Three-hourly daytime UTC schedule + event-driven refreshes + manual dispatch + PR validation. Non-PR triggers run `Find-Trackers -AllActiveMajors`, fan out a matrix job per tracker, and write idempotent `[Release Readiness]` issues; PR triggers validate outputs only. | Shared support code lives in [`PublicReportSanitizer.ps1`](scripts/PublicReportSanitizer.ps1) for public Markdown/JSON redaction and [`TrackerIssueLifecycle.sh`](scripts/TrackerIssueLifecycle.sh) for tested issue-selection and race-compensation primitives. ### Tag-existence rule (canonical signal) The trackers detector is grounded in **tag existence as the source of truth for "shipped vs in-flight"**. A release is in-flight if and only if its expected tag has NOT been published — branch existence, commit recency, and milestone state are all secondary signals. - SR shipped tag pattern: `<major>.0.<patch>` (e.g. `10.0.71` shipped → SR7 retired, no longer produces a tracker) - Preview shipped tag pattern: `<major>.0.0-preview.<N>.<date>[.<build>]` (e.g. `11.0.0-preview.5.26304.4` shipped → preview5 no longer produces a tracker) - RC shipped tag pattern: `<major>.0.0-rc.<N>.<date>[.<build>]` (e.g. `11.0.0-rc.1.26425.128` shipped → RC1 no longer produces a tracker) **Post-ship lifecycle (`shipped` mode).** Most shipped SRs are retired the moment their tag exists. The **one exception** is the *most-recently-shipped* SR (highest shipped patch), which keeps emitting as `mode='shipped'` so its tracker issue stays useful through post-ship follow-up — adding the new build to the GitHub issue version dropdown, publishing release notes, closing out the milestone. Shipped reports never retroactively return `Not Ready`: unresolved work is split into urgent hotfix-vs-next-SR follow-ups and structured carry-forward items. Each immutable shipped tag is **create-once**: if it was never tracked (for example, the tag appeared before a scheduled updater ran), the workflow creates it; once a human closes that exact tagged generation, scheduled runs do not resurrect it. An untagged hotfix is explicitly marked `hotfixInProgress=true`, forces a yellow follow-up verdict, and is likewise create-once. Hotfix closure is scoped to the live version **and branch commit**: the same generation stays closed, while new commits or a new version can create fresh evidence. Workflow decisions use the generated report markers, not detector-time hotfix fields, so tag/commit changes between detection and reporting cannot apply stale lifecycle state. Older shipped SRs remain retired. Shipped commit inventory and fix ancestry are evaluated against the immutable stable tag and the prior SR cycle's latest stable tag, never against the mutable SR branch or current `main`. This keeps the full SR inventory visible when an SR publishes multiple hotfix tags. If either tag does not resolve locally, generation fails with an explicit fetch instruction rather than emitting a falsely empty/clean tracker. During the normal tag-before-GitHub-Release window, the local stable tag is already authoritative for immutable contents and the report labels its date as tagged-commit evidence until publication metadata appears. If the Releases API is unavailable, the same immutable local-tag bounds remain usable, but the report emits a publication-status-unknown warning instead of claiming the tag is published. Both report generators dot-source [`PublicReportSanitizer.ps1`](scripts/PublicReportSanitizer.ps1), so public Markdown and JSON use one shared redaction implementation. If the live SR branch has commits after the latest stable tag or has already bumped toward an untagged hotfix in the same SR patch decade, the detector keeps the latest shipped SR in `shipped` mode, anchors contents to the stable tag, and emits a WATCH follow-up. This catches the pre-bump window as soon as branch HEAD advances rather than waiting for `PatchVersion` to change. ## Quick Start ### One-shot portfolio report (matches a full scheduled fan-out) ```bash # Detect every active in-flight + candidate tracker across all active majors pwsh .github/skills/release-readiness/scripts/Find-ReleaseReadinessTrackers.ps1 \ -AllActiveMajors \ -OutputJson trackers.json # Emits a JSON envelope with one tracker per active branch, each carrying: # branchType: 'sr' | 'preview' | 'rc' # branchName: canonical proposed branch slug (always populated) # branchExists: true if the branch is on origin, false for candidates # mode: 'in-flight' | 'candidate' | 'shipped' # hotfixInProgress: true only when the latest shipped SR branch is ahead of its stable tag # hotfixVersion/hotfixCommit: mutable hotfix generation used for close/recreate idempotency # surveyRef: ref to actually survey (branch itself, or net<major>.0 for candidates) # canonicalKey: stable join key (e.g. net10-sr8, net11-preview6, net11-rc1) # issueTitle: title for the maintained tracker issue # regressionLabels: list of regressed-in-* labels relevant to this branch ``` ### SR (Servicing Release) ```bash # In-flight SR pwsh .github/skills/release-readiness/scripts/Get-ReleaseReadiness.ps1 \ -SrBranch release/10.0.1xx-sr8 \ -RegressionLabels regressed-in-10.0.70,regressed-in-10.0.80 \ -TrackerKey net10-sr8 \ -OutputDir CustomAgentLogsTmp/release-readiness/sr8 # SR candidate (no branch yet — survey main; pass the PRIOR SR as -SrBranch) pwsh .github/skills/release-readiness/scripts/Get-ReleaseReadiness.ps1 \ -SrBranch release/10.0.1xx-sr8 \ -Candidate \ -RegressionLabels regressed-in-10.0.80,regressed-in-10.0.90 \ -TrackerKey net10-sr9 \ -OutputDir CustomAgentLogsTmp/release-readiness/sr9-candidate ``` ### Preview ```bash # In-flight preview pwsh .github/skills/release-readiness/scripts/Get-PreviewReadiness.ps1 \ -Branch release/11.0.1xx-preview6 \ -Mode in-flight \ '-PublicSafe:$false' \ -TrackerKey net11-preview6 \ -OutputDir CustomAgentLogsTmp/release-readiness/preview6 # Preview candidate (branch not cut yet — survey net11.0 instead) pwsh .github/skills/release-readiness/scripts/Get-PreviewReadiness.ps1 \ -Branch release/11.0.1xx-preview6 \ -Mode candidate \ -SurveyRef net11.0 \ '-PublicSafe:$false' \ -TrackerKey net11-preview6 \ -OutputDir CustomAgentLogsTmp/release-readiness/preview6-candidate ``` ### Release Candidate ```bash pwsh .github/skills/release-readiness/scripts/Get-PreviewReadiness.ps1 \ -Branch release/11.0.1xx-rc1 \ -Mode in-flight \ '-PublicSafe:$false' \ -TrackerKey net11-rc1 \ -OutputDir CustomAgentLogsTmp/release-readiness/rc1 ``` The unattended public survey does not know the release-owner-confirmed workload-set version or private shipping source. It therefore keeps **Consumer installability** `UNKNOWN` rather than guessing that the newest coherent package is the blessed one. Complete the local gate below before declaring a Preview ready. ### Copy-ready release handoff / Loop draft Generate the appropriate Preview or SR readiness JSON first. Then follow [`references/release-handoff.md`](references/release-handoff.md) to gather separately verified public build, test, assessment, rollback, and workload-set evidence and render it: ```bash pwsh .github/skills/release-readiness/scripts/New-ReleaseHandoff.ps1 \ -ReadinessJson ./release-readiness.json \ -EvidenceJson ./release-evidence.json \ -OutputDir ./release-handoff ``` This is a deterministic projection of the readiness report, not a second survey. It supports Preview and SR (including SR10) through one editorial renderer while preserving their different readiness semantics. It does not read or write Loop or SharePoint. Do not copy private source-page content into the evidence file; unknown fields must remain `TBD`. ### Preview: local net11 official-build health For net11 preview runs through this skill from a local checkout, invoke `Get-PreviewReadiness.ps1 '-PublicSafe:$false'`. The script then automatically queries the internal official `dotnet-maui` pipeline (Azure DevOps definition `1095`, org `dnceng`, project `internal`) when the current Azure CLI identity has access. No build ID is required. It independently checks: 1. `refs/heads/net11.0` — the inflight source/survey lane. 2. `refs/heads/release/11.0.1xx-previewN` — the evaluated release branch, when that branch exists. Candidate mode still checks `net11.0`; it adds the prospective release ref only after that ref exists. Identical refs are queried once. The local report includes each branch's health classification, build ID and number, pipeline status/result, source SHA, and internal build URL. A failed or canceled current build is `red`; a partially successful build is `partial-success`; a build behind the newest trigger-eligible commit is `stale`; a queued/running build is `in-progress`; missing or malformed evidence is `unknown`. Discovery examines a bounded five-build window. It prefers a build at exact branch HEAD, then scans by queue time and skips only candidates proven stale before accepting one proven current. Indeterminate candidates are buffered: disagreeing possible outcomes remain `unknown`, while a later proven-current failure remains `red` only when every buffered candidate is also a completed failure/cancellation. A terminal window containing only same-branch failed/canceled indeterminate builds also remains blocking as `failed-or-stale` because every candidate is either red or stale. Its rendering preserves that uncertainty and requires restoring currency evidence before choosing failure repair versus a current-HEAD rerun. This prevents both false readiness upgrades and loss of certain blocking evidence. The internal check is intentionally fail-open: - `GITHUB_ACTIONS=true` skips it before any Azure command runs. - Missing Azure CLI, expired login, or inaccessible dnceng/internal access yields `skipped` and does not downgrade the public-data verdict. - Azure CLI and GitHub branch queries have bounded execution; a timeout yields `unknown` rather than hanging the local readiness run. - Local `red`/`stale`/`failed-or-stale` maps to `BLOCKED`, `in-progress`/`partial-success` to `WATCH`, and `unknown` to `UNKNOWN`. For `failed-or-stale`, restore build-currency evidence first; then either repair the failed build if it is current or run the official build at current HEAD if it is stale. - `-PublicSafe:$true` omits all internal IDs, SHAs, URLs, and branch rows. The public workflow uses this behavior and never receives internal credentials. The script remains public-safe by default. This skill and the release-readiness agent explicitly pass `'-PublicSafe:$false'` for enriched local net11 reports; never reuse those artifacts in a public tracker issue. `-IncludeInternal` remains an explicit compatibility override when a caller requests a sanitized internal classification, and `-InternalBuildId` remains a diagnostic override for the evaluated release branch. ### Preview: authoritative blessed-build source (.NET Release Tracker) For **Previews**, this skill's public survey (CI health + regression classification on `net<major>.0` or the preview branch) tells you whether the code is *ready*, but it **cannot on its own name which staged build is the official, blessed preview** — that designation lives in the private **.NET Release Tracker** plugin. So when answering *"run release readiness … is net11 preview6 ready?"* / *"which build is the official preview6?"*, consult that authoritative source **in addition to** running `Get-PreviewReadiness.ps1`: 1. **Classify access first (deterministic gate — fetches no release data, always exits 0):** ```bash pwsh ./.github/skills/dependency-flow/scripts/Get-PreviewReleaseReadiness.ps1 # -> RELEASE_TRACKER_STATUS=NO_ACCESS | ACCESS_ON_INACTIVE_ACCOUNT | AVAILABLE_NOT_ENABLED | AVAILABLE_ENABLED ``` 2. **Branch on the token:** - `AVAILABLE_ENABLED` → invoke the **`dotnet-release-tracker`** skill for the blessed SDK/runtime + BAR id + stage, and present it as the authoritative official preview build. It is a **skill/plugin, not an MCP tool** — don't look for a `release-tracker` entry in the tool list and give up; run the skill (reload/restart the session if it's enabled but hasn't loaded yet). Combine it with this skill's CI/regression verdict for the full picture. - `AVAILABLE_NOT_ENABLED` → the caller has access but the plugin isn't enabled locally; offer the one-time user-scope opt-in, then re-run the gate. - `ACCESS_ON_INACTIVE_ACCOUNT` → access exists, but only under a logged-in **inactive** `gh` account (named in the gate's `inactiveAccount`); the plugin loads under the active identity, so advise `gh auth switch --user <account>` and re-run the gate — do **not** invoke the plugin or claim availability under the current identity. - `NO_ACCESS` → report from public data only. For the official-build line, fall back to the **latest build on the public `.NET 11.0.1xx SDK Preview N` channel** (public BAR/Maestro) and present it **labeled** as a display-only public-feed candidate — "source: public preview feed; may not be the final official build." Keep VMR validation **UNKNOWN**: do not compare/update the MAUI pin or render ✅ from that candidate. Don't name or hint at the private tracker tool (see dependency-flow's privacy guardrail). The full tier table, the user-scope opt-in snippet, and the privacy guardrails live in dependency-flow's **"Preview release readiness (authoritative source + access tiers)"** section ([`../dependency-flow/SKILL.md`](../dependency-flow/SKILL.md)) — cross-reference it rather than duplicating it here. > **Blessed ≠ green.** The release tracker names the *official* build; it does **not** substitute for the ship-readiness judgment. A build can be blessed while this skill still reports open `regressed-in-*` blockers — surface both. **Don't maintain a standing "🏷️ Official (blessed) preview build" table in the tracker.** The deterministic CI body already owns the public build-pin handling: its **"🏷️ Preview N component build — branch pins + update paths"** section states the pins are explicitly *not* the blessed build, carries the drift-proof "verify locally" prompt, infers Android/macOS-iOS subscription health from the public PR trail, and identifies VMR as a local official-build reconciliation path. Because the blessed build number is embargoed (withheld from the public issue), a standing public table just renders "🔒 withheld" and duplicates that callout. So a local run with tracker access should **report the blessed SDK/runtime build in its conversational answer**, and only add a line to _Release Captain Notes_ when there's a **decision or exception worth persisting** — e.g. the blessed build differs from the branch pin, a promoted build was rejected, or an Android/macOS-iOS subscription is confirmed broken. Don't re-create the section the CI body already renders. ### Preview: consumer-installability gate The branch being green is insufficient: a customer must be able to acquire the exact SDK workload set, its component manifests, and representative Android, Apple (including tvOS), Emscripten, MAUI, and runtime packs from a clean source configuration. Use the exact workload-set **CLI version** confirmed by the release owner. Do not substitute the branch SDK version, and do not assume the newest coherent package is blessed. Workload-set CLI and NuGet versions have different normalization: `11.0.100-preview.6.26363.2` maps to `11.100.0-preview.6.26363.2` for the NuGet package. If all assets are public, the confirmed version is enough: ```bash pwsh .github/skills/release-readiness/scripts/Get-PreviewReadiness.ps1 \ -Branch release/11.0.1xx-preview6 \ -Mode in-flight \ -ConfirmedWorkloadSetVersion 11.0.100-preview.6.26363.2 \ '-PublicSafe:$false' \ -OutputDir CustomAgentLogsTmp/release-readiness/preview6-local ``` If an authenticated shipping feed is required: 1. Create a short-lived PAT at [`https://dev.azure.com/dnceng/_usersSettings/tokens`](https://dev.azure.com/dnceng/_usersSettings/tokens). Select the `dnceng` organization and grant only **Packaging > Read**. Use the shortest practical expiration. Never paste the PAT into a command argument, NuGet.Config, report, issue, PR, chat transcript, or repository file. 2. Put the credential in NuGet's standard environment variable. The suffix must exactly match the source name passed to `-AdditionalPackageSource`. ```bash read -s -p "dnceng Packaging Read PAT: " DNCENG_PACKAGING_PAT; echo export NuGetPackageSourceCredentials_internal_preview6="Username=release-readiness;Password=${DNCENG_PACKAGING_PAT};ValidAuthenticationTypes=Basic" unset DNCENG_PACKAGING_PAT ```
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub