WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit e2a89fc

Browse files
author
Vijay Ramesh
committed
initial commit
0 parents  commit e2a89fc

File tree

13 files changed

+6115
-0
lines changed

13 files changed

+6115
-0
lines changed

.gitignore

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
lerna-debug.log*
8+
9+
# Diagnostic reports (https://nodejs.org/api/report.html)
10+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11+
12+
# Runtime data
13+
pids
14+
*.pid
15+
*.seed
16+
*.pid.lock
17+
18+
# Directory for instrumented libs generated by jscoverage/JSCover
19+
lib-cov
20+
21+
# Coverage directory used by tools like istanbul
22+
coverage
23+
*.lcov
24+
25+
# nyc test coverage
26+
.nyc_output
27+
28+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29+
.grunt
30+
31+
# Bower dependency directory (https://bower.io/)
32+
bower_components
33+
34+
# node-waf configuration
35+
.lock-wscript
36+
37+
# Compiled binary addons (https://nodejs.org/api/addons.html)
38+
build/Release
39+
40+
# Dependency directories
41+
node_modules/
42+
jspm_packages/
43+
44+
# TypeScript v1 declaration files
45+
typings/
46+
47+
# TypeScript cache
48+
*.tsbuildinfo
49+
50+
# Optional npm cache directory
51+
.npm
52+
53+
# Optional eslint cache
54+
.eslintcache
55+
56+
# Optional REPL history
57+
.node_repl_history
58+
59+
# Output of 'npm pack'
60+
*.tgz
61+
62+
# Yarn Integrity file
63+
.yarn-integrity
64+
65+
# dotenv environment variables file
66+
.env
67+
.env.test
68+
69+
# parcel-bundler cache (https://parceljs.org/)
70+
.cache
71+
72+
# next.js build output
73+
.next
74+
75+
# nuxt.js build output
76+
.nuxt
77+
78+
# vuepress build output
79+
.vuepress/dist
80+
81+
# Serverless directories
82+
.serverless/
83+
84+
# FuseBox cache
85+
.fusebox/
86+
87+
# DynamoDB Local files
88+
.dynamodb/
89+

Dockerfile

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
FROM node:slim
2+
3+
# Labels for GitHub to read your action
4+
LABEL "com.github.actions.name"="PR Lint Action"
5+
LABEL "com.github.actions.description"="Lint PRs to ensure they contain a ticket and more!"
6+
LABEL "com.github.actions.icon"="book-open"
7+
LABEL "com.github.actions.color"="blue"
8+
9+
# Copy the package.json and package-lock.json
10+
COPY package*.json ./
11+
12+
# Install dependencies
13+
RUN npm ci
14+
15+
# Copy the rest of your action's code
16+
COPY . .
17+
18+
# Run `node /index.js`
19+
ENTRYPOINT ["node", "/index.js"]

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License
2+
3+
Copyright (c) 2019 Vijay Ramesh
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# pr-lint-action
2+
3+
A GitHub Action that verifies your pull request contains a reference to a ticket. It will optionally check the PR title contains `[PROJ-1234]` and the branch contains PROJ-1234 or PROJ_1234. This helps ensure every PR gets mapped to a ticket in Jira!
4+
5+
## Usage
6+
7+
Add `.github/pr-lint.workflow` with the following:
8+
9+
```
10+
workflow "PR Lint Action" {
11+
on = "pull_request"
12+
resolves = "PR Lint Action"
13+
}
14+
15+
action "PR Lint Action" {
16+
uses = "vijaykramesh/pr-lint-action@master"
17+
secrets = ["GITHUB_TOKEN"]
18+
}
19+
```
20+
21+
## Configuration
22+
23+
Configure by creating a `.github/pr-lint.yml` file:
24+
25+
For example:
26+
27+
```yml
28+
projects: ['PROJ', 'ABC']
29+
check_title: true
30+
check_branch: true
31+
ignore_case: true
32+
```
33+
34+
## Testing
35+
36+
Run `jest test` to test:
37+
38+
```
39+
PASS ./index.test.js
40+
pr-lint-action
41+
✓ fails if check_title is true and title does not match (106ms)
42+
✓ passes if check_title is false and title does not match (67ms)
43+
✓ passes if check_title is true and title matches (61ms)
44+
✓ fails if check_branch is true and branch does not match (57ms)
45+
✓ passes if check_branch is false and branch does not match (59ms)
46+
✓ passes if check_branch is true and branch matches (57ms)
47+
✓ fails if check_branch and check_title is true and title does not match (59ms)
48+
✓ fails if check_branch and check_title is true and title does not match (59ms)
49+
✓ passes if check_branch and check_title is true and both match (58ms)
50+
✓ passes if ignore_case and lower case title/branch (55ms)
51+
✓ fails if not ignore_case and lower case title/branch (109ms)
52+
```

fixtures/all.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
projects: ['PROJ']
2+
check_title: true
3+
check_branch: true
4+
ignore_case: true

fixtures/branch.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
projects: ['PROJ']
2+
check_title: false
3+
check_branch: true
4+
ignore_case: true

fixtures/no-ignore-case.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
projects: ['PROJ']
2+
check_title: true
3+
check_branch: true
4+
ignore_case: false

fixtures/title.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
projects: ['PROJ']
2+
check_title: true
3+
check_branch: false
4+
ignore_case: true

index.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
const { Toolkit } = require('actions-toolkit')
2+
const getConfig = require('./utils/config')
3+
4+
const CONFIG_FILENAME = 'pr-lint.yml'
5+
6+
const defaults = {
7+
projects: ['PROJ'],
8+
check_title: true,
9+
check_branch: false,
10+
ignore_case: false
11+
}
12+
13+
Toolkit.run(
14+
async tools => {
15+
const repoInfo = {
16+
owner: tools.context.payload.repository.owner.login,
17+
repo: tools.context.payload.repository.name
18+
}
19+
const config = {
20+
...defaults,
21+
...(await getConfig(tools.github, CONFIG_FILENAME, repoInfo))
22+
}
23+
24+
const title = config.ignore_case ?
25+
tools.context.payload.pull_request.title.toLowerCase() :
26+
tools.context.payload.pull_request.title
27+
28+
const head_branch = config.ignore_case ?
29+
tools.context.payload.pull_request.head_ref_name.toLowerCase() :
30+
tools.context.payload.pull_request.head_ref_name
31+
32+
const projects = config.projects.map(project => config.ignore_case ? project.toLowerCase() : project)
33+
const title_passed = (() => {
34+
if (config.check_title) {
35+
// check the title matches [PROJECT-1234] somewhere
36+
if (!projects.some(project => title.match(new RegExp('\\[' + project + '-\\d*\\]')))) {
37+
tools.log('PR title does not contain approved project')
38+
return false
39+
}
40+
}
41+
return true
42+
})()
43+
44+
const branch_passed = (() => {
45+
// check the branch matches PROJECT-1234 or PROJECT_1234 somewhere
46+
if (config.check_branch) {
47+
if (!projects.some(project => head_branch.match(new RegExp(project + '[-_]\\d*')))) {
48+
tools.log('PR branch does not contain an approved project')
49+
return false
50+
}
51+
}
52+
return true
53+
})()
54+
55+
const statuses = [title_passed, branch_passed]
56+
57+
if (statuses.some(status => status === false )){
58+
tools.exit.failure("PR Linting Failed")
59+
} else {
60+
tools.exit.success()
61+
}
62+
},
63+
{ event: ['pull_request.opened', 'pull_request.edited', 'pull_request.synchronize'], secrets: ['GITHUB_TOKEN'] }
64+
)

0 commit comments

Comments
 (0)