Skip to content

Commit 298285b

Browse files
authored
Adding public API to all manual projects (#779)
* Adding public API to all manual projects * Add `nuke shipapi`, `nuke ensureapideclared`, and `nuke declareapi` * Attempt to make GitHub talk to you * Add some logging, fix a potential regex issue * Actually pass the GitHub Token * The code was correct the first time * Fix basic logic * Try give the token more permissions? * PR target * Let's hope this PR mechanism works? Can't test until merged now! * Install workload as well * Make BuildTools exempt from public API
1 parent 2269659 commit 298285b

File tree

146 files changed

+13315
-96
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

146 files changed

+13315
-96
lines changed

.editorconfig

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11

22
[*]
33
charset = utf-8
4-
end_of_line = crlf
4+
end_of_line = lf
55
trim_trailing_whitespace = false
6-
insert_final_newline = false
6+
insert_final_newline = true
77
indent_style = space
88
indent_size = 4
99

@@ -35,6 +35,16 @@ dotnet_style_qualification_for_property = false:warning
3535
dotnet_style_require_accessibility_modifiers = for_non_interface_members:hint
3636
csharp_style_inlined_variable_declaration = true:hint
3737
dotnet_sort_system_directives_first = true
38+
dotnet_public_api_analyzer.require_api_files = true
39+
dotnet_diagnostic.RS0016.severity = error
40+
dotnet_diagnostic.RS0017.severity = error
41+
42+
# we should care more about this one day
43+
dotnet_diagnostic.RS0041.severity = warn
44+
45+
# public api warnings silk.net doesn't care about
46+
dotnet_diagnostic.RS0026.severity = none # Don't add multiple public overloads with optional parameters
47+
dotnet_diagnostic.RS0027.severity = none # Overloads w/ optional parameters should have the most parameters of all overloads
3848

3949
# ReSharper properties
4050
resharper_autodetect_indent_settings = true
@@ -77,4 +87,4 @@ tab_width = 4
7787

7888
# License header + warning generated if missing
7989
file_header_template=Licensed to the .NET Foundation under one or more agreements.\nThe .NET Foundation licenses this file to you under the MIT license.
80-
dotnet_diagnostic.IDE0073.severity = warning
90+
dotnet_diagnostic.IDE0073.severity = warning

.github/workflows/public-api.yml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
name: Public API
2+
on:
3+
push:
4+
branches:
5+
- "*"
6+
create:
7+
tags:
8+
- "*"
9+
pull_request_target:
10+
permissions:
11+
issues: write
12+
pull-requests: write
13+
jobs:
14+
Check:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v2
18+
with:
19+
token: ${{ secrets.PUSHABLE_GITHUB_TOKEN }}
20+
ref: "refs/pull/${{ github.event.number }}/merge"
21+
path: inbound_pr
22+
- name: Add workloads for restore
23+
run: |
24+
dotnet workload install android
25+
- name: Checkout submodules, configure git
26+
run: |
27+
git -c submodule.third_party/git-hooks.update=none submodule update --init --recursive
28+
git config --local user.email "9011267+dotnet-bot@users.noreply.github.com"
29+
git config --local user.name "The Silk.NET Automaton"
30+
- name: Cache .tmp, ~/.nuget/packages
31+
uses: actions/cache@v2
32+
with:
33+
path: |
34+
.tmp
35+
~/.nuget/packages
36+
key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj') }}
37+
- name: Setup .NET 6.0
38+
uses: actions/setup-dotnet@v1
39+
with:
40+
dotnet-version: 6.0.100
41+
- name: Ensure Public API Declared
42+
run: ./build.sh EnsureApiDeclared
43+
env:
44+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
45+
Ship:
46+
if: ${{ github.repository == 'dotnet/Silk.NET' && github.event_name == 'create' }}
47+
runs-on: ubuntu-latest
48+
steps:
49+
- uses: actions/checkout@v2
50+
with:
51+
token: ${{ secrets.PUSHABLE_GITHUB_TOKEN }}
52+
- name: Checkout submodules, configure git
53+
run: |
54+
git -c submodule.third_party/git-hooks.update=none submodule update --init --recursive
55+
git config --local user.email "9011267+dotnet-bot@users.noreply.github.com"
56+
git config --local user.name "The Silk.NET Automaton"
57+
- name: Cache .tmp, ~/.nuget/packages
58+
uses: actions/cache@v2
59+
with:
60+
path: |
61+
.tmp
62+
~/.nuget/packages
63+
key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj') }}
64+
- name: Setup .NET 6.0
65+
uses: actions/setup-dotnet@v1
66+
with:
67+
dotnet-version: 6.0.100
68+
- name: Ship Public API
69+
run: ./build.sh ShipApi
70+
env:
71+
PUSHABLE_GITHUB_TOKEN: ${{ secrets.PUSHABLE_GITHUB_TOKEN }}

build/comments/footer.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
---
3+
4+
<sub>This is an automated comment from Silk.NET's NUKE DevOps solution, created from [a GitHub Actions run](https://github.com/dotnet/Silk.NET/actions/runs/{actionsRun}). If this was created by mistake, just let a maintainer know and they'll happily ignore this. Comment type: `{typeId}`</sub>

build/comments/public_api_declared.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
![Public API Declared](https://img.shields.io/badge/public%20api-declared-green)
2+
3+
Public API issues have been fixed 🎉
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
![Public API Not Declared](https://img.shields.io/badge/public%20api-not%20declared-red)
2+
3+
Thanks for your contribution adding to the Silk.NET API surface! Note that for manual projects we use the [Public API Analyzer](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md) wherein the entirety of the public API (for manual projects) are tracked in text files, in hope that this analyzer will warn us about breaking changes before we make them.
4+
5+
It looks like you either:
6+
- haven't added all of your new APIs into this text file. Don't worry, it's a simple fix, you can do this automatically by running `nuke declareapi` and pushing the changed `PublicAPI.Unshipped.txt` files.
7+
- have made a breaking change 😮 If this is intentional, make sure you talk to a maintainer!
8+
9+
This comment will automatically update once you've fixed this issue! For more information see:
10+
- [Public API Analyzers Help](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
11+
- [Public API Analyzers Diagnostic Descriptions](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/Microsoft.CodeAnalysis.PublicApiAnalyzers.md)
12+
- [The GitHub Actions Run That Flagged This](https://github.com/dotnet/Silk.NET/actions/runs/{actionsRun})
13+
14+
(Note to maintainers: this comment won't stop you from merging so if you're fine with this just merge anyway)

build/nuke/Build.PublicApi.cs

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.IO;
6+
using System.Linq;
7+
using Nuke.Common;
8+
using Nuke.Common.CI.GitHubActions;
9+
using Nuke.Common.IO;
10+
using Nuke.Common.Tooling;
11+
using Octokit;
12+
using Octokit.Internal;
13+
using static Nuke.Common.Tools.Git.GitTasks;
14+
using static Nuke.Common.Tooling.ProcessTasks;
15+
using static Nuke.Common.Tools.DotNet.DotNetTasks;
16+
17+
partial class Build
18+
{
19+
const string FormatDeclCmd =
20+
"format analyzers {0} --diagnostics=RS0016 --severity=error -v=diag --include-generated";
21+
22+
Target ShipApi => CommonTarget
23+
(
24+
x => x.Executes
25+
(
26+
() =>
27+
{
28+
foreach (var unshippedFile in RootDirectory.GlobFiles("**/PublicAPI.Unshipped.txt"))
29+
{
30+
var shippedFile = unshippedFile.Parent / "PublicAPI.Shipped.txt";
31+
if (!File.Exists(shippedFile))
32+
{
33+
// common.props should've made this file, so if it's not here then i'm guessing this isn't a
34+
// public api after all.
35+
continue;
36+
}
37+
38+
var shippedLines = File.ReadAllLines(shippedFile).ToList();
39+
var unshippedLines = File.ReadAllLines(unshippedFile).ToList();
40+
for (var i = 0; i < unshippedLines.Count; i++)
41+
{
42+
var unshippedLine = unshippedLines[i];
43+
if (unshippedLine.StartsWith("//") || unshippedLine.StartsWith("#"))
44+
{
45+
continue;
46+
}
47+
48+
if (!shippedLines.Contains(unshippedLine))
49+
{
50+
shippedLines.Add(unshippedLine);
51+
}
52+
53+
unshippedLines.RemoveAt(i);
54+
i--; // so we don't skip the next element
55+
}
56+
57+
File.WriteAllLines(unshippedFile, unshippedLines);
58+
File.WriteAllLines(shippedFile, shippedLines);
59+
}
60+
61+
MakePr();
62+
}
63+
)
64+
);
65+
66+
Target DeclareApi => CommonTarget(x => x.Executes(() => DotNet(string.Format(FormatDeclCmd, "Silk.NET.sln"))));
67+
68+
Target EnsureApiDeclared => CommonTarget
69+
(
70+
x => x.Executes
71+
(
72+
async () =>
73+
{
74+
try
75+
{
76+
var cmd = string.Format
77+
(
78+
FormatDeclCmd,
79+
GitHubActions.Instance.GitHubRef?.Contains("/pull/") ?? false
80+
? "inbound_pr/Silk.NET.sln"
81+
: "Silk.NET.sln"
82+
);
83+
84+
// I have no trust of incoming code, so let's take the github token away from them before they think
85+
// about adding dodgy MSBuild targets that could swipe it
86+
var githubToken = EnvironmentInfo.GetVariable<string>("GITHUB_TOKEN");
87+
EnvironmentInfo.SetVariable("GITHUB_TOKEN", string.Empty);
88+
89+
// run the format command
90+
DotNet($"{cmd} --verify-no-changes");
91+
92+
// add our github token back
93+
EnvironmentInfo.SetVariable("GITHUB_TOKEN", githubToken);
94+
await AddOrUpdatePrComment("public_api", "public_api_declared", true);
95+
}
96+
catch (ProcessException)
97+
{
98+
await AddOrUpdatePrComment("public_api", "public_api_not_declared");
99+
throw;
100+
}
101+
}
102+
)
103+
);
104+
105+
void MakePr()
106+
{
107+
var pushableToken = EnvironmentInfo.GetVariable<string>("PUSHABLE_GITHUB_TOKEN");
108+
var curBranch = GitCurrentBranch(RootDirectory);
109+
if (GitHubActions.Instance?.GitHubRepository == "dotnet/Silk.NET" &&
110+
!string.IsNullOrWhiteSpace(pushableToken))
111+
{
112+
if (curBranch == "HEAD" || string.IsNullOrWhiteSpace(curBranch))
113+
{
114+
curBranch = "main"; // not a good assumption to make, but fine for now for our purposes
115+
// (tags are created from main usually)
116+
}
117+
118+
// it's assumed that the pushable token was used to checkout the repo
119+
Git("fetch --all", RootDirectory);
120+
Git("pull");
121+
Git("add **/PublicAPI.*.txt", RootDirectory);
122+
var newBranch = $"ci/{curBranch}/ship_apis";
123+
var curCommit = GitCurrentCommit(RootDirectory);
124+
var commitCmd = StartProcess
125+
(
126+
$"git commit -m \"Move unshipped APIs to shipped\""
127+
)
128+
.AssertWaitForExit();
129+
if (!commitCmd.Output.Any(x => x.Text.Contains("nothing to commit", StringComparison.OrdinalIgnoreCase)))
130+
{
131+
commitCmd.AssertZeroExitCode();
132+
}
133+
134+
// ensure there are no other changes
135+
Git("checkout HEAD .nuke/", RootDirectory);
136+
Git("reset --hard", RootDirectory);
137+
if (GitCurrentCommit(RootDirectory) != curCommit) // might get "nothing to commit", you never know...
138+
{
139+
Logger.Info("Checking for existing branch...");
140+
var exists = StartProcess("git", $"checkout \"{newBranch}\"", RootDirectory)
141+
.AssertWaitForExit()
142+
.ExitCode == 0;
143+
if (!exists)
144+
{
145+
Logger.Info("None found, creating a new one...");
146+
Git($"checkout -b \"{newBranch}\"");
147+
}
148+
149+
Git($"merge -X theirs \"{curBranch}\" --allow-unrelated-histories");
150+
Git($"push --set-upstream origin \"{newBranch}\"");
151+
if (!exists)
152+
{
153+
var github = new GitHubClient
154+
(
155+
new ProductHeaderValue("Silk.NET-CI"),
156+
new InMemoryCredentialStore(new Credentials(pushableToken))
157+
);
158+
159+
var pr = github.PullRequest.Create
160+
("dotnet", "Silk.NET", new("Move unshipped APIs to shipped", newBranch, curBranch))
161+
.GetAwaiter()
162+
.GetResult();
163+
}
164+
}
165+
}
166+
}
167+
}

0 commit comments

Comments
 (0)