-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdangerfile.ts
103 lines (83 loc) · 3.64 KB
/
dangerfile.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
If this is your first time editing/reading a Dangerfile, here's a summary:
It's a JS runtime which helps you provide continuous feedback inside GitHub.
You can see the docs here: http://danger.systems/js
If you want to test changes to Danger locally, I'd recommend checking out an existing PR
and then running the `danger pr` command from the terminal.
For example:
`npx danger pr https://github.com/facebook/react/pull/11865
*/
import { danger, markdown, message, warn } from 'danger';
const BIG_PR_LIMIT = 600;
const MAX_ALLOWED_EMPTY_CHECKBOXES = 2;
const MIN_TICKED_CHECKBOXES_FOR_PRAISE = 6;
const DESCRIPTION_TITLE_LENGTH = '# Description'.length;
const LINES_TO_EXCLUDE_FROM_COUNT_GLOB = '{**/schemaTypes.ts,fixtures/**,package*.json,**/*.spec.ts,**/*.md}';
let errorNumber = 0;
function warnAndGenerateMarkdown(warning: string, markdownStr: string): void {
errorNumber += 1;
warn(`${warning} (${errorNumber})`);
markdown(`> (${errorNumber}) : ${markdownStr}`);
}
async function splitBigPR() {
const linesCount = (await danger.git.linesOfCode('**/*')) || 0;
// exclude fixtures and auto generated files
const excludeLinesCount = (await danger.git.linesOfCode(LINES_TO_EXCLUDE_FROM_COUNT_GLOB)) || 0;
const totalLinesCount = linesCount - excludeLinesCount;
if (totalLinesCount > BIG_PR_LIMIT) {
warnAndGenerateMarkdown(
':exclamation: Big PR',
'Pull Request size seems relatively large. If Pull Request contains multiple changes, please split each into separate PRs which will make them easier to review.',
);
}
}
async function updatePackageLock() {
const packageChanged = danger.git.modified_files.includes('package.json');
const packageDiff = await danger.git.JSONDiffForFile('package.json');
let dependenciesChanged: boolean;
// packageDiff contains a property for each object that has changed in package.json
if (packageDiff.dependencies || packageDiff.devDependencies || packageDiff.peerDependencies) {
dependenciesChanged = true;
}
const lockfileChanged = danger.git.modified_files.includes('package-lock.json');
if (packageChanged && dependenciesChanged && !lockfileChanged) {
warnAndGenerateMarkdown(
':exclamation: package-lock.json',
"Changes were made to package.json, but not to package-lock.json - <i>'Perhaps you need to run `npm install`?'</i>",
);
}
}
function positiveFeedback() {
if (danger.github.pr.deletions > danger.github.pr.additions) {
message(':thumbsup: You removed more code than added!');
}
}
function checkCheckboxesAreTicked() {
const prDescriptionChecklist = danger.github.pr.body?.split('## Checklist:')[1];
if (!prDescriptionChecklist) return;
const emptyCheckboxes = prDescriptionChecklist.match(/\[ \]/g)?.length || 0;
const tickedCheckboxes = prDescriptionChecklist.match(/\[x\]/g)?.length || 0;
if (emptyCheckboxes > MAX_ALLOWED_EMPTY_CHECKBOXES) {
warnAndGenerateMarkdown(
':exclamation: checkboxes',
`There are ${emptyCheckboxes} empty checkboxes, have you updated the checklist?`,
);
}
if (tickedCheckboxes >= MIN_TICKED_CHECKBOXES_FOR_PRAISE) {
message(':thumbsup: You ticked most of the checkboxes!');
}
}
function checkDescriptionLength() {
const prDescription = danger.github.pr.body?.split('## Type of change')[0];
const descriptionLength = prDescription.replace(/<!--(.|\r\n)*-->/gm, '').trim().length;
if (descriptionLength <= DESCRIPTION_TITLE_LENGTH) {
warnAndGenerateMarkdown(':exclamation: description', 'Have you added a description?');
}
}
(async function () {
await splitBigPR();
positiveFeedback();
await updatePackageLock();
checkCheckboxesAreTicked();
checkDescriptionLength();
})();