Skip to content

Switch to PublicApiAnalyzers #7018

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Nov 22, 2021

Conversation

rainersigwald
Copy link
Member

@rainersigwald rainersigwald commented Nov 5, 2021

Abandon GenAPI for the new hotness in public API change tracking, which

  1. Is a Roslyn analyzer.
  2. Works cross-platform.
  3. Has clear messages.
  4. Actually tracks the API, instead of making us do it manually on review.

Based off the vs17.0 branch so I didn't accidentally canonize new API.

This is the modern replacement for GenAPI that Roslyn itself has been
using for a while, and it makes clearer errors and works cross-platform.
This is also public, shipping API.
with

  <Target Name="CreatePublicAPI" BeforeTargets="BeforeBuild">
    <MakeDir Directories="@(AdditionalFiles->'%(RootDir)%(Directory)')" />
    <Touch Files="@(AdditionalFiles)" AlwaysCreate="true" />
  </Target>
Get-ChildItem -Recurse PublicAPI.Shipped.txt | % {Remove-Item $_}
Get-ChildItem -Recurse PublicAPI.Unshipped.txt | % {Rename-Item $_ PublicAPI.Shipped.txt -Force ; New-Item $_ -ItemType file}
The vast majority of our API is not nullable aware so disable this.
The generic parameter was correct but this avoids this C# error:

error CS1658: Type parameter declaration must be an identifier not a type. See also error CS0081.
The new PublicAPI.Shipped.txt stuff should do the trick.
@rainersigwald rainersigwald added the Area: Our Own Build Problems affecting the build or build infrastructure of the MSBuild repo itself. label Nov 5, 2021
@rainersigwald rainersigwald added this to the MSBuild 17.1 milestone Nov 5, 2021
@rainersigwald
Copy link
Member Author

@ladipro, I'd especially like your review on this because of the StringTools API-tracking stuff.

Copy link
Contributor

@jeffkl jeffkl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GenAPI has served us well but I'm excited to see us adopt more evolved solution!

@rainersigwald
Copy link
Member Author

The merge I just pushed will demonstrate what the errors look like in CI (that's totally why I'm doing it, nothing to do with laziness).

@rainersigwald
Copy link
Member Author

rainersigwald commented Nov 5, 2021

Not too bad IMO:

https://dev.azure.com/dnceng/public/_build/results?buildId=1456841&view=results

image

Now I'll push a better merge.

@rainersigwald
Copy link
Member Author

Now I'll push a better merge.

Let my failure to do this be a WARNING and a CAVEAT to this: I used "fix all in project" and it only did the first TF of that project. You can instead use "fix all in solution" to get everything (per dotnet/roslyn-analyzers#4954 (comment)).

<GenAPIAssemblyName>$(AssemblyName)</GenAPIAssemblyName>
<GenAPIAssemblyName Condition="'$(GenAPIAssemblyName)' == ''">$(MSBuildProjectName)</GenAPIAssemblyName>
<GenAPIShortFrameworkIdentifier Condition="$([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETFramework'">net</GenAPIShortFrameworkIdentifier>
<GenAPIShortFrameworkIdentifier Condition="$([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETStandard'">netstandard</GenAPIShortFrameworkIdentifier>
<GenAPIShortFrameworkIdentifier Condition="$([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETCoreApp'">netstandard</GenAPIShortFrameworkIdentifier>
<GenAPITargetPath>$(RepoRoot)ref\$(GenAPIAssemblyName)\$(GenAPIShortFrameworkIdentifier)\$(GenAPIAssemblyName).cs</GenAPITargetPath>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed GenAPITargetPath wasn't used before. Was it getting picked up somewhere else in the build, or was this an unused property?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was used in the GenAPI package's targets somewhere.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, and we're not using them anymore so should we get rid of some of these variables? Or proactively rename them to match the analyzer we're moving to.

Consider this a nit though.

This is used only in Debug and the difference is only the one thing
so I don't think it's worth having separate Debug/Release APIs.
Copy link
Member

@ladipro ladipro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thank you! What is supposed to go into the Unshipped files? The documentation just says they must exist; no details given.

@rainersigwald
Copy link
Member Author

What is supposed to go into the Unshipped files?

Lol, yeah, we should write up some docs. The PublicApiAnalyzers process goes like this:

  1. The analyzer keeps the PublicAPI.*.txt files updated.
  2. New API surface goes into PublicAPI.Unshipped.txt.
  3. At release time, we must manually promote the Unshipped public API to Shipped

The idea is to distinguish between new public API surface in a given release (can still be changed if we figure out a better API shape, because we don't have to maintain compat with daily builds) and shipped public API surface (which we shouldn't change because someone might be using it).

I'll write up a doc.

@Forgind Forgind added merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now. and removed merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now. labels Nov 8, 2021
Primarily to give a place to mention what we now need to do for
PublicApiAnalyzers.
This allows us to delete the `ref` folder entirely.

This was an intermediate state of D.B.targets:

```
  <PropertyGroup Condition="'$(GenerateReferenceAssemblySource)' == 'true'">
    <GenAPIAssemblyName>$(AssemblyName)</GenAPIAssemblyName>
    <GenAPIAssemblyName Condition="'$(GenAPIAssemblyName)' == ''">$(MSBuildProjectName)</GenAPIAssemblyName>
    <GenAPIShortFrameworkIdentifier Condition="$([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETFramework'">net</GenAPIShortFrameworkIdentifier>
    <GenAPIShortFrameworkIdentifier Condition="$([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETStandard'">netstandard</GenAPIShortFrameworkIdentifier>
    <GenAPIShortFrameworkIdentifier Condition="$([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETCoreApp'">netstandard</GenAPIShortFrameworkIdentifier>
    <PublicApiTfm Condition="$([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETFramework'">net</PublicApiTfm>
    <PublicApiTfm Condition="$([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETFramework' and $([MSBuild]::GetTargetFrameworkVersion('$(TargetFramework)')) == '3.5'">net35</PublicApiTfm>
    <PublicApiTfm Condition="$([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETStandard'">netstandard</PublicApiTfm>
    <PublicApiTfm Condition="$([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETCoreApp'">netstandard</PublicApiTfm>

    <GenAPIFolderPath>$(RepoRoot)ref\$(GenAPIAssemblyName)\$(GenAPIShortFrameworkIdentifier)\</GenAPIFolderPath>
  </PropertyGroup>

  <ItemGroup Condition="'$(GenerateReferenceAssemblySource)' == 'true'">
    <!-- Ensure API stability for shipping packages -->
    <PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" PrivateAssets="all" />

    <AdditionalFiles Include="PublicAPI/$(PublicApiTfm)/PublicAPI.Shipped.txt" />
    <AdditionalFiles Include="PublicAPI/$(PublicApiTfm)/PublicAPI.Unshipped.txt" />
  </ItemGroup>

  <Target Name="MovePublicAPI" BeforeTargets="BeforeBuild" Condition="'$(GenerateReferenceAssemblySource)' == 'true'">
    <MakeDir Directories="$(MSBuildProjectDirectory)/PublicAPI/$(PublicApiTfm)" />
    <Copy SourceFiles="$(GenAPIFolderPath)PublicAPI.Shipped.txt;$(GenAPIFolderPath)PublicAPI.Unshipped.txt"
      DestinationFolder="$(MSBuildProjectDirectory)/PublicAPI/$(PublicApiTfm)" />
  </Target>
  ```
Conflicts:
	ref/Microsoft.Build/net/Microsoft.Build.cs
	ref/Microsoft.Build/netstandard/Microsoft.Build.cs
@Forgind Forgind added the merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now. label Nov 17, 2021
@rainersigwald rainersigwald merged commit 2127450 into dotnet:main Nov 22, 2021
@rainersigwald rainersigwald deleted the publicapianalyzers branch November 22, 2021 17:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Our Own Build Problems affecting the build or build infrastructure of the MSBuild repo itself. merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants