Skip to content

Commit bc372f1

Browse files
jeffhandleyCopilot
andauthored
Update release processes to support release servicing branches (#1620)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 711e5bb commit bc372f1

8 files changed

Lines changed: 199 additions & 86 deletions

File tree

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ The following process is used when publishing new releases to NuGet.org.
1010

1111
## 2. Prepare the release
1212

13-
From a local clone of the repository, use Copilot CLI to invoke the `prepare-release` skill. The skill assesses the semantic version, bumps the version in [`src/Directory.Build.props`](../../src/Directory.Build.props), runs API compatibility checks, reviews documentation, drafts release notes, and creates a pull request with all release artifacts.
13+
From a local clone of the repository, use Copilot CLI to invoke the `prepare-release` skill. The skill assesses the semantic version, bumps the version in [`src/Directory.Build.props`](../src/Directory.Build.props), runs API compatibility checks, reviews documentation, drafts release notes, and creates a pull request with all release artifacts.
1414

1515
Review the PR, request changes if needed, and merge when ready.
1616

@@ -20,6 +20,15 @@ After the prepare-release PR is merged, invoke the `publish-release` skill. The
2020

2121
Review the draft release on GitHub, check 'Set as a pre-release' if appropriate, and click 'Publish release'.
2222

23+
## Branching
24+
25+
The `main` branch is the next-MAJOR preview and development line; currently, it produces the `2.0.0-preview.*` series. Nightly `cron` CI on `main` publishes CI-suffixed packages to GitHub Packages.
26+
Long-lived `release/{MAJOR}.x` branches are created on demand when a shipped MAJOR needs servicing releases. Every push to a `release/*` branch publishes a CI-suffixed package to GitHub Packages, so servicing CI packages are commit-driven rather than clock-driven.
27+
Short-lived `release-{version}` branches are local prepare-release work branches that become pull requests, such as `release-2.0.0-preview.1` or `release-1.3.1`.
28+
Official NuGet.org publishes occur only when a GitHub Release is created from a branch's tag.
29+
The prepare-release skill asks for the source/base branch first so the release PR targets the same line it assessed.
30+
For the agent-facing, structured version of these rules, see [release-branches.md](skills/shared-resources/release-branches.md).
31+
2332
## 4. Monitor the Release workflow
2433

2534
- After publishing, a workflow will produce build artifacts and publish the NuGet packages to NuGet.org

.github/skills/bump-version/SKILL.md

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,21 @@ compatibility: Requires gh CLI with repo access for creating branches and pull r
88

99
Assess and bump the SDK version in `src/Directory.Build.props` to prepare for the next release. This skill owns the [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html) assessment logic — the [SemVer assessment guide](references/semver-assessment.md) is the single source of truth for version assessment criteria used across the release workflow by both the **prepare-release** and **publish-release** skills.
1010

11+
Use the shared [release branch reference](../shared-resources/release-branches.md) for branch roles, previous-release lookup rules, and release work-branch naming.
12+
1113
> **Note**: For comprehensive release preparation — including ApiCompat/ApiDiff, documentation review, and release notes — use the **prepare-release** skill, which incorporates version assessment as part of its broader workflow.
1214
1315
## Process
1416

1517
### Step 1: Read Current Version and Previous Release
1618

17-
Read `src/Directory.Build.props` on the default branch and extract:
19+
Read `src/Directory.Build.props` on the current branch and extract:
1820
- `<VersionPrefix>` — the `MAJOR.MINOR.PATCH` version
21+
- `<VersionSuffix>` — the prerelease suffix, when present
1922

20-
Display the current version to the user.
23+
The candidate version is `{VersionPrefix}` plus `-{VersionSuffix}` when the suffix is present (for example, `2.0.0-preview.1`). Display the current candidate version to the user.
2124

22-
Determine the previous release tag from `gh release list` (most recent **published** release). Draft releases must be ignored — they represent a pending release that has not yet shipped. Use `--exclude-drafts` or filter to only published releases when querying.
25+
Determine the previous release tag from `gh release list` (most recent **published** release). Draft releases must be ignored — they represent a pending release that has not yet shipped. Use `--exclude-drafts` or filter to only published releases when querying. The lookup is branch-aware: from a `release/{MAJOR}.x` branch, restrict candidates to tags matching `v{MAJOR}.*`; from `main`, use the most recent published release globally. See [release-branches.md](../shared-resources/release-branches.md) for details.
2326

2427
### Step 2: Assess and Determine Next Version
2528

@@ -40,26 +43,31 @@ When context about queued changes is available or can be gathered, assess the ve
4043

4144
#### Default Suggestion (Fallback)
4245

43-
When a quick bump is needed without full change analysis, suggest the next **minor** version:
46+
When a quick bump is needed without full change analysis, suggest based on the candidate version:
4447

45-
- Current `1.0.0` → suggest `1.1.0`
46-
- Current `1.2.3` → suggest `1.3.0`
48+
- **Stable candidate** — suggest the next **minor** version:
49+
- Current `1.0.0` → suggest `1.1.0`
50+
- Current `1.2.3` → suggest `1.3.0`
51+
- **Prerelease candidate** — if the suffix starts with an identifier such as `preview.` or `rc.` followed by an integer, suggest incrementing the trailing integer:
52+
- Current `2.0.0-preview.1` → suggest `2.0.0-preview.2`
53+
- Current `2.0.0-rc.1` → suggest `2.0.0-rc.2`
4754

4855
Present the suggestion and let the user confirm or provide an alternative.
4956

50-
Parse the confirmed version into its `VersionPrefix` component.
57+
Parse the confirmed version into its `VersionPrefix` and `VersionSuffix` components. Stable versions have no suffix.
5158

5259
### Step 3: Create Pull Request
5360

54-
1. Create a new branch named `bump-version-to-{version}` (e.g. `bump-version-to-1.1.0`) from the default branch
61+
1. Create a new branch named `bump-version-to-{version}` (e.g. `bump-version-to-1.1.0`) from the current branch
5562
2. Update `src/Directory.Build.props`:
56-
- Set `<VersionPrefix>` to the new version
63+
- Set `<VersionPrefix>` to the confirmed stable component
64+
- Set `<VersionSuffix>` for prerelease versions, or clear it for stable versions; add the element if it is missing
5765
- Update `<PackageValidationBaselineVersion>` if the MAJOR version has changed
5866
3. Commit with message: `Bump version to {version}`
5967
4. Push the branch and create a pull request:
6068
- **Title**: `Bump version to {version}`
6169
- **Label**: `infrastructure`
62-
- **Base**: default branch
70+
- **Base**: the current branch (which, for a servicing branch like `release/1.x`, is that servicing branch — not `main`)
6371

6472
### Step 4: Confirm
6573

.github/skills/bump-version/references/semver-assessment.md

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,31 @@ Recommend a PATCH version increment if no MAJOR or MINOR criteria are met.
5656
- MINOR: `MAJOR.(MINOR+1).0`
5757
- PATCH: `MAJOR.MINOR.(PATCH+1)`
5858

59-
**Examples** from previous release `v1.2.0`:
59+
### Prereleases
6060

61-
| Level | Recommended |
62-
|-------|-------------|
63-
| PATCH | `v1.2.1` |
64-
| MINOR | `v1.3.0` |
65-
| MAJOR | `v2.0.0` |
61+
While the candidate version uses a prerelease suffix (e.g., `X.Y.Z-preview.N`, `X.Y.Z-rc.N`), the recommended next version increments the trailing integer of the suffix: `preview.3``preview.4`, `rc.1``rc.2`.
62+
63+
Going to GA drops the suffix entirely: `2.0.0-rc.2``2.0.0`.
64+
65+
This is purely about how to *compute* the next version. It does **not** declare any new policy about what kinds of changes are permitted between previews — refer to the existing [versioning documentation](../../../../docs/versioning.html) for breaking-change policy.
66+
67+
### Branch context
68+
69+
The "previous release" lookup is constrained to tags matching `v{MAJOR}.*` when assessing from a `release/{MAJOR}.x` servicing branch. On `main`, the lookup is unconstrained (most recent published release globally).
70+
71+
The MAJOR/MINOR/PATCH classification criteria above are unchanged regardless of branch.
72+
73+
See [release-branches.md](../../shared-resources/release-branches.md) for branch-role definitions and previous-release lookup rules.
74+
75+
**Examples**:
76+
77+
| Previous release | Branch | Level | Recommended |
78+
|--------------------|---------------|-----------------------|------------------------|
79+
| `v1.2.0` | `main` | PATCH | `v1.2.1` |
80+
| `v1.2.0` | `main` | MINOR | `v1.3.0` |
81+
| `v1.2.0` | `main` | MAJOR | `v2.0.0` |
82+
| `v2.0.0-preview.1` | `main` | (prerelease bump) | `v2.0.0-preview.2` |
83+
| `v1.3.0` | `release/1.x` | PATCH | `v1.3.1` |
6684

6785
## Comparing Against the Candidate Version
6886

@@ -83,6 +101,7 @@ Present the assessment as a summary table followed by a rationale:
83101
84102
| Aspect | Finding |
85103
|--------|---------|
104+
| Branch context | release/1.x |
86105
| Previous release | v1.0.0 |
87106
| Breaking changes | None confirmed |
88107
| New API surface | Yes — 3 PRs add new public APIs |

0 commit comments

Comments
 (0)