Skip to content

build: adopt PublicApiSharp.Analyzers for public API tracking - #4428

Merged
glennawatson merged 3 commits into
mainfrom
chore/adopt-publicapisharp-analyzers
Aug 13, 2026
Merged

build: adopt PublicApiSharp.Analyzers for public API tracking#4428
glennawatson merged 3 commits into
mainfrom
chore/adopt-publicapisharp-analyzers

Conversation

@glennawatson

@glennawatson glennawatson commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

What kind of change does this PR introduce?

Build.

What is the new behavior?

Public API tracking moves to PublicApiSharp.Analyzers (PAS0001-PAS0005), matching Splat.

  • One PublicAPI.txt per project per target framework, holding nested C# that reads like source. Always current - no shipped/unshipped split and no promotion step, so an API change is reviewed as the diff itself.
  • Wired through EnablePublicApiBaseline; the package resolves the per-TFM baseline, so the AdditionalFiles glob is gone.
  • 232 baselines, covering every target framework including Apple.
  • The generated *_wpftmp projects are excluded from tracking: they sit in the real project's directory and resolve the same baseline path, so they overwrote it.

Two defects turned up while getting the build green, fixed here:

  • Samples, tests and benchmarks were still tracked. Each folder's Directory.Build.props sets TrackPublicApi to false, but it did so after importing the root props - which had already defaulted the value, derived EnablePublicApiBaseline from it and added the analyzer PackageReference. Both survived the later override, so ReactiveUI.Benchmarks, ReactiveUI.Samples.Maui and the ReactiveUI.Test.Utilities / ReactiveUI.TestGuiMocks helpers were all one baseline resolution away from failing on PAS0004. src/tests escaped only because it sets IsTestProject before the import. Moving the property group above the import fixes all three; the root already guards its default with Condition="'$(TrackPublicApi)' == ''".
  • The MAUI sample emitted 3762 uncoded warnings on Android. Unrelated to public API, but it blocked -warnaserror on the solution. See the commit for the mechanism; a stock dotnet new maui app reproduces it identically and the Android 37 band does not.

What is the current behavior?

Microsoft.CodeAnalysis.PublicApiAnalyzers with a PublicAPI.Shipped.txt / PublicAPI.Unshipped.txt pair per target framework, and tools/generate-publicapi.* to fold one into the other.

What might this PR break?

  • No product code changed and no public API changed; the baselines are a re-expression of the existing surface in the new format.
  • tools/generate-publicapi.sh / .ps1 are removed. To regenerate a baseline, empty it first, then run:
    dotnet format analyzers <proj> -f <tfm> --diagnostics PAS0001 PAS0003 --severity info
    The fix only adds and updates entries. A member that has since been removed is PAS0002, which has no code fix, so regenerating in place leaves a stale entry behind and fails the next build.

Checklist

  • I have read the Contribute guide
  • Tests have been added or updated (for bug fixes / features)
  • Docs have been added or updated (for bug fixes / features)
  • Changes target the main branch
  • PR title follows Conventional Commits

Additional information

Every baseline was regenerated from empty against current main, on .NET 11 preview 7 on both hosts:

  • 168 on Linux - the base, net4x, -windows and Android target frameworks.
  • 64 on a real Windows guest, which has the ios / tvos / macos / maccatalyst workloads Linux cannot install. Which target frameworks a project even offers is host-dependent, so each host is asked what it can build rather than told.

Verified two ways, both from clean:

  • dotnet build reactiveui.slnx -c Release -t:Rebuild -warnaserror on Linux: 0 warnings, 0 errors.
  • dotnet build reactiveui.slnx -c Release on real Windows: no errors. This is what actually checks the Apple, Windows and net4x baselines, since PAS0001/PAS0002/PAS0003 are errors by default.

glennawatson added a commit that referenced this pull request Aug 13, 2026
## What kind of change does this PR introduce?

Build.

## What is the new behavior?

`PublicApiSharp.Analyzers` moves to 1.0.7.

- 1.0.7 fixes the enum-member comparison, so a public enum whose
baseline is already correct no longer reports PAS0003.
- No baseline is regenerated. A full `dotnet build reactiveui.slnx -c
Release -t:Rebuild` produces no PAS diagnostics of any ID, so all 232
baselines still match byte-for-byte.

## What is the current behavior?

`PublicApiSharp.Analyzers` 1.0.5, as introduced by #4428. This PR
targets that branch, because `main` has no reference to the package at
all.

1.0.6 was tried first and is unusable here: it renders enum members with
their trailing separator but parses the baseline without it, so every
public enum member fails.

```
error PAS0003: 'Refresh = 4,' differs from the baseline;
  baseline declares 'Refresh = 4' but the API is 'Refresh = 4,'
```

That was 10 members across the three public enums in `ReactiveUI.Core`,
over 26 target frameworks - 130 errors - and no baseline could satisfy
it. `dotnet format analyzers` wrote zero changes (the fixer agreed the
file was already correct), and hand-editing the baseline to the
comma-less form the message asks for made it unparseable with `PAS0005:
Syntax error, ',' expected`.

## What might this PR break?

- None. No product code and no public API changed, and no baseline file
changed.

## Checklist
- [x] I have read the [Contribute
guide](https://www.reactiveui.net/contribute/index.html)
- [ ] Tests have been added or updated (for bug fixes / features)
- [ ] Docs have been added or updated (for bug fixes / features)
- [ ] Changes target the `main` branch
- [x] PR title follows [Conventional
Commits](https://www.conventionalcommits.org/)

## Additional information

Verified on Linux, so the Apple target framework baselines were not
exercised; everything Linux can compile, including the Windows target
frameworks via `EnableWindowsTargeting`, is green. The full solution
rebuild reports 0 errors. The only warnings come from
`examples/ReactiveUI.Samples.Maui` - un-IDed JNI registration notices
emitted by `Xamarin.Android.Common.targets` - and are unrelated to this
change.
@glennawatson
glennawatson force-pushed the chore/adopt-publicapisharp-analyzers branch from dfbf267 to 4c128b3 Compare August 13, 2026 03:28
- Track the public surface as one always-current PublicAPI.txt per project
  per target framework, holding nested C# that reads like source, so an API
  change is reviewed as the diff itself.
- Drop the shipped/unshipped pair and its promotion step, along with
  Microsoft.CodeAnalysis.PublicApiAnalyzers and tools/generate-publicapi.*.
- Resolve the baseline through EnablePublicApiBaseline; the package's targets
  add it per inner build, so the AdditionalFiles glob is no longer needed.
- Exclude the generated *_wpftmp projects, which sit in the real project's
  directory and would otherwise overwrite its baseline.
- Set TrackPublicApi before the root import in the examples, tests and
  benchmarks props. Setting it after left the derived EnablePublicApiBaseline
  and the analyzer reference switched on, so those projects were still tracked.
…AUI sample

The release link on the .NET 10 Android band (AndroidLinkMode=SdkOnly) strips
the connector, the n_ native callback and the delegate backing field out of
Mono.Android.dll before the marshal-method classifier looks for them. It finds
none of the registration pattern, so all 470 methods fall back to dynamic
registration - and say so, twice per method per ABI, as warnings the SDK logs
with no diagnostic code. No NoWarn can reach them and -warnaserror turns them
into a failed build.

- Turn marshal methods off for the android target framework, which states what
  the band already does rather than changing how the app registers anything.
- A stock `dotnet new maui` app reproduces it identically and the 37 band does
  not, so this is the toolchain rather than anything in this repository.
@glennawatson
glennawatson force-pushed the chore/adopt-publicapisharp-analyzers branch from 4c128b3 to 3cf8d5d Compare August 13, 2026 03:29
- MauiVersion to 11.0.0-preview.7.26406.9, matching the MAUI workload manifest.
- AspNetVersion, MicrosoftExtensionsVersion and SystemTextJsonVersion to
  11.0.0-preview.7.26381.103, matching the SDK.
- Microsoft.Maui.Controls.Compatibility stays put; it ships no preview 6 or 7
  and is already conditioned to net10.
@codecov

codecov Bot commented Aug 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.89%. Comparing base (efa283c) to head (86fcd69).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4428   +/-   ##
=======================================
  Coverage   93.89%   93.89%           
=======================================
  Files         359      359           
  Lines       15104    15104           
  Branches     1568     1568           
=======================================
  Hits        14182    14182           
  Misses        679      679           
  Partials      243      243           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sonarqubecloud

Copy link
Copy Markdown

@glennawatson
glennawatson merged commit 749b862 into main Aug 13, 2026
13 checks passed
@glennawatson
glennawatson deleted the chore/adopt-publicapisharp-analyzers branch August 13, 2026 05:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants