Merge pull request #996 from mikepenz/feature/merge_configs

Add support for multi source configuration
This commit is contained in:
Mike Penz
2023-01-03 17:13:37 +01:00
committed by GitHub
11 changed files with 148 additions and 95 deletions
+3 -1
View File
@@ -195,7 +195,9 @@ The action supports flexible configuration options to modify vast areas of its b
> **Warning** It is required to have a `checkout` step prior to the changelog step if `configuration` is used, to allow the action to discover the configuration file. Use `configurationJson` as alternative.
This configuration is a `.json` file in the following format. (The below shocases *example* configurations for all possible options. In most scenarios most of the settings will not be needed, and the defaults will be appropiate.)
> **Note** It is possible to provide the configuration as file and as json via the yml file. The order of config values used: `configurationJson` > `configuration` > `DefaultConfiguration`.
This configuration is a `JSON` in the following format. (The below shocases *example* configurations for all possible options. In most scenarios most of the settings will not be needed, and the defaults will be appropiate.)
```json
{
+17
View File
@@ -0,0 +1,17 @@
import {mergeConfiguration, parseConfiguration, resolveConfiguration} from '../src/utils'
jest.setTimeout(180000)
it('Configurations are merged correctly', async () => {
const configurationJson = parseConfiguration(`{
"sort": "DESC",
"empty_template": "- no magic changes",
"trim_values": true
}`)
const configurationFile = resolveConfiguration('', 'configs/configuration.json')
const mergedConfiguration = mergeConfiguration(configurationJson, configurationFile)
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}`)
})
+11 -11
View File
@@ -1,5 +1,5 @@
import {ReleaseNotes} from '../src/releaseNotes'
import {resolveConfiguration} from '../src/utils'
import {mergeConfiguration, resolveConfiguration} from '../src/utils'
import {Octokit} from '@octokit/rest'
jest.setTimeout(180000)
@@ -10,7 +10,7 @@ const octokit = new Octokit({
})
it('Should have empty changelog (tags)', async () => {
const configuration = resolveConfiguration('', 'configs/configuration.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs/configuration.json'))
const releaseNotes = new ReleaseNotes(octokit, {
owner: 'mikepenz',
repo: 'release-changelog-builder-action',
@@ -31,7 +31,7 @@ it('Should have empty changelog (tags)', async () => {
})
it('Should match generated changelog (tags)', async () => {
const configuration = resolveConfiguration('', 'configs/configuration.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs/configuration.json'))
const releaseNotes = new ReleaseNotes(octokit, {
owner: 'mikepenz',
repo: 'release-changelog-builder-action',
@@ -57,7 +57,7 @@ it('Should match generated changelog (tags)', async () => {
})
it('Should match generated changelog (refs)', async () => {
const configuration = resolveConfiguration('', 'configs_test/configuration_all_placeholders.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_all_placeholders.json'))
const releaseNotes = new ReleaseNotes(octokit, {
owner: 'mikepenz',
repo: 'release-changelog-builder-action',
@@ -91,7 +91,7 @@ nhoelzl
})
it('Should match generated changelog and replace all occurrences (refs)', async () => {
const configuration = resolveConfiguration('', 'configs_test/configuration_replace_all_placeholders.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_replace_all_placeholders.json'))
const releaseNotes = new ReleaseNotes(octokit, {
owner: 'mikepenz',
repo: 'release-changelog-builder-action',
@@ -127,7 +127,7 @@ nhoelzl
})
it('Should match ordered ASC', async () => {
const configuration = resolveConfiguration('', 'configs_test/configuration_asc.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_asc.json'))
const releaseNotes = new ReleaseNotes(octokit, {
owner: 'mikepenz',
repo: 'release-changelog-builder-action',
@@ -148,7 +148,7 @@ it('Should match ordered ASC', async () => {
})
it('Should match ordered DESC', async () => {
const configuration = resolveConfiguration('', 'configs_test/configuration_desc.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_desc.json'))
const releaseNotes = new ReleaseNotes(octokit, {
owner: 'mikepenz',
repo: 'release-changelog-builder-action',
@@ -169,7 +169,7 @@ it('Should match ordered DESC', async () => {
})
it('Should match ordered by title ASC', async () => {
const configuration = resolveConfiguration('', 'configs_test/configuration_sort_title_asc.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_sort_title_asc.json'))
const releaseNotes = new ReleaseNotes(octokit, {
owner: 'mikepenz',
repo: 'release-changelog-builder-action',
@@ -192,7 +192,7 @@ it('Should match ordered by title ASC', async () => {
})
it('Should match ordered by title DESC', async () => {
const configuration = resolveConfiguration('', 'configs_test/configuration_sort_title_desc.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_sort_title_desc.json'))
const releaseNotes = new ReleaseNotes(octokit, {
owner: 'mikepenz',
repo: 'release-changelog-builder-action',
@@ -215,7 +215,7 @@ it('Should match ordered by title DESC', async () => {
})
it('Should ignore PRs not merged into develop branch', async () => {
const configuration = resolveConfiguration('', 'configs_test/configuration_base_branches_develop.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_base_branches_develop.json'))
const releaseNotes = new ReleaseNotes(octokit, {
owner: 'mikepenz',
repo: 'release-changelog-builder-action',
@@ -236,7 +236,7 @@ it('Should ignore PRs not merged into develop branch', async () => {
})
it('Should ignore PRs not merged into main branch', async () => {
const configuration = resolveConfiguration('', 'configs_test/configuration_base_branches_main.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_base_branches_main.json'))
const releaseNotes = new ReleaseNotes(octokit, {
owner: 'mikepenz',
repo: 'release-changelog-builder-action',
+15 -15
View File
@@ -1,10 +1,10 @@
import {resolveConfiguration} from '../src/utils'
import {mergeConfiguration, resolveConfiguration} from '../src/utils'
import {ReleaseNotesBuilder} from '../src/releaseNotesBuilder'
jest.setTimeout(180000)
it('Should match generated changelog (unspecified fromTag)', async () => {
const configuration = resolveConfiguration('', 'configs/configuration.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs/configuration.json'))
const releaseNotesBuilder = new ReleaseNotesBuilder(
null,
null,
@@ -34,7 +34,7 @@ it('Should match generated changelog (unspecified fromTag)', async () => {
})
it('Should match generated changelog (unspecified tags)', async () => {
const configuration = resolveConfiguration('', 'configs/configuration.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs/configuration.json'))
const releaseNotesBuilder = new ReleaseNotesBuilder(
null,
null,
@@ -59,7 +59,7 @@ it('Should match generated changelog (unspecified tags)', async () => {
})
it('Should use empty placeholder', async () => {
const configuration = resolveConfiguration('', 'configs/configuration.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs/configuration.json'))
const releaseNotesBuilder = new ReleaseNotesBuilder(
null,
null,
@@ -84,7 +84,7 @@ it('Should use empty placeholder', async () => {
})
it('Should fill empty placeholders', async () => {
const configuration = resolveConfiguration('', 'configs_test/configuration_empty_all_placeholders.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_empty_all_placeholders.json'))
const releaseNotesBuilder = new ReleaseNotesBuilder(
null,
null,
@@ -111,7 +111,7 @@ it('Should fill empty placeholders', async () => {
})
it('Should fill `template` placeholders', async () => {
const configuration = resolveConfiguration('', 'configs_test/configuration_empty_all_placeholders.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_empty_all_placeholders.json'))
const releaseNotesBuilder = new ReleaseNotesBuilder(
null,
null,
@@ -138,7 +138,7 @@ it('Should fill `template` placeholders', async () => {
})
it('Should fill `template` placeholders, ignore', async () => {
const configuration = resolveConfiguration('', 'configs_test/configuration_empty_all_placeholders.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_empty_all_placeholders.json'))
const releaseNotesBuilder = new ReleaseNotesBuilder(
null,
null,
@@ -165,7 +165,7 @@ it('Should fill `template` placeholders, ignore', async () => {
})
it('Uncategorized category', async () => {
const configuration = resolveConfiguration('', 'configs_test/configuration_uncategorized_category.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_uncategorized_category.json'))
const releaseNotesBuilder = new ReleaseNotesBuilder(
null,
null,
@@ -192,7 +192,7 @@ it('Uncategorized category', async () => {
})
it('Verify commit based changelog', async () => {
const configuration = resolveConfiguration('', 'configs_test/configuration_commits.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_commits.json'))
const releaseNotesBuilder = new ReleaseNotesBuilder(
null,
null,
@@ -219,7 +219,7 @@ it('Verify commit based changelog', async () => {
})
it('Verify commit based changelog, with emoji categorisation', async () => {
const configuration = resolveConfiguration('', 'configs_test/configuration_commits_emoji.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_commits_emoji.json'))
const releaseNotesBuilder = new ReleaseNotesBuilder(
null,
null,
@@ -246,7 +246,7 @@ it('Verify commit based changelog, with emoji categorisation', async () => {
})
it('Verify default inclusion of open PRs', async () => {
const configuration = resolveConfiguration('', 'configs_test/configuration_including_open.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_including_open.json'))
const releaseNotesBuilder = new ReleaseNotesBuilder(
null, // baseUrl
null, // token
@@ -273,7 +273,7 @@ it('Verify default inclusion of open PRs', async () => {
})
it('Verify custom categorisation of open PRs', async () => {
const configuration = resolveConfiguration('', 'configs_test/configuration_excluding_open.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_excluding_open.json'))
const releaseNotesBuilder = new ReleaseNotesBuilder(
null, // baseUrl
null, // token
@@ -300,7 +300,7 @@ it('Verify custom categorisation of open PRs', async () => {
})
it('Verify reviewers who approved are fetched and also release information', async () => {
const configuration = resolveConfiguration('', 'configs_test/configuration_approvers.json')
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_approvers.json'))
const releaseNotesBuilder = new ReleaseNotesBuilder(
null, // baseUrl
null, // token
@@ -327,7 +327,7 @@ it('Verify reviewers who approved are fetched and also release information', asy
})
it('Fetch release information', async () => {
const configuration = resolveConfiguration('', 'configs_test/configuration_approvers.json')
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}}'
const releaseNotesBuilder = new ReleaseNotesBuilder(
null, // baseUrl
@@ -353,7 +353,7 @@ it('Fetch release information', async () => {
})
it('Fetch release information for non existing tag / release', async () => {
const configuration = resolveConfiguration('', 'configs_test/configuration_approvers.json')
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}}'
const releaseNotesBuilder = new ReleaseNotesBuilder(
null, // baseUrl
Generated Vendored
+47 -24
View File
@@ -395,18 +395,19 @@ function run() {
// read in path specification, resolve github workspace, and repo path
const inputPath = core.getInput('path');
const repositoryPath = (0, utils_1.retrieveRepositoryPath)(inputPath);
// read in configuration file if possible
let configuration = undefined;
// read in configuration from json if possible
let configJson = undefined;
const configurationJson = core.getInput('configurationJson', {
trimWhitespace: true
});
if (configurationJson) {
configuration = (0, utils_1.parseConfiguration)(configurationJson);
configJson = (0, utils_1.parseConfiguration)(configurationJson);
}
if (!configuration) {
// read in the configuration from the file if possible
const configurationFile = core.getInput('configuration');
configuration = (0, utils_1.resolveConfiguration)(repositoryPath, configurationFile);
}
const configFile = (0, utils_1.resolveConfiguration)(repositoryPath, configurationFile);
// merge configs, use default values from DefaultConfig on missing definition
const configuration = (0, utils_1.mergeConfiguration)(configJson, configFile);
// read in repository inputs
const baseUrl = core.getInput('baseUrl');
const token = core.getInput('token');
@@ -821,7 +822,6 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ReleaseNotes = void 0;
const core = __importStar(__nccwpck_require__(2186));
const commits_1 = __nccwpck_require__(3916);
const configuration_1 = __nccwpck_require__(5527);
const pullRequests_1 = __nccwpck_require__(4217);
const transform_1 = __nccwpck_require__(1644);
const utils_1 = __nccwpck_require__(918);
@@ -862,7 +862,7 @@ class ReleaseNotes {
core.setOutput('commits', diffInfo.commits);
if (mergedPullRequests.length === 0) {
core.warning(`⚠️ No pull requests found`);
return (0, transform_1.replaceEmptyTemplate)(this.options.configuration.empty_template || configuration_1.DefaultConfiguration.empty_template, this.options);
return (0, transform_1.replaceEmptyTemplate)(this.options.configuration.empty_template, this.options);
}
core.startGroup('📦 Build changelog');
const resultChangelog = (0, transform_1.buildChangelog)(diffInfo, mergedPullRequests, this.options);
@@ -903,7 +903,7 @@ class ReleaseNotes {
const lastCommit = commits[commits.length - 1];
let fromDate = firstCommit.date;
const toDate = lastCommit.date;
const maxDays = configuration.max_back_track_time_days || configuration_1.DefaultConfiguration.max_back_track_time_days;
const maxDays = configuration.max_back_track_time_days;
const maxFromDate = toDate.clone().subtract(maxDays, 'days');
if (maxFromDate.isAfter(fromDate)) {
core.info(`⚠️ Adjusted 'fromDate' to go max ${maxDays} back`);
@@ -911,9 +911,9 @@ class ReleaseNotes {
}
core.info(`️ Fetching PRs between dates ${fromDate.toISOString()} to ${toDate.toISOString()} for ${owner}/${repo}`);
const pullRequestsApi = new pullRequests_1.PullRequests(octokit);
const pullRequests = yield pullRequestsApi.getBetweenDates(owner, repo, fromDate, toDate, configuration.max_pull_requests || configuration_1.DefaultConfiguration.max_pull_requests);
const pullRequests = yield pullRequestsApi.getBetweenDates(owner, repo, fromDate, toDate, configuration.max_pull_requests);
core.info(`️ Retrieved ${pullRequests.length} PRs for ${owner}/${repo} in date range from API`);
const prCommits = (0, commits_1.filterCommits)(commits, configuration.exclude_merge_branches || configuration_1.DefaultConfiguration.exclude_merge_branches);
const prCommits = (0, commits_1.filterCommits)(commits, configuration.exclude_merge_branches);
core.info(`️ Retrieved ${prCommits.length} release commits for ${owner}/${repo}`);
// create array of commits for this release
const releaseCommitHashes = prCommits.map(commmit => {
@@ -927,14 +927,14 @@ class ReleaseNotes {
let allPullRequests = mergedPullRequests;
if (includeOpen) {
// retrieve all open pull requests
const openPullRequests = yield pullRequestsApi.getOpen(owner, repo, configuration.max_pull_requests || configuration_1.DefaultConfiguration.max_pull_requests);
const openPullRequests = yield pullRequestsApi.getOpen(owner, repo, configuration.max_pull_requests);
core.info(`️ Retrieved ${openPullRequests.length} open PRs for ${owner}/${repo}`);
// all pull requests
allPullRequests = allPullRequests.concat(openPullRequests);
core.info(`️ Retrieved ${allPullRequests.length} total PRs for ${owner}/${repo}`);
}
// retrieve base branches we allow
const baseBranches = configuration.base_branches || configuration_1.DefaultConfiguration.base_branches;
const baseBranches = configuration.base_branches;
const baseBranchPatterns = baseBranches.map(baseBranch => {
return new RegExp(baseBranch.replace('\\\\', '\\'), 'gu');
});
@@ -987,7 +987,7 @@ class ReleaseNotes {
if (commits.length === 0) {
return [diffInfo, []];
}
const prCommits = (0, commits_1.filterCommits)(commits, configuration.exclude_merge_branches || configuration_1.DefaultConfiguration.exclude_merge_branches);
const prCommits = (0, commits_1.filterCommits)(commits, configuration.exclude_merge_branches);
core.info(`️ Retrieved ${prCommits.length} commits for ${owner}/${repo}`);
const prs = prCommits.map(function (commit) {
return {
@@ -1058,7 +1058,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ReleaseNotesBuilder = void 0;
const core = __importStar(__nccwpck_require__(2186));
const configuration_1 = __nccwpck_require__(5527);
const rest_1 = __nccwpck_require__(5375);
const releaseNotes_1 = __nccwpck_require__(5882);
const tags_1 = __nccwpck_require__(7532);
@@ -1125,7 +1124,7 @@ class ReleaseNotesBuilder {
// ensure proper from <-> to tag range
core.startGroup(`🔖 Resolve tags`);
const tagsApi = new tags_1.Tags(octokit);
const tagRange = yield tagsApi.retrieveRange(this.repositoryPath, this.owner, this.repo, this.fromTag, this.toTag, this.ignorePreReleases, this.configuration.max_tags_to_fetch || configuration_1.DefaultConfiguration.max_tags_to_fetch, this.configuration.tag_resolver || configuration_1.DefaultConfiguration.tag_resolver);
const tagRange = yield tagsApi.retrieveRange(this.repositoryPath, this.owner, this.repo, this.fromTag, this.toTag, this.ignorePreReleases, this.configuration.max_tags_to_fetch, this.configuration.tag_resolver);
let thisTag = tagRange.to;
if (!thisTag) {
(0, utils_1.failOrError)(`💥 Missing or couldn't resolve 'toTag'`, this.failOnError);
@@ -1569,14 +1568,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.validateTransformer = exports.replaceEmptyTemplate = exports.buildChangelog = void 0;
const core = __importStar(__nccwpck_require__(2186));
const configuration_1 = __nccwpck_require__(5527);
const pullRequests_1 = __nccwpck_require__(4217);
const utils_1 = __nccwpck_require__(918);
const EMPTY_MAP = new Map();
function buildChangelog(diffInfo, prs, options) {
// sort to target order
const config = options.configuration;
const sort = config.sort || configuration_1.DefaultConfiguration.sort;
const sort = config.sort;
prs = (0, pullRequests_1.sortPullRequests)(prs, sort);
core.info(`️ Sorted all pull requests ascending: ${JSON.stringify(sort)}`);
// drop duplicate pull requests
@@ -1628,14 +1626,14 @@ function buildChangelog(diffInfo, prs, options) {
const transformedMap = new Map();
// convert PRs to their text representation
for (const pr of prs) {
transformedMap.set(pr, transform(fillPrTemplate(pr, config.pr_template || configuration_1.DefaultConfiguration.pr_template, placeholders, placeholderPrMap, config), validatedTransformers));
transformedMap.set(pr, transform(fillPrTemplate(pr, config.pr_template, placeholders, placeholderPrMap, config), validatedTransformers));
}
core.info(`️ Used ${validatedTransformers.length} transformers to adjust message`);
core.info(`✒️ Wrote messages for ${prs.length} pull requests`);
// bring PRs into the order of categories
const categorized = new Map();
const categories = config.categories || configuration_1.DefaultConfiguration.categories;
const ignoredLabels = config.ignore_labels || configuration_1.DefaultConfiguration.ignore_labels;
const categories = config.categories;
const ignoredLabels = config.ignore_labels;
for (const category of categories) {
categorized.set(category, []);
}
@@ -1768,7 +1766,7 @@ function buildChangelog(diffInfo, prs, options) {
placeholderMap.set('CHANGES', diffInfo.changes.toString());
placeholderMap.set('COMMITS', diffInfo.commits.toString());
fillAdditionalPlaceholders(options, placeholderMap);
let transformedChangelog = config.template || configuration_1.DefaultConfiguration.template;
let transformedChangelog = config.template;
transformedChangelog = replacePlaceholders(transformedChangelog, EMPTY_MAP, placeholderMap, placeholders, placeholderPrMap, config);
transformedChangelog = replacePrPlaceholders(transformedChangelog, placeholderPrMap, config);
transformedChangelog = cleanupPrPlaceholders(transformedChangelog, placeholders);
@@ -1917,7 +1915,7 @@ function transform(filled, transformers) {
return transformed;
}
function validateTransformers(specifiedTransformers) {
const transformers = specifiedTransformers || configuration_1.DefaultConfiguration.transformers;
const transformers = specifiedTransformers;
return transformers
.map(transformer => {
return validateTransformer(transformer);
@@ -2041,7 +2039,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.haveEveryElements = exports.haveCommonElements = exports.createOrSet = exports.writeOutput = exports.directoryExistsSync = exports.parseConfiguration = exports.resolveConfiguration = exports.failOrError = exports.retrieveRepositoryPath = void 0;
exports.haveEveryElements = exports.haveCommonElements = exports.createOrSet = exports.writeOutput = exports.directoryExistsSync = exports.mergeConfiguration = exports.parseConfiguration = exports.resolveConfiguration = exports.failOrError = exports.retrieveRepositoryPath = void 0;
const core = __importStar(__nccwpck_require__(2186));
const fs = __importStar(__nccwpck_require__(7147));
const path = __importStar(__nccwpck_require__(1017));
@@ -2130,6 +2128,31 @@ function parseConfiguration(config) {
}
}
exports.parseConfiguration = parseConfiguration;
/**
* Merges the configurations, will fallback to the DefaultConfiguration value
*/
function mergeConfiguration(jc, fc) {
return {
max_tags_to_fetch: (jc === null || jc === void 0 ? void 0 : jc.max_tags_to_fetch) || (fc === null || fc === void 0 ? void 0 : fc.max_tags_to_fetch) || configuration_1.DefaultConfiguration.max_tags_to_fetch,
max_pull_requests: (jc === null || jc === void 0 ? void 0 : jc.max_pull_requests) || (fc === null || fc === void 0 ? void 0 : fc.max_pull_requests) || configuration_1.DefaultConfiguration.max_pull_requests,
max_back_track_time_days: (jc === null || jc === void 0 ? void 0 : jc.max_back_track_time_days) || (fc === null || fc === void 0 ? void 0 : fc.max_back_track_time_days) || configuration_1.DefaultConfiguration.max_back_track_time_days,
exclude_merge_branches: (jc === null || jc === void 0 ? void 0 : jc.exclude_merge_branches) || (fc === null || fc === void 0 ? void 0 : fc.exclude_merge_branches) || configuration_1.DefaultConfiguration.exclude_merge_branches,
sort: (jc === null || jc === void 0 ? void 0 : jc.sort) || (fc === null || fc === void 0 ? void 0 : fc.sort) || configuration_1.DefaultConfiguration.sort,
template: (jc === null || jc === void 0 ? void 0 : jc.template) || (fc === null || fc === void 0 ? void 0 : fc.template) || configuration_1.DefaultConfiguration.template,
pr_template: (jc === null || jc === void 0 ? void 0 : jc.pr_template) || (fc === null || fc === void 0 ? void 0 : fc.pr_template) || configuration_1.DefaultConfiguration.pr_template,
empty_template: (jc === null || jc === void 0 ? void 0 : jc.empty_template) || (fc === null || fc === void 0 ? void 0 : fc.empty_template) || configuration_1.DefaultConfiguration.empty_template,
categories: (jc === null || jc === void 0 ? void 0 : jc.categories) || (fc === null || fc === void 0 ? void 0 : fc.categories) || configuration_1.DefaultConfiguration.categories,
ignore_labels: (jc === null || jc === void 0 ? void 0 : jc.ignore_labels) || (fc === null || fc === void 0 ? void 0 : fc.ignore_labels) || configuration_1.DefaultConfiguration.ignore_labels,
label_extractor: (jc === null || jc === void 0 ? void 0 : jc.label_extractor) || (fc === null || fc === void 0 ? void 0 : fc.label_extractor) || configuration_1.DefaultConfiguration.label_extractor,
duplicate_filter: (jc === null || jc === void 0 ? void 0 : jc.duplicate_filter) || (fc === null || fc === void 0 ? void 0 : fc.duplicate_filter) || configuration_1.DefaultConfiguration.duplicate_filter,
transformers: (jc === null || jc === void 0 ? void 0 : jc.transformers) || (fc === null || fc === void 0 ? void 0 : fc.transformers) || configuration_1.DefaultConfiguration.transformers,
tag_resolver: (jc === null || jc === void 0 ? void 0 : jc.tag_resolver) || (fc === null || fc === void 0 ? void 0 : fc.tag_resolver) || configuration_1.DefaultConfiguration.tag_resolver,
base_branches: (jc === null || jc === void 0 ? void 0 : jc.base_branches) || (fc === null || fc === void 0 ? void 0 : fc.base_branches) || configuration_1.DefaultConfiguration.base_branches,
custom_placeholders: (jc === null || jc === void 0 ? void 0 : jc.custom_placeholders) || (fc === null || fc === void 0 ? void 0 : fc.custom_placeholders) || configuration_1.DefaultConfiguration.custom_placeholders,
trim_values: (jc === null || jc === void 0 ? void 0 : jc.trim_values) || (fc === null || fc === void 0 ? void 0 : fc.trim_values) || configuration_1.DefaultConfiguration.trim_values
};
}
exports.mergeConfiguration = mergeConfiguration;
/**
* Checks if a given directory exists
*/
Generated Vendored
+1 -1
View File
File diff suppressed because one or more lines are too long
+9 -7
View File
@@ -1,6 +1,6 @@
import * as core from '@actions/core'
import * as github from '@actions/github'
import {parseConfiguration, resolveConfiguration, retrieveRepositoryPath, writeOutput} from './utils'
import {mergeConfiguration, parseConfiguration, resolveConfiguration, retrieveRepositoryPath, writeOutput} from './utils'
import {ReleaseNotesBuilder} from './releaseNotesBuilder'
import {Configuration} from './configuration'
@@ -13,18 +13,20 @@ async function run(): Promise<void> {
const inputPath = core.getInput('path')
const repositoryPath = retrieveRepositoryPath(inputPath)
// read in configuration file if possible
let configuration: Configuration | undefined = undefined
// read in configuration from json if possible
let configJson: Configuration | undefined = undefined
const configurationJson: string = core.getInput('configurationJson', {
trimWhitespace: true
})
if (configurationJson) {
configuration = parseConfiguration(configurationJson)
configJson = parseConfiguration(configurationJson)
}
if (!configuration) {
// read in the configuration from the file if possible
const configurationFile: string = core.getInput('configuration')
configuration = resolveConfiguration(repositoryPath, configurationFile)
}
const configFile = resolveConfiguration(repositoryPath, configurationFile)
// merge configs, use default values from DefaultConfig on missing definition
const configuration = mergeConfiguration(configJson, configFile)
// read in repository inputs
const baseUrl = core.getInput('baseUrl')
+8 -18
View File
@@ -1,6 +1,6 @@
import * as core from '@actions/core'
import {Commits, filterCommits, DiffInfo, DefaultDiffInfo} from './commits'
import {Configuration, DefaultConfiguration} from './configuration'
import {Configuration} from './configuration'
import {PullRequestInfo, PullRequests} from './pullRequests'
import {Octokit} from '@octokit/rest'
import {buildChangelog, replaceEmptyTemplate} from './transform'
@@ -62,7 +62,7 @@ export class ReleaseNotes {
if (mergedPullRequests.length === 0) {
core.warning(`⚠️ No pull requests found`)
return replaceEmptyTemplate(this.options.configuration.empty_template || DefaultConfiguration.empty_template, this.options)
return replaceEmptyTemplate(this.options.configuration.empty_template, this.options)
}
core.startGroup('📦 Build changelog')
@@ -105,7 +105,7 @@ export class ReleaseNotes {
let fromDate = firstCommit.date
const toDate = lastCommit.date
const maxDays = configuration.max_back_track_time_days || DefaultConfiguration.max_back_track_time_days
const maxDays = configuration.max_back_track_time_days
const maxFromDate = toDate.clone().subtract(maxDays, 'days')
if (maxFromDate.isAfter(fromDate)) {
core.info(`⚠️ Adjusted 'fromDate' to go max ${maxDays} back`)
@@ -115,17 +115,11 @@ export class ReleaseNotes {
core.info(`️ Fetching PRs between dates ${fromDate.toISOString()} to ${toDate.toISOString()} for ${owner}/${repo}`)
const pullRequestsApi = new PullRequests(octokit)
const pullRequests = await pullRequestsApi.getBetweenDates(
owner,
repo,
fromDate,
toDate,
configuration.max_pull_requests || DefaultConfiguration.max_pull_requests
)
const pullRequests = await pullRequestsApi.getBetweenDates(owner, repo, fromDate, toDate, configuration.max_pull_requests)
core.info(`️ Retrieved ${pullRequests.length} PRs for ${owner}/${repo} in date range from API`)
const prCommits = filterCommits(commits, configuration.exclude_merge_branches || DefaultConfiguration.exclude_merge_branches)
const prCommits = filterCommits(commits, configuration.exclude_merge_branches)
core.info(`️ Retrieved ${prCommits.length} release commits for ${owner}/${repo}`)
@@ -144,11 +138,7 @@ export class ReleaseNotes {
let allPullRequests = mergedPullRequests
if (includeOpen) {
// retrieve all open pull requests
const openPullRequests = await pullRequestsApi.getOpen(
owner,
repo,
configuration.max_pull_requests || DefaultConfiguration.max_pull_requests
)
const openPullRequests = await pullRequestsApi.getOpen(owner, repo, configuration.max_pull_requests)
core.info(`️ Retrieved ${openPullRequests.length} open PRs for ${owner}/${repo}`)
@@ -159,7 +149,7 @@ export class ReleaseNotes {
}
// retrieve base branches we allow
const baseBranches = configuration.base_branches || DefaultConfiguration.base_branches
const baseBranches = configuration.base_branches
const baseBranchPatterns = baseBranches.map(baseBranch => {
return new RegExp(baseBranch.replace('\\\\', '\\'), 'gu')
})
@@ -216,7 +206,7 @@ export class ReleaseNotes {
return [diffInfo, []]
}
const prCommits = filterCommits(commits, configuration.exclude_merge_branches || DefaultConfiguration.exclude_merge_branches)
const prCommits = filterCommits(commits, configuration.exclude_merge_branches)
core.info(`️ Retrieved ${prCommits.length} commits for ${owner}/${repo}`)
+3 -3
View File
@@ -1,5 +1,5 @@
import * as core from '@actions/core'
import {Configuration, DefaultConfiguration} from './configuration'
import {Configuration} from './configuration'
import {Octokit} from '@octokit/rest'
import {ReleaseNotes} from './releaseNotes'
import {Tags} from './tags'
@@ -77,8 +77,8 @@ export class ReleaseNotesBuilder {
this.fromTag,
this.toTag,
this.ignorePreReleases,
this.configuration.max_tags_to_fetch || DefaultConfiguration.max_tags_to_fetch,
this.configuration.tag_resolver || DefaultConfiguration.tag_resolver
this.configuration.max_tags_to_fetch,
this.configuration.tag_resolver
)
let thisTag = tagRange.to
+7 -13
View File
@@ -1,5 +1,5 @@
import * as core from '@actions/core'
import {Category, Configuration, DefaultConfiguration, Extractor, Placeholder, Transformer} from './configuration'
import {Category, Configuration, Extractor, Placeholder, Transformer} from './configuration'
import {CommentInfo, EMPTY_COMMENT_INFO, PullRequestInfo, sortPullRequests} from './pullRequests'
import {ReleaseNotesOptions} from './releaseNotes'
import {DiffInfo} from './commits'
@@ -18,7 +18,7 @@ const EMPTY_MAP = new Map<string, string>()
export function buildChangelog(diffInfo: DiffInfo, prs: PullRequestInfo[], options: ReleaseNotesOptions): string {
// sort to target order
const config = options.configuration
const sort = config.sort || DefaultConfiguration.sort
const sort = config.sort
prs = sortPullRequests(prs, sort)
core.info(`️ Sorted all pull requests ascending: ${JSON.stringify(sort)}`)
@@ -73,21 +73,15 @@ export function buildChangelog(diffInfo: DiffInfo, prs: PullRequestInfo[], optio
const transformedMap = new Map<PullRequestInfo, string>()
// convert PRs to their text representation
for (const pr of prs) {
transformedMap.set(
pr,
transform(
fillPrTemplate(pr, config.pr_template || DefaultConfiguration.pr_template, placeholders, placeholderPrMap, config),
validatedTransformers
)
)
transformedMap.set(pr, transform(fillPrTemplate(pr, config.pr_template, placeholders, placeholderPrMap, config), validatedTransformers))
}
core.info(`️ Used ${validatedTransformers.length} transformers to adjust message`)
core.info(`✒️ Wrote messages for ${prs.length} pull requests`)
// 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
const categories = config.categories
const ignoredLabels = config.ignore_labels
for (const category of categories) {
categorized.set(category, [])
@@ -252,7 +246,7 @@ export function buildChangelog(diffInfo: DiffInfo, prs: PullRequestInfo[], optio
placeholderMap.set('COMMITS', diffInfo.commits.toString())
fillAdditionalPlaceholders(options, placeholderMap)
let transformedChangelog = config.template || DefaultConfiguration.template
let transformedChangelog = config.template
transformedChangelog = replacePlaceholders(transformedChangelog, EMPTY_MAP, placeholderMap, placeholders, placeholderPrMap, config)
transformedChangelog = replacePrPlaceholders(transformedChangelog, placeholderPrMap, config)
transformedChangelog = cleanupPrPlaceholders(transformedChangelog, placeholders)
@@ -453,7 +447,7 @@ function transform(filled: string, transformers: RegexTransformer[]): string {
}
function validateTransformers(specifiedTransformers: Transformer[]): RegexTransformer[] {
const transformers = specifiedTransformers || DefaultConfiguration.transformers
const transformers = specifiedTransformers
return transformers
.map(transformer => {
return validateTransformer(transformer)
+25
View File
@@ -84,6 +84,31 @@ export function parseConfiguration(config: string): Configuration | undefined {
}
}
/**
* Merges the configurations, will fallback to the DefaultConfiguration value
*/
export function mergeConfiguration(jc?: Configuration, fc?: Configuration): Configuration {
return {
max_tags_to_fetch: jc?.max_tags_to_fetch || fc?.max_tags_to_fetch || DefaultConfiguration.max_tags_to_fetch,
max_pull_requests: jc?.max_pull_requests || fc?.max_pull_requests || DefaultConfiguration.max_pull_requests,
max_back_track_time_days: jc?.max_back_track_time_days || fc?.max_back_track_time_days || DefaultConfiguration.max_back_track_time_days,
exclude_merge_branches: jc?.exclude_merge_branches || fc?.exclude_merge_branches || DefaultConfiguration.exclude_merge_branches,
sort: jc?.sort || fc?.sort || DefaultConfiguration.sort,
template: jc?.template || fc?.template || DefaultConfiguration.template,
pr_template: jc?.pr_template || fc?.pr_template || DefaultConfiguration.pr_template,
empty_template: jc?.empty_template || fc?.empty_template || DefaultConfiguration.empty_template,
categories: jc?.categories || fc?.categories || DefaultConfiguration.categories,
ignore_labels: jc?.ignore_labels || fc?.ignore_labels || DefaultConfiguration.ignore_labels,
label_extractor: jc?.label_extractor || fc?.label_extractor || DefaultConfiguration.label_extractor,
duplicate_filter: jc?.duplicate_filter || fc?.duplicate_filter || DefaultConfiguration.duplicate_filter,
transformers: jc?.transformers || fc?.transformers || DefaultConfiguration.transformers,
tag_resolver: jc?.tag_resolver || fc?.tag_resolver || DefaultConfiguration.tag_resolver,
base_branches: jc?.base_branches || fc?.base_branches || DefaultConfiguration.base_branches,
custom_placeholders: jc?.custom_placeholders || fc?.custom_placeholders || DefaultConfiguration.custom_placeholders,
trim_values: jc?.trim_values || fc?.trim_values || DefaultConfiguration.trim_values
}
}
/**
* Checks if a given directory exists
*/