agentskills.codes
RE

Orchestrate an MSBuild release: create the tracking issue, branch, configure DARC channels and subscriptions, bump version in main, final-brand the release branch, insert into VS, and publish post-GA. Covers the full monthly release lifecycle aligned with VS shipping cadence.

Install

mkdir -p .claude/skills/release-dotnet && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/16649" && unzip -o skill.zip -d .claude/skills/release-dotnet && rm skill.zip

Installs to .claude/skills/release-dotnet

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Orchestrate an MSBuild release: create the tracking issue, branch, configure DARC channels and subscriptions, bump version in main, final-brand the release branch, insert into VS, and publish post-GA. Covers the full monthly release lifecycle aligned with VS shipping cadence.
276 charsno explicit “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)

About this skill

MSBuild Release Orchestration

This skill guides an agent through the MSBuild release process defined in documentation/release-checklist.md. The checklist is the single source of truth — this skill provides context on how to execute it.

Overview

MSBuild is a component that gets inserted into Visual Studio. VS ships monthly; MSBuild must branch and prepare its bits before VS is ready to take them. See the release process doc for the full timeline diagram.

The insertion pipeline routes MSBuild branches to VS branches:

  • main → VS main (daily canary)
  • vs* release branch → VS main (replaces mainmain after branch snap)

VS handles the progression from mainrel/insidersrel/stable on its own schedule. MSBuild's responsibility is to have final-branded bits in VS main before the insiders snap date.

Each monthly VS release produces:

  • A new vs* branch from main
  • Final branding on that branch
  • A version bump in main
  • DARC channel/subscription updates
  • A VS insertion
  • Post-GA publishing to nuget.org and docs

The process is organized into 6 timeline-gated phases (0–5), each with an explicit trigger.

Execution model: This skill is designed for an interactive Copilot session. The agent walks through each phase step-by-step, but every command that modifies state (git push, DARC writes, pipeline changes, PR creation) requires user approval before execution. Read-only queries (DARC get-*, git log, etc.) can run without approval.

Required Inputs

Before starting any phase, ensure you have these values (the user must provide them — version increments are irregular and cannot be computed):

InputExampleHow to determine
PREVIOUS_RELEASE_VERSION18.5Previous entry in the merge-flow chain
THIS_RELEASE_VERSION18.6Current VersionPrefix in eng/Versions.props (drop .0)
NEXT_VERSION18.7User-provided — not computable from current version
BRANCH_SNAP_DATE2026-04-08From VS-Dates wiki — when MSBuild branches vs* from main, insertion targets VS main
INSIDERS_SNAP_DATE2026-04-22From VS-Dates wiki — when VS snaps mainrel/insiders; final-branded bits must be in VS main before this
STABLE_SNAP_DATE2026-05-06From VS-Dates wiki — when VS promotes rel/insidersrel/stable
VS_SHIP_DATE2026-05-12When VS ships publicly (GA) — triggers post-release tasks
PACKAGE_VALIDATION_BASELINE_VERSION18.7.0-preview-26230-02See How to determine PACKAGE_VALIDATION_BASELINE_VERSION below — non-trivial: most "obvious" picks are wrong.

How to determine PACKAGE_VALIDATION_BASELINE_VERSION

The value is the latest {{THIS_RELEASE_VERSION}}.0-preview-NNNNN-NN MSBuild package that is both:

  1. Published on the public dotnet-tools feed — this is the feed darc publish pushes to and that ApiCompat restores baselines from. If the version isn't here, ApiCompat fails with NU1102.
  2. Produced from a commit reachable from vs{{THIS_RELEASE_VERSION}} — i.e. a vs{{THIS_RELEASE_VERSION}} commit prior to stabilization (Phase 4.2), or the main commit vs{{THIS_RELEASE_VERSION}} was branched from.

Two tempting wrong answers — and why they're wrong:

Wrong pickWhy it fails
❌ The {{THIS_RELEASE_VERSION}}.X package that actually ships in VS (e.g. 18.7.1)After Phase 4.2 Stabilize-Release.ps1 runs, builds become final-versioned. So such package is not resolvable from public CI.
❌ Blindly the most recent {{THIS_RELEASE_VERSION}}.0-preview-* on dotnet-toolsAfter vs{{THIS_RELEASE_VERSION}} branches, main keeps producing {{THIS_RELEASE_VERSION}}.0-preview-* until this main-bump PR merges — so the most recent feed entries may be {{NEXT_VERSION}}-content builds wearing {{THIS_RELEASE_VERSION}} branding. Picking one drifts the API baseline forward and silently hides real compat breaks.

Procedure:

Determinized (preferred): run the helper, which does all of the below mechanically (requires az login with devdiv access):

pwsh ./scripts/Get-PackageValidationBaseline.ps1 -ThisReleaseVersion {{THIS_RELEASE_VERSION}}
# -> prints e.g. 18.9.0-preview-26330-01

It computes git merge-base origin/main origin/vs{{THIS_RELEASE_VERSION}}, finds the matching successful build in pipeline 9434, derives the package version from the OfficialBuildId, and verifies it on the dotnet-tools feed. The manual procedure below is the fallback / explanation of what the script does:

  1. Open MSBuild official build pipeline 9434.
  2. Filter runs to branch vs{{THIS_RELEASE_VERSION}}. Find the run that final-branded the release (it produces {{THIS_RELEASE_VERSION}}.X — no -preview- — corresponding to the commit that ran Stabilize-Release.ps1; see Phase 4.2 + 4.3). Anything successful before that on vs{{THIS_RELEASE_VERSION}} is a candidate.
  3. If vs{{THIS_RELEASE_VERSION}} has no successful pre-stabilization preview runs (common — the branch sees little churn before stabilization), fall back to the most recent successful main run whose commit is the branch-point ancestor:
    git merge-base origin/main origin/vs{{THIS_RELEASE_VERSION}} gives the SHA — find a main run at or before that SHA in pipeline 9434.
  4. Read the package version from that run's Pack step output: {{THIS_RELEASE_VERSION}}.0-preview-NNNNN-NN (example: 18.7.0-preview-26230-02).
  5. Verify the exact version is on the dotnet-tools feed (search Microsoft.Build). If not, fall back to the next-older eligible run.
  6. Use that version. Do not include any +sha suffix.

Prerequisites

  • gh cli
  • az cli
  • darc cli

Phase Summary

PhaseTriggerKey Actions
0: InstantiateUser-initiatedValidate inputs, create GitHub tracking issue
1: Branch & PrepareBRANCH_SNAP_DATECreate vs* branch, DARC channel setup (batched PR), merge-flow config, VisualStudio.ChannelName
2: DARC Subscription UpdatesPhase 1 branch exists (vs* created)Retarget main-targeting subs + VMR backflow to next channel, retired-branch cleanup (batched PR), Arcade verify
3: Bump MainPhase 2 mergedBranding PR in main (VersionPrefix → next, ApiCompat baseline, refresh OptProf baseline)
4: Final Branding7 days before INSIDERS_SNAP_DATEPublic API promotion, Stabilize-Release.ps1, OptProf bootstrap, get final-branded bits into VS main before insiders snap
5: Post-GAVS shipped (VS_SHIP_DATE)nuget.org publish, docs, GitHub release, cleanup

DARC Batching

DARC write commands push to the maestro-configuration repo. Batch related changes into one PR:

  1. Choose a branch name like release/msbuild-{{THIS_RELEASE_VERSION}}
  2. Add --configuration-branch <name> --no-pr to every write command except the last
  3. Last command: use --configuration-branch <name> without --no-pr to create the PR
  4. Get the PR reviewed and merged

Read-only commands (get-default-channels, get-subscriptions, get-channel) don't need these flags.

Non-interactive (-q). darc add-default-channel / add-subscription prompt y/n when the target branch does not exist yet (e.g. pre-creating the vs{{NEXT_VERSION}} mapping in Phase 1.2c, or adding the new vs{{THIS_RELEASE_VERSION}} backflow in Phase 2). Console input is redirected in an agent session, so the prompt fails the command — always pass -q for these "branch doesn't exist yet" writes.

Phase 2 — what moves vs. what stays. When rotating main to the next channel, retarget only the subscriptions whose target branch is main (dotnet/dotnet @ main, dotnet/fsharp @ main). Never retarget a subscription that targets a VMR servicing/release branch (dotnet/dotnet @ release/*) — that includes the SDK band paired with the new vs{{THIS_RELEASE_VERSION}} branch and any .NET-next preview band (release/*-preview*). Those stay on VS {{THIS_RELEASE_VERSION}} so the new release branch owns their downstream flow; moving them steals it. (This bit the 18.9 release: the band and preview subs were moved and had to be reverted.)

Phase 2 — VMR backflow rotation (easy to miss). Backflow (dotnet/dotnet → msbuild, source-enabled) must rotate too when the new vs{{THIS_RELEASE_VERSION}} is paired with an SDK band (skip for a VS-only release): repoint the → main backflow to the next SDK band channel (.NET <NEXT_BAND> SDK, the channel dotnet/dotnet @ main publishes to), and add a backflow from the outgoing band channel into the new vs{{THIS_RELEASE_VERSION}} branch (mirror the prior release branch's backflow, e.g. vs18.0 ← .NET 10.0.1xx SDK). See checklist steps 2.2b / 2.3f / 2.3g.

Executing a Phase

When asked to execute a specific phase:

  1. Read the full phase from documentation/release-checklist.md
  2. Verify the trigger condition is met (previous phases completed)
  3. Execute steps in order — respect sequential/parallel annotations
  4. For DARC commands: batch writes into one co

Content truncated.

Search skills

Search the agent skills registry