From 8d8e5d4fdad7e9c4c6e34fafe5d2caed2cdb7739 Mon Sep 17 00:00:00 2001 From: Thomas Robert de Saint Vincent Date: Tue, 6 Dec 2022 16:35:14 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20allow=20custom=20regex=20for=20issu?= =?UTF-8?q?es=20+=20remove=20issues=20from=20commit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 +++- lib/assets/default-config.js | 2 + lib/helper/parse-commits.js | 25 ++++++---- lib/helper/resolve-issue-ref.js | 6 ++- .../fixtures/contexts/context-custom.json | 47 +++++++++++++++++++ .../fixtures/notes/notes-custom.md | 10 ++++ test/integration/generate-notes.test.js | 19 ++++++++ 7 files changed, 105 insertions(+), 13 deletions(-) create mode 100644 test/integration/fixtures/contexts/context-custom.json create mode 100644 test/integration/fixtures/notes/notes-custom.md diff --git a/README.md b/README.md index b402345..f1acd1c 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,9 @@ module.exports = { issueResolution: { template: '{baseUrl}/{owner}/{repo}/issues/{ref}', baseUrl: 'https://github.com', - source: 'github.com' + source: 'github.com', + removeFromCommit: false, + regex: /#\d+/g } } } @@ -152,11 +154,12 @@ Besides, You are allowed to provide helpers with the same names to override defa `issueResolution` defines how issues are resolved to. The default and the only supported source currently is `github.com`, or you can provide your own `issueResolution.template` to override the default resolution to GitHub. -There are four variables that can be used in `issueResolution.template`: +There are five variables that can be used in `issueResolution.template`: - `baseUrl` - `owner` - `repo` - `ref`, which is the numeric ID of issue +- `issue`, which is the full issue ```ts interface ReleaseNotesOptions { @@ -167,6 +170,8 @@ interface ReleaseNotesOptions { template?: string baseUrl?: string source?: 'github.com' | null // currently only GitHub is supported, PR welcome :) + regex?: RegExp, // regex to match the issue(s). If not provided, will find issues thanks to [issue-regex](https://www.npmjs.com/package/issue-regex) + removeFromCommit?: boolean // if true, will remove found issue(s) from commit name } } ``` diff --git a/lib/assets/default-config.js b/lib/assets/default-config.js index 75d9052..b6c59b2 100644 --- a/lib/assets/default-config.js +++ b/lib/assets/default-config.js @@ -32,6 +32,8 @@ module.exports = { // template // baseUrl // source + // removeFromCommit + // regex } } } diff --git a/lib/helper/parse-commits.js b/lib/helper/parse-commits.js index 0b25271..3564237 100644 --- a/lib/helper/parse-commits.js +++ b/lib/helper/parse-commits.js @@ -8,7 +8,7 @@ function parseIssuesAndTasks ({ message = '' } = {}, options) { const matched = message.match(/(?:^|\s)wip(#\w[\w-_]*)(?:$|\s)/) // e.g. replace wip#1 to #1 - const issues = (message.replace(/wip(#\d+)/g, '$1').match(issueRegex()) || []) + const issues = (message.replace(/wip(#\d+)/g, '$1').match(options.regex ?? issueRegex()) || []) .map((issue) => ({ text: issue, link: resolveIssueRef(issue, options) @@ -24,8 +24,12 @@ function parseIssuesAndTasks ({ message = '' } = {}, options) { } } -function parseGitmoji ({ subject = '', message = '', body = '' } = {}) { +function parseGitmoji ({ subject = '', message = '', body = '' } = {}, issues = []) { subject = emojify(subject.trim()) + if (issues.length > 0) { + subject = issues.reduce((acc, curr) => acc.replace(curr.text, ''), subject).trim() + } + const matched = emojiRegex().exec(subject) if (!matched || matched.index !== 0) return null @@ -38,13 +42,16 @@ function parseGitmoji ({ subject = '', message = '', body = '' } = {}) { module.exports = function parseCommits (commits = [], mixins = {}, options = {}) { const taskMap = new Map() return commits - .map(c => ({ - ...c, - ...mixins, - ...parseGitmoji(c), - ...parseIssuesAndTasks(c, options.issues), - wip: [] - })) + .map(c => { + const issues = parseIssuesAndTasks(c, options.issues) + return { + ...c, + ...mixins, + ...parseGitmoji(c, options?.issues?.removeFromCommit ? issues.issues : []), + ...issues, + wip: [] + } + }) .reduce((acc, commit) => { if (commit.gitmoji) { if (!Array.isArray(acc[commit.gitmoji])) acc[commit.gitmoji] = [] diff --git a/lib/helper/resolve-issue-ref.js b/lib/helper/resolve-issue-ref.js index 97cb594..ff1b4ad 100644 --- a/lib/helper/resolve-issue-ref.js +++ b/lib/helper/resolve-issue-ref.js @@ -12,16 +12,18 @@ module.exports = function (shorthand = '', { repo, baseUrl, template, + regex, source = 'github.com' } = {}) { - const matched = shorthand.match(/(?:(\w[\w-.]+)\/(\w[\w-.]+)|\B)#([1-9]\d*)\b/) + const matched = shorthand.match(regex ?? /(?:(\w[\w-.]+)\/(\w[\w-.]+)|\B)#([1-9]\d*)\b/) if (matched) { - const [, matchedOwner, matchedRepo, issueRef] = matched + const [issue, matchedOwner, matchedRepo, issueRef] = matched return (template || getIssueUrlTemplate(source)) .replace('{baseUrl}', baseUrl || '') .replace('{owner}', matchedOwner || owner || '') .replace('{repo}', matchedRepo || repo || '') .replace('{ref}', issueRef || '') + .replace('{issue}', issue) } return shorthand } diff --git a/test/integration/fixtures/contexts/context-custom.json b/test/integration/fixtures/contexts/context-custom.json new file mode 100644 index 0000000..a644e58 --- /dev/null +++ b/test/integration/fixtures/contexts/context-custom.json @@ -0,0 +1,47 @@ +{ + "options": { + "repositoryUrl": "git+https://github.com/momocow/semantic-release-gitmoji.git" + }, + "lastRelease": { + "version": "0.0.0", + "gitHead": "gitHead", + "gitTag": "v0.0.0" + }, + "nextRelease": { + "gitHead": "gitHead" + }, + "commits": [ + { + "commit": { + "short": "123456" + }, + "message": "CUSTOM-4242 :sparkles: (scope1): use custom ticket regex", + "subject": "CUSTOM-4242 :sparkles: (scope1): use custom ticket regex", + "body": "" + }, + { + "commit": { + "short": "654321" + }, + "message": ":sparkles: (scope2): no ticket", + "subject": ":sparkles: (scope2): no ticket", + "body": "" + }, + { + "commit": { + "short": "654456" + }, + "message": ":bug: (scope3): with github issue #42", + "subject": ":bug: (scope3): with github issue #42", + "body": "" + }, + { + "commit": { + "short": "123321" + }, + "message": "CUSTOM-4242 CUSTOM-4243 :sparkles: (scope4): multiple issues", + "subject": "CUSTOM-4242 CUSTOM-4243 :sparkles: (scope4): multiple issues", + "body": "" + } + ] +} diff --git a/test/integration/fixtures/notes/notes-custom.md b/test/integration/fixtures/notes/notes-custom.md new file mode 100644 index 0000000..11ce0b3 --- /dev/null +++ b/test/integration/fixtures/notes/notes-custom.md @@ -0,0 +1,10 @@ +# [v0.1.0](https://github.com/momocow/semantic-release-gitmoji/compare/v0.0.0...v0.1.0) (2022-12-06) + +## ✨ New Features +- [`123321`](https://github.com/momocow/semantic-release-gitmoji/commit/123321) (scope4): multiple issues (Issues: [`CUSTOM-4242`](https://custom-url/CUSTOM-4242) [`CUSTOM-4243`](https://custom-url/CUSTOM-4243)) +- [`654321`](https://github.com/momocow/semantic-release-gitmoji/commit/654321) (scope2): no ticket +- [`123456`](https://github.com/momocow/semantic-release-gitmoji/commit/123456) (scope1): use custom ticket regex (Issues: [`CUSTOM-4242`](https://custom-url/CUSTOM-4242)) + +## 🐛 Bug Fixes +- [`654456`](https://github.com/momocow/semantic-release-gitmoji/commit/654456) (scope3): with github issue #42 + diff --git a/test/integration/generate-notes.test.js b/test/integration/generate-notes.test.js index 2923aef..227f128 100644 --- a/test/integration/generate-notes.test.js +++ b/test/integration/generate-notes.test.js @@ -94,6 +94,25 @@ const CASES = [ } }), expectedNotes: readNotesSync('custom-helper') + }, + { + name: 'default config + custom issueResolution', + pluginConfig: { + releaseNotes: { + issueResolution: { + removeFromCommit: true, + regex: /CUSTOM-\d{4}/g, + template: 'https://custom-url/{issue}' + } + } + }, + context: getContext('custom', { + nextRelease: { + version: '0.1.0', + gitTag: 'v0.1.0' + } + }), + expectedNotes: readNotesSync('custom') } ]