Merge pull request #84 from mikepenz/feature/ignore_labels
Introduce new `ignore_labels` configuration
This commit is contained in:
@@ -151,6 +151,9 @@ This configuration is a `.json` file in the following format.
|
||||
"labels": ["test"]
|
||||
}
|
||||
],
|
||||
"ignore_labels": [
|
||||
"ignore"
|
||||
],
|
||||
"sort": "ASC",
|
||||
"template": "${{CHANGELOG}}\n\n<details>\n<summary>Uncategorized</summary>\n\n${{UNCATEGORIZED}}\n</details>",
|
||||
"pr_template": "- ${{TITLE}}\n - PR: #${{NUMBER}}",
|
||||
@@ -175,6 +178,8 @@ This configuration is a `.json` file in the following format.
|
||||
|
||||
Any section of the configuration can be omitted to have defaults apply.
|
||||
|
||||
💡 `ignore_labels` take precedence over category labels, allowing to specifically exclude certain PRs.
|
||||
|
||||
Defaults for the configuration can be found in the [configuration.ts](https://github.com/mikepenz/release-changelog-builder-action/blob/develop/src/configuration.ts)
|
||||
|
||||
Please see the [Configuration Specification](#configuration-specification) for detailed descriptions on the offered configuration options.
|
||||
@@ -239,12 +244,14 @@ Table of supported placeholders allowed to be used in the `template` and `empty_
|
||||
|----------------------------|----------------------------------------------------------------------------------------------------|:---------:|
|
||||
| `${{CHANGELOG}}` | The contents of the changelog, matching the labels as specified in the categories configuration | |
|
||||
| `${{UNCATEGORIZED}}` | All pull requests not matching a specified label in categories | |
|
||||
| `${{IGNORED}}` | All pull requests defining labels matching the `ignore_labels` configuration | |
|
||||
| `${{OWNER}}` | Describes the owner of the repository the changelog was generated for | x |
|
||||
| `${{REPO}}` | The repository name of the repo the changelog was generated for | x |
|
||||
| `${{FROM_TAG}}` | Defines the 'start' from where the changelog did consider merged pull requests | x |
|
||||
| `${{TO_TAG}}` | Defines until which tag the changelog did consider merged pull requests | x |
|
||||
| `${{CATEGORIZED_COUNT}}` | The count of PRs which were categorized | |
|
||||
| `${{UNCATEGORIZED_COUNT}}` | The count of PRs and changes which were not categorized. No label overlapping with category labels | |
|
||||
| `${{IGNORED_COUNT}}` | The count of PRs and changes which were specifically ignored from the changelog. | |
|
||||
|
||||
|
||||
### Configuration Specification
|
||||
@@ -255,7 +262,8 @@ Table of descriptions for the `configuration.json` options.
|
||||
|--------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| categories | An array of `category` specifications, offering a flexible way to group changes into categories |
|
||||
| category.title | The display name of a category in the changelog |
|
||||
| category.labels | An array of labels, to match pull request labels against. If any PR label, matches any category label, the pull request will show up under this category |
|
||||
| category.labels | An array of labels, to match pull request labels against. If any PR label matches any category label, the pull request will show up under this category |
|
||||
| ignore_labels | An array of labels, to match pull request labels against. If any PR label overlaps, the pull request will be ignored from the changelog. This takes precedence over category labels |
|
||||
| sort | The sort order of pull requests. [ASC, DESC] |
|
||||
| template | Specifies the global template to pick for creating the changelog. See [Template placeholders](#template-placeholders) for possible values |
|
||||
| pr_template | Defines the per pull request template. See [PR Template placeholders](#pr-template-placeholders) for possible values |
|
||||
|
||||
@@ -87,5 +87,26 @@ it('Should fill `template` placeholders', async () => {
|
||||
|
||||
const changeLog = await releaseNotesBuilder.build()
|
||||
console.log(changeLog)
|
||||
expect(changeLog).toStrictEqual(`## 🧪 Tests\n\n- [CI] Specify Test Case\n - PR: #10\n\n\n\nmikepenz\nrelease-changelog-builder-action\nv0.0.1\nv0.0.3\n1\n0`)
|
||||
expect(changeLog).toStrictEqual(`## 🧪 Tests\n\n- [CI] Specify Test Case\n - PR: #10\n\n\n\n\nmikepenz\nrelease-changelog-builder-action\nv0.0.1\nv0.0.3\n1\n0\n0`)
|
||||
})
|
||||
|
||||
it('Should fill `template` placeholders, ignore', async () => {
|
||||
jest.setTimeout(180000)
|
||||
|
||||
const configuration = resolveConfiguration('', 'configs_test/configuration_empty_all_placeholders.json')
|
||||
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||
null,
|
||||
'.',
|
||||
'mikepenz',
|
||||
'release-changelog-builder-action',
|
||||
'v0.9.1',
|
||||
'v0.9.5',
|
||||
false,
|
||||
false,
|
||||
configuration
|
||||
)
|
||||
|
||||
const changeLog = await releaseNotesBuilder.build()
|
||||
console.log(changeLog)
|
||||
expect(changeLog).toStrictEqual(`## 🚀 Features\n\n- Enhance sorting by using proper semver\n - PR: #51\n\n## 🧪 Tests\n\n- Improve test cases\n - PR: #49\n\n\n- Bump @types/node from 14.11.8 to 14.11.10\n - PR: #47\n- Adjust code to move fromTag resolving to main.ts\n - PR: #48\n- dev -> main\n - PR: #52\n- Update package.json to updated description\n - PR: #53\n- dev -> main\n - PR: #54\n\n- New additional placeholders for \`template\` and \`empty_template\`\n - PR: #50\n\nmikepenz\nrelease-changelog-builder-action\nv0.9.1\nv0.9.5\n2\n5\n1`)
|
||||
})
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"template": "${{CHANGELOG}}\n${{UNCATEGORIZED}}\n${{OWNER}}\n${{REPO}}\n${{FROM_TAG}}\n${{TO_TAG}}\n${{CATEGORIZED_COUNT}}\n${{UNCATEGORIZED_COUNT}}",
|
||||
"template": "${{CHANGELOG}}\n${{UNCATEGORIZED}}\n${{IGNORED}}\n${{OWNER}}\n${{REPO}}\n${{FROM_TAG}}\n${{TO_TAG}}\n${{CATEGORIZED_COUNT}}\n${{UNCATEGORIZED_COUNT}}\n${{IGNORED_COUNT}}",
|
||||
"empty_template": "${{OWNER}}\n${{REPO}}\n${{FROM_TAG}}\n${{TO_TAG}}"
|
||||
}
|
||||
+1186
-9
File diff suppressed because it is too large
Load Diff
+1
-1
File diff suppressed because one or more lines are too long
@@ -8,6 +8,7 @@ export interface Configuration {
|
||||
pr_template: string
|
||||
empty_template: string
|
||||
categories: Category[]
|
||||
ignore_labels: string[]
|
||||
transformers: Transformer[]
|
||||
tag_resolver: TagResolver
|
||||
}
|
||||
@@ -49,6 +50,7 @@ export const DefaultConfiguration: Configuration = {
|
||||
labels: ['test']
|
||||
}
|
||||
], // the categories to support for the ordering
|
||||
ignore_labels: [ "ignore" ], // list of lables being ignored from the changelog
|
||||
transformers: [], // transformers to apply on the PR description according to the `pr_template`
|
||||
tag_resolver: {
|
||||
// defines the logic on how to resolve the previous tag, only relevant if `fromTag` is not specified
|
||||
|
||||
+33
-8
@@ -42,25 +42,34 @@ export function buildChangelog(
|
||||
// bring PRs into the order of categories
|
||||
const categorized = new Map<Category, string[]>()
|
||||
const categories = config.categories || DefaultConfiguration.categories
|
||||
const ignoredLabels = config.ignore_labels || DefaultConfiguration.ignore_labels
|
||||
|
||||
for (const category of categories) {
|
||||
categorized.set(category, [])
|
||||
}
|
||||
|
||||
const categorizedPrs: string[] = []
|
||||
const uncategorized: string[] = []
|
||||
const ignoredPrs: string[] = []
|
||||
const uncategorizedPrs: string[] = []
|
||||
|
||||
// bring elements in order
|
||||
for (const [pr, body] of transformedMap) {
|
||||
let matched = false
|
||||
if (haveCommonElements(ignoredLabels, pr.labels)) {
|
||||
ignoredPrs.push(body)
|
||||
continue
|
||||
}
|
||||
|
||||
let matched = false
|
||||
for (const [category, pullRequests] of categorized) {
|
||||
if (haveCommonElements(category.labels, pr.labels)) {
|
||||
pullRequests.push(body)
|
||||
matched = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!matched) {
|
||||
uncategorized.push(body)
|
||||
uncategorizedPrs.push(body)
|
||||
} else {
|
||||
categorizedPrs.push(body)
|
||||
}
|
||||
@@ -81,14 +90,22 @@ export function buildChangelog(
|
||||
changelog = `${changelog}\n`
|
||||
}
|
||||
}
|
||||
core.info(`✒️ Wrote ${categorized.size} categorized pull requests down`)
|
||||
core.info(`✒️ Wrote ${categorizedPrs.length} categorized pull requests down`)
|
||||
|
||||
let changelogUncategorized = ''
|
||||
for (const pr of uncategorized) {
|
||||
for (const pr of uncategorizedPrs) {
|
||||
changelogUncategorized = `${changelogUncategorized + pr}\n`
|
||||
}
|
||||
core.info(
|
||||
`✒️ Wrote ${uncategorized.length} non categorized pull requests down`
|
||||
`✒️ Wrote ${uncategorizedPrs.length} non categorized pull requests down`
|
||||
)
|
||||
|
||||
let changelogIgnored = ''
|
||||
for (const pr of ignoredPrs) {
|
||||
changelogIgnored = `${changelogIgnored + pr}\n`
|
||||
}
|
||||
core.info(
|
||||
`✒️ Wrote ${ignoredPrs.length} ignored pull requests down`
|
||||
)
|
||||
|
||||
// fill template
|
||||
@@ -101,6 +118,10 @@ export function buildChangelog(
|
||||
'${{UNCATEGORIZED}}',
|
||||
changelogUncategorized
|
||||
)
|
||||
transformedChangelog = transformedChangelog.replace(
|
||||
'${{IGNORED}}',
|
||||
changelogIgnored
|
||||
)
|
||||
|
||||
// fill other placeholders
|
||||
transformedChangelog = transformedChangelog.replace(
|
||||
@@ -109,7 +130,11 @@ export function buildChangelog(
|
||||
)
|
||||
transformedChangelog = transformedChangelog.replace(
|
||||
'${{UNCATEGORIZED_COUNT}}',
|
||||
uncategorized.length.toString()
|
||||
uncategorizedPrs.length.toString()
|
||||
)
|
||||
transformedChangelog = transformedChangelog.replace(
|
||||
'${{IGNORED_COUNT}}',
|
||||
ignoredPrs.length.toString()
|
||||
)
|
||||
transformedChangelog = fillAdditionalPlaceholders(
|
||||
transformedChangelog,
|
||||
|
||||
Reference in New Issue
Block a user