Implement commit_template
This commit is contained in:
@@ -3,6 +3,7 @@ import {Extractor, PullConfiguration, Regex, Rule} from './pr-collector/types.js
|
||||
export interface Configuration extends PullConfiguration {
|
||||
template: string
|
||||
pr_template: string
|
||||
commit_template: string // (COMMIT and HYBRID mode only for PRs converted to commits)
|
||||
empty_template: string
|
||||
categories: Category[]
|
||||
ignore_labels: string[]
|
||||
@@ -25,6 +26,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.
|
||||
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*
|
||||
mode?: 'HYBRID' | 'COMMIT' | 'PR' // defines if this category applies to PRs, commits or both
|
||||
entries?: string[] // array of single changelog entries, used to construct the changelog. (this is filled during the build)
|
||||
}
|
||||
|
||||
@@ -70,6 +72,7 @@ export const DefaultConfiguration: Configuration = {
|
||||
},
|
||||
template: '#{{CHANGELOG}}', // the global template to host the changelog
|
||||
pr_template: '- #{{TITLE}}\n - PR: ##{{NUMBER}}', // the per PR template to pick
|
||||
commit_template: '- #{{TITLE}}', // the per PR template to pick for commit based mode
|
||||
empty_template: '- no changes', // the template to use if no pull requests are found
|
||||
categories: [
|
||||
{
|
||||
@@ -106,7 +109,6 @@ export const DefaultConfiguration: Configuration = {
|
||||
|
||||
export const DefaultCommitConfiguration: Configuration = {
|
||||
...DefaultConfiguration,
|
||||
pr_template: '- #{{TITLE}}', // the per PR template to pick
|
||||
categories: [
|
||||
{
|
||||
title: '## 🚀 Features',
|
||||
|
||||
+61
-6
@@ -127,22 +127,47 @@ export function buildChangelog(diffInfo: DiffInfo, origPrs: PullRequestInfo[], o
|
||||
|
||||
core.info(`ℹ️ Using ${validatedTransformers.length} transformers to rewrite content`)
|
||||
|
||||
const includePrs = options.mode === 'PR' || options.mode === 'HYBRID'
|
||||
const includeCommits = options.mode === 'COMMIT' || options.mode === 'HYBRID'
|
||||
|
||||
// convert PRs to their text representation
|
||||
const realPrs = includePrs ? prs.filter(x => x.number !== 0) : []
|
||||
const commitPrs = includeCommits ? prs.filter(x => x.number === 0) : []
|
||||
|
||||
if (validatedTransformers.length > 0) {
|
||||
for (const pr of prs) {
|
||||
const prAsObject = pr as unknown as Record<string, unknown>
|
||||
transformObject(prAsObject, validatedTransformers)
|
||||
}
|
||||
core.info(`✒️ Transformed ${prs.length} pull requests`)
|
||||
|
||||
if (includePrs) {
|
||||
core.info(`✒️ Transformed ${realPrs.length} pull requests`)
|
||||
}
|
||||
|
||||
if (includeCommits) {
|
||||
core.info(`✒️ Transformed ${commitPrs.length} commits`)
|
||||
}
|
||||
}
|
||||
|
||||
const prInfoMap = buildInfoMapAndFillPlaceholderContext(
|
||||
prs,
|
||||
realPrs,
|
||||
config.pr_template,
|
||||
groupedPlaceholders,
|
||||
customPlaceholdersTemplateContext,
|
||||
config
|
||||
)
|
||||
|
||||
const commitInfoMap = buildInfoMapAndFillPlaceholderContext(
|
||||
commitPrs,
|
||||
config.commit_template,
|
||||
groupedPlaceholders,
|
||||
customPlaceholdersTemplateContext,
|
||||
config
|
||||
)
|
||||
|
||||
// If the mode is not HYBRID, the map will contain only one or the other map
|
||||
const combinedInfoMap = mergeMaps(prInfoMap, commitInfoMap)
|
||||
|
||||
// bring PRs into the order of categories
|
||||
const categories = config.categories
|
||||
const flatCategories = flatten(config.categories)
|
||||
@@ -154,7 +179,7 @@ export function buildChangelog(diffInfo: DiffInfo, origPrs: PullRequestInfo[], o
|
||||
}
|
||||
}
|
||||
|
||||
const prStrings = buildPrStringsAndFillCategoryEntries(prInfoMap, config.ignore_labels, categories, flatCategories)
|
||||
const prStrings = buildPrStringsAndFillCategoryEntries(combinedInfoMap, config.ignore_labels, categories, flatCategories)
|
||||
core.info(`ℹ️ Ordered all pull requests into ${categories.length} categories`)
|
||||
|
||||
// serialize and provide the categorized content as json
|
||||
@@ -272,7 +297,8 @@ function buildPrStringsAndFillCategoryEntries(
|
||||
}
|
||||
|
||||
let matchedOnce = false // in case we matched once at least, the PR can't be uncategorized
|
||||
for (const category of categories) {
|
||||
const filteredCategories = filterCategoriesByPrType(categories, pr)
|
||||
for (const category of filteredCategories) {
|
||||
const [matched, consumed] = recursiveCategorizePr(category, pr, body)
|
||||
if (consumed) {
|
||||
continue prLoop
|
||||
@@ -282,7 +308,8 @@ function buildPrStringsAndFillCategoryEntries(
|
||||
|
||||
if (!matchedOnce) {
|
||||
// we allow to have pull requests included in an "uncategorized" category
|
||||
for (const category of flatCategories) {
|
||||
const filteredFlatCategories = filterCategoriesByPrType(flatCategories, pr)
|
||||
for (const category of filteredFlatCategories) {
|
||||
category.entries = category.entries || []
|
||||
if ((category.labels === undefined || category.labels.length === 0) && category.rules === undefined) {
|
||||
// check if any exclude label matches for the "uncategorized" category
|
||||
@@ -546,7 +573,15 @@ export function renderEmptyChangelogTemplate(template: string, options: ReleaseN
|
||||
|
||||
const releaseNotesTemplateContext = buildCoreReleaseNotesTemplateContext(options)
|
||||
|
||||
return renderTemplateAndFillPlaceholderContext(template, releaseNotesTemplateContext, placeholders, undefined, options.configuration)
|
||||
const renderedEmptyChangelogTemplate = renderTemplateAndFillPlaceholderContext(
|
||||
template,
|
||||
releaseNotesTemplateContext,
|
||||
placeholders,
|
||||
undefined,
|
||||
options.configuration
|
||||
)
|
||||
|
||||
return renderedEmptyChangelogTemplate
|
||||
}
|
||||
|
||||
function buildCoreReleaseNotesTemplateContext(options: ReleaseNotesOptions): TemplateContext {
|
||||
@@ -867,3 +902,23 @@ function hasChildWithEntries(category: Category): boolean {
|
||||
}
|
||||
return hasEntries
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the provided categories based on the type of pull request information.
|
||||
*
|
||||
* @param {Category[]} categories - The list of categories to filter.
|
||||
* @param {PullRequestInfo} prInfo - The pull request information used to determine the type of PR.
|
||||
* @returns {Category[]} The filtered list of categories:
|
||||
* - If 'prInfo' represents a real pull request (has a number other than 0), it excludes categories with mode 'COMMIT'.
|
||||
* - If 'prInfo' represents a commit (has number 0), it excludes categories with mode 'PR'.
|
||||
* - Defaults to keeping categories with mode 'HYBRID' in either case.
|
||||
*/
|
||||
function filterCategoriesByPrType(categories: Category[], prInfo: PullRequestInfo): Category[] {
|
||||
const isRealPr = prInfo.number !== 0
|
||||
|
||||
if (isRealPr) {
|
||||
return categories.filter(category => (category.mode || 'HYBRID') !== 'COMMIT')
|
||||
} else {
|
||||
return categories.filter(category => (category.mode || 'HYBRID') !== 'PR')
|
||||
}
|
||||
}
|
||||
|
||||
+25
-1
@@ -107,6 +107,16 @@ export function checkExportedData(exportCache: boolean, cacheInput: string | nul
|
||||
options.toTag.date = moment(options.toTag.date)
|
||||
}
|
||||
|
||||
// Handle backwards compatibility for addition of `commit_template` in COMMIT and HYBRID mode
|
||||
// If there is no provided commit_template, fallback to the provided pr_template,
|
||||
// and if that is not provided either, fallback to the default commit_template
|
||||
const {mode, configuration} = options
|
||||
const prTemplate = configuration?.pr_template
|
||||
const commitTemplate = configuration?.commit_template
|
||||
if ((mode === 'COMMIT' || mode === 'HYBRID') && !commitTemplate) {
|
||||
options.configuration.commit_template = prTemplate || DefaultConfiguration.commit_template
|
||||
}
|
||||
|
||||
return {
|
||||
diffInfo,
|
||||
mergedPullRequests,
|
||||
@@ -198,6 +208,19 @@ export function mergeConfiguration(jc?: Configuration, fc?: Configuration, mode?
|
||||
def = DefaultConfiguration
|
||||
}
|
||||
|
||||
// Handle backwards compatibility for addition of `commit_template` in COMMIT and HYBRID mode
|
||||
// If there is no provided commit_template, fallback to the provided pr_template,
|
||||
// and if that is not provided either, fallback to the default commit_template
|
||||
const prTemplate = jc?.pr_template || fc?.pr_template
|
||||
let commitTemplate = jc?.commit_template || fc?.commit_template
|
||||
if ((mode === 'COMMIT' || mode === 'HYBRID') && !commitTemplate) {
|
||||
if (prTemplate) {
|
||||
commitTemplate = prTemplate
|
||||
} else {
|
||||
commitTemplate = def.commit_template
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
max_tags_to_fetch: jc?.max_tags_to_fetch || fc?.max_tags_to_fetch || def.max_tags_to_fetch,
|
||||
max_pull_requests: jc?.max_pull_requests || fc?.max_pull_requests || def.max_pull_requests,
|
||||
@@ -205,7 +228,8 @@ export function mergeConfiguration(jc?: Configuration, fc?: Configuration, mode?
|
||||
exclude_merge_branches: jc?.exclude_merge_branches || fc?.exclude_merge_branches || def.exclude_merge_branches,
|
||||
sort: jc?.sort || fc?.sort || def.sort,
|
||||
template: jc?.template || fc?.template || def.template,
|
||||
pr_template: jc?.pr_template || fc?.pr_template || def.pr_template,
|
||||
pr_template: prTemplate || def.pr_template,
|
||||
commit_template: commitTemplate || def.commit_template,
|
||||
empty_template: jc?.empty_template || fc?.empty_template || def.empty_template,
|
||||
categories: jc?.categories || fc?.categories || def.categories,
|
||||
ignore_labels: jc?.ignore_labels || fc?.ignore_labels || def.ignore_labels,
|
||||
|
||||
Reference in New Issue
Block a user