in functions/src/issues.ts [624:719]
async checkMatchesTemplate(
org: string,
name: string,
issue: types.internal.Issue
): Promise<CheckMatchesTemplateResult> {
const result = new CheckMatchesTemplateResult();
const templateOpts = this.parseIssueOptions(org, name, issue);
const templatePath = templateOpts.path;
result.templatePath = templatePath;
log.debug("Template options: ", templateOpts);
if (!templateOpts.validate) {
log.debug(`Template optons specify no verification.`);
result.skipped = true;
return result;
}
const validationConfig = this.config.getRepoTemplateValidationConfig(
org,
name,
templatePath
);
log.debug("Validation config: ", validationConfig);
// Try to get the issue template, but skip validation if we can't.
let data = undefined;
try {
data = await this.gh_client.getIssueTemplate(
org,
name,
templateOpts.path
);
} catch (e) {
const err = `failed to get issue template for ${org}/${name} at ${templateOpts.path};`;
log.warn(`checkMatchesTemplate: ${err}: ${JSON.stringify(e)}`);
result.failure = {
otherError: err
};
return result;
}
const checker = new template.TemplateChecker("###", "[REQUIRED]", data);
const issueBody = issue.body;
const missingSections = checker.matchesTemplateSections(issueBody);
if (missingSections.invalid.length > 0) {
log.debug(
`checkMatchesTemplate: missing ${missingSections.invalid.length} sections from the template.`
);
result.matches = false;
result.message = MSG_FOLLOW_TEMPLATE;
result.failure = {
missingSections: missingSections.invalid
};
return result;
}
const emptySections = checker.getRequiredSectionsEmpty(issueBody);
let maxEmptySections = 0;
if (validationConfig && validationConfig.required_section_validation) {
switch (validationConfig.required_section_validation) {
case "strict":
// Any empty required section is a violation
maxEmptySections = 0;
break;
case "relaxed":
// As long as you fill out one required section, it's ok
maxEmptySections = emptySections.all.length - 1;
break;
case "none":
maxEmptySections = emptySections.all.length;
break;
}
}
const numEmptySections = emptySections.invalid.length;
if (numEmptySections > maxEmptySections) {
log.debug(
`checkMatchesTemplate: ${numEmptySections} required sections are empty, which is greater than ${maxEmptySections}.`
);
result.matches = false;
result.message = MSG_MISSING_INFO;
result.failure = {
emptySections: emptySections.invalid
};
} else if (numEmptySections > 0) {
log.debug(
`checkMatchesTemplate: ${numEmptySections} required sections are empty but max was ${maxEmptySections}.`
);
}
return result;
}