Skip to content

Commit e83dc8a

Browse files
committed
Add scopes option to filter analysis/changelog
1 parent 86301c8 commit e83dc8a

File tree

8 files changed

+83
-8
lines changed

8 files changed

+83
-8
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ jobs:
4242
- **release_branches** _(optional)_ - Comma separated list of branches (JavaScript regular expression accepted) that will generate the release tags. Other branches and pull-requests generate versions postfixed with the commit hash and do not generate any repository tag. Examples: `master` or `.*` or `release.*,hotfix.*,master`... (default: `master,main`).
4343
- **pre_release_branches** _(optional)_ - Comma separated list of branches (JavaScript regular expression accepted) that will generate the pre-release tags.
4444

45+
#### Filter commits
46+
47+
- **scopes** _(optional)_ - Comma separated list of scopes (JavaScript regular expression accepted) to consider when tagging, and to include in the changelog. If this option is specified, then commits with scopes not matching this list will not be analyzed nor included in the changelog.
48+
4549
#### Customize the tag
4650

4751
- **default_bump** _(optional)_ - Which type of bump to use when [none is explicitly provided](#bumping) when commiting to a release branch (default: `patch`). You can also set `false` to avoid generating a new tag when none is explicitly provided. Can be `patch, minor or major`.

action.yml

+3
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ inputs:
4444
pre_release_branches:
4545
description: "Comma separated list of branches (bash reg exp accepted) that will generate pre-release tags."
4646
required: false
47+
scopes:
48+
description: "Comma separated list of scopes (bash reg exp accepted) to analyze and to include in the changelog."
49+
required: false
4750
commit_sha:
4851
description: "The commit SHA value to add the tag. If specified, it uses this value instead GITHUB_SHA. It could be useful when a previous step merged a branch into github.ref."
4952
required: false

package-lock.json

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"@semantic-release/commit-analyzer": "^8.0.1",
2828
"@semantic-release/release-notes-generator": "^9.0.1",
2929
"conventional-changelog-conventionalcommits": "^4.6.1",
30+
"conventional-commits-parser": "^3.2.0",
3031
"semver": "^7.3.5"
3132
},
3233
"devDependencies": {

src/action.ts

+18
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as core from '@actions/core';
2+
import { sync as parser } from 'conventional-commits-parser';
23
import { gte, inc, parse, ReleaseType, SemVer, valid } from 'semver';
34
import { analyzeCommits } from '@semantic-release/commit-analyzer';
45
import { generateNotes } from '@semantic-release/release-notes-generator';
@@ -24,6 +25,7 @@ export default async function main() {
2425
const customTag = core.getInput('custom_tag');
2526
const releaseBranches = core.getInput('release_branches');
2627
const preReleaseBranches = core.getInput('pre_release_branches');
28+
const scopes = core.getInput('scopes');
2729
const appendToPreReleaseTag = core.getInput('append_to_pre_release_tag');
2830
const createAnnotatedTag = /true/i.test(
2931
core.getInput('create_annotated_tag')
@@ -123,6 +125,22 @@ export default async function main() {
123125

124126
commits = await getCommits(previousTag.commit.sha, commitRef);
125127

128+
if (scopes.length) {
129+
const isInScope = (scope: string) =>
130+
scopes.split(',').some((includedScope) => scope.match(includedScope));
131+
commits = commits.filter((commit) => {
132+
const scope = parser(commit.message).scope;
133+
if (scope) {
134+
const isInScopes = scopes
135+
.split(',')
136+
.some((includedScope) => scope.match(includedScope));
137+
return isInScopes;
138+
} else {
139+
return false;
140+
}
141+
});
142+
}
143+
126144
let bump = await analyzeCommits(
127145
{
128146
releaseRules: mappedReleaseRules

tests/action.test.ts

+42
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,48 @@ describe('github-tag-action', () => {
215215
);
216216
expect(mockSetFailed).not.toBeCalled();
217217
});
218+
219+
it('does skip commits not included in scopes', async () => {
220+
/*
221+
* Given
222+
*/
223+
setInput('scopes', 'yes');
224+
const commits = [
225+
{ message: 'fix(YES): 1ne', hash: null },
226+
{ message: 'feat(NO): 2wo', hash: null },
227+
];
228+
jest
229+
.spyOn(utils, 'getCommits')
230+
.mockImplementation(async (sha) => commits);
231+
232+
const validTags = [
233+
{
234+
name: 'v1.2.3',
235+
commit: { sha: '012345', url: '' },
236+
zipball_url: '',
237+
tarball_url: 'string',
238+
node_id: 'string',
239+
},
240+
];
241+
jest
242+
.spyOn(utils, 'getValidTags')
243+
.mockImplementation(async () => validTags);
244+
245+
/*
246+
* When
247+
*/
248+
await action();
249+
250+
/*
251+
* Then
252+
*/
253+
expect(mockCreateTag).toHaveBeenCalledWith(
254+
'v1.2.4',
255+
expect.any(Boolean),
256+
expect.any(String)
257+
);
258+
expect(mockSetFailed).not.toBeCalled();
259+
});
218260
});
219261

220262
describe('release branches', () => {

tests/helper.test.ts

+10-8
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@ export function setCommitSha(sha: string) {
1818
process.env['GITHUB_SHA'] = sha;
1919
}
2020

21-
export function setInput(key: string, value: string) {
22-
process.env[`INPUT_${key.toUpperCase()}`] = value;
21+
export function setInput(key: string, value: string | undefined) {
22+
if (value) {
23+
process.env[`INPUT_${key.toUpperCase()}`] = value;
24+
} else {
25+
delete process.env[`INPUT_${key.toUpperCase()}`];
26+
}
2327
}
2428

2529
export function setInputs(map: { [key: string]: string }) {
@@ -34,12 +38,10 @@ export function loadDefaultInputs() {
3438
const actionJson = yaml.load(actionYaml) as {
3539
inputs: { [key: string]: { default?: string } };
3640
};
37-
const defaultInputs = Object.keys(actionJson['inputs'])
38-
.filter((key) => actionJson['inputs'][key].default)
39-
.reduce(
40-
(obj, key) => ({ ...obj, [key]: actionJson['inputs'][key].default }),
41-
{}
42-
);
41+
const defaultInputs = Object.keys(actionJson['inputs']).reduce(
42+
(obj, key) => ({ ...obj, [key]: actionJson['inputs'][key].default }),
43+
{}
44+
);
4345
setInputs(defaultInputs);
4446
}
4547

types/semantic.d.ts

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
/// <reference types="semver" />
22

3+
declare module 'conventional-commits-parser' {
4+
export function sync(message: string): { scope?: string };
5+
}
6+
37
declare module '@semantic-release/commit-analyzer' {
48
export function analyzeCommits(
59
config: {

0 commit comments

Comments
 (0)