-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ae7b77d
commit 1256450
Showing
11 changed files
with
13,592 additions
and
3,905 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
env: | ||
browser: true | ||
es2021: true | ||
node: true | ||
jest: true | ||
extends: airbnb-base | ||
parserOptions: | ||
ecmaVersion: latest | ||
sourceType: module | ||
rules: | ||
camelcase: off | ||
max-len: | ||
- "error" | ||
- code: 150 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
name: yarn lint | ||
on: push | ||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Install modules | ||
run: yarn | ||
- name: Run ESLint | ||
run: yarn install && yarn lint |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
name: yarn test | ||
on: push | ||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Install modules | ||
run: yarn | ||
- name: Run tests | ||
run: yarn install && yarn test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
name: pr-lint-action | ||
description: A GitHub Action that verifies your pull request contains a reference to a ticket. | ||
runs: | ||
using: docker | ||
image: Dockerfile | ||
branding: | ||
icon: activity | ||
color: white |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,111 +1,111 @@ | ||
const { Toolkit } = require('actions-toolkit') | ||
const getConfig = require('./utils/config') | ||
const { Toolkit } = require('actions-toolkit'); | ||
|
||
const CONFIG_FILENAME = 'pr-lint.yml' | ||
const getConfig = require('./utils/config'); | ||
|
||
const CONFIG_FILENAME = 'pr-lint.yml'; | ||
|
||
const defaults = { | ||
projects: ['PROJ'], | ||
check_title: true, | ||
check_branch: false, | ||
check_commits: false, | ||
ignore_case: false | ||
ignore_case: false, | ||
}; | ||
|
||
function createProjectRegex(project, ignoreCase = false) { | ||
if (ignoreCase) { | ||
return new RegExp(`${project}[-_]\\d*`, 'i'); | ||
} | ||
return new RegExp(`${project}[-_]\\d*`); | ||
} | ||
function findFailedCommits(projects, commitsInPR, ignoreCase) { | ||
const failedCommits = []; | ||
commitsInPR.forEach((commit) => { | ||
if (!projects.some((project) => commit.commit.message.match(createProjectRegex(project, ignoreCase)))) { | ||
failedCommits.push(commit.commit.message); | ||
} | ||
}); | ||
return failedCommits; | ||
} | ||
|
||
function createWrappedProjectRegex(project) { | ||
return new RegExp(`\\[${project}-\\d*\\]`); | ||
} | ||
|
||
Toolkit.run( | ||
async tools => { | ||
const { repository, pull_request } = tools.context.payload | ||
async (tools) => { | ||
const { repository, pull_request } = tools.context.payload; | ||
|
||
const repoInfo = { | ||
owner: repository.owner.login, | ||
repo: repository.name, | ||
ref: pull_request.head.ref | ||
} | ||
ref: pull_request.head.ref, | ||
}; | ||
|
||
const config = { | ||
...defaults, | ||
...(await getConfig(tools.github, CONFIG_FILENAME, repoInfo)) | ||
} | ||
...(await getConfig(tools.github, CONFIG_FILENAME, repoInfo)), | ||
}; | ||
|
||
const title = config.ignore_case ? | ||
pull_request.title.toLowerCase() : | ||
pull_request.title | ||
const title = config.ignore_case | ||
? pull_request.title.toLowerCase() | ||
: pull_request.title; | ||
|
||
const head_branch = config.ignore_case ? | ||
pull_request.head.ref.toLowerCase() : | ||
pull_request.head.ref | ||
const head_branch = config.ignore_case | ||
? pull_request.head.ref.toLowerCase() | ||
: pull_request.head.ref; | ||
|
||
const projects = config.projects.map(project => config.ignore_case ? project.toLowerCase() : project) | ||
const projects = config.projects.map((project) => (config.ignore_case ? project.toLowerCase() : project)); | ||
const title_passed = (() => { | ||
if (config.check_title) { | ||
// check the title matches [PROJECT-1234] somewhere | ||
if (!projects.some(project => title.match(createWrappedProjectRegex(project)))) { | ||
tools.log('PR title ' + title + ' does not contain approved project with format [PROJECT-1234]') | ||
return false | ||
if (!projects.some((project) => title.match(createWrappedProjectRegex(project)))) { | ||
tools.log(`PR title ${title} does not contain approved project with format [PROJECT-1234]`); | ||
return false; | ||
} | ||
} | ||
return true | ||
})() | ||
return true; | ||
})(); | ||
|
||
const branch_passed = (() => { | ||
// check the branch matches PROJECT-1234 or PROJECT_1234 somewhere | ||
if (config.check_branch) { | ||
if (!projects.some(project => head_branch.match(createProjectRegex(project)))) { | ||
tools.log('PR branch ' + head_branch + ' does not contain an approved project with format PROJECT-1234 or PROJECT_1234') | ||
return false | ||
if (!projects.some((project) => head_branch.match(createProjectRegex(project)))) { | ||
tools.log(`PR branch ${head_branch} does not contain an approved project with format PROJECT-1234 or PROJECT_1234`); | ||
return false; | ||
} | ||
} | ||
return true | ||
})() | ||
return true; | ||
})(); | ||
|
||
const commits_passed = await (async () => { | ||
// check the branch matches PROJECT-1234 or PROJECT_1234 somewhere | ||
if (config.check_commits) { | ||
const listCommitsParams = { | ||
owner: repository.owner.login, | ||
repo: repository.name, | ||
pull_number: pull_request.number | ||
} | ||
const commitsInPR = (await tools.github.pulls.listCommits(listCommitsParams)).data | ||
pull_number: pull_request.number, | ||
}; | ||
const commitsInPR = (await tools.github.pulls.listCommits(listCommitsParams)).data; | ||
const failedCommits = findFailedCommits(projects, commitsInPR, config.ignore_case); | ||
|
||
if(failedCommits.length) { | ||
if (failedCommits.length) { | ||
failedCommits.forEach( | ||
failedCommit => tools.log('Commit message \'' + failedCommit + '\' does not contain an approved project') | ||
) | ||
return false | ||
(failedCommit) => tools.log(`Commit message '${failedCommit}' does not contain an approved project`), | ||
); | ||
return false; | ||
} | ||
} | ||
return true | ||
})() | ||
return true; | ||
})(); | ||
|
||
const statuses = [title_passed, branch_passed, commits_passed] | ||
const statuses = [title_passed, branch_passed, commits_passed]; | ||
|
||
if (statuses.some(status => status === false )){ | ||
tools.exit.failure("PR Linting Failed") | ||
if (statuses.some((status) => status === false)) { | ||
tools.exit.failure('PR Linting Failed'); | ||
} else { | ||
tools.exit.success() | ||
tools.exit.success(); | ||
} | ||
}, | ||
{ event: ['pull_request.opened', 'pull_request.edited', 'pull_request.synchronize', 'pull_request.ready_for_review'], secrets: ['GITHUB_TOKEN'] } | ||
) | ||
|
||
function findFailedCommits(projects, commitsInPR, ignoreCase) { | ||
const failedCommits = []; | ||
commitsInPR.forEach(commit => { | ||
if (!projects.some(project => commit.commit.message.match(createProjectRegex(project, ignoreCase)))) { | ||
failedCommits.push(commit.commit.message); | ||
} | ||
}); | ||
return failedCommits; | ||
} | ||
|
||
function createProjectRegex(project, ignoreCase = false) { | ||
if (ignoreCase) { | ||
return new RegExp(project + '[-_]\\d*', 'i') | ||
} | ||
return new RegExp(project + '[-_]\\d*') | ||
} | ||
|
||
function createWrappedProjectRegex(project) { | ||
return new RegExp('\\[' + project + '-\\d*\\]') | ||
} | ||
{ event: ['pull_request.opened', 'pull_request.edited', 'pull_request.synchronize', 'pull_request.ready_for_review'], secrets: ['GITHUB_TOKEN'] }, | ||
); |
Oops, something went wrong.