- introduce new configuration option to define category labels to be exhaustive
- require all labels of a category to be present in the matching PR - update to typescript 4.4.x - recompile dist
This commit is contained in:
@@ -290,6 +290,7 @@ Table of descriptions for the `configuration.json` options to configure the resu
|
|||||||
| categories | An array of `category` specifications, offering a flexible way to group changes into categories |
|
| 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.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 |
|
||||||
|
| category.exhaustive | Will require all labels defined within this category to be present on the matching PR. |
|
||||||
| 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 |
|
| 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] |
|
| 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 |
|
| template | Specifies the global template to pick for creating the changelog. See [Template placeholders](#template-placeholders) for possible values |
|
||||||
@@ -325,7 +326,7 @@ $ npm run build && npm run package
|
|||||||
$ npm test
|
$ npm test
|
||||||
|
|
||||||
# Verify lint is happy
|
# Verify lint is happy
|
||||||
$ npm run lint -- --fix
|
$ npm run lint -- --fixnpm run lint -- --fix
|
||||||
```
|
```
|
||||||
|
|
||||||
It's suggested to export the token to your path before running the tests so that API calls can be done to GitHub.
|
It's suggested to export the token to your path before running the tests so that API calls can be done to GitHub.
|
||||||
|
|||||||
+121
-72
@@ -6,79 +6,79 @@ import { DefaultConfiguration } from '../src/configuration';
|
|||||||
jest.setTimeout(180000)
|
jest.setTimeout(180000)
|
||||||
|
|
||||||
let configuration = DefaultConfiguration
|
let configuration = DefaultConfiguration
|
||||||
configuration.categories = [
|
configuration.categories = [
|
||||||
{
|
{
|
||||||
"title": "## 🚀 Features",
|
"title": "## 🚀 Features",
|
||||||
"labels": ["[Feature]"]
|
"labels": ["[Feature]"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "## 🐛 Fixes",
|
"title": "## 🐛 Fixes",
|
||||||
"labels": ["[Bug]", "[Issue]"]
|
"labels": ["[Bug]", "[Issue]"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "## 🧪 Tests",
|
"title": "## 🧪 Tests",
|
||||||
"labels": ["[Test]"]
|
"labels": ["[Test]"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
let mergedPullRequests: PullRequestInfo[] = []
|
let mergedPullRequests: PullRequestInfo[] = []
|
||||||
mergedPullRequests.push({
|
mergedPullRequests.push({
|
||||||
number: 1,
|
number: 1,
|
||||||
title: "[Feature][AB-1234] - this is a PR 1 title message",
|
title: "[Feature][AB-1234] - this is a PR 1 title message",
|
||||||
htmlURL: "",
|
htmlURL: "",
|
||||||
baseBranch: "",
|
baseBranch: "",
|
||||||
mergedAt: moment(),
|
mergedAt: moment(),
|
||||||
mergeCommitSha: "sha1",
|
mergeCommitSha: "sha1",
|
||||||
author: "Mike",
|
author: "Mike",
|
||||||
repoName: "test-repo",
|
repoName: "test-repo",
|
||||||
labels: new Set<string>(),
|
labels: new Set<string>(),
|
||||||
milestone: "",
|
milestone: "",
|
||||||
body: "no magic body for this matter",
|
body: "no magic body for this matter",
|
||||||
assignees: [],
|
assignees: [],
|
||||||
requestedReviewers: []
|
requestedReviewers: []
|
||||||
}, {
|
}, {
|
||||||
number: 2,
|
number: 2,
|
||||||
title: "[Issue][AB-4321] - this is a PR 2 title message",
|
title: "[Issue][AB-4321] - this is a PR 2 title message",
|
||||||
htmlURL: "",
|
htmlURL: "",
|
||||||
baseBranch: "",
|
baseBranch: "",
|
||||||
mergedAt: moment(),
|
mergedAt: moment(),
|
||||||
mergeCommitSha: "sha1",
|
mergeCommitSha: "sha1",
|
||||||
author: "Mike",
|
author: "Mike",
|
||||||
repoName: "test-repo",
|
repoName: "test-repo",
|
||||||
labels: new Set<string>(),
|
labels: new Set<string>(),
|
||||||
milestone: "",
|
milestone: "",
|
||||||
body: "no magic body for this matter",
|
body: "no magic body for this matter",
|
||||||
assignees: [],
|
assignees: [],
|
||||||
requestedReviewers: []
|
requestedReviewers: []
|
||||||
}, {
|
}, {
|
||||||
number: 3,
|
number: 3,
|
||||||
title: "[Issue][Feature][AB-1234321] - this is a PR 3 title message",
|
title: "[Issue][Feature][AB-1234321] - this is a PR 3 title message",
|
||||||
htmlURL: "",
|
htmlURL: "",
|
||||||
baseBranch: "",
|
baseBranch: "",
|
||||||
mergedAt: moment(),
|
mergedAt: moment(),
|
||||||
mergeCommitSha: "sha1",
|
mergeCommitSha: "sha1",
|
||||||
author: "Mike",
|
author: "Mike",
|
||||||
repoName: "test-repo",
|
repoName: "test-repo",
|
||||||
labels: new Set<string>(),
|
labels: new Set<string>(),
|
||||||
milestone: "",
|
milestone: "",
|
||||||
body: "no magic body for this matter",
|
body: "no magic body for this matter",
|
||||||
assignees: [],
|
assignees: [],
|
||||||
requestedReviewers: []
|
requestedReviewers: []
|
||||||
}, {
|
}, {
|
||||||
number: 4,
|
number: 4,
|
||||||
title: "[AB-404] - not found label",
|
title: "[AB-404] - not found label",
|
||||||
htmlURL: "",
|
htmlURL: "",
|
||||||
baseBranch: "",
|
baseBranch: "",
|
||||||
mergedAt: moment(),
|
mergedAt: moment(),
|
||||||
mergeCommitSha: "sha1",
|
mergeCommitSha: "sha1",
|
||||||
author: "Mike",
|
author: "Mike",
|
||||||
repoName: "test-repo",
|
repoName: "test-repo",
|
||||||
labels: new Set<string>(),
|
labels: new Set<string>(),
|
||||||
milestone: "",
|
milestone: "",
|
||||||
body: "no magic body for this matter",
|
body: "no magic body for this matter",
|
||||||
assignees: [],
|
assignees: [],
|
||||||
requestedReviewers: []
|
requestedReviewers: []
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Extract label from title, combined regex', async () => {
|
it('Extract label from title, combined regex', async () => {
|
||||||
configuration.label_extractor = [
|
configuration.label_extractor = [
|
||||||
@@ -189,3 +189,52 @@ it('Extract label from title, match multiple', async () => {
|
|||||||
|
|
||||||
expect(resultChangelog).toStrictEqual(`## 🚀 Features\n\n- [Feature][AB-1234] - this is a PR 1 title message\n - PR: #1\n- [Issue][Feature][AB-1234321] - this is a PR 3 title message\n - PR: #3\n\n## 🐛 Fixes\n\n- [Issue][AB-4321] - this is a PR 2 title message\n - PR: #2\n- [Issue][Feature][AB-1234321] - this is a PR 3 title message\n - PR: #3\n\n`)
|
expect(resultChangelog).toStrictEqual(`## 🚀 Features\n\n- [Feature][AB-1234] - this is a PR 1 title message\n - PR: #1\n- [Issue][Feature][AB-1234321] - this is a PR 3 title message\n - PR: #3\n\n## 🐛 Fixes\n\n- [Issue][AB-4321] - this is a PR 2 title message\n - PR: #2\n- [Issue][Feature][AB-1234321] - this is a PR 3 title message\n - PR: #3\n\n`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Extract label from title, match multiple exhaustive', async () => {
|
||||||
|
let customConfig = configuration
|
||||||
|
customConfig.categories = [
|
||||||
|
{
|
||||||
|
"title": "## 🚀 Features and 🐛 Issues",
|
||||||
|
"labels": ["[Feature]", "[Issue]"],
|
||||||
|
"exhaustive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "## 🚀 Features",
|
||||||
|
"labels": ["[Feature]", "[Feature2]"],
|
||||||
|
"exhaustive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "## 🐛 Fixes",
|
||||||
|
"labels": ["[Issue]", "[Issue2]"],
|
||||||
|
"exhaustive": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
customConfig.label_extractor = [
|
||||||
|
{
|
||||||
|
"pattern": "\\[Feature\\]",
|
||||||
|
"on_property": "title",
|
||||||
|
"method": "match"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pattern": "\\[Issue\\]",
|
||||||
|
"on_property": "title",
|
||||||
|
"method": "match"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const resultChangelog = buildChangelog(
|
||||||
|
mergedPullRequests,
|
||||||
|
{
|
||||||
|
owner: "mikepenz",
|
||||||
|
repo: "test-repo",
|
||||||
|
fromTag: "1.0.0",
|
||||||
|
toTag: "2.0.0",
|
||||||
|
failOnError: false,
|
||||||
|
commitMode: false,
|
||||||
|
configuration: customConfig
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(resultChangelog).toStrictEqual(`## 🚀 Features and 🐛 Issues\n\n- [Issue][Feature][AB-1234321] - this is a PR 3 title message\n - PR: #3\n\n`)
|
||||||
|
})
|
||||||
|
|||||||
+37
-26
@@ -80,7 +80,7 @@ class Commits {
|
|||||||
sha: commit.sha || '',
|
sha: commit.sha || '',
|
||||||
summary: commit.commit.message.split('\n')[0],
|
summary: commit.commit.message.split('\n')[0],
|
||||||
message: commit.commit.message,
|
message: commit.commit.message,
|
||||||
date: moment_1.default((_a = commit.commit.committer) === null || _a === void 0 ? void 0 : _a.date),
|
date: (0, moment_1.default)((_a = commit.commit.committer) === null || _a === void 0 ? void 0 : _a.date),
|
||||||
author: ((_b = commit.commit.author) === null || _b === void 0 ? void 0 : _b.name) || '',
|
author: ((_b = commit.commit.author) === null || _b === void 0 ? void 0 : _b.name) || '',
|
||||||
prNumber: undefined
|
prNumber: undefined
|
||||||
});
|
});
|
||||||
@@ -269,7 +269,7 @@ class GitCommandManager {
|
|||||||
}
|
}
|
||||||
execGit(args, allowAllExitCodes = false, silent = false) {
|
execGit(args, allowAllExitCodes = false, silent = false) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
utils_1.directoryExistsSync(this.workingDirectory, true);
|
(0, utils_1.directoryExistsSync)(this.workingDirectory, true);
|
||||||
const result = new GitOutput();
|
const result = new GitOutput();
|
||||||
const stdout = [];
|
const stdout = [];
|
||||||
const options = {
|
const options = {
|
||||||
@@ -349,10 +349,10 @@ function run() {
|
|||||||
try {
|
try {
|
||||||
// read in path specification, resolve github workspace, and repo path
|
// read in path specification, resolve github workspace, and repo path
|
||||||
const inputPath = core.getInput('path');
|
const inputPath = core.getInput('path');
|
||||||
const repositoryPath = utils_1.retrieveRepositoryPath(inputPath);
|
const repositoryPath = (0, utils_1.retrieveRepositoryPath)(inputPath);
|
||||||
// read in configuration file if possible
|
// read in configuration file if possible
|
||||||
const configurationFile = core.getInput('configuration');
|
const configurationFile = core.getInput('configuration');
|
||||||
const configuration = utils_1.resolveConfiguration(repositoryPath, configurationFile);
|
const configuration = (0, utils_1.resolveConfiguration)(repositoryPath, configurationFile);
|
||||||
// read in repository inputs
|
// read in repository inputs
|
||||||
const token = core.getInput('token');
|
const token = core.getInput('token');
|
||||||
const owner = core.getInput('owner') || github.context.repo.owner;
|
const owner = core.getInput('owner') || github.context.repo.owner;
|
||||||
@@ -370,10 +370,10 @@ function run() {
|
|||||||
const outputFile = core.getInput('outputFile');
|
const outputFile = core.getInput('outputFile');
|
||||||
if (outputFile !== '') {
|
if (outputFile !== '') {
|
||||||
core.debug(`Enabled writing the changelog to disk`);
|
core.debug(`Enabled writing the changelog to disk`);
|
||||||
utils_1.writeOutput(repositoryPath, outputFile, result);
|
(0, utils_1.writeOutput)(repositoryPath, outputFile, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error /* eslint-disable-line @typescript-eslint/no-explicit-any */) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -444,7 +444,7 @@ class PullRequests {
|
|||||||
});
|
});
|
||||||
return mapPullRequest(data);
|
return mapPullRequest(data);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e /* eslint-disable-line @typescript-eslint/no-explicit-any */) {
|
||||||
core.warning(`⚠️ Cannot find PR ${owner}/${repo}#${prNumber} - ${e.message}`);
|
core.warning(`⚠️ Cannot find PR ${owner}/${repo}#${prNumber} - ${e.message}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -471,7 +471,7 @@ class PullRequests {
|
|||||||
}
|
}
|
||||||
const firstPR = prs[0];
|
const firstPR = prs[0];
|
||||||
if (firstPR === undefined ||
|
if (firstPR === undefined ||
|
||||||
(firstPR.merged_at && fromDate.isAfter(moment_1.default(firstPR.merged_at))) ||
|
(firstPR.merged_at && fromDate.isAfter((0, moment_1.default)(firstPR.merged_at))) ||
|
||||||
mergedPRs.length >= maxPullRequests) {
|
mergedPRs.length >= maxPullRequests) {
|
||||||
if (mergedPRs.length >= maxPullRequests) {
|
if (mergedPRs.length >= maxPullRequests) {
|
||||||
core.warning(`⚠️ Reached 'maxPullRequests' count ${maxPullRequests}`);
|
core.warning(`⚠️ Reached 'maxPullRequests' count ${maxPullRequests}`);
|
||||||
@@ -526,7 +526,7 @@ const mapPullRequest = (pr) => {
|
|||||||
title: pr.title,
|
title: pr.title,
|
||||||
htmlURL: pr.html_url,
|
htmlURL: pr.html_url,
|
||||||
baseBranch: pr.base.ref,
|
baseBranch: pr.base.ref,
|
||||||
mergedAt: moment_1.default(pr.merged_at),
|
mergedAt: (0, moment_1.default)(pr.merged_at),
|
||||||
mergeCommitSha: pr.merge_commit_sha || '',
|
mergeCommitSha: pr.merge_commit_sha || '',
|
||||||
author: ((_a = pr.user) === null || _a === void 0 ? void 0 : _a.login) || '',
|
author: ((_a = pr.user) === null || _a === void 0 ? void 0 : _a.login) || '',
|
||||||
repoName: pr.base.repo.full_name,
|
repoName: pr.base.repo.full_name,
|
||||||
@@ -612,7 +612,7 @@ class ReleaseNotes {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
core.startGroup('📦 Build changelog');
|
core.startGroup('📦 Build changelog');
|
||||||
const resultChangelog = transform_1.buildChangelog(mergedPullRequests, this.options);
|
const resultChangelog = (0, transform_1.buildChangelog)(mergedPullRequests, this.options);
|
||||||
core.endGroup();
|
core.endGroup();
|
||||||
return resultChangelog;
|
return resultChangelog;
|
||||||
});
|
});
|
||||||
@@ -627,7 +627,7 @@ class ReleaseNotes {
|
|||||||
commits = yield commitsApi.getDiff(owner, repo, fromTag, toTag);
|
commits = yield commitsApi.getDiff(owner, repo, fromTag, toTag);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
utils_1.failOrError(`💥 Failed to retrieve - Invalid tag? - Because of: ${error}`, failOnError);
|
(0, utils_1.failOrError)(`💥 Failed to retrieve - Invalid tag? - Because of: ${error}`, failOnError);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
if (commits.length === 0) {
|
if (commits.length === 0) {
|
||||||
@@ -659,7 +659,7 @@ class ReleaseNotes {
|
|||||||
const pullRequestsApi = new pullRequests_1.PullRequests(octokit);
|
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 || configuration_1.DefaultConfiguration.max_pull_requests);
|
||||||
core.info(`ℹ️ Retrieved ${pullRequests.length} merged PRs for ${owner}/${repo}`);
|
core.info(`ℹ️ Retrieved ${pullRequests.length} merged PRs for ${owner}/${repo}`);
|
||||||
const prCommits = commits_1.filterCommits(commits, configuration.exclude_merge_branches ||
|
const prCommits = (0, commits_1.filterCommits)(commits, configuration.exclude_merge_branches ||
|
||||||
configuration_1.DefaultConfiguration.exclude_merge_branches);
|
configuration_1.DefaultConfiguration.exclude_merge_branches);
|
||||||
core.info(`ℹ️ Retrieved ${prCommits.length} release commits for ${owner}/${repo}`);
|
core.info(`ℹ️ Retrieved ${prCommits.length} release commits for ${owner}/${repo}`);
|
||||||
// create array of commits for this release
|
// create array of commits for this release
|
||||||
@@ -691,7 +691,7 @@ class ReleaseNotes {
|
|||||||
if (commits.length === 0) {
|
if (commits.length === 0) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const prCommits = commits_1.filterCommits(commits, configuration.exclude_merge_branches ||
|
const prCommits = (0, commits_1.filterCommits)(commits, configuration.exclude_merge_branches ||
|
||||||
configuration_1.DefaultConfiguration.exclude_merge_branches);
|
configuration_1.DefaultConfiguration.exclude_merge_branches);
|
||||||
core.info(`ℹ️ Retrieved ${prCommits.length} commits for ${owner}/${repo}`);
|
core.info(`ℹ️ Retrieved ${prCommits.length} commits for ${owner}/${repo}`);
|
||||||
return prCommits.map(function (commit) {
|
return prCommits.map(function (commit) {
|
||||||
@@ -778,7 +778,7 @@ class ReleaseNotesBuilder {
|
|||||||
var _a, _b;
|
var _a, _b;
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
if (!this.owner) {
|
if (!this.owner) {
|
||||||
utils_1.failOrError(`💥 Missing or couldn't resolve 'owner'`, this.failOnError);
|
(0, utils_1.failOrError)(`💥 Missing or couldn't resolve 'owner'`, this.failOnError);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -786,7 +786,7 @@ class ReleaseNotesBuilder {
|
|||||||
core.debug(`Resolved 'owner' as ${this.owner}`);
|
core.debug(`Resolved 'owner' as ${this.owner}`);
|
||||||
}
|
}
|
||||||
if (!this.repo) {
|
if (!this.repo) {
|
||||||
utils_1.failOrError(`💥 Missing or couldn't resolve 'owner'`, this.failOnError);
|
(0, utils_1.failOrError)(`💥 Missing or couldn't resolve 'owner'`, this.failOnError);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -805,7 +805,7 @@ class ReleaseNotesBuilder {
|
|||||||
configuration_1.DefaultConfiguration.max_tags_to_fetch, this.configuration.tag_resolver || configuration_1.DefaultConfiguration.tag_resolver);
|
configuration_1.DefaultConfiguration.max_tags_to_fetch, this.configuration.tag_resolver || configuration_1.DefaultConfiguration.tag_resolver);
|
||||||
const thisTag = (_a = tagRange.to) === null || _a === void 0 ? void 0 : _a.name;
|
const thisTag = (_a = tagRange.to) === null || _a === void 0 ? void 0 : _a.name;
|
||||||
if (!thisTag) {
|
if (!thisTag) {
|
||||||
utils_1.failOrError(`💥 Missing or couldn't resolve 'toTag'`, this.failOnError);
|
(0, utils_1.failOrError)(`💥 Missing or couldn't resolve 'toTag'`, this.failOnError);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -815,7 +815,7 @@ class ReleaseNotesBuilder {
|
|||||||
}
|
}
|
||||||
const previousTag = (_b = tagRange.from) === null || _b === void 0 ? void 0 : _b.name;
|
const previousTag = (_b = tagRange.from) === null || _b === void 0 ? void 0 : _b.name;
|
||||||
if (previousTag == null) {
|
if (previousTag == null) {
|
||||||
utils_1.failOrError(`💥 Unable to retrieve previous tag given ${this.toTag}`, this.failOnError);
|
(0, utils_1.failOrError)(`💥 Unable to retrieve previous tag given ${this.toTag}`, this.failOnError);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
this.fromTag = previousTag;
|
this.fromTag = previousTag;
|
||||||
@@ -832,7 +832,7 @@ class ReleaseNotesBuilder {
|
|||||||
};
|
};
|
||||||
const releaseNotes = new releaseNotes_1.ReleaseNotes(octokit, options);
|
const releaseNotes = new releaseNotes_1.ReleaseNotes(octokit, options);
|
||||||
return ((yield releaseNotes.pull()) ||
|
return ((yield releaseNotes.pull()) ||
|
||||||
transform_1.fillAdditionalPlaceholders(this.configuration.empty_template ||
|
(0, transform_1.fillAdditionalPlaceholders)(this.configuration.empty_template ||
|
||||||
configuration_1.DefaultConfiguration.empty_template, options));
|
configuration_1.DefaultConfiguration.empty_template, options));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -953,7 +953,7 @@ class Tags {
|
|||||||
else {
|
else {
|
||||||
core.info(`ℹ️ Only one tag found for the given repository. Usually this is the case for the initial release.`);
|
core.info(`ℹ️ Only one tag found for the given repository. Usually this is the case for the initial release.`);
|
||||||
// if not specified try to retrieve tag from git
|
// if not specified try to retrieve tag from git
|
||||||
const gitHelper = yield gitHelper_1.createCommandManager(repositoryPath);
|
const gitHelper = yield (0, gitHelper_1.createCommandManager)(repositoryPath);
|
||||||
const initialCommit = yield gitHelper.initialCommit();
|
const initialCommit = yield gitHelper.initialCommit();
|
||||||
core.info(`🔖 Resolved initial commit (${initialCommit}) from 'git rev-list --max-parents=0 HEAD'`);
|
core.info(`🔖 Resolved initial commit (${initialCommit}) from 'git rev-list --max-parents=0 HEAD'`);
|
||||||
return { name: initialCommit, commit: initialCommit };
|
return { name: initialCommit, commit: initialCommit };
|
||||||
@@ -991,7 +991,7 @@ class Tags {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// if not specified try to retrieve tag from git
|
// if not specified try to retrieve tag from git
|
||||||
const gitHelper = yield gitHelper_1.createCommandManager(repositoryPath);
|
const gitHelper = yield (0, gitHelper_1.createCommandManager)(repositoryPath);
|
||||||
const latestTag = yield gitHelper.latestTag();
|
const latestTag = yield gitHelper.latestTag();
|
||||||
core.info(`🔖 Resolved current tag (${latestTag}) from 'git rev-list --tags --skip=0 --max-count=1'`);
|
core.info(`🔖 Resolved current tag (${latestTag}) from 'git rev-list --tags --skip=0 --max-count=1'`);
|
||||||
resultToTag = {
|
resultToTag = {
|
||||||
@@ -1133,7 +1133,7 @@ function buildChangelog(prs, options) {
|
|||||||
const config = options.configuration;
|
const config = options.configuration;
|
||||||
const sort = config.sort || configuration_1.DefaultConfiguration.sort;
|
const sort = config.sort || configuration_1.DefaultConfiguration.sort;
|
||||||
const sortAsc = sort.toUpperCase() === 'ASC';
|
const sortAsc = sort.toUpperCase() === 'ASC';
|
||||||
prs = pullRequests_1.sortPullRequests(prs, sortAsc);
|
prs = (0, pullRequests_1.sortPullRequests)(prs, sortAsc);
|
||||||
core.info(`ℹ️ Sorted all pull requests ascending: ${sort}`);
|
core.info(`ℹ️ Sorted all pull requests ascending: ${sort}`);
|
||||||
// extract additional labels from the commit message
|
// extract additional labels from the commit message
|
||||||
const labelExtractors = validateTransformers(config.label_extractor);
|
const labelExtractors = validateTransformers(config.label_extractor);
|
||||||
@@ -1195,9 +1195,17 @@ function buildChangelog(prs, options) {
|
|||||||
}
|
}
|
||||||
let matched = false;
|
let matched = false;
|
||||||
for (const [category, pullRequests] of categorized) {
|
for (const [category, pullRequests] of categorized) {
|
||||||
if (haveCommonElements(category.labels.map(lbl => lbl.toLocaleLowerCase()), pr.labels)) {
|
if (category.exhaustive === true) {
|
||||||
pullRequests.push(body);
|
if (haveEveryElements(category.labels.map(lbl => lbl.toLocaleLowerCase()), pr.labels)) {
|
||||||
matched = true;
|
pullRequests.push(body);
|
||||||
|
matched = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (haveCommonElements(category.labels.map(lbl => lbl.toLocaleLowerCase()), pr.labels)) {
|
||||||
|
pullRequests.push(body);
|
||||||
|
matched = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!matched) {
|
if (!matched) {
|
||||||
@@ -1264,6 +1272,9 @@ exports.fillAdditionalPlaceholders = fillAdditionalPlaceholders;
|
|||||||
function haveCommonElements(arr1, arr2) {
|
function haveCommonElements(arr1, arr2) {
|
||||||
return arr1.some(item => arr2.has(item));
|
return arr1.some(item => arr2.has(item));
|
||||||
}
|
}
|
||||||
|
function haveEveryElements(arr1, arr2) {
|
||||||
|
return arr1.every(item => arr2.has(item));
|
||||||
|
}
|
||||||
function fillTemplate(pr, template) {
|
function fillTemplate(pr, template) {
|
||||||
var _a, _b, _c;
|
var _a, _b, _c;
|
||||||
let transformed = template;
|
let transformed = template;
|
||||||
@@ -1432,7 +1443,7 @@ function directoryExistsSync(inputPath, required) {
|
|||||||
try {
|
try {
|
||||||
stats = fs.statSync(inputPath);
|
stats = fs.statSync(inputPath);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error /* eslint-disable-line @typescript-eslint/no-explicit-any */) {
|
||||||
if (error.code === 'ENOENT') {
|
if (error.code === 'ENOENT') {
|
||||||
if (!required) {
|
if (!required) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1460,7 +1471,7 @@ function writeOutput(githubWorkspacePath, outputFile, changelog) {
|
|||||||
try {
|
try {
|
||||||
fs.writeFileSync(outputPath, changelog);
|
fs.writeFileSync(outputPath, changelog);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error /* eslint-disable-line @typescript-eslint/no-explicit-any */) {
|
||||||
core.warning(`⚠️ Could not write the file to disk - ${error.message}`);
|
core.warning(`⚠️ Could not write the file to disk - ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
Generated
+7
-7
@@ -31,7 +31,7 @@
|
|||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"prettier": "2.3.2",
|
"prettier": "2.3.2",
|
||||||
"ts-jest": "^27.0.5",
|
"ts-jest": "^27.0.5",
|
||||||
"typescript": "^4.3.5"
|
"typescript": "^4.4.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/core": {
|
"node_modules/@actions/core": {
|
||||||
@@ -6616,9 +6616,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "4.3.5",
|
"version": "4.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.2.tgz",
|
||||||
"integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
|
"integrity": "sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
@@ -12049,9 +12049,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"typescript": {
|
"typescript": {
|
||||||
"version": "4.3.5",
|
"version": "4.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.2.tgz",
|
||||||
"integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
|
"integrity": "sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"unbox-primitive": {
|
"unbox-primitive": {
|
||||||
|
|||||||
+1
-1
@@ -54,6 +54,6 @@
|
|||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"prettier": "2.3.2",
|
"prettier": "2.3.2",
|
||||||
"ts-jest": "^27.0.5",
|
"ts-jest": "^27.0.5",
|
||||||
"typescript": "^4.3.5"
|
"typescript": "^4.4.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,19 +16,20 @@ export interface Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Category {
|
export interface Category {
|
||||||
title: string
|
title: string // the title of this category
|
||||||
labels: string[]
|
labels: string[] // labels to associate PRs to this category
|
||||||
|
exhaustive?: boolean // requires all labels to be present in the PR
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Transformer {
|
export interface Transformer {
|
||||||
pattern: string
|
pattern: string // the regex pattern to match
|
||||||
target?: string
|
target?: string // the target string to transform the source string using the regex to
|
||||||
flags?: string // the regex flag to use for RegExp
|
flags?: string // the regex flag to use for RegExp
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Extractor extends Transformer {
|
export interface Extractor extends Transformer {
|
||||||
on_property?: 'title' | 'author' | 'milestone' | 'body' | undefined // retrieve the property to extract the value from
|
on_property?: 'title' | 'author' | 'milestone' | 'body' | undefined // retrieve the property to extract the value from
|
||||||
method?: 'replace' | 'match' | undefined // the method to use to extract the value
|
method?: 'replace' | 'match' | undefined // the method to use to extract the value, `match` will not use the `target` property
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TagResolver {
|
export interface TagResolver {
|
||||||
|
|||||||
+1
-1
@@ -56,7 +56,7 @@ async function run(): Promise<void> {
|
|||||||
core.debug(`Enabled writing the changelog to disk`)
|
core.debug(`Enabled writing the changelog to disk`)
|
||||||
writeOutput(repositoryPath, outputFile, result)
|
writeOutput(repositoryPath, outputFile, result)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error: any /* eslint-disable-line @typescript-eslint/no-explicit-any */) {
|
||||||
core.setFailed(error.message)
|
core.setFailed(error.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -40,7 +40,7 @@ export class PullRequests {
|
|||||||
})
|
})
|
||||||
|
|
||||||
return mapPullRequest(data)
|
return mapPullRequest(data)
|
||||||
} catch (e) {
|
} catch (e: any /* eslint-disable-line @typescript-eslint/no-explicit-any */) {
|
||||||
core.warning(
|
core.warning(
|
||||||
`⚠️ Cannot find PR ${owner}/${repo}#${prNumber} - ${e.message}`
|
`⚠️ Cannot find PR ${owner}/${repo}#${prNumber} - ${e.message}`
|
||||||
)
|
)
|
||||||
|
|||||||
+24
-8
@@ -103,14 +103,26 @@ export function buildChangelog(
|
|||||||
|
|
||||||
let matched = false
|
let matched = false
|
||||||
for (const [category, pullRequests] of categorized) {
|
for (const [category, pullRequests] of categorized) {
|
||||||
if (
|
if (category.exhaustive === true) {
|
||||||
haveCommonElements(
|
if (
|
||||||
category.labels.map(lbl => lbl.toLocaleLowerCase()),
|
haveEveryElements(
|
||||||
pr.labels
|
category.labels.map(lbl => lbl.toLocaleLowerCase()),
|
||||||
)
|
pr.labels
|
||||||
) {
|
)
|
||||||
pullRequests.push(body)
|
) {
|
||||||
matched = true
|
pullRequests.push(body)
|
||||||
|
matched = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (
|
||||||
|
haveCommonElements(
|
||||||
|
category.labels.map(lbl => lbl.toLocaleLowerCase()),
|
||||||
|
pr.labels
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
pullRequests.push(body)
|
||||||
|
matched = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,6 +225,10 @@ function haveCommonElements(arr1: string[], arr2: Set<string>): Boolean {
|
|||||||
return arr1.some(item => arr2.has(item))
|
return arr1.some(item => arr2.has(item))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function haveEveryElements(arr1: string[], arr2: Set<string>): Boolean {
|
||||||
|
return arr1.every(item => arr2.has(item))
|
||||||
|
}
|
||||||
|
|
||||||
function fillTemplate(pr: PullRequestInfo, template: string): string {
|
function fillTemplate(pr: PullRequestInfo, template: string): string {
|
||||||
let transformed = template
|
let transformed = template
|
||||||
transformed = transformed.replace(/\${{NUMBER}}/g, pr.number.toString())
|
transformed = transformed.replace(/\${{NUMBER}}/g, pr.number.toString())
|
||||||
|
|||||||
+2
-2
@@ -96,7 +96,7 @@ export function directoryExistsSync(
|
|||||||
let stats: fs.Stats
|
let stats: fs.Stats
|
||||||
try {
|
try {
|
||||||
stats = fs.statSync(inputPath)
|
stats = fs.statSync(inputPath)
|
||||||
} catch (error) {
|
} catch (error: any /* eslint-disable-line @typescript-eslint/no-explicit-any */) {
|
||||||
if (error.code === 'ENOENT') {
|
if (error.code === 'ENOENT') {
|
||||||
if (!required) {
|
if (!required) {
|
||||||
return false
|
return false
|
||||||
@@ -132,7 +132,7 @@ export function writeOutput(
|
|||||||
core.debug(`outputPath = '${outputPath}'`)
|
core.debug(`outputPath = '${outputPath}'`)
|
||||||
try {
|
try {
|
||||||
fs.writeFileSync(outputPath, changelog)
|
fs.writeFileSync(outputPath, changelog)
|
||||||
} catch (error) {
|
} catch (error: any /* eslint-disable-line @typescript-eslint/no-explicit-any */) {
|
||||||
core.warning(`⚠️ Could not write the file to disk - ${error.message}`)
|
core.warning(`⚠️ Could not write the file to disk - ${error.message}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user