Skip to content

Commit 04ea279

Browse files
Add Copilot agent skill for updating integration tests after .NET releases (#687)
Create a reusable skill that guides Copilot through updating integration tests when a new .NET version reaches preview1 or GA. The skill: - Uses releases-index.json as the source of truth for version data - Identifies release type (preview vs GA) and support model (LTS vs STS) - Provides step-by-step instructions for updating all test files - Includes checklists for both preview1 and GA release updates Resolves #665 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 5951b8f commit 04ea279

2 files changed

Lines changed: 700 additions & 0 deletions

File tree

Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
---
2+
name: update-integration-tests
3+
description: >
4+
Update the integration tests in this repository after a .NET preview1 or GA release.
5+
Use this skill when asked to update tests for a new .NET version release, when an issue
6+
mentions updating integration tests for a .NET release, or when test failures indicate
7+
a new .NET version has shipped and tests are out of date.
8+
---
9+
10+
# Updating Integration Tests After a .NET Release
11+
12+
This skill guides the process of updating integration tests when a new major .NET version reaches **preview1** or **GA (General Availability)**.
13+
14+
## Step 0: Run the Coverage Check Script
15+
16+
Before making any changes, run the helper script to identify exactly what needs updating:
17+
18+
```bash
19+
python3 .github/skills/update-integration-tests/check-test-coverage.py
20+
```
21+
22+
This script fetches the .NET releases index, parses the test files, and reports:
23+
- Missing version entries in `_channels`, `_runtimeBranches`, and `_sdkBranches`
24+
- Incorrect Quality values (e.g., a GA version still using `Quality.Preview`)
25+
- Missing `[InlineData]` entries for specific version tests
26+
- Missing aka.ms test entries
27+
- LTS/STS alias correctness
28+
29+
Use the script output to guide the changes below.
30+
31+
## Step 1: Fetch Release Data
32+
33+
Fetch the .NET releases index to determine the current state of all .NET versions:
34+
35+
```bash
36+
curl -s https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json
37+
```
38+
39+
This JSON file contains an array of release entries. Each entry has these key fields:
40+
41+
| Field | Description | Example Values |
42+
|-------|-------------|----------------|
43+
| `channel-version` | The .NET major.minor version | `"11.0"`, `"10.0"` |
44+
| `support-phase` | Current lifecycle phase | `"preview"`, `"active"`, `"eol"` |
45+
| `release-type` | Support model | `"lts"`, `"sts"` |
46+
| `latest-sdk` | Latest SDK version string | `"11.0.100-preview.1.26104.118"`, `"10.0.103"` |
47+
| `latest-runtime` | Latest runtime version string | `"11.0.0-preview.1.26104.118"`, `"10.0.3"` |
48+
49+
For detailed per-release version information (including ASP.NET Core and Windows Desktop runtime versions), fetch the channel's `releases.json`:
50+
51+
```bash
52+
curl -s https://builds.dotnet.microsoft.com/dotnet/release-metadata/X.0/releases.json
53+
```
54+
55+
The per-release JSON contains component versions under the first release entry:
56+
- `releases[0].sdk.version` — SDK version (e.g., `"11.0.100-preview.1.26104.118"`)
57+
- `releases[0].runtime.version` — .NET runtime version (e.g., `"11.0.0-preview.1.26104.118"`)
58+
- `releases[0].aspnetcore-runtime.version` — ASP.NET Core runtime version
59+
- `releases[0].windowsdesktop.version` — Windows Desktop runtime version
60+
61+
## Step 2: Determine What Updates Are Needed
62+
63+
Compare the releases index data against the test files to identify gaps. **Important: Check ALL active and preview versions**, not just the newest one. Previous updates may have left gaps (e.g., a version going from preview to GA without updating `_sdkBranches`).
64+
65+
### How to identify the release type
66+
67+
| `support-phase` value | What it means | Test update type |
68+
|---|---|---|
69+
| `"preview"` | Version is in preview (preview1 or later) | **Preview update** — add new version entries with `Quality.Preview` |
70+
| `"active"` | Version has reached GA and is actively supported | **GA update** — change preview entries to `Quality.None` + `Quality.Ga`, update LTS/STS aliases |
71+
72+
### How to identify LTS vs STS
73+
74+
Use the `release-type` field from the releases index:
75+
- `"lts"` → Long Term Support — this version should be the target of the `"LTS"` test channel alias
76+
- `"sts"` → Standard Term Support — this version should be the target of the `"STS"` test channel alias
77+
78+
Only the **latest active** LTS and STS versions should be referenced by the `"LTS"` and `"STS"` aliases.
79+
80+
## Step 3: Make the Test Updates
81+
82+
### Key Files
83+
84+
All test files are under `tests/Install-Scripts.Test/`:
85+
86+
| File | Purpose |
87+
|------|---------|
88+
| `GivenThatIWantToInstallDotnetFromAScript.cs` | Tests that install .NET SDK and runtimes using channels, branches, quality flags, and specific versions |
89+
| `GivenThatIWantToGetTheSdkLinksFromAScript.cs` | Dry-run tests that verify SDK download links resolve correctly for channels, runtimes, and exact versions |
90+
| `AkaMsLinksTests.cs` | Tests that verify aka.ms redirect links work for SDK and runtime downloads |
91+
| `Assets/*.verified.txt` | Verified snapshot files for exact-version dry-run tests (used by the Verify library). **Only created for GA versions, not preview.** |
92+
| `Utils/Quality.cs` | Defines the `Quality` flags enum: `None`, `Daily`, `Preview`, `Ga`, `All` |
93+
94+
---
95+
96+
### Preview Release Updates
97+
98+
When the releases index shows a version with `"support-phase": "preview"` that is not yet in the tests, add entries for it.
99+
100+
Use the `latest-sdk` and `latest-runtime` values from the releases index (or the per-release `releases.json`) as the specific version numbers.
101+
102+
#### `GivenThatIWantToInstallDotnetFromAScript.cs`
103+
104+
**`_channels` list** — Add a preview entry at the end (before the closing `};`):
105+
```csharp
106+
("X.0", "X\\.0\\..*", Quality.Preview),
107+
```
108+
109+
**`_runtimeBranches` list** — Add at the end:
110+
```csharp
111+
("X.0", "X\\.0\\..*", Quality.Preview),
112+
```
113+
114+
**`_sdkBranches` list** — Add at the end:
115+
```csharp
116+
("X.0.1xx", "X\\.0\\..*", Quality.Preview),
117+
```
118+
119+
**`WhenInstallingASpecificVersionOfTheSdk`** — Add `[InlineData]` using the `latest-sdk` value from the releases index:
120+
```csharp
121+
[InlineData("X.0.100-preview.N.NNNNN.NNN")]
122+
```
123+
124+
**`WhenInstallingASpecificVersionOfDotnetRuntime`** — Add `[InlineData]` using `runtime.version` from `releases.json`:
125+
```csharp
126+
[InlineData("X.0.0-preview.N.NNNNN.NNN")]
127+
```
128+
129+
**`WhenInstallingASpecificVersionOfAspNetCoreRuntime`** — Use `aspnetcore-runtime.version`:
130+
```csharp
131+
[InlineData("X.0.0-preview.N.NNNNN.NNN")]
132+
```
133+
134+
**`WhenInstallingASpecificVersionOfWindowsdesktopRuntime`** — Use `windowsdesktop.version`:
135+
```csharp
136+
[InlineData("X.0.0-preview.N.NNNNN.NNN")]
137+
```
138+
139+
**Do NOT add entries to these tests for preview versions** (they are GA-only):
140+
- `WhenAnExactVersionIsPassedToBash`
141+
- `WhenAnExactVersionIsPassedToPowershell`
142+
- `WhenInstallingAnAlreadyInstalledVersion`
143+
144+
#### `GivenThatIWantToGetTheSdkLinksFromAScript.cs`
145+
146+
**`WhenChannelResolvesToASpecificRuntimeVersion`** — Add `[InlineData]` entries for the new channel across all three runtime type blocks. Insert after the last numeric version for each block, before `"STS"`, `"LTS"`, or `"master"` entries:
147+
148+
```csharp
149+
// In the "dotnet" block:
150+
[InlineData("X.0", "dotnet")]
151+
[InlineData("X.0", "dotnet", true)]
152+
153+
// In the "aspnetcore" block:
154+
[InlineData("X.0", "aspnetcore")]
155+
[InlineData("X.0", "aspnetcore", true)]
156+
157+
// In the "windowsdesktop" block:
158+
[InlineData("X.0", "windowsdesktop")]
159+
[InlineData("X.0", "windowsdesktop", true)]
160+
```
161+
162+
**`WhenChannelResolvesToASpecificSDKVersion`** — Add:
163+
```csharp
164+
[InlineData("X.0")]
165+
```
166+
Insert after the last numeric version `[InlineData]`, before `"STS"`.
167+
168+
**Do NOT add entries to `WhenAnExactVersionIsPassedToBash` or `WhenAnExactVersionIsPassedToPowershell`** for preview versions. These tests use the Verify library and require `.verified.txt` snapshot files that can only be generated from the actual script output. They are only added during GA updates.
169+
170+
#### `AkaMsLinksTests.cs`
171+
172+
Aka.ms link tests should **not** be added at preview1 stage. The aka.ms redirect links are not live until GA.
173+
174+
---
175+
176+
### GA Release Updates
177+
178+
When the releases index shows a version with `"support-phase": "active"` whose tests still use `Quality.Preview`, update them.
179+
180+
Use `latest-sdk` and `latest-runtime` from the releases index to get the GA version numbers. For the initial GA release, versions are typically `X.0.100` (SDK), `X.0.0` (runtimes).
181+
182+
#### `GivenThatIWantToInstallDotnetFromAScript.cs`
183+
184+
**`_channels` list** — Replace the preview entry with GA entries:
185+
```csharp
186+
// Before:
187+
("X.0", "X\\.0\\..*", Quality.Preview),
188+
189+
// After:
190+
("X.0", "X\\.0\\..*", Quality.None),
191+
("X.0", "X\\.0\\..*", Quality.Ga),
192+
```
193+
194+
**Update `"LTS"` or `"STS"` alias** — Use the `release-type` field from the releases index to determine which alias to update. Find the **latest active** version with the matching `release-type` and update the alias to match its version regex:
195+
```csharp
196+
// If release-type is "lts" and X.0 is the newest active LTS:
197+
("LTS", "X\\.0\\..*", Quality.None),
198+
199+
// If release-type is "sts" and X.0 is the newest active STS:
200+
("STS", "X\\.0\\..*", Quality.None),
201+
```
202+
203+
To determine the correct alias targets, filter the releases index for entries where `support-phase` is `"active"` and group by `release-type`. The highest `channel-version` in each group gets the alias.
204+
205+
**`_runtimeBranches` list** — Update quality from Preview to None:
206+
```csharp
207+
// Before:
208+
("X.0", "X\\.0\\..*", Quality.Preview),
209+
// After:
210+
("X.0", "X\\.0\\..*", Quality.None),
211+
```
212+
213+
**`_sdkBranches` list** — Change `Quality.Preview` to `Quality.Daily`. This follows the established pattern — all GA versions (7.0, 8.0, 9.0, etc.) use `Quality.Daily` for their SDK branch entries:
214+
```csharp
215+
// Before:
216+
("X.0.1xx", "X\\.0\\..*", Quality.Preview),
217+
// After:
218+
("X.0.1xx", "X\\.0\\..*", Quality.Daily),
219+
```
220+
221+
**Specific version tests** — Replace preview version strings with GA versions from the releases index. For the initial GA release, use the `.0` versions from the first GA release in `releases.json`:
222+
- `WhenInstallingASpecificVersionOfTheSdk`: `"X.0.100"`
223+
- `WhenInstallingASpecificVersionOfDotnetRuntime`: `"X.0.0"`
224+
- `WhenInstallingASpecificVersionOfAspNetCoreRuntime`: `"X.0.0"`
225+
- `WhenInstallingASpecificVersionOfWindowsdesktopRuntime`: `"X.0.0"`
226+
227+
#### `GivenThatIWantToGetTheSdkLinksFromAScript.cs`
228+
229+
**`WhenAnExactVersionIsPassedToBash` and `WhenAnExactVersionIsPassedToPowershell`** — Add the GA SDK version:
230+
```csharp
231+
[InlineData("X.0.100", null)]
232+
```
233+
234+
**Verified asset files** — Create `.verified.txt` snapshot files under `tests/Install-Scripts.Test/Assets/`. Copy the format from existing files (e.g., the `10.0.100` files) and replace version numbers. File naming convention:
235+
```
236+
GivenThatIWantToGetTheSdkLinksFromAScript.WhenAnExactVersionIsPassedToBash_version=X.0.100_runtime=null.verified.txt
237+
GivenThatIWantToGetTheSdkLinksFromAScript.WhenAnExactVersionIsPassedToPowershell_version=X.0.100_runtime=null.verified.txt
238+
```
239+
240+
Bash verified file content template:
241+
```
242+
dotnet_install: Warning: Use of --runtime-id is obsolete and should be limited to the versions below 2.1. To override architecture, use --architecture option instead. To override OS, use --os option instead.
243+
dotnet-install: Payload URLs:
244+
dotnet-install: URL #0 - primary: https://builds.dotnet.microsoft.com/dotnet/Sdk/X.0.100/dotnet-sdk-X.0.100-osx-x64.tar.gz
245+
dotnet-install: URL #1 - legacy: https://builds.dotnet.microsoft.com/dotnet/Sdk/X.0.100/dotnet-dev-osx-x64.X.0.100.tar.gz
246+
dotnet-install: URL #2 - primary: https://ci.dot.net/public/Sdk/X.0.100/dotnet-sdk-X.0.100-osx-x64.tar.gz
247+
dotnet-install: URL #3 - legacy: https://ci.dot.net/public/Sdk/X.0.100/dotnet-dev-osx-x64.X.0.100.tar.gz
248+
dotnet-install: Repeatable invocation: ./dotnet-install.sh --version "X.0.100" --install-dir "dotnet-sdk" --architecture "x64" --os "osx" -runtimeid "osx"
249+
```
250+
251+
PowerShell verified file content template:
252+
```
253+
dotnet-install: Payload URLs:
254+
dotnet-install: URL #0 - primary: https://builds.dotnet.microsoft.com/dotnet/Sdk/X.0.100/dotnet-sdk-X.0.100-win-x64.zip
255+
dotnet-install: URL #1 - legacy: https://builds.dotnet.microsoft.com/dotnet/Sdk/X.0.100/dotnet-dev-win-x64.X.0.100.zip
256+
dotnet-install: URL #2 - primary: https://ci.dot.net/public/Sdk/X.0.100/dotnet-sdk-X.0.100-win-x64.zip
257+
dotnet-install: URL #3 - legacy: https://ci.dot.net/public/Sdk/X.0.100/dotnet-dev-win-x64.X.0.100.zip
258+
dotnet-install: Repeatable invocation: .\dotnet-install.ps1 -Version "X.0.100" -InstallDir "dotnet-sdk" -Architecture "x64"
259+
```
260+
261+
#### `AkaMsLinksTests.cs`
262+
263+
**`SDK_IntegrationTest`** — Add a GA quality entry:
264+
```csharp
265+
[InlineData("X.0", "ga", @"https://aka.ms/dotnet/X.0/dotnet-sdk-")]
266+
```
267+
268+
**`Runtime_IntegrationTest`** — The runtime aka.ms tests are currently very sparse (only 6.0 and 7.0 windowsdesktop daily entries are active). Adding new runtime entries is optional. Check if existing patterns suggest adding them.
269+
270+
## Step 4: Validate
271+
272+
After making changes, verify that the solution builds:
273+
```bash
274+
dotnet build tests/Install-Scripts.Test/Install-Scripts.Test.csproj
275+
```
276+
277+
Run the coverage check script again to confirm all gaps are filled:
278+
```bash
279+
python3 .github/skills/update-integration-tests/check-test-coverage.py
280+
```
281+
282+
## Checklist Summary
283+
284+
### Preview1
285+
- [ ] Ran `check-test-coverage.py` to identify gaps
286+
- [ ] Fetched releases index and per-release details for exact version numbers
287+
- [ ] `_channels`: Added preview entry
288+
- [ ] `_runtimeBranches`: Added preview entry
289+
- [ ] `_sdkBranches`: Added preview entry with `Quality.Preview`
290+
- [ ] `WhenChannelResolvesToASpecificRuntimeVersion`: Added InlineData for dotnet, aspnetcore, windowsdesktop
291+
- [ ] `WhenChannelResolvesToASpecificSDKVersion`: Added InlineData for the channel
292+
- [ ] Specific version install tests: Added InlineData with real version numbers (SDK, runtime, aspnetcore, windowsdesktop)
293+
- [ ] Verified no entries added to GA-only tests (`WhenAnExactVersionIsPassedToBash/Powershell`, `WhenInstallingAnAlreadyInstalledVersion`)
294+
- [ ] **Checked all active versions** — fixed any stale entries from prior updates (e.g., `_sdkBranches` still using `Quality.Preview` for a version that went GA)
295+
- [ ] Build succeeds
296+
297+
### GA
298+
- [ ] Ran `check-test-coverage.py` to identify gaps
299+
- [ ] Fetched releases index and identified the GA version numbers and LTS/STS classification
300+
- [ ] `_channels`: Changed from Preview to None + Ga; updated LTS/STS alias
301+
- [ ] `_runtimeBranches`: Changed from Preview to None
302+
- [ ] `_sdkBranches`: Changed from `Quality.Preview` to `Quality.Daily`
303+
- [ ] Specific version install tests: Updated from preview to GA version numbers
304+
- [ ] `WhenAnExactVersionIsPassedToBash/Powershell`: Added GA SDK version InlineData
305+
- [ ] Verified asset files: Created `.verified.txt` files for new exact versions
306+
- [ ] `AkaMsLinksTests.SDK_IntegrationTest`: Added GA quality entry
307+
- [ ] Build succeeds

0 commit comments

Comments
 (0)