- adjust logic to collect entries in the category (with the side effect for it to have autamtic support to inject changelog lines)

This commit is contained in:
Mike Penz
2024-03-01 19:11:06 +00:00
committed by GitHub
parent 47ab0d34bc
commit eaf255d3da
3 changed files with 59 additions and 17 deletions
+1 -1
View File
@@ -518,7 +518,7 @@ Regex replace pattern
"source": "TITLE", "source": "TITLE",
"transformer": { "transformer": {
"pattern": "\\s*\\[([A-Z].{2,4}-.{2,5})\\][\\S\\s]*", "pattern": "\\s*\\[([A-Z].{2,4}-.{2,5})\\][\\S\\s]*",
"target": ", [$1](https://corp.ticket-system.com/browse/$1)" "target": "- [$1](https://corp.ticket-system.com/browse/$1)"
} }
} }
``` ```
+1
View File
@@ -32,6 +32,7 @@ export interface Category {
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 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* consume?: boolean // defines if the matched PR will be consumed by this category. Consumed PRs won't show up in any category *after*
entries?: string[] // array of single changelog entries, used to construc the changelog. (this is filled during the build)
} }
/** /**
+57 -16
View File
@@ -135,21 +135,24 @@ export function buildChangelog(diffInfo: DiffInfo, origPrs: PullRequestInfo[], o
core.info(`✒️ Wrote messages for ${prs.length} pull requests`) core.info(`✒️ Wrote messages for ${prs.length} pull requests`)
// bring PRs into the order of categories // bring PRs into the order of categories
const categorized = new Map<Category, string[]>()
const categories = config.categories const categories = config.categories
const ignoredLabels = config.ignore_labels const ignoredLabels = config.ignore_labels
for (const category of categories) { const flatCategories = flatten(config.categories)
categorized.set(category, [])
}
const categorizedPrs: string[] = [] const categorizedPrs: string[] = []
const ignoredPrs: string[] = [] const ignoredPrs: string[] = []
const openPrs: string[] = [] const openPrs: string[] = []
const uncategorizedPrs: string[] = [] const uncategorizedPrs: string[] = []
// set-up the category object
for (const category of flatCategories) {
if (!category.entries) {
category.entries = []
}
}
// bring elements in order // bring elements in order
for (const [pr, body] of transformedMap) { prLoop: for (const [pr, body] of transformedMap) {
if ( if (
haveCommonElementsArr( haveCommonElementsArr(
ignoredLabels.map(lbl => lbl.toLocaleLowerCase('en')), ignoredLabels.map(lbl => lbl.toLocaleLowerCase('en')),
@@ -165,17 +168,18 @@ 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 of categories) {
const matched = categorizePr(category, pr) const [matched, consumed] = recursiveCategorizePr(category, pr, body)
if (matched) { if (consumed) {
pullRequests.push(body) // if matched add the PR to the list continue prLoop
} }
matchedOnce = matchedOnce || matched matchedOnce = matchedOnce || matched
} }
if (!matchedOnce) { if (!matchedOnce) {
// we allow to have pull requests included in an "uncategorized" category // we allow to have pull requests included in an "uncategorized" category
for (const [category, pullRequests] of categorized) { for (const category of flatCategories) {
const pullRequests = category.entries || []
if ((category.labels === undefined || category.labels.length === 0) && category.rules === undefined) { if ((category.labels === undefined || category.labels.length === 0) && category.rules === undefined) {
// check if any exclude label matches for the "uncategorized" category // check if any exclude label matches for the "uncategorized" category
if (category.exclude_labels !== undefined) { if (category.exclude_labels !== undefined) {
@@ -209,15 +213,16 @@ export function buildChangelog(diffInfo: DiffInfo, origPrs: PullRequestInfo[], o
core.info(`️ Ordered all pull requests into ${categories.length} categories`) core.info(`️ Ordered all pull requests into ${categories.length} categories`)
// serialize and provide the categorized content as json // serialize and provide the categorized content as json
const transformedCategorized = Array.from(categorized).reduce( const transformedCategorized = {}
(obj, [key, value]) => Object.assign(obj, {[key.key || key.title]: value}), for (const category of flatCategories) {
{} Object.assign(transformedCategorized, {[category.key || category.title]: category.entries})
) }
core.setOutput('categorized', JSON.stringify(transformedCategorized)) core.setOutput('categorized', JSON.stringify(transformedCategorized))
// construct final changelog // construct final changelog
let changelog = '' let changelog = ''
for (const [category, pullRequests] of categorized) { for (const category of flatCategories) {
const pullRequests = category.entries || []
changelog = attachCategoryChangelog(changelog, category, pullRequests) changelog = attachCategoryChangelog(changelog, category, pullRequests)
} }
core.info(`✒️ Wrote ${categorizedPrs.length} categorized pull requests down`) core.info(`✒️ Wrote ${categorizedPrs.length} categorized pull requests down`)
@@ -294,6 +299,33 @@ export function buildChangelog(diffInfo: DiffInfo, origPrs: PullRequestInfo[], o
return transformedChangelog return transformedChangelog
} }
function recursiveCategorizePr(category: Category, pr: PullRequestInfo, body: string): boolean[] {
let matched = false
let consumed = false
if (category.categories) {
for (const childCategory of category.categories) {
const pullRequests = childCategory.entries || []
matched = categorizePr(childCategory, pr)
if (matched) {
pullRequests.push(body) // if matched add the PR to the list
}
if (childCategory.consume) {
consumed = true
continue
}
}
}
if (!consumed) {
const pullRequests = category.entries || []
matched = categorizePr(category, pr)
if (matched) {
pullRequests.push(body) // if matched add the PR to the list
}
}
return [matched, consumed]
}
function categorizePr(category: Category, pr: PullRequestInfo): boolean { function categorizePr(category: Category, pr: PullRequestInfo): boolean {
let matched = false // check if we matched within the given category let matched = false // check if we matched within the given category
// check if any exclude label matches // check if any exclude label matches
@@ -636,3 +668,12 @@ function extractValuesFromString(value: string, extractor: RegexTransformer): st
return null return null
} }
} }
function flatten(categories?: Category[]): Category[] {
if (!categories) {
return []
}
return categories.reduce(function (r: Category[], i) {
return r.concat([i]).concat(flatten(i.categories))
}, [])
}