- break out some functionality when transforming the pull requests into the changelog

This commit is contained in:
Mike Penz
2024-03-01 18:22:00 +00:00
committed by GitHub
parent 8e8a8fc1c9
commit 47ab0d34bc
2 changed files with 78 additions and 67 deletions
+2
View File
@@ -30,6 +30,8 @@ export interface Category {
exhaustive?: boolean // requires all labels to be present in the PR exhaustive?: boolean // requires all labels to be present in the PR
exhaustive_rules?: boolean // requires all rules to be present in the PR (if not set, defaults to exhaustive value) exhaustive_rules?: boolean // requires all rules to be present in the PR (if not set, defaults to exhaustive value)
empty_content?: string // if the category has no matching PRs, this content will be used. If not set, the category will be skipped in the changelog. empty_content?: string // if the category has no matching PRs, this content will be used. If not set, the category will be skipped in the changelog.
categories?: Category[] // allows for nested categories, items matched for a child category won't show up in the parent
consume?: boolean // defines if the matched PR will be consumed by this category. Consumed PRs won't show up in any category *after*
} }
/** /**
+76 -67
View File
@@ -111,7 +111,6 @@ export function buildChangelog(diffInfo: DiffInfo, origPrs: PullRequestInfo[], o
for (const label of extracted) { for (const label of extracted) {
pr.labels.push(label) pr.labels.push(label)
} }
if (core.isDebug()) { if (core.isDebug()) {
core.debug(` Extracted the following labels (${JSON.stringify(extracted)}) for PR ${pr.number}`) core.debug(` Extracted the following labels (${JSON.stringify(extracted)}) for PR ${pr.number}`)
} }
@@ -167,57 +166,7 @@ export function buildChangelog(diffInfo: DiffInfo, origPrs: PullRequestInfo[], o
let matchedOnce = false // in case we matched once at least, the PR can't be uncategorized let matchedOnce = false // in case we matched once at least, the PR can't be uncategorized
for (const [category, pullRequests] of categorized) { for (const [category, pullRequests] of categorized) {
let matched = false // check if we matched within the given category const matched = categorizePr(category, pr)
// check if any exclude label matches
if (category.exclude_labels !== undefined) {
if (
haveCommonElementsArr(
category.exclude_labels.map(lbl => lbl.toLocaleLowerCase('en')),
pr.labels
)
) {
if (core.isDebug()) {
const excludeLabels = JSON.stringify(category.exclude_labels)
core.debug(` PR ${pr.number} with labels: ${pr.labels} excluded from category via exclude label: ${excludeLabels}`)
}
continue // one of the exclude labels matched, skip the PR for this category
}
}
// in case we have exhaustive matching enabled, and have labels and/or rules
// validate for an exhaustive match (e.g. every provided rule applies)
if (category.exhaustive === true && (category.labels !== undefined || category.rules !== undefined)) {
if (category.labels !== undefined) {
matched = haveEveryElementsArr(
category.labels.map(lbl => lbl.toLocaleLowerCase('en')),
pr.labels
)
}
let exhaustive_rules = true
if (category.exhaustive_rules !== undefined) {
exhaustive_rules = category.exhaustive_rules
}
if ((matched || category.labels === undefined) && category.rules !== undefined) {
matched = matchesRules(category.rules, pr, exhaustive_rules)
}
} else {
// if not exhaustive, do individual matches
if (category.labels !== undefined) {
// check if either any of the labels applies
matched = haveCommonElementsArr(
category.labels.map(lbl => lbl.toLocaleLowerCase('en')),
pr.labels
)
}
let exhaustive_rules = false
if (category.exhaustive_rules !== undefined) {
exhaustive_rules = category.exhaustive_rules
}
if (!matched && category.rules !== undefined) {
// if no label did apply, check if any rule applies
matched = matchesRules(category.rules, pr, exhaustive_rules)
}
}
if (matched) { if (matched) {
pullRequests.push(body) // if matched add the PR to the list pullRequests.push(body) // if matched add the PR to the list
} }
@@ -269,21 +218,7 @@ export function buildChangelog(diffInfo: DiffInfo, origPrs: PullRequestInfo[], o
// construct final changelog // construct final changelog
let changelog = '' let changelog = ''
for (const [category, pullRequests] of categorized) { for (const [category, pullRequests] of categorized) {
if (pullRequests.length > 0) { changelog = attachCategoryChangelog(changelog, category, pullRequests)
if (category.title) {
changelog = `${changelog + category.title}\n\n`
}
for (const pr of pullRequests) {
changelog = `${changelog + pr}\n`
}
changelog = `${changelog}\n` // add space between sections
} else if (category.empty_content !== undefined) {
if (category.title) {
changelog = `${changelog + category.title}\n\n`
}
changelog = `${changelog + category.empty_content}\n\n`
}
} }
core.info(`✒️ Wrote ${categorizedPrs.length} categorized pull requests down`) core.info(`✒️ Wrote ${categorizedPrs.length} categorized pull requests down`)
if (core.isDebug()) { if (core.isDebug()) {
@@ -359,6 +294,80 @@ export function buildChangelog(diffInfo: DiffInfo, origPrs: PullRequestInfo[], o
return transformedChangelog return transformedChangelog
} }
function categorizePr(category: Category, pr: PullRequestInfo): boolean {
let matched = false // check if we matched within the given category
// check if any exclude label matches
if (category.exclude_labels !== undefined) {
if (
haveCommonElementsArr(
category.exclude_labels.map(lbl => lbl.toLocaleLowerCase('en')),
pr.labels
)
) {
if (core.isDebug()) {
const excludeLabels = JSON.stringify(category.exclude_labels)
core.debug(` PR ${pr.number} with labels: ${pr.labels} excluded from category via exclude label: ${excludeLabels}`)
}
return false // one of the exclude labels matched, skip the PR for this category
}
}
// in case we have exhaustive matching enabled, and have labels and/or rules
// validate for an exhaustive match (e.g. every provided rule applies)
if (category.exhaustive === true && (category.labels !== undefined || category.rules !== undefined)) {
if (category.labels !== undefined) {
matched = haveEveryElementsArr(
category.labels.map(lbl => lbl.toLocaleLowerCase('en')),
pr.labels
)
}
let exhaustive_rules = true
if (category.exhaustive_rules !== undefined) {
exhaustive_rules = category.exhaustive_rules
}
if ((matched || category.labels === undefined) && category.rules !== undefined) {
matched = matchesRules(category.rules, pr, exhaustive_rules)
}
} else {
// if not exhaustive, do individual matches
if (category.labels !== undefined) {
// check if either any of the labels applies
matched = haveCommonElementsArr(
category.labels.map(lbl => lbl.toLocaleLowerCase('en')),
pr.labels
)
}
let exhaustive_rules = false
if (category.exhaustive_rules !== undefined) {
exhaustive_rules = category.exhaustive_rules
}
if (!matched && category.rules !== undefined) {
// if no label did apply, check if any rule applies
matched = matchesRules(category.rules, pr, exhaustive_rules)
}
}
return matched
}
function attachCategoryChangelog(changelog: string, category: Category, pullRequests: string[]): string {
if (pullRequests.length > 0) {
if (category.title) {
changelog = `${changelog + category.title}\n\n`
}
for (const pr of pullRequests) {
changelog = `${changelog + pr}\n`
}
changelog = `${changelog}\n` // add space between sections
} else if (category.empty_content !== undefined) {
if (category.title) {
changelog = `${changelog + category.title}\n\n`
}
changelog = `${changelog + category.empty_content}\n\n`
}
return changelog
}
export function replaceEmptyTemplate(template: string, options: ReleaseNotesOptions): string { export function replaceEmptyTemplate(template: string, options: ReleaseNotesOptions): string {
const placeholders = new Map<string, Placeholder[]>() const placeholders = new Map<string, Placeholder[]>()
for (const ph of options.configuration.custom_placeholders || []) { for (const ph of options.configuration.custom_placeholders || []) {