Skip to content

Commit

Permalink
feat: Allow configuration for custom types (#53)
Browse files Browse the repository at this point in the history
* Access input types.

* Move logging

* Try throw.

* Try target

* Back to self.

* Run in test

* Back to first workflow

* … and test.

* Prod

* Plain string

* Support custom types.

* Clean up

* More cleanup

* Print description for default types.
  • Loading branch information
amannn committed Oct 21, 2020
1 parent bbeb269 commit 2fe39e2
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/lint-pr-title.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: 'Lint PR title'
on:
pull_request_target:
pull_request:
types:
- opened
- edited
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ jobs:
- uses: amannn/action-semantic-pull-request@v1.2.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Optionally you can configure which types are allowed.
# Default: https://github.com/commitizen/conventional-commit-types
with:
types: fix, feat
```

Note the usage of [`pull_request_target`](https://github.blog/2020-08-03-github-actions-improvements-for-fork-and-pull-request-workflows/) as the event trigger is necessary for a fork-based workflow so the API token is valid for status reporting.
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ runs:
branding:
icon: 'shield'
color: 'green'
inputs:
types:
description: "Provide custom types if you don't want the default ones from https://www.conventionalcommits.org"
7 changes: 6 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ module.exports = async function run() {
try {
const client = new github.GitHub(process.env.GITHUB_TOKEN);

let types;
if (process.env.INPUT_TYPES) {
types = process.env.INPUT_TYPES.split(',').map((type) => type.trim());
}

const contextPullRequest = github.context.payload.pull_request;
if (!contextPullRequest) {
throw new Error(
Expand All @@ -32,7 +37,7 @@ module.exports = async function run() {
let validationError;
if (!isWip) {
try {
await validatePrTitle(pullRequest.title);
await validatePrTitle(pullRequest.title, types);
} catch (error) {
validationError = error;
}
Expand Down
31 changes: 22 additions & 9 deletions src/validatePrTitle.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,37 @@ const conventionalCommitsConfig = require('conventional-changelog-conventionalco
const conventionalCommitTypes = require('conventional-commit-types');
const parser = require('conventional-commits-parser').sync;

module.exports = async function validatePrTitle(prTitle) {
const defaultTypes = Object.keys(conventionalCommitTypes.types);

module.exports = async function validatePrTitle(prTitle, types = defaultTypes) {
const {parserOpts} = await conventionalCommitsConfig();
const result = parser(prTitle, parserOpts);

function printAvailableTypes() {
return `Available types:\n${types
.map((type) => {
let bullet = ` - ${type}`;
if (types === defaultTypes) {
bullet += `: ${conventionalCommitTypes.types[type].description}`;
}
return bullet;
})
.join('\n')}`;
}

if (!result.type) {
throw new Error(
`No release type found in pull request title "${prTitle}".` +
'\n\nAdd a prefix like "fix: ", "feat: " or "feat!: " to indicate what kind of release this pull request corresponds to. The title should match the commit mesage format as specified by https://www.conventionalcommits.org/.'
`No release type found in pull request title "${prTitle}". Add a prefix to indicate what kind of release this pull request corresponds to (see https://www.conventionalcommits.org/).\n\n${printAvailableTypes()}`
);
}

const allowedTypes = Object.keys(conventionalCommitTypes.types);
if (!allowedTypes.includes(result.type)) {
if (!types.includes(result.type)) {
throw new Error(
`Unknown release type "${result.type}" found in pull request title "${prTitle}".` +
`\n\nPlease use one of these recognized types: ${allowedTypes.join(
', '
)}.`
`Unknown release type "${
result.type
}" found in pull request title "${prTitle}". \n\n${printAvailableTypes()}`
);
}
};
24 changes: 21 additions & 3 deletions src/validatePrTitle.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const validatePrTitle = require('./validatePrTitle');

it('detects valid PR titles', async () => {
it('allows valid PR titles that use the default types', async () => {
const inputs = [
'fix: Fix bug',
'fix!: Fix bug',
Expand All @@ -10,8 +10,7 @@ it('detects valid PR titles', async () => {
];

for (let index = 0; index < inputs.length; index++) {
const input = inputs[index];
await validatePrTitle(input);
await validatePrTitle(inputs[index]);
}
});

Expand All @@ -26,3 +25,22 @@ it('throws for PR titles with an unknown type', async () => {
/Unknown release type "foo" found in pull request title "foo: Bar"./
);
});

describe('custom types', () => {
it('allows PR titles with a supported type', async () => {
const inputs = ['foo: Foobar', 'bar: Foobar', 'baz: Foobar'];
const types = ['foo', 'bar', 'baz'];

for (let index = 0; index < inputs.length; index++) {
await validatePrTitle(inputs[index], types);
}
});

it('throws for PR titles with an unknown type', async () => {
await expect(
validatePrTitle('fix: Foobar', ['foo', 'bar'])
).rejects.toThrow(
/Unknown release type "fix" found in pull request title "fix: Foobar"./
);
});
});

0 comments on commit 2fe39e2

Please sign in to comment.