Skip to content

Commit

Permalink
PublicApiAnalyzer refinements (#3677)
Browse files Browse the repository at this point in the history
  • Loading branch information
tobias-tengler committed Jun 27, 2021
1 parent 233f245 commit d2d09d8
Show file tree
Hide file tree
Showing 14 changed files with 118 additions and 262 deletions.
26 changes: 13 additions & 13 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,27 @@
"tools": {
"dotnet-sonarscanner": {
"version": "4.8.0",
"commands": [
"dotnet-sonarscanner"
]
"commands": ["dotnet-sonarscanner"]
},
"boost.tool": {
"version": "0.2.6",
"commands": [
"boo"
]
"commands": ["boo"]
},
"dotnet-format": {
"version": "5.1.225507",
"commands": [
"dotnet-format"
]
"commands": ["dotnet-format"]
},
"nuke.globaltool": {
"version": "5.1.2",
"commands": [
"nuke"
]
"commands": ["nuke"]
},
"dotnet-format": {
"version": "5.1.225507",
"commands": ["dotnet-format"]
},
"nuke.globaltool": {
"version": "5.1.2",
"commands": ["nuke"]
}
}
}
}
62 changes: 1 addition & 61 deletions .devops/azure-pipelines.release-hotchocolate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,8 @@ stages:
dependsOn: []
continueOnError: true
strategy:
parallel: 5
parallel: 2
steps:
- task: UseDotNet@2
displayName: "Install .NET Core 2.1"
inputs:
packageType: 'sdk'
version: '2.1.816'
- task: UseDotNet@2
displayName: "Install .NET Core 3.1"
inputs:
packageType: 'sdk'
version: '3.1.409'
- task: UseDotNet@2
displayName: "Install .NET 5.0"
inputs:
packageType: 'sdk'
version: '5.0.300'
- task: UseDotNet@2
displayName: "Install .NET Core"
inputs:
packageType: 'sdk'
useGlobalJson: true
- task: CmdLine@2
displayName: "Run Tests"
inputs:
Expand All @@ -47,26 +27,6 @@ stages:
displayName: "Pack"
dependsOn: []
steps:
- task: UseDotNet@2
displayName: "Install .NET Core 2.1"
inputs:
packageType: 'sdk'
version: '2.1.816'
- task: UseDotNet@2
displayName: "Install .NET Core 3.1"
inputs:
packageType: 'sdk'
version: '3.1.409'
- task: UseDotNet@2
displayName: "Install .NET 5.0"
inputs:
packageType: 'sdk'
version: '5.0.300'
- task: UseDotNet@2
displayName: "Install .NET Core"
inputs:
packageType: 'sdk'
useGlobalJson: true
- task: CmdLine@2
displayName: "Create Packages"
inputs:
Expand All @@ -80,26 +40,6 @@ stages:
displayName: "Publish"
dependsOn: [Test, Pack]
steps:
- task: UseDotNet@2
displayName: "Install .NET Core 2.1"
inputs:
packageType: 'sdk'
version: '2.1.816'
- task: UseDotNet@2
displayName: "Install .NET Core 3.1"
inputs:
packageType: 'sdk'
version: '3.1.409'
- task: UseDotNet@2
displayName: "Install .NET 5.0"
inputs:
packageType: 'sdk'
version: '5.0.300'
- task: UseDotNet@2
displayName: "Install .NET Core"
inputs:
packageType: 'sdk'
useGlobalJson: true
- task: DownloadBuildArtifacts@0
displayName: "Download Packages"
inputs:
Expand Down
20 changes: 0 additions & 20 deletions .devops/azure-pipelines.sonar-hotchocolate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,6 @@ stages:
displayName: "Sonar"
dependsOn: [ ]
steps:
- task: UseDotNet@2
displayName: "Install .NET Core 2.1"
inputs:
packageType: 'sdk'
version: '2.1.816'
- task: UseDotNet@2
displayName: "Install .NET Core 3.1"
inputs:
packageType: 'sdk'
version: '3.1.409'
- task: UseDotNet@2
displayName: "Install .NET 5.0"
inputs:
packageType: 'sdk'
version: '5.0.300'
- task: UseDotNet@2
displayName: "Install .NET Core"
inputs:
packageType: 'sdk'
useGlobalJson: true
- task: JavaToolInstaller@0
displayName: "Install Java"
inputs:
Expand Down
20 changes: 0 additions & 20 deletions .devops/azure-pipelines.sonar-pr-hotchocolate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,6 @@ stages:
displayName: "Sonar Pull-Request"
dependsOn: []
steps:
- task: UseDotNet@2
displayName: "Install .NET Core 2.1"
inputs:
packageType: 'sdk'
version: '2.1.816'
- task: UseDotNet@2
displayName: "Install .NET Core 3.1"
inputs:
packageType: 'sdk'
version: '3.1.409'
- task: UseDotNet@2
displayName: "Install .NET 5.0"
inputs:
packageType: 'sdk'
version: '5.0.300'
- task: UseDotNet@2
displayName: "Install .NET Core"
inputs:
packageType: 'sdk'
useGlobalJson: true
- task: JavaToolInstaller@0
displayName: "Install Java"
inputs:
Expand Down
22 changes: 1 addition & 21 deletions .devops/azure-pipelines.test-pr-hotchocolate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,8 @@ stages:
dependsOn: []
continueOnError: true
strategy:
parallel: 5
parallel: 2
steps:
- task: UseDotNet@2
displayName: "Install .NET Core 2.1"
inputs:
packageType: 'sdk'
version: '2.1.816'
- task: UseDotNet@2
displayName: "Install .NET Core 3.1"
inputs:
packageType: 'sdk'
version: '3.1.409'
- task: UseDotNet@2
displayName: "Install .NET 5.0"
inputs:
packageType: 'sdk'
version: '5.0.300'
- task: UseDotNet@2
displayName: "Install .NET Core"
inputs:
packageType: 'sdk'
useGlobalJson: true
- task: CmdLine@2
displayName: "Run Tests"
inputs:
Expand Down
16 changes: 16 additions & 0 deletions .github/workflows/check-public-api.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Check Public API

on:
pull_request:
branches:
- main

jobs:
check-public-api:
name: "Check Public API"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-dotnet@v1
- run: ./build.sh CheckPublicApi
name: "Check for undocumented public API changes"
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -311,3 +311,6 @@ src/All.sln

# asp .net core
appsettings.user.json

# Nuke
.nuke/temp
94 changes: 72 additions & 22 deletions API-Baselines.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,58 @@ This document contains information regarding API baseline files and how to work

## Files

Each project contains two files tracking the public API surface of this project.
Each project contains two files tracking the public API surface of said project. These files are used by the [Microsoft.CodeAnalysis.PublicApiAnalyzers](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers) roslyn analyzer as a reference to what the public API surface looked like previously.

### PublicAPI.Shipped.txt

This file contains APIs that were released in the last major version.

This file should only be modified after a major release by the maintainers and should never be modified otherwise. There is a [script](#scripts) to perform this automatically.
This file should only be modified after a major release by the maintainers and should never be modified otherwise. There is a [script](#MarkApiShipped) to perform this automatically.

### PublicAPI.Unshipped.txt

This file contains API changes since the last major version.

## Scenarios
## Types of public API changes

There are three types of public API changes that need to be documented.

### New APIs

A new entry needs to be added to the `PublicAPI.Unshipped.txt` file for a new API. For example:
This case will be indicated by an error/warning like the following:

```
RS0016: Symbol 'X' is not part of the declared API
```

It can be resolved by adding the new symbol to the `PublicAPI.Unshipped.txt` file:

```
#nullable enable
Microsoft.AspNetCore.Builder.NewApplicationBuilder.New() -> Microsoft.AspNetCore.Builder.IApplicationBuilder!
```

Your IDE should warn you about this case and prompt you to add the new API to `PublicAPI.Unshipped.txt`. It will also be displayed as a warning in the build output.
This change can be performed automatically by your IDE or using a [script](#AddUnshipped).

> Note: Currently not every IDE supports Code-Fixes provided by a Roslyn Analyzer. Visual Studio Code for example does not at the moment - Visual Studio 2019 does.
> Note: Be sure to apply the Code-Fix on a solution level, if there are many new APIs that need to be documented.
> ![image](https://user-images.githubusercontent.com/45513122/119241399-47bbbe80-bb56-11eb-9253-92e2878cd428.png)
### Removed APIs

A new entry needs to be added to the `PublicAPI.Unshipped.txt` file for a removed API. For example:
This case will be indicated by an error/warning like the following:

```
RS0017: Symbol 'X' is part of the declared API, but is either not public or could not be found
```

It can be resolved by adding the removed symbol to the `PublicAPI.Unshipped.txt` file:

```
#nullable enable
*REMOVED*Microsoft.Builder.OldApplicationBuilder.New() -> Microsoft.AspNetCore.Builder.IApplicationBuilder!
```

This change needs to be done by hand. Copy the relevant line from `PublicAPI.Shipped.txt` into `PublicAPI.Unshipped.txt` and place `*REMOVED*` in front of it.
This change needs to be done manually. Copy the relevant line from `PublicAPI.Shipped.txt` into `PublicAPI.Unshipped.txt` and place `*REMOVED*` in front of it.

### Updated APIs

Expand All @@ -54,7 +67,7 @@ Two new entries need to be added to the `PublicAPI.Unshipped.txt` file for an up
Microsoft.AspNetCore.DataProtection.Infrastructure.IApplicationDiscriminator.Discriminator.get -> string?
```

The removed case needs to be handled by hand as explained [here](#removed-apis).
The removed case needs to be done manually as explained [here](#removed-apis).

## Ignoring projects

Expand All @@ -72,33 +85,70 @@ If you need to manually ignore a project, include the following in its `.csproj`

The two text files mentioned above need to be added to each new project.

There is a template file called `PublicAPI.empty.txt` in the `scripts` directory that can be copied over into a new project.
There is a template file called `PublicAPI.empty.txt` in the `src` directory that can be copied over into a new project.

```sh
cp scripts/PublicAPI.empty.txt src/<new-project-folder>/PublicAPI.Shipped.txt
cp scripts/PublicAPI.empty.txt src/<new-project-folder>/PublicAPI.Unshipped.txt
DIR="<new-project-folder>"
cp "src/PublicAPI.empty.txt" "src/$DIR/PublicAPI.Shipped.txt"
cp "src/PublicAPI.empty.txt" "src/$DIR/PublicAPI.Unshipped.txt"
```

## Pipeline Job

A PR to `main` will trigger a Pipeline job that runs the [CheckPublicApi script](#CheckPublicApi).

The job is defined as part of [this Pipeline definition](./.github/workflows/check-public-api.yml).

## Scripts

There are three scripts to help you manage the `PublicAPI.*.txt` files. They can be found [here](./scripts).
There are some helpful scripts that accommodate working with the analyzer.

### mark-api-shipped.ps1
The scripts can be executed via _Nuke_. Choose the appropriate `build` script for your platform (in the root directory) and pass one of the following arguments.

This transfers all changes in the `PublicAPI.Unshipped.txt` to the `PublicAPI.Shipped.txt` files.
### CheckPublicApi

It also takes care of removing lines marked with `*REMOVE*` (removals of APIs).
Executes a build and fails if there are undocumented changes.

### display-unshipped-api.ps1
```bash
./build.sh CheckPublicApi
```

This will output the contents of all `PublicAPI.Unshipped.txt` files throughout the project.
### AddUnshipped

### diff-shipped-api.ps1
This will use the `dotnet-format` tool to fix all the `RS0016` warnings of the `Microsoft.CodeAnalysis.PublicApiAnalyzers`.

```bash
./build.sh AddUnshipped
```

### DiffShippedApi

This shows all changes of `PublicAPI.Shipped.txt` files between git refs. Tags, commit hashes and branch names are supported.

Example:
```bash
./build.sh DiffShippedApi --from 11.0.0 --to 12.0.0
```

### DisplayUnshippedApi

```sh
diff-shipped-api.ps1 -from 11.0.0 -to 12.0.0
This will output the contents of all `PublicAPI.Unshipped.txt` files throughout the project.

```bash
./build.sh DisplayUnshippedApi
```

If we only want to see the breaking changes, we can add the `breaking` flag:

```bash
./build.sh DisplayUnshippedApi --breaking
```

### MarkApiShipped

This transfers all changes in the `PublicAPI.Unshipped.txt` to the `PublicAPI.Shipped.txt` files.

It also takes care of removing lines marked with `*REMOVE*` (removals of APIs).

```bash
./build.sh MarkApiShipped
```
Loading

0 comments on commit d2d09d8

Please sign in to comment.