Sort the public API tracking files, with a script that keeps them that way - #3245
Merged
Merged
Conversation
The analyzer does not care about order and its code fix appends, so these files accrete in whatever order entries were added and drift out of any order they are put into - RESPite's 236-line shipped file was unsorted too, so this is drift rather than one file having been neglected. Nothing keeps them sorted between runs, so the script is what does, at a moment somebody is already editing them. Sorting and promotion are separate, and promotion is opt-in: "shipped" means released and frozen, so folding unshipped in mid-cycle would freeze API that has not shipped and cannot then change without it looking like a break. Default is sort-only; --promote is the release step; --check writes nothing and exits 1, for CI if we want it later. The sort key strips the modifier (and any [SERxxx] annotation) rather than sorting the raw line. That is the whole point: sorting raw groups by modifier instead, so a type's surface splits across abstract/override/static/virtual blocks and a bare one. RedisValue went from 7 blocks to 1, ConfigurationOptions from 10 to 1; sorting raw would have left both at 4, which is a 3000-line reorder that still cannot show a type in one place. Run here with no --promote, since unshipped is empty after 3.2.15 - so this is purely the sort. Verified it is a pure reorder: same entry multiset and same counts in all three files before and after, plus a clean full build and a RunAnalyzers=true sweep, which is what actually exercises RS0016/RS0017 on every target framework. Re-running is a no-op.
mgravell
added a commit
that referenced
this pull request
Sep 17, 2026
One conflict, in PublicAPI.Unshipped.txt, and it is the promotion rather than anything this branch did: main moved the five RedisValue.EqualityComparer entries into Shipped when 3.2.15 went out, while this branch still carried them alongside its own 76. Resolved by keeping this branch's entries and dropping those five - they are in Shipped now, and confirmed present there before removing them, since a duplicate across the two files is what RS0025 rejects. Unshipped is then sorted with eng/public-api.py, which arrived in the same merge. That is the case it exists for: this file is append-only across branches, so it is where API additions collide, and sorting it is what stops the next one landing in the same place. Verified with a clean full-solution build, a RunAnalyzers=true sweep of the library - the thing that actually exercises RS0016/RS0017 per target framework - and --check reporting nothing left to do.
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.
Adds
eng/public-api.pyand runs it. The diff is large but the content is unchanged - verified as a pure reorder, see below.Previously pushed straight to main as 213f3c3 and reverted in 17e16f1: a 3000-line reorder that conflicts with open PRs wants review first, whatever the mechanical verification says. Nothing is wrong with the content.
Why a script
The analyzer does not care about order and its code fix appends, so these files accrete in whatever order entries were added and drift out of any order they are put into. RESPite's 236-line shipped file was unsorted too, so this is general drift rather than one neglected file - nothing maintains order between runs. The script is what does, run at a moment somebody is already editing them.
Promotion is opt-in on purpose. "Shipped" means released and frozen, so folding unshipped in mid-cycle would freeze API that has not shipped and then cannot change without it looking like a break. Promotion belongs to the release: ship the package, then promote. This PR runs with no
--promote, since unshipped is empty after 3.2.15 - so it is purely the sort.The sort key is the point
It strips the modifier (and any
[SERxxx]annotation) rather than sorting the raw line, so a type's surface stays in one block. Sorting raw groups by modifier instead:RedisValue.*(68 entries)ConfigurationOptions.*(117)A 3000-line reorder that still cannot show a type in one place would not be worth doing.
Verification
/p:RunAnalyzers=truebuild of the library - which is what actually exercises RS0016/RS0017 on every target framework, since analyzers otherwise run on one TFM only.Cost worth weighing before merging
This conflicts with the open PRs that touch
PublicAPI.Shipped.txt- #2107, #2221, #2547, #2838 (which appends 132 lines), #2959, #3125. Each resolves by re-adding its entries and re-running the script, but that is real work for whoever owns them, and some are old enough that a conflict may finish them off.If that is too disruptive now, the alternative moment is the v4 break, when those branches need rebasing anyway and the churn is already priced in. The script is useful either way.
Not included
A CI step running
--check. Without one this will drift again, but it is a separate decision - say the word and it is one line in the workflow.