Merge pull request #1240 from mikepenz/feature/inverse_config_default

Inverse default template format to `#{{}}`
This commit is contained in:
Mike Penz
2023-08-31 21:23:20 +02:00
committed by GitHub
19 changed files with 118 additions and 117 deletions
+52 -51
View File
@@ -239,8 +239,8 @@ This configuration is a `JSON` in the following format. (The below showcases *ex
"order": "ASC",
"on_property": "mergedAt"
},
"template": "${{CHANGELOG}}\n\n<details>\n<summary>Uncategorized</summary>\n\n${{UNCATEGORIZED}}\n</details>",
"pr_template": "- ${{TITLE}}\n - PR: #${{NUMBER}}",
"template": "#{{CHANGELOG}}\n\n<details>\n<summary>Uncategorized</summary>\n\n#{{UNCATEGORIZED}}\n</details>",
"pr_template": "- #{{TITLE}}\n - PR: ##{{NUMBER}}",
"empty_template": "- no changes",
"label_extractor": [
{
@@ -350,21 +350,22 @@ Table of supported placeholders allowed to be used in the `pr_template` configur
| **Placeholder** | **Description** |
|-------------------|----------------------------------------------------------------------------------------------------|
| `${{NUMBER}}` | The number referencing this pull request. E.g. 13. |
| `${{TITLE}}` | Specified title of the merged pull request. |
| `${{URL}}` | Url linking to the pull request on GitHub. |
| `${{STATUS}}` | Status of the PR. Usually always `merged`. Possibly `Open` if `includeOpen` is configured. |
| `${{CREATED_AT}}` | The ISO time, the pull request was created at. |
| `${{MERGED_AT}}` | The ISO time, the pull request was merged at. |
| `${{MERGE_SHA}}` | The commit SHA, the pull request was merged with. |
| `${{AUTHOR}}` | Author creating and opening the pull request. |
| `${{LABELS}}` | The labels associated with this pull request, joined by `,`. |
| `${{MILESTONE}}` | Milestone this PR was part of, as assigned on GitHub. |
| `${{BODY}}` | Description/Body of the pull request as specified on GitHub. |
| `${{ASSIGNEES}}` | Login names of assigned GitHub users, joined by `,`. |
| `${{REVIEWERS}}` | GitHub Login names of specified reviewers, joined by `,`. Requires `fetchReviewers` to be enabled. |
| `${{APPROVERS}}` | GitHub Login names of users who approved the PR, joined by `,`. |
| `#{{NUMBER}}` | The number referencing this pull request. E.g. 13. |
| `#{{TITLE}}` | Specified title of the merged pull request. |
| `#{{URL}}` | Url linking to the pull request on GitHub. |
| `#{{STATUS}}` | Status of the PR. Usually always `merged`. Possibly `Open` if `includeOpen` is configured. |
| `#{{CREATED_AT}}` | The ISO time, the pull request was created at. |
| `#{{MERGED_AT}}` | The ISO time, the pull request was merged at. |
| `#{{MERGE_SHA}}` | The commit SHA, the pull request was merged with. |
| `#{{AUTHOR}}` | Author creating and opening the pull request. |
| `#{{LABELS}}` | The labels associated with this pull request, joined by `,`. |
| `#{{MILESTONE}}` | Milestone this PR was part of, as assigned on GitHub. |
| `#{{BODY}}` | Description/Body of the pull request as specified on GitHub. |
| `#{{ASSIGNEES}}` | Login names of assigned GitHub users, joined by `,`. |
| `#{{REVIEWERS}}` | GitHub Login names of specified reviewers, joined by `,`. Requires `fetchReviewers` to be enabled. |
| `#{{APPROVERS}}` | GitHub Login names of users who approved the PR, joined by `,`. |
> **Note**: `v4` updates the default placeholders format to `#{{}}`. The old format `${{}}` will be supported until v5 for backwards compatiblity.
<details><summary><b>Array Placeholders</b></summary>
<p>
@@ -376,9 +377,9 @@ When using `*` values are joined by `,`.
| **Placeholder** | **Description** |
|---------------------|-------------------------------------------------------------------------------------|
| `${{ASSIGNEES[*]}}` | Login names of assigned GitHub users. |
| `${{REVIEWERS[*]}}` | GitHub Login names of specified reviewers. Requires `fetchReviewers` to be enabled. |
| `${{APPROVERS[*]}}` | GitHub Login names of users who approved the PR. |
| `#{{ASSIGNEES[*]}}` | Login names of assigned GitHub users. |
| `#{{REVIEWERS[*]}}` | GitHub Login names of specified reviewers. Requires `fetchReviewers` to be enabled. |
| `#{{APPROVERS[*]}}` | GitHub Login names of users who approved the PR. |
Additionally there are special array placeholders like `REVIEWS` which allows access to it's properties via
`(KEY)[(*/index)].(property)`.
@@ -387,19 +388,19 @@ For example: `REVIEWS[*].author` or `REVIEWS[*].body`
| **Placeholder** | **Description** |
|-------------------------------|--------------------------------------------|
| `${{REVIEWS[*].author}}` | GitHub Login names of specified reviewers. |
| `${{REVIEWS[*].body}}` | The body of the review. |
| `${{REVIEWS[*].htmlURL}}` | The URL to the given review. |
| `${{REVIEWS[*].submittedAt}}` | The date whent he review was submitted. |
| `${{REVIEWS[*].state}}` | The state of the given review. |
| `#{{REVIEWS[*].author}}` | GitHub Login names of specified reviewers. |
| `#{{REVIEWS[*].body}}` | The body of the review. |
| `#{{REVIEWS[*].htmlURL}}` | The URL to the given review. |
| `#{{REVIEWS[*].submittedAt}}` | The date whent he review was submitted. |
| `#{{REVIEWS[*].state}}` | The state of the given review. |
Similar to `REVIEWS`, `REFERENCED` PRs also offer special placeholders.
| **Placeholder** | **Description** |
|-------------------------------|---------------------------------------------------------------------------|
| `${{REFERENCED[*].number}}` | The PR number of the referenced PR. |
| `${{REFERENCED[*].title}}` | The title of the referenced PR. |
| `${{REFERENCED[*]."..."}}` | Allows to use most other PR properties as placeholder. |
| `#{{REFERENCED[*].number}}` | The PR number of the referenced PR. |
| `#{{REFERENCED[*].title}}` | The title of the referenced PR. |
| `#{{REFERENCED[*]."..."}}` | Allows to use most other PR properties as placeholder. |
</p>
</details>
@@ -412,27 +413,27 @@ Table of supported placeholders allowed to be used in the `template` and `empty_
| **Placeholder** | **Description** | **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 | |
| `${{OPEN}}` | All open pull requests. Will only be fetched if `includeOpen` is enabled. | |
| `${{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 |
| `${{FROM_TAG_DATE}}` | Defines the date at which the 'start' tag was created. Requires `fetchReleaseInformation`. | x |
| `${{TO_TAG}}` | Defines until which tag the changelog did consider merged pull requests | x |
| `${{TO_TAG_DATE}}` | Defines the date at which the 'until' tag was created. Requires `fetchReleaseInformation`. | x |
| `${{RELEASE_DIFF}}` | Introduces a link to the full diff between from tag and to tag releases | x |
| `${{CHANGED_FILES}}` | The count of changed files. | |
| `${{ADDITIONS}}` | The count of code additions (lines). | |
| `${{DELETIONS}}` | The count of code deletions (lines). | |
| `${{CHANGES}}` | The count of total changes (lines). | |
| `${{COMMITS}}` | The count of commits in this release. | |
| `${{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 | |
| `${{OPEN_COUNT}}` | The count of open PRs. Will only be fetched if `includeOpen` is configured. | |
| `${{IGNORED_COUNT}}` | The count of PRs and changes which were specifically ignored from the changelog. | |
| `${{DAYS_SINCE}}` | Days between the 2 releases. Requires `fetchReleaseInformation` to be enabled. | x |
| `#{{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 | |
| `#{{OPEN}}` | All open pull requests. Will only be fetched if `includeOpen` is enabled. | |
| `#{{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 |
| `#{{FROM_TAG_DATE}}` | Defines the date at which the 'start' tag was created. Requires `fetchReleaseInformation`. | x |
| `#{{TO_TAG}}` | Defines until which tag the changelog did consider merged pull requests | x |
| `#{{TO_TAG_DATE}}` | Defines the date at which the 'until' tag was created. Requires `fetchReleaseInformation`. | x |
| `#{{RELEASE_DIFF}}` | Introduces a link to the full diff between from tag and to tag releases | x |
| `#{{CHANGED_FILES}}` | The count of changed files. | |
| `#{{ADDITIONS}}` | The count of code additions (lines). | |
| `#{{DELETIONS}}` | The count of code deletions (lines). | |
| `#{{CHANGES}}` | The count of total changes (lines). | |
| `#{{COMMITS}}` | The count of commits in this release. | |
| `#{{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 | |
| `#{{OPEN_COUNT}}` | The count of open PRs. Will only be fetched if `includeOpen` is configured. | |
| `#{{IGNORED_COUNT}}` | The count of PRs and changes which were specifically ignored from the changelog. | |
| `#{{DAYS_SINCE}}` | Days between the 2 releases. Requires `fetchReleaseInformation` to be enabled. | x |
### Configuration Specification
@@ -494,8 +495,8 @@ Custom placeholders can be defined via the `configuration.json` as `custom_place
```json
{
"template": "**Epics**\n${{EPIC[*]}}\n\n${{CHANGELOG}}",
"pr_template": "- ${{TITLE}} - ${{URL}} ${{EPIC}}",
"template": "**Epics**\n#{{EPIC[*]}}\n\n#{{CHANGELOG}}",
"pr_template": "- #{{TITLE}} - #{{URL}} #{{EPIC}}",
"custom_placeholders": [
{
"name": "EPIC",
@@ -518,7 +519,7 @@ This example will look for JIRA tickets in the EPIC project, and extract all of
| custom_placeholders.source | The source PLACEHOLDER, requires to be one of the existing Template or PR Template placeholders. |
| custom_placeholders.transformer | The transformer specification used to extract the value from the original source PLACEHOLDER. |
A placeholder with the name as `CUSTOM_PLACEHOLDER` can be used as `${{CUSTOM_PLACEHOLDER}}` in the target template.
A placeholder with the name as `CUSTOM_PLACEHOLDER` can be used as `#{{CUSTOM_PLACEHOLDER}}` in the target template.
By default the same restriction applies as for PR vs template placeholder. E.g. a global placeholder can only be used in the global template (and not in the PR template).
Custom placeholders offer one new feature though. PR related placeholders can be used in the global template via the following syntax:
+1 -1
View File
@@ -14,6 +14,6 @@ it('Configurations are merged correctly', async () => {
console.log(mergedConfiguration)
expect(JSON.stringify(mergedConfiguration)).toEqual(
`{\"max_tags_to_fetch\":200,\"max_pull_requests\":1000,\"max_back_track_time_days\":1000,\"exclude_merge_branches\":[],\"sort\":\"DESC\",\"template\":\"$\{\{CHANGELOG}}\",\"pr_template\":\"- $\{\{TITLE}}\\n - PR: #$\{\{NUMBER}}\",\"empty_template\":\"- no magic changes\",\"categories\":[{\"title\":\"## 🚀 Features\",\"labels\":[\"feature\"]},{\"title\":\"## 🐛 Fixes\",\"labels\":[\"fix\"]},{\"title\":\"## 🧪 Tests\",\"labels\":[\"test\"]}],\"ignore_labels\":[\"ignore\"],\"label_extractor\":[],\"transformers\":[],\"tag_resolver\":{\"method\":\"semver\"},\"base_branches\":[],\"custom_placeholders\":[],\"trim_values\":true}`
`{\"max_tags_to_fetch\":200,\"max_pull_requests\":1000,\"max_back_track_time_days\":1000,\"exclude_merge_branches\":[],\"sort\":\"DESC\",\"template\":\"#\{\{CHANGELOG}}\",\"pr_template\":\"- #\{\{TITLE}}\\n - PR: ##\{\{NUMBER}}\",\"empty_template\":\"- no magic changes\",\"categories\":[{\"title\":\"## 🚀 Features\",\"labels\":[\"feature\"]},{\"title\":\"## 🐛 Fixes\",\"labels\":[\"fix\"]},{\"title\":\"## 🧪 Tests\",\"labels\":[\"test\"]}],\"ignore_labels\":[\"ignore\"],\"label_extractor\":[],\"transformers\":[],\"tag_resolver\":{\"method\":\"semver\"},\"base_branches\":[],\"custom_placeholders\":[],\"trim_values\":true}`
)
})
+9 -9
View File
@@ -86,7 +86,7 @@ it('Should use empty placeholder', async () => {
false, // enable commitMode
false, // enable exportCache
false, // enable exportOnly
"caches/rcba_0.0.2-0.0.3_cache.json", // path to the cache
'caches/rcba_0.0.2-0.0.3_cache.json', // path to the cache
configuration
)
@@ -115,7 +115,7 @@ it('Should fill empty placeholders', async () => {
false, // enable commitMode
false, // enable exportCache
false, // enable exportOnly
"caches/rcba_0.0.2-0.0.3_cache.json", // path to the cache
'caches/rcba_0.0.2-0.0.3_cache.json', // path to the cache
configuration
)
@@ -146,7 +146,7 @@ it('Should fill `template` placeholders', async () => {
false, // enable commitMode
false, // enable exportCache
false, // enable exportOnly
"caches/rcba_0.0.1-0.0.3_cache.json", // path to the cache
'caches/rcba_0.0.1-0.0.3_cache.json', // path to the cache
configuration
)
@@ -178,7 +178,7 @@ it('Should fill `template` placeholders, ignore', async () => {
false, // enable commitMode
false, // enable exportCache
false, // enable exportOnly
"caches/rcba_0.9.1-0.9.5_cache.json", // path to the cache
'caches/rcba_0.9.1-0.9.5_cache.json', // path to the cache
configuration
)
@@ -209,7 +209,7 @@ it('Uncategorized category', async () => {
false, // enable commitMode
false, // enable exportCache
false, // enable exportOnly
"caches/rcba_0.9.1-0.9.5_cache.json", // path to the cache
'caches/rcba_0.9.1-0.9.5_cache.json', // path to the cache
configuration
)
@@ -240,7 +240,7 @@ it('Verify commit based changelog', async () => {
true, // enable commitMode
false, // enable exportCache
false, // enable exportOnly
"caches/rcba_0.0.1-0.0.3_commit_cache.json", // path to the cache
'caches/rcba_0.0.1-0.0.3_commit_cache.json', // path to the cache
configuration
)
@@ -271,7 +271,7 @@ it('Verify commit based changelog, with emoji categorisation', async () => {
true, // enable commitMode
false, // enable exportCache
false, // enable exportOnly
"caches/stackzy_bd3242-17a9e4_cache.json", // path to the cache
'caches/stackzy_bd3242-17a9e4_cache.json', // path to the cache
configuration
)
@@ -377,7 +377,7 @@ it('Verify reviewers who approved are fetched and also release information', asy
it('Fetch release information', async () => {
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_approvers.json'))
configuration.template = '${{FROM_TAG}}-${{FROM_TAG_DATE}}\n${{TO_TAG}}-${{TO_TAG_DATE}}\n${{DAYS_SINCE}}'
configuration.template = '#{{FROM_TAG}}-#{{FROM_TAG_DATE}}\n#{{TO_TAG}}-#{{TO_TAG_DATE}}\n#{{DAYS_SINCE}}'
const releaseNotesBuilder = new ReleaseNotesBuilder(
null, // baseUrl
null, // token
@@ -407,7 +407,7 @@ it('Fetch release information', async () => {
it('Fetch release information for non existing tag / release', async () => {
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_approvers.json'))
configuration.template = '${{FROM_TAG}}-${{FROM_TAG_DATE}}\n${{TO_TAG}}-${{TO_TAG_DATE}}\n${{DAYS_SINCE}}'
configuration.template = '#{{FROM_TAG}}-#{{FROM_TAG_DATE}}\n#{{TO_TAG}}-#{{TO_TAG_DATE}}\n#{{DAYS_SINCE}}'
const releaseNotesBuilder = new ReleaseNotesBuilder(
null, // baseUrl
null, // token
+11 -11
View File
@@ -3,7 +3,7 @@ import {Octokit} from '@octokit/rest'
import {buildChangelog} from '../src/transform'
import {pullData} from '../src/pr-collector/prCollector'
import fetch from 'node-fetch'
import { Data } from '../src/releaseNotesBuilder'
import {Data} from '../src/releaseNotesBuilder'
jest.setTimeout(180000)
@@ -37,7 +37,7 @@ it('Should have empty changelog (tags)', async () => {
if (enablePullData) {
data = await pullData(octokit, options)
} else {
data = checkExportedData(false, "caches/rcba_0.0.2-0.0.3_cache.json")
data = checkExportedData(false, 'caches/rcba_0.0.2-0.0.3_cache.json')
}
const changeLog = buildChangelog(data!.diffInfo, data!.mergedPullRequests, options)
console.log(changeLog)
@@ -64,7 +64,7 @@ it('Should match generated changelog (tags)', async () => {
if (enablePullData) {
data = await pullData(octokit, options)
} else {
data = checkExportedData(false, "caches/rcba_0.0.1-0.0.3_cache.json")
data = checkExportedData(false, 'caches/rcba_0.0.1-0.0.3_cache.json')
}
const changeLog = buildChangelog(data!.diffInfo, data!.mergedPullRequests, options)
console.log(changeLog)
@@ -97,7 +97,7 @@ it('Should match generated changelog (refs)', async () => {
if (enablePullData) {
data = await pullData(octokit, options)
} else {
data = checkExportedData(false, "caches/rcba_5ec7a2-fa3788_cache.json")
data = checkExportedData(false, 'caches/rcba_5ec7a2-fa3788_cache.json')
}
const changeLog = buildChangelog(data!.diffInfo, data!.mergedPullRequests, options)
console.log(changeLog)
@@ -137,7 +137,7 @@ it('Should match generated changelog and replace all occurrences (refs)', async
if (enablePullData) {
data = await pullData(octokit, options)
} else {
data = checkExportedData(false, "caches/rcba_5ec7a2-fa3788_cache.json")
data = checkExportedData(false, 'caches/rcba_5ec7a2-fa3788_cache.json')
}
const changeLog = buildChangelog(data!.diffInfo, data!.mergedPullRequests, options)
console.log(changeLog)
@@ -180,7 +180,7 @@ it('Should match ordered ASC', async () => {
if (enablePullData) {
data = await pullData(octokit, options)
} else {
data = checkExportedData(false, "caches/rcba_0.3.0-0.5.0_cache.json")
data = checkExportedData(false, 'caches/rcba_0.3.0-0.5.0_cache.json')
}
const changeLog = buildChangelog(data!.diffInfo, data!.mergedPullRequests, options)
console.log(changeLog)
@@ -208,7 +208,7 @@ it('Should match ordered DESC', async () => {
if (enablePullData) {
data = await pullData(octokit, options)
} else {
data = checkExportedData(false, "caches/rcba_0.3.0-0.5.0_cache.json")
data = checkExportedData(false, 'caches/rcba_0.3.0-0.5.0_cache.json')
}
const changeLog = buildChangelog(data!.diffInfo, data!.mergedPullRequests, options)
console.log(changeLog)
@@ -235,7 +235,7 @@ it('Should match ordered by title ASC', async () => {
if (enablePullData) {
data = await pullData(octokit, options)
} else {
data = checkExportedData(false, "caches/rcba_0.3.0-0.5.0_cache.json")
data = checkExportedData(false, 'caches/rcba_0.3.0-0.5.0_cache.json')
}
const changeLog = buildChangelog(data!.diffInfo, data!.mergedPullRequests, options)
console.log(changeLog)
@@ -264,7 +264,7 @@ it('Should match ordered by title DESC', async () => {
if (enablePullData) {
data = await pullData(octokit, options)
} else {
data = checkExportedData(false, "caches/rcba_0.3.0-0.5.0_cache.json")
data = checkExportedData(false, 'caches/rcba_0.3.0-0.5.0_cache.json')
}
const changeLog = buildChangelog(data!.diffInfo, data!.mergedPullRequests, options)
console.log(changeLog)
@@ -293,7 +293,7 @@ it('Should ignore PRs not merged into develop branch', async () => {
if (enablePullData) {
data = await pullData(octokit, options)
} else {
data = checkExportedData(false, "caches/rcba_1.3.1-1.4.0_base_develop_cache.json")
data = checkExportedData(false, 'caches/rcba_1.3.1-1.4.0_base_develop_cache.json')
}
const changeLog = buildChangelog(data!.diffInfo, data!.mergedPullRequests, options)
console.log(changeLog)
@@ -320,7 +320,7 @@ it('Should ignore PRs not merged into main branch', async () => {
if (enablePullData) {
data = await pullData(octokit, options)
} else {
data = checkExportedData(false, "caches/rcba_1.3.1-1.4.0_base_main_cache.json")
data = checkExportedData(false, 'caches/rcba_1.3.1-1.4.0_base_main_cache.json')
}
const changeLog = buildChangelog(data!.diffInfo, data!.mergedPullRequests, options)
console.log(changeLog)
+5 -5
View File
@@ -409,7 +409,7 @@ it('Reference PRs', async () => {
labels: []
}
]
customConfig.pr_template = '${{NUMBER}} -- ${{REFERENCED[*].number}}'
customConfig.pr_template = '#{{NUMBER}} -- #{{REFERENCED[*].number}}'
customConfig.reference = {
pattern: '.* #(.).*', // matches the 1 from "abcdefg #1 adfasdf"
on_property: 'body',
@@ -440,7 +440,7 @@ it('Use empty_content for empty category', async () => {
it('Commit SHA-1 in commitMode', async () => {
const customConfig = Object.assign({}, DefaultConfiguration)
customConfig.sort = 'DESC'
customConfig.pr_template = '${{MERGE_SHA}}'
customConfig.pr_template = '#{{MERGE_SHA}}'
const resultChangelog = buildChangelog(DefaultDiffInfo, pullRequestsWithLabels, {
owner: 'mikepenz',
@@ -461,7 +461,7 @@ it('Commit SHA-1 in commitMode', async () => {
it('Release Diff', async () => {
const customConfig = Object.assign({}, DefaultConfiguration)
customConfig.template = '${{RELEASE_DIFF}}\n${{DAYS_SINCE}}'
customConfig.template = '#{{RELEASE_DIFF}}\n#{{DAYS_SINCE}}'
const resultChangelog = buildChangelog(DefaultDiffInfo, pullRequestsWithLabels, {
owner: 'mikepenz',
@@ -542,8 +542,8 @@ it('Extract custom placeholder from PR body and replace in global template', asy
}
]
customConfig.template =
'${{CHANGELOG}}\n\n${{C_PLACEHOLER_2[2]}}\n\n${{C_PLACEHOLER_2[*]}}${{C_PLACEHOLDER_1[7]}}${{C_PLACEHOLER_2[1493]}}${{C_PLACEHOLER_4[*]}}${{C_PLACEHOLER_4[0]}}${{C_PLACEHOLER_3[1]}}'
customConfig.pr_template = '${{BODY}} ----> ${{C_PLACEHOLDER_1}}${{C_PLACEHOLER_3}}'
'#{{CHANGELOG}}\n\n#{{C_PLACEHOLER_2[2]}}\n\n#{{C_PLACEHOLER_2[*]}}#{{C_PLACEHOLDER_1[7]}}#{{C_PLACEHOLER_2[1493]}}#{{C_PLACEHOLER_4[*]}}#{{C_PLACEHOLER_4[0]}}#{{C_PLACEHOLER_3[1]}}'
customConfig.pr_template = '#{{BODY}} ----> #{{C_PLACEHOLDER_1}}#{{C_PLACEHOLER_3}}'
expect(buildChangelogTest(customConfig, mergedPullRequests)).toStrictEqual(
`## 🚀 Features\n\nno magic body1 for this matter ----> - body1body1\nno magic body3 for this matter ----> - body3\n\n## 🐛 Fixes\n\nno magic body2 for this matter ----> - body2\nno magic body3 for this matter ----> - body3\n\n## 🧪 Others\n\nno magic body4 for this matter ----> - body4\n\n\n\n\n- ody3\n\n\n- ody1\n- ody2\n- ody3\n- ody4`
+3 -3
View File
@@ -90,9 +90,9 @@
"order": "ASC",
"on_property": "mergedAt"
},
"template": "${{CHANGELOG}}\n${{UNCATEGORIZED}}\n${{IGNORED}}\n${{OWNER}}\n${{REPO}}\n${{FROM_TAG}}\n${{TO_TAG}}\n${{RELEASE_DIFF}}\n${{CATEGORIZED_COUNT}}\n${{UNCATEGORIZED_COUNT}}\n${{IGNORED_COUNT}}\n${{CHANGED_FILES}}\n${{ADDITIONS}}\n${{DELETIONS}}\n${{CHANGES}}\n${{COMMITS}}",
"pr_template": "- ${{TITLE}}\n - PR: #${{NUMBER}}",
"empty_template": "${{OWNER}}\n${{REPO}}\n${{FROM_TAG}}\n${{TO_TAG}}\n${{RELEASE_DIFF}}",
"template": "#{{CHANGELOG}}\n#{{UNCATEGORIZED}}\n#{{IGNORED}}\n#{{OWNER}}\n#{{REPO}}\n#{{FROM_TAG}}\n#{{TO_TAG}}\n#{{RELEASE_DIFF}}\n#{{CATEGORIZED_COUNT}}\n#{{UNCATEGORIZED_COUNT}}\n#{{IGNORED_COUNT}}\n#{{CHANGED_FILES}}\n#{{ADDITIONS}}\n#{{DELETIONS}}\n#{{CHANGES}}\n#{{COMMITS}}",
"pr_template": "- #{{TITLE}}\n - PR: ##{{NUMBER}}",
"empty_template": "#{{OWNER}}\n#{{REPO}}\n#{{FROM_TAG}}\n#{{TO_TAG}}\n#{{RELEASE_DIFF}}",
"categories": [
{
"title": "## 🚀 Features",
+3 -3
View File
@@ -117,9 +117,9 @@
"order": "ASC",
"on_property": "mergedAt"
},
"template": "${{CHANGELOG}}\n\nUncategorized:\n${{UNCATEGORIZED}}\n\nIgnored:\n${{IGNORED}}\n\n${{UNCATEGORIZED_COUNT}}\n${{IGNORED_COUNT}}",
"pr_template": "- ${{TITLE}}\n",
"empty_template": "${{OWNER}}\n${{REPO}}\n${{FROM_TAG}}\n${{TO_TAG}}",
"template": "#{{CHANGELOG}}\n\nUncategorized:\n#{{UNCATEGORIZED}}\n\nIgnored:\n#{{IGNORED}}\n\n#{{UNCATEGORIZED_COUNT}}\n#{{IGNORED_COUNT}}",
"pr_template": "- #{{TITLE}}\n",
"empty_template": "#{{OWNER}}\n#{{REPO}}\n#{{FROM_TAG}}\n#{{TO_TAG}}",
"categories": [
{
"title": "## 📦 Uncategorized",
+2 -2
View File
@@ -31,8 +31,8 @@
"max_back_track_time_days": 1000,
"exclude_merge_branches": [],
"sort": "ASC",
"template": "${{CHANGELOG}}",
"pr_template": "- ${{TITLE}}\n - PR: #${{NUMBER}}",
"template": "#{{CHANGELOG}}",
"pr_template": "- #{{TITLE}}\n - PR: ##{{NUMBER}}",
"empty_template": "- no changes",
"categories": [
{
+2 -2
View File
@@ -579,8 +579,8 @@
"max_back_track_time_days": 1000,
"exclude_merge_branches": [],
"sort": "ASC",
"template": "${{CHANGELOG}}",
"pr_template": "- ${{TITLE}}\n - PR: #${{NUMBER}}",
"template": "#{{CHANGELOG}}",
"pr_template": "- #{{TITLE}}\n - PR: ##{{NUMBER}}",
"empty_template": "- no changes",
"categories": [
{
+3 -3
View File
@@ -443,9 +443,9 @@
"order": "ASC",
"on_property": "mergedAt"
},
"template": "${{CHANGELOG}}\n${{UNCATEGORIZED}}\n${{IGNORED}}\n${{OWNER}}\n${{REPO}}\n${{FROM_TAG}}\n${{TO_TAG}}\n${{RELEASE_DIFF}}\n${{CATEGORIZED_COUNT}}\n${{UNCATEGORIZED_COUNT}}\n${{IGNORED_COUNT}}\n${{CHANGED_FILES}}\n${{ADDITIONS}}\n${{DELETIONS}}\n${{CHANGES}}\n${{COMMITS}}",
"pr_template": "- ${{TITLE}}\n - PR: #${{NUMBER}}",
"empty_template": "${{OWNER}}\n${{REPO}}\n${{FROM_TAG}}\n${{TO_TAG}}\n${{RELEASE_DIFF}}",
"template": "#{{CHANGELOG}}\n#{{UNCATEGORIZED}}\n#{{IGNORED}}\n#{{OWNER}}\n#{{REPO}}\n#{{FROM_TAG}}\n#{{TO_TAG}}\n#{{RELEASE_DIFF}}\n#{{CATEGORIZED_COUNT}}\n#{{UNCATEGORIZED_COUNT}}\n#{{IGNORED_COUNT}}\n#{{CHANGED_FILES}}\n#{{ADDITIONS}}\n#{{DELETIONS}}\n#{{CHANGES}}\n#{{COMMITS}}",
"pr_template": "- #{{TITLE}}\n - PR: ##{{NUMBER}}",
"empty_template": "#{{OWNER}}\n#{{REPO}}\n#{{FROM_TAG}}\n#{{TO_TAG}}\n#{{RELEASE_DIFF}}",
"categories": [
{
"title": "## 🚀 Features",
@@ -171,8 +171,8 @@
"max_back_track_time_days": 1000,
"exclude_merge_branches": [],
"sort": "DESC",
"template": "${{CHANGELOG}}",
"pr_template": "${{NUMBER}}",
"template": "#{{CHANGELOG}}",
"pr_template": "#{{NUMBER}}",
"empty_template": "- no changes",
"categories": [
{
+2 -2
View File
@@ -127,8 +127,8 @@
"max_back_track_time_days": 1000,
"exclude_merge_branches": [],
"sort": "DESC",
"template": "${{CHANGELOG}}",
"pr_template": "${{NUMBER}}",
"template": "#{{CHANGELOG}}",
"pr_template": "#{{NUMBER}}",
"empty_template": "- no changes",
"categories": [
{
+2 -2
View File
@@ -87,8 +87,8 @@
"max_back_track_time_days": 1000,
"exclude_merge_branches": [],
"sort": "ASC",
"template": "${{CHANGELOG}}",
"pr_template": "- ${{TITLE}}\n - PR: #${{NUMBER}}",
"template": "#{{CHANGELOG}}",
"pr_template": "- #{{TITLE}}\n - PR: ##{{NUMBER}}",
"empty_template": "- no changes",
"categories": [
{
+2 -2
View File
@@ -468,8 +468,8 @@
"order": "ASC",
"on_property": "mergedAt"
},
"template": "${{CHANGELOG}}",
"pr_template": "${{TITLE}}",
"template": "#{{CHANGELOG}}",
"pr_template": "#{{TITLE}}",
"empty_template": "- no changes",
"categories": [
{
Generated Vendored
+9 -9
View File
@@ -18,8 +18,8 @@ exports.DefaultConfiguration = {
order: 'ASC',
on_property: 'mergedAt' // the property to sort on. (mergedAt falls back to createdAt)
},
template: '${{CHANGELOG}}',
pr_template: '- ${{TITLE}}\n - PR: #${{NUMBER}}',
template: '#{{CHANGELOG}}',
pr_template: '- #{{TITLE}}\n - PR: ##{{NUMBER}}',
empty_template: '- no changes',
categories: [
{
@@ -2380,7 +2380,7 @@ function replacePlaceholders(template, arrayPlaceholderMap /* arrayPlaceholderKe
return transformed;
}
function handlePlaceholder(template, key, value, placeholders /* placeholders to apply */, placeholderPrMap /* map to keep replaced placeholder values with their key */, configuration) {
let transformed = template.replaceAll(`\${{${key}}}`, configuration.trim_values ? value.trim() : value);
let transformed = template.replaceAll(`#{{${key}}}`, configuration.trim_values ? value.trim() : value);
// replace custom placeholders
const phs = placeholders.get(key);
if (phs) {
@@ -2393,7 +2393,7 @@ function handlePlaceholder(template, key, value, placeholders /* placeholders to
if (placeholderPrMap) {
(0, utils_1.createOrSet)(placeholderPrMap, placeholder.name, extractedValue);
}
transformed = transformed.replaceAll(`\${{${placeholder.name}}}`, configuration.trim_values ? extractedValue.trim() : extractedValue);
transformed = transformed.replaceAll(`#{{${placeholder.name}}}`, configuration.trim_values ? extractedValue.trim() : extractedValue);
if (core.isDebug()) {
core.debug(` Custom Placeholder successfully matched data - ${extractValues} (${placeholder.name})`);
}
@@ -2442,9 +2442,9 @@ function replacePrPlaceholders(template, placeholderPrMap /* map with all pr rel
let transformed = template;
for (const [key, values] of placeholderPrMap) {
for (let i = 0; i < values.length; i++) {
transformed = transformed.replaceAll(`\${{${key}[${i}]}}`, configuration.trim_values ? values[i].trim() : values[i]);
transformed = transformed.replaceAll(`#{{${key}[${i}]}}`, configuration.trim_values ? values[i].trim() : values[i]);
}
transformed = transformed.replaceAll(`\${{${key}[*]}}`, values.join(''));
transformed = transformed.replaceAll(`#{{${key}[*]}}`, values.join(''));
}
return transformed;
}
@@ -2452,7 +2452,7 @@ function cleanupPrPlaceholders(template, placeholders) {
let transformed = template;
for (const [, phs] of placeholders) {
for (const ph of phs) {
transformed = transformed.replaceAll(new RegExp(`\\$\\{\\{${ph.name}(?:\\[.+?\\])?\\}\\}`, 'gu'), '');
transformed = transformed.replaceAll(new RegExp(`#\\{\\{${ph.name}(?:\\[.+?\\])?\\}\\}`, 'gu'), '');
}
}
return transformed;
@@ -2460,7 +2460,7 @@ function cleanupPrPlaceholders(template, placeholders) {
function cleanupPlaceholders(template) {
let transformed = template;
for (const phs of ['REVIEWS', 'REFERENCED', 'ASSIGNEES', 'REVIEWERS', 'APPROVERS']) {
transformed = transformed.replaceAll(new RegExp(`\\$\\{\\{${phs}\\[.+?\\]\\..*?\\}\\}`, 'gu'), '');
transformed = transformed.replaceAll(new RegExp(`#\\{\\{${phs}\\[.+?\\]\\..*?\\}\\}`, 'gu'), '');
}
return transformed;
}
@@ -2717,7 +2717,7 @@ function readConfiguration(filename) {
function parseConfiguration(config) {
try {
// for compatiblity with the `yml` file we require to use `#{{}}` instead of `${{}}` - replace it here.
const configurationJSON = JSON.parse(config.replace(/#{{/g, '${{'));
const configurationJSON = JSON.parse(config.replace(/\${{/g, '#{{'));
return configurationJSON;
}
catch (error) {
Generated Vendored
+1 -1
View File
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -70,8 +70,8 @@ export const DefaultConfiguration: Configuration = {
order: 'ASC', // the sorting order
on_property: 'mergedAt' // the property to sort on. (mergedAt falls back to createdAt)
},
template: '${{CHANGELOG}}', // the global template to host the changelog
pr_template: '- ${{TITLE}}\n - PR: #${{NUMBER}}', // the per PR template to pick
template: '#{{CHANGELOG}}', // the global template to host the changelog
pr_template: '- #{{TITLE}}\n - PR: ##{{NUMBER}}', // the per PR template to pick
empty_template: '- no changes', // the template to use if no pull requests are found
categories: [
{
+6 -6
View File
@@ -456,7 +456,7 @@ function handlePlaceholder(
placeholderPrMap: Map<string, string[]> | undefined /* map to keep replaced placeholder values with their key */,
configuration: Configuration
): string {
let transformed = template.replaceAll(`\${{${key}}}`, configuration.trim_values ? value.trim() : value)
let transformed = template.replaceAll(`#{{${key}}}`, configuration.trim_values ? value.trim() : value)
// replace custom placeholders
const phs = placeholders.get(key)
if (phs) {
@@ -470,7 +470,7 @@ function handlePlaceholder(
createOrSet(placeholderPrMap, placeholder.name, extractedValue)
}
transformed = transformed.replaceAll(
`\${{${placeholder.name}}}`,
`#{{${placeholder.name}}}`,
configuration.trim_values ? extractedValue.trim() : extractedValue
)
@@ -542,9 +542,9 @@ function replacePrPlaceholders(
let transformed = template
for (const [key, values] of placeholderPrMap) {
for (let i = 0; i < values.length; i++) {
transformed = transformed.replaceAll(`\${{${key}[${i}]}}`, configuration.trim_values ? values[i].trim() : values[i])
transformed = transformed.replaceAll(`#{{${key}[${i}]}}`, configuration.trim_values ? values[i].trim() : values[i])
}
transformed = transformed.replaceAll(`\${{${key}[*]}}`, values.join(''))
transformed = transformed.replaceAll(`#{{${key}[*]}}`, values.join(''))
}
return transformed
}
@@ -553,7 +553,7 @@ function cleanupPrPlaceholders(template: string, placeholders: Map<string, Place
let transformed = template
for (const [, phs] of placeholders) {
for (const ph of phs) {
transformed = transformed.replaceAll(new RegExp(`\\$\\{\\{${ph.name}(?:\\[.+?\\])?\\}\\}`, 'gu'), '')
transformed = transformed.replaceAll(new RegExp(`#\\{\\{${ph.name}(?:\\[.+?\\])?\\}\\}`, 'gu'), '')
}
}
return transformed
@@ -562,7 +562,7 @@ function cleanupPrPlaceholders(template: string, placeholders: Map<string, Place
function cleanupPlaceholders(template: string): string {
let transformed = template
for (const phs of ['REVIEWS', 'REFERENCED', 'ASSIGNEES', 'REVIEWERS', 'APPROVERS']) {
transformed = transformed.replaceAll(new RegExp(`\\$\\{\\{${phs}\\[.+?\\]\\..*?\\}\\}`, 'gu'), '')
transformed = transformed.replaceAll(new RegExp(`#\\{\\{${phs}\\[.+?\\]\\..*?\\}\\}`, 'gu'), '')
}
return transformed
}
+1 -1
View File
@@ -153,7 +153,7 @@ function readConfiguration(filename: string): Configuration | undefined {
export function parseConfiguration(config: string): Configuration | undefined {
try {
// for compatiblity with the `yml` file we require to use `#{{}}` instead of `${{}}` - replace it here.
const configurationJSON: Configuration = JSON.parse(config.replace(/#{{/g, '${{'))
const configurationJSON: Configuration = JSON.parse(config.replace(/\${{/g, '#{{'))
return configurationJSON
} catch (error) {
core.info(`⚠️ Configuration provided, but it couldn't be parsed. Fallback to Defaults.`)