feat(dev-infra): add support for new global approvers in pullapprove (#36324)

Pullapprove as added a few new features to allow for us to better
execute our expectation for global approvals. We need to allow for
an expectation that our global approver groups are not in the list
of approved groups. Additionally, since approval groups apply to
all files in the repo, the global approval groups also do not have
conditions defined for them, which means pullapprove verification
need to allow for no conditions need to be defined.

PR Close #36324
This commit is contained in:
Joey Perrott 2020-03-30 08:44:30 -07:00 committed by Alex Rickabaugh
parent fe2b6923ba
commit 719224bffd
2 changed files with 44 additions and 37 deletions

View File

@ -34,6 +34,7 @@ const CONDITION_TYPES = {
INCLUDE_GLOBS: /^contains_any_globs/, INCLUDE_GLOBS: /^contains_any_globs/,
EXCLUDE_GLOBS: /^not contains_any_globs/, EXCLUDE_GLOBS: /^not contains_any_globs/,
ATTR_LENGTH: /^len\(.*\)/, ATTR_LENGTH: /^len\(.*\)/,
GLOBAL_APPROVAL: /^global-(docs-)?approvers not in groups.approved$/,
}; };
/** A PullApprove group to be able to test files against. */ /** A PullApprove group to be able to test files against. */
@ -48,43 +49,47 @@ export class PullApproveGroup {
public hasMatchers = false; public hasMatchers = false;
constructor(public groupName: string, group: PullApproveGroupConfig) { constructor(public groupName: string, group: PullApproveGroupConfig) {
for (let condition of group.conditions) { if (group.conditions) {
condition = condition.trim(); for (let condition of group.conditions) {
condition = condition.trim();
if (condition.match(CONDITION_TYPES.INCLUDE_GLOBS)) { if (condition.match(CONDITION_TYPES.INCLUDE_GLOBS)) {
const [conditions, misconfiguredLines] = getLinesForContainsAnyGlobs(condition); const [conditions, misconfiguredLines] = getLinesForContainsAnyGlobs(condition);
conditions.forEach(globString => this.includeConditions.push({ conditions.forEach(globString => this.includeConditions.push({
glob: globString, glob: globString,
matcher: new Minimatch(globString, {dot: true}), matcher: new Minimatch(globString, {dot: true}),
matchedFiles: new Set<string>(), matchedFiles: new Set<string>(),
})); }));
this.misconfiguredLines.push(...misconfiguredLines); this.misconfiguredLines.push(...misconfiguredLines);
this.hasMatchers = true; this.hasMatchers = true;
} else if (condition.match(CONDITION_TYPES.EXCLUDE_GLOBS)) { } else if (condition.match(CONDITION_TYPES.EXCLUDE_GLOBS)) {
const [conditions, misconfiguredLines] = getLinesForContainsAnyGlobs(condition); const [conditions, misconfiguredLines] = getLinesForContainsAnyGlobs(condition);
conditions.forEach(globString => this.excludeConditions.push({ conditions.forEach(globString => this.excludeConditions.push({
glob: globString, glob: globString,
matcher: new Minimatch(globString, {dot: true}), matcher: new Minimatch(globString, {dot: true}),
matchedFiles: new Set<string>(), matchedFiles: new Set<string>(),
})); }));
this.misconfiguredLines.push(...misconfiguredLines); this.misconfiguredLines.push(...misconfiguredLines);
this.hasMatchers = true; this.hasMatchers = true;
} else if (condition.match(CONDITION_TYPES.ATTR_LENGTH)) { } else if (condition.match(CONDITION_TYPES.ATTR_LENGTH)) {
// Currently a noop as we do not take any action on this condition type. // Currently a noop as we do not take any action on this condition type.
} else { } else if (condition.match(CONDITION_TYPES.GLOBAL_APPROVAL)) {
const errMessage = // Currently a noop as we don't take any action for global approval conditions.
`Unrecognized condition found, unable to parse the following condition: \n\n` + } else {
`From the [${groupName}] group:\n` + const errMessage =
` - ${condition}` + `Unrecognized condition found, unable to parse the following condition: \n\n` +
`\n\n` + `From the [${groupName}] group:\n` +
`Known condition regexs:\n` + ` - ${condition}` +
`${Object.entries(CONDITION_TYPES).map(([k, v]) => ` ${k} - $ { `\n\n` +
v `Known condition regexs:\n` +
`${Object.entries(CONDITION_TYPES).map(([k, v]) => ` ${k} - $ {
v
}
`).join('\n')}` +
`\n\n`;
console.error(errMessage);
process.exit(1);
} }
`).join('\n')}` +
`\n\n`;
console.error(errMessage);
process.exit(1);
} }
} }
} }

View File

@ -8,9 +8,11 @@
import {parse as parseYaml} from 'yaml'; import {parse as parseYaml} from 'yaml';
export interface PullApproveGroupConfig { export interface PullApproveGroupConfig {
conditions: string; conditions?: string;
reviewers: { reviewers: {
users: string[], users: string[],
teams?: string[],
}|{
teams: string[], teams: string[],
}; };
} }
@ -30,4 +32,4 @@ export interface PullApproveConfig {
export function parsePullApproveYaml(rawYaml: string): PullApproveConfig { export function parsePullApproveYaml(rawYaml: string): PullApproveConfig {
return parseYaml(rawYaml) as PullApproveConfig; return parseYaml(rawYaml) as PullApproveConfig;
} }