RunApiDiff script and documentation improvements#10241
Open
jeffhandley wants to merge 49 commits intomainfrom
Open
RunApiDiff script and documentation improvements#10241jeffhandley wants to merge 49 commits intomainfrom
jeffhandley wants to merge 49 commits intomainfrom
Conversation
The SearchQueryService on some Azure DevOps feeds (especially per-build shipping feeds) has an unpopulated search index that returns 0 results. The flat2 (PackageBaseAddress) API works reliably on all feeds. This changes DownloadPackage to try flat2 first, falling back to SearchQueryService if flat2 doesn't find a match.
Make the -CoreRepo parameter optional. When omitted, the script resolves the git repository root relative to its own location using 'git rev-parse --show-toplevel'. If the root cannot be determined, it fails with a descriptive error.
Paths containing ~ or relative segments fail when passed to the api diff tool. Resolve both paths to their full absolute form before use.
The previous/before version is typically a GA release available on nuget.org. Default to the public NuGet feed instead of the dotnet10 Azure DevOps feed.
…nal for GA Rename PreviousPreviewOrRC/CurrentPreviewOrRC to PreviousReleaseKind/ CurrentReleaseKind for clarity. Make PreviousPreviewNumberVersion and CurrentPreviewNumberVersion optional, defaulting to '0' when the release kind is 'ga'. For non-GA release kinds, a validation error is raised if the version number is not provided.
…wRCNumber Rename PreviousDotNetVersion/CurrentDotNetVersion to PreviousMajorMinor/ CurrentMajorMinor and PreviousPreviewNumberVersion/ CurrentPreviewNumberVersion to PreviousPreviewRCNumber/ CurrentPreviewRCNumber for clarity.
When TmpFolder is not specified, create a unique temporary directory using GetTempPath and GetRandomFileName.
When CurrentMajorMinor, CurrentReleaseKind, or CurrentPreviewRCNumber are not specified, query the CurrentNuGetFeed for the latest Microsoft.NETCore.App.Ref package version and parse the version components from it (e.g. 11.0.0-preview.1.26104.118 -> 11.0, preview, 1).
Extract version discovery into a reusable DiscoverVersionFromFeed function and apply it to both Previous and Current parameters. When PreviousMajorMinor or PreviousReleaseKind are not specified, they are discovered from the PreviousNuGetFeed (default: nuget.org, which will resolve to the latest GA version).
Allow the simplest invocation: .\RunApiDiff.ps1 <current-nuget-feed-url>
Document all parameters, their defaults, and auto-discovery behavior. Add quick start, prerequisites, and multiple usage examples.
Note the transport feed should match the version being compared, and mention the -InstallApiDiff flag as an alternative.
Both feeds now default to nuget.org. The same-version validation added previously will catch the case where both resolve to the same version and prompt the user to specify different feeds or explicit version parameters.
Replace the separate -PreviousReleaseKind/-PreviousPreviewRCNumber and -CurrentReleaseKind/-CurrentPreviewRCNumber parameters with single -PreviousPrereleaseLabel and -CurrentPrereleaseLabel parameters that accept values like 'preview.7' or 'rc.1'. Omit for GA releases. The labels are parsed internally into ReleaseKind and PreviewRCNumber for use by the existing helper functions.
…el from it Rename -PreviousPackageVersion/-CurrentPackageVersion to -PreviousVersion/-CurrentVersion. When a Version is provided, the MajorMinor and PrereleaseLabel values are automatically parsed from it, eliminating the need to specify them separately. Add ValidatePattern to PrereleaseLabel parameters to enforce the 'preview.N' or 'rc.N' format. Update examples to show the simplified usage with only -PreviousVersion and -CurrentVersion.
Move ParseVersionString to the Functions section and reuse it inside DiscoverVersionFromFeed instead of duplicating the regex parsing.
All helper functions are now defined together in the Functions section rather than being scattered in the execution section.
This function was never called and referenced a nonexistent variable (\). It was leftover from when the apidiff tool was built from source rather than installed as a dotnet tool.
Replace Invoke-Expression string-building with direct & invocation and argument splatting for the apidiff tool call. This avoids the fragile Invoke-Expression pattern and properly handles paths with spaces.
Add previousMajorMinor, previousReleaseKind, previousPreviewRCNumber, currentMajorMinor, currentReleaseKind, and currentPreviewRCNumber as explicit parameters instead of referencing script-scoped variables. Switch callers to use named parameters for clarity. Mark required parameters as Mandatory.
Remove the misleading 'Generate strings with no whitespace' comment that no longer described what followed, and remove a double blank line.
The GA patch branch was producing folder names like '7.01' instead of '7.0.1' due to a missing dot separator between dotNetVersion and previewNumberVersion.
Change ExcludeNetCore, ExcludeAspNetCore, ExcludeWindowsDesktop, and InstallApiDiff from [bool] to [switch]. This follows PowerShell idiom, allowing -ExcludeNetCore instead of -ExcludeNetCore \$true.
Make releaseKind and previewNumberVersion optional in DownloadPackage since they are unused when an exact version is provided. Add validation that either version or both search params are specified. Switch all DownloadPackage calls to use named parameters for clarity.
Write-Output sends to stdout which can interfere with function return values. Write-Host sends to the display stream only, which is correct for informational/colored messages.
The pattern was unanchored and too permissive, matching partial strings like '7.0abc'. Now uses ^(\d+\.\d+)?$ to match either empty or a properly formatted major.minor version.
The validation above already ensures both releaseKind and previewNumberVersion are non-empty, so the ElseIf guard was always true. Replace with a simple Else.
Call GetAuthHeadersForFeed once at the top of DownloadPackage and reuse the headers for both version search and package download, instead of calling it twice.
Instead of string-replacing the feed URL to construct a download path, use the PackageBaseAddress endpoint discovered from the service index. This handles feeds with non-standard URL patterns correctly.
Eliminates the last script-scoped variable reference from ProcessSdk.
Replaces 11 positional arguments with named parameters for clarity and to prevent parameter ordering mistakes.
Build an array of SDK names filtered by exclude flags, then loop over them with splatted common parameters. Eliminates three nearly identical long lines.
Pass the array of SDK names to CreateReadme so it only generates links for SDKs that were diffed, avoiding broken links when Exclude flags are used.
The default exclude file paths (ApiDiffAttributesToExclude.txt and ApiDiffAssembliesToExclude.txt) were resolving relative to the current working directory instead of the script's directory, causing FileNotFoundException when running from the repo root.
…stale comments - Set \ once before CoreRepo and exclude file resolution instead of computing it twice. - Add tmpFolder as an explicit parameter to DownloadPackage and ProcessSdk, eliminating the last script-scoped variable reference from helper functions. - Remove stale '#D:\\core' comment from CoreRepo parameter. - Fix misleading 'Recreate api-diff folder' comment to 'Create if it doesn't exist'.
ericstj
reviewed
Feb 10, 2026
ericstj
reviewed
Feb 10, 2026
ericstj
reviewed
Feb 10, 2026
ericstj
reviewed
Feb 10, 2026
Introduce a project-scoped Copilot skill (.github/skills/api-diff/) that guides API diff generation using release-notes/RunApiDiff.ps1. SKILL.md provides a concise workflow overview with links to reference files for each stage: - reference/interpreting-input.md: version format mapping rules, clarification prompts for ambiguous input, and usage examples - reference/parameters.md: full script parameter reference (version, feed, and switch parameters) - reference/progress-monitoring.md: disk-based progress monitoring to report newly generated diff files during script execution
ericstj
reviewed
Feb 10, 2026
Co-authored-by: Eric StJohn <ericstj@microsoft.com>
Reduce the skill's responsibility to a single job: interpret the user's prompt, map it to RunApiDiff.ps1 parameters, and run the script. Remove interactive clarification flows, progress monitoring via disk polling, and duplicated parameter logic that was redundant with RunApiDiff.md/ps1. Add note about ANSI progress bar output making completion detection difficult, instructing agents to check process exit status instead. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Change PreviousNuGetFeed default from nuget.org to the dnceng public transport feed constructed from PreviousMajorMinor, matching the existing CurrentNuGetFeed behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
DiscoverVersionFromFeed now accepts an sdkName parameter instead of hardcoding microsoft.netcore.app.ref, enabling version queries for AspNetCore and WindowsDesktop framework packs independently. ProcessSdk no longer passes exact NETCore versions to non-NETCore SDK downloads, allowing each framework to resolve its own version from the feed. This handles pre-.NET 10 releases where framework versions could differ. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace GetNextVersion (which hardcoded preview.7 → rc.1, rc.2 → ga) with GetNextVersionFromFeed that queries the NuGet feed to find the actual next milestone. This handles any number of previews or RCs without assumptions about the release cadence. When no newer version exists on the same major, the function probes the next major version's feed automatically. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove reference/interpreting-input.md and reference/parameters.md, consolidating the skill into a single file. The skill now only adds natural language to parameter mapping and defers to RunApiDiff.md for the full parameter reference. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Running the API Diff for 11.0.0-preview.1 revealed some opportunities to make this script more user-friendly. The first hurdle faced was the search index for the staging NuGet feed for preview.1 did not have any results, and this led to needing to find all of the version parameter values through other means. Copilot CLI figured it all out, but it was difficult to achieve by hand, and its results weren't fully deterministic. Once the logic was understood, this led to a series of Copilot-authored improvements to the script and documentation with each step captured as its own commit.
A lot of the documentation and logic was based on running the diff after a release was published, but we began running it before the releases during .NET 10 and we intend to continue that approach going forward.