Skip to content

Commit 8638e2f

Browse files
authored
feat(jiraIssue): add initial implementation (#1)
`jiraIssue()` is a Danger plugin that adds a JIRA issue link to the Danger pull request comment. If a pull request title does not contain the supplied JIRA issue identifier (e.g. ABC-123), then Danger will comment with a warning on the pull request asking the developer to include the JIRA issue identifier in the pull request title. Example usage: ```js // dangerfile.js import jiraIssue from 'danger-plugin-jira-issue' jiraIssue({ key: 'JIRA', url: 'https://myjira.atlassian.net/browse', emoji: ':paperclip:', }) ``` BREAKING CHANGE: this commit introduces functionality ready for a 1.0.0 release.
1 parent d136089 commit 8638e2f

File tree

14 files changed

+527
-32
lines changed

14 files changed

+527
-32
lines changed

.esdoc.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"source": "./src",
3+
"destination": "./docs"
4+
}

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,6 @@ typings/
6464

6565
# Distributed source
6666
dist/
67+
68+
# Generated documentation
69+
docs/

.npmignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.babelrc
2+
.editorconfig
3+
.esdoc.json
4+
.travis.yml
5+
yarn.lock
6+
node_modules/
7+
src/

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ notifications:
77
node_js:
88
- '7'
99
- '6'
10-
- '4'
1110
before_script:
1211
- npm prune
1312
after_success:

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,21 @@ Install:
1414
yarn add danger-plugin-jira-issue --dev
1515
```
1616

17-
Import and invoke the `jiraIssue()` function in your `dangerfile.js` or `dangerfile.ts`:
17+
At a glance:
1818

1919
```js
20+
// dangerfile.js
2021
import jiraIssue from 'danger-plugin-jira-issue'
2122

2223
jiraIssue({
23-
// TODO options
24+
key: 'JIRA',
25+
url: 'https://myjira.atlassian.net/browse',
26+
emoji: ':paperclip:',
2427
})
2528
```
2629

30+
See the [documentation](https://doc.esdoc.org/github.com/macklinu/danger-plugin-jira-issue/) for detailed information .
31+
2732
## Development
2833

2934
Install [Yarn](https://yarnpkg.com/en/), and install the dependencies - `yarn install`.

package.json

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33
"version": "0.0.0-development",
44
"description": "Danger plugin to link JIRA issue in pull request",
55
"main": "dist/index.js",
6+
"types": "types/index.d.ts",
67
"scripts": {
78
"precommit": "lint-staged",
89
"commit": "git-cz",
910
"commitmsg": "validate-commit-msg",
10-
"build": "babel src --out-dir dist --ignore __tests__,__mocks__",
11+
"build": "babel src --out-dir dist --ignore *.test.js",
1112
"test": "jest",
13+
"predocs": "rm -rf docs/",
14+
"docs": "esdoc -c .esdoc.json",
1215
"prepublish": "npm run build",
1316
"semantic-release": "semantic-release pre && npm publish && semantic-release post"
1417
},
@@ -27,17 +30,23 @@
2730
"url": "https://github.com/macklinu/danger-plugin-jira-issue/issues"
2831
},
2932
"homepage": "https://github.com/macklinu/danger-plugin-jira-issue#readme",
33+
"engines": {
34+
"node": ">= 6.0.0"
35+
},
3036
"devDependencies": {
3137
"babel-cli": "^6.24.1",
3238
"babel-jest": "^20.0.1",
3339
"babel-preset-es2015": "^6.24.1",
3440
"commitizen": "^2.9.6",
3541
"cz-conventional-changelog": "^2.0.0",
42+
"esdoc": "^0.5.2",
3643
"husky": "^0.13.3",
3744
"jest": "^20.0.1",
3845
"lint-staged": "^3.4.1",
3946
"prettier": "^1.3.1",
4047
"semantic-release": "^6.3.6",
48+
"typescript": "^2.3.2",
49+
"typings-tester": "^0.2.2",
4150
"validate-commit-msg": "^2.12.1"
4251
},
4352
"config": {
@@ -47,7 +56,7 @@
4756
},
4857
"lint-staged": {
4958
"*.js": [
50-
"prettier --single-quote --trailing-comma=all --no-semi",
59+
"prettier --single-quote --trailing-comma=all --no-semi --write",
5160
"git add"
5261
]
5362
}

src/__tests__/index.test.js

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/index.js

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,30 @@
1-
export default function jiraIssue() {}
1+
import { join } from 'path'
2+
3+
const link = (href, text) => `<a href="${href}">${text}</a>`
4+
5+
/**
6+
* A Danger plugin to add a JIRA issue link to the Danger pull request comment.
7+
* If a pull request title does not contain the supplied JIRA issue identifier (e.g. ABC-123),
8+
* then Danger will comment with a warning on the pull request asking the developer
9+
* to include the JIRA issue identifier in the pull request title.
10+
*
11+
* @param {Object} options - The JIRA options object.
12+
* @param {string} options.key - The JIRA issue key (e.g. the ABC in ABC-123).
13+
* @param {string} options.url - The JIRA instance issue base URL (e.g. https://jira.atlassian.com/browse/).
14+
* @param {string} [options.emoji=':link:'] - The emoji to display with the JIRA issue link.
15+
* See the possible emoji values, listed as keys in the [GitHub API `/emojis` response](https://api.github.com/emojis).
16+
*/
17+
export default function jiraIssue({ key, url, emoji = ':link:' } = {}) {
18+
if (!url) throw Error(`'url' missing - must supply JIRA installation URL`)
19+
if (!key) throw Error(`'key' missing - must supply JIRA issue key`)
20+
21+
const jiraKeyRegex = new RegExp(`^.*(${key}-[0-9]+).*$`, 'g')
22+
const match = jiraKeyRegex.exec(danger.github.pr.title)
23+
if (match) {
24+
const jiraIssue = match[1]
25+
const jiraUrl = link(join(url, jiraIssue), jiraIssue)
26+
message(`${emoji} ${jiraUrl}`)
27+
} else {
28+
warn(`Please add the JIRA issue key to the PR title (e.g. ${key}-123)`)
29+
}
30+
}

src/index.test.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import jiraIssue from '../'
2+
3+
describe('jiraIssue()', () => {
4+
beforeEach(() => {
5+
global.warn = jest.fn()
6+
global.message = jest.fn()
7+
})
8+
afterEach(() => {
9+
global.danger = undefined
10+
global.warn = undefined
11+
global.message = undefined
12+
})
13+
it('throws when supplied invalid configuration', () => {
14+
expect(() => jiraIssue()).toThrow()
15+
expect(() => jiraIssue({})).toThrow()
16+
expect(() => jiraIssue({ key: 'ABC' })).toThrow()
17+
expect(() => jiraIssue({ url: 'http://my.jira/browse' })).toThrow()
18+
})
19+
it('warns when PR title is missing JIRA issue key', () => {
20+
global.danger = { github: { pr: { title: 'Change some things' } } }
21+
jiraIssue({
22+
key: 'ABC',
23+
url: 'http://my.jira/browse',
24+
})
25+
expect(global.warn).toHaveBeenCalledWith(
26+
'Please add the JIRA issue key to the PR title (e.g. ABC-123)',
27+
)
28+
})
29+
it('adds the JIRA issue link to the messages table', () => {
30+
global.danger = {
31+
github: { pr: { title: '[ABC-808] Change some things' } },
32+
}
33+
jiraIssue({
34+
key: 'ABC',
35+
url: 'http://my.jira/browse',
36+
})
37+
expect(global.message).toHaveBeenCalledWith(
38+
':link: <a href="http:/my.jira/browse/ABC-808">ABC-808</a>',
39+
)
40+
})
41+
it('properly concatenates URL parts (trailing slash in url)', () => {
42+
global.danger = {
43+
github: { pr: { title: '[ABC-808] Change some things' } },
44+
}
45+
jiraIssue({
46+
key: 'ABC',
47+
url: 'http://my.jira/browse/',
48+
})
49+
expect(global.message).toHaveBeenCalledWith(
50+
':link: <a href="http:/my.jira/browse/ABC-808">ABC-808</a>',
51+
)
52+
})
53+
it('matches JIRA issue anywhere in title', () => {
54+
global.danger = { github: { pr: { title: 'My changes - ABC-123' } } }
55+
jiraIssue({
56+
key: 'ABC',
57+
url: 'http://my.jira/browse',
58+
})
59+
expect(global.message).toHaveBeenCalledWith(
60+
':link: <a href="http:/my.jira/browse/ABC-123">ABC-123</a>',
61+
)
62+
})
63+
it('does not match lowercase JIRA key in PR title', () => {
64+
global.danger = {
65+
github: { pr: { title: '[abc-808] Change some things' } },
66+
}
67+
jiraIssue({
68+
key: 'ABC',
69+
url: 'http://my.jira/browse',
70+
})
71+
expect(global.warn).toHaveBeenCalled()
72+
})
73+
it('honors custom emoji configuration', () => {
74+
global.danger = { github: { pr: { title: '(ABC-123) Change stuff' } } }
75+
jiraIssue({
76+
key: 'ABC',
77+
url: 'http://my.jira/browse',
78+
emoji: ':paperclip:',
79+
})
80+
expect(global.message).toHaveBeenCalledWith(
81+
':paperclip: <a href="http:/my.jira/browse/ABC-123">ABC-123</a>',
82+
)
83+
})
84+
})

types/index.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
interface Options {
2+
key: string
3+
url: string
4+
emoji?: string
5+
}
6+
7+
export default function jiraIssue(options: Options): void

0 commit comments

Comments
 (0)