Skip to content

Commit 0d4a130

Browse files
authored
Add base branch baseline file for additional PR filtering (#8264)
1 parent 620272b commit 0d4a130

File tree

1 file changed

+64
-11
lines changed
  • tools/codeowners-utils/Azure.Sdk.Tools.CodeownersLinter

1 file changed

+64
-11
lines changed

tools/codeowners-utils/Azure.Sdk.Tools.CodeownersLinter/Program.cs

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,21 @@ static void Main(string[] args)
2121
stopWatch.Start();
2222

2323
// The storage URIs are in the azure-sdk-write-teams-container-blobs pipeline variable group.
24-
// The URIs do not contain the SAS.
2524
var teamUserBlobStorageUriOption = new Option<string>
2625
(name: "--teamUserBlobStorageURI",
27-
description: "The team/user blob storage URI without the SAS.");
26+
description: "The team/user blob storage URI.");
2827
teamUserBlobStorageUriOption.AddAlias("-tUri");
2928
teamUserBlobStorageUriOption.IsRequired = true;
3029

3130
var userOrgVisibilityBlobStorageUriOption = new Option<string>
3231
(name: "--userOrgVisibilityBlobStorageURI",
33-
description: "The user/org blob storage URI without the SAS.");
32+
description: "The user/org blob storage URI.");
3433
userOrgVisibilityBlobStorageUriOption.AddAlias("-uUri");
3534
userOrgVisibilityBlobStorageUriOption.IsRequired = true;
3635

3736
var repoLabelBlobStorageUriOption = new Option<string>
3837
(name: "--repoLabelBlobStorageURI",
39-
description: "The repo/label blob storage URI without the SAS.");
38+
description: "The repo/label blob storage URI.");
4039
repoLabelBlobStorageUriOption.AddAlias("-rUri");
4140
repoLabelBlobStorageUriOption.IsRequired = true;
4241

@@ -68,6 +67,13 @@ static void Main(string[] args)
6867
description: "Generate the baseline error file.");
6968
generateBaselineOption.AddAlias("-gbl");
7069

70+
var baseBranchBaselineFileOption = new Option<string>
71+
(name: "--baseBranchBaselineFile",
72+
description: "The full path to base branch baseline file to be generated or used. The file will be generated if -gbl is set and used to further filter errors if -fbl is set.");
73+
baseBranchBaselineFileOption.AddAlias("-bbf");
74+
baseBranchBaselineFileOption.IsRequired = false;
75+
baseBranchBaselineFileOption.SetDefaultValue(null);
76+
7177
var rootCommand = new RootCommand
7278
{
7379
teamUserBlobStorageUriOption,
@@ -76,7 +82,8 @@ static void Main(string[] args)
7682
repoRootOption,
7783
repoNameOption,
7884
filterBaselineErrorsOption,
79-
generateBaselineOption
85+
generateBaselineOption,
86+
baseBranchBaselineFileOption
8087
};
8188

8289
int returnCode = 1;
@@ -98,13 +105,15 @@ static void Main(string[] args)
98105
string repoName = context.ParseResult.GetValueForOption(repoNameOption);
99106
bool filterBaselineErrors = context.ParseResult.GetValueForOption(filterBaselineErrorsOption);
100107
bool generateBaseline = context.ParseResult.GetValueForOption(generateBaselineOption);
108+
string baseBranchBaselineFile = context.ParseResult.GetValueForOption(baseBranchBaselineFileOption);
101109
returnCode = LintCodeownersFile(teamUserBlobStorageUri,
102110
userOrgVisibilityBlobStorageUri,
103111
repoLabelBlobStorageUri,
104112
repoRoot,
105113
repoName,
106114
filterBaselineErrors,
107-
generateBaseline);
115+
generateBaseline,
116+
baseBranchBaselineFile);
108117
});
109118

110119
rootCommand.Invoke(args);
@@ -124,6 +133,18 @@ static void Main(string[] args)
124133
/// Verify the arguments and call to process the CODEOWNERS file. If errors are being filtered with a
125134
/// baseline, or used to regenerate the baseline, that's done in here. Note that filtering errors and
126135
/// regenerating the baseline cannot both be done in the same run.
136+
///
137+
/// The baseBranchBaselineFile
138+
/// This file will be primarily used in PR validation where two calls will be made. be made. The first
139+
/// call will use the -gbl option and generate the secondary file to a different location. It can't use
140+
/// the standard CODEOWNERS_baseline_error.txt file because it'll be being used in combination with this
141+
/// file. The second call, to verify CODEOWNERS changes in the PR, will verify against the default
142+
/// CODEOWNERS_baseline_error.txt and, if there are any remaining errors, check to see if those exist in the
143+
/// secondary baseline file. The reason for doing this is prevent PRs from being blocked if there are issues
144+
/// in the baseline branch. The typical scenario here will be people leaving the company, the base branch's
145+
/// CODEOWNERS hasn't yet been updated to reflect this and because of that any PRs with CODEOWNERS changes
146+
/// would get blocked. If the remaining errors in the PR validation exist in the base branch's errors then
147+
/// the linter will return a pass instead of a failure.
127148
/// </summary>
128149
/// <param name="teamUserBlobStorageUri">URI of the team/user data in blob storate</param>
129150
/// <param name="userOrgVisibilityBlobStorageUri">URI of the org visibility in blob storage</param>
@@ -132,6 +153,7 @@ static void Main(string[] args)
132153
/// <param name="repoName">The repository name, including org. Eg. Azure/azure-sdk</param>
133154
/// <param name="filterBaselineErrors">Boolean, if true then errors should be filtered using the repository's baseline.</param>
134155
/// <param name="generateBaseline">Boolean, if true then regenerate the baseline file from the error encountered during parsing.</param>
156+
/// <param name="baseBranchBaselineFile">The name of the base branch baseline file to generate or use.</param>
135157
/// <returns>integer, used to set the return code</returns>
136158
/// <exception cref="ArgumentException">Thrown if any arguments, or argument combinations, are invalid.</exception>
137159
static int LintCodeownersFile(string teamUserBlobStorageUri,
@@ -140,7 +162,8 @@ static int LintCodeownersFile(string teamUserBlobStorageUri,
140162
string repoRoot,
141163
string repoName,
142164
bool filterBaselineErrors,
143-
bool generateBaseline)
165+
bool generateBaseline,
166+
string baseBranchBaselineFile)
144167
{
145168
// Don't allow someone to create and use a baseline in the same run
146169
if (filterBaselineErrors && generateBaseline)
@@ -165,7 +188,20 @@ static int LintCodeownersFile(string teamUserBlobStorageUri,
165188
{
166189
throw new ArgumentException($"The repository label data for {repoName} does not exist. Should this be running in this repository?");
167190
}
168-
191+
192+
bool useBaseBranchBaselineFile = false;
193+
if (!string.IsNullOrEmpty(baseBranchBaselineFile))
194+
{
195+
if ((filterBaselineErrors && File.Exists(baseBranchBaselineFile)) || generateBaseline)
196+
{
197+
useBaseBranchBaselineFile = true;
198+
}
199+
else
200+
{
201+
throw new ArgumentException($"The base branch baseline file {baseBranchBaselineFile} does not exist.");
202+
}
203+
}
204+
169205
string codeownersBaselineFile = Path.Combine(repoRoot, ".github", BaselineConstants.BaselineErrorFile);
170206
bool codeownersBaselineFileExists = false;
171207
// If the baseline is to be used, verify that it exists.
@@ -192,7 +228,15 @@ static int LintCodeownersFile(string teamUserBlobStorageUri,
192228
// Regenerate the baseline file if that option was selected
193229
if (generateBaseline)
194230
{
195-
BaselineUtils baselineUtils = new BaselineUtils(codeownersBaselineFile);
231+
BaselineUtils baselineUtils = null;
232+
if (useBaseBranchBaselineFile)
233+
{
234+
baselineUtils = new BaselineUtils(baseBranchBaselineFile);
235+
}
236+
else
237+
{
238+
baselineUtils = new BaselineUtils(codeownersBaselineFile);
239+
}
196240
baselineUtils.GenerateBaseline(errors);
197241
}
198242

@@ -215,11 +259,20 @@ static int LintCodeownersFile(string teamUserBlobStorageUri,
215259
errors = baselineUtils.FilterErrorsUsingBaseline(errors);
216260
}
217261
}
262+
263+
// After the file has been filered with the standard CODEOWNERS baseline file, if there are
264+
// still remaining errors and there is a base branch baseline file, further filter with that
265+
// file.
266+
if (useBaseBranchBaselineFile && errors.Count > 0)
267+
{
268+
BaselineUtils baselineUtils = new BaselineUtils(baseBranchBaselineFile);
269+
errors = baselineUtils.FilterErrorsUsingBaseline(errors);
270+
}
218271
}
219272

220273
int returnCode = 0;
221-
// If there are errors, ensure the returnCode is non-zero and output the errors.
222-
if (errors.Count > 0)
274+
// If there are errors, and this isn't a baseline generation, ensure the returnCode is non-zero and output the errors.
275+
if ((errors.Count > 0) && !generateBaseline)
223276
{
224277
returnCode = 1;
225278

0 commit comments

Comments
 (0)