Skip to content

Commit e8ed648

Browse files
Release 2.1.1 - Fix PR updates
Update PR checks in case any new commits are added in an existing PR
1 parent 2546865 commit e8ed648

File tree

4 files changed

+102
-43
lines changed

4 files changed

+102
-43
lines changed

README.md

+16
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
# Commit Message Lint
23
Github app to validate commit message and pull request title on a pull request
34

@@ -25,6 +26,21 @@ COMMIT_MESSAGE_REGEX: <Commit Message Regex>
2526
## Usage
2627
Go to the `checks` section on your PR to see the result of the check run performed by the app. It will show you the result as well as the commit messages which failed.
2728

29+
## Local setup
30+
Step 1. Clone the application.
31+
Step 2. Run `npm install`
32+
Step 3. Create `.env` file in the root directory and set the following environment variables in `.env` file :
33+
```
34+
APP_ID - Github app id (get from app settings page)
35+
WEBHOOK_PROXY_URL - URL of the hosted application, use ngrok for local
36+
WEBHOOK_SECRET - webhook secret for security, same as the one set in github app settings
37+
PRIVATE_KEY - Get from github app settings page
38+
LOG_LEVEL - Log level
39+
REGEX_CONFIG_FILE_NAME - config file which contains repo config, keep it as config.yml
40+
GITHUB_BASE_PATH - Github API path, keep it as https://api.github.com
41+
```
42+
Step 4. Run `npm start` to start the application
43+
2844
## Contributors
2945
[Anshul Soni](https://www.linkedin.com/in/anshul-soni-3903a2101/)
3046

constants.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ module.exports = {
3838
events: {
3939
PULL_REQUEST_OPEN: 'pull_request.opened',
4040
CHECK_RUN_REREQUESTED: 'check_run.rerequested',
41-
CHECK_SUITE_REREQUESTED: 'check_suite.rerequested'
41+
CHECK_SUITE_REREQUESTED: 'check_suite.rerequested',
42+
CHECK_SUITE_REQUESTED: 'check_suite.requested'
4243
}
4344
};

controllers/pullRequest.js

+70-39
Original file line numberDiff line numberDiff line change
@@ -21,28 +21,38 @@ const outputTitleFail = constants.output_title_fail;
2121

2222
/**
2323
* Commit messages and PR title Validator
24-
* @param {Object} app
25-
* @param {Object} context
26-
* @param {Object} configuration
27-
* @param {Boolean} updateCheckRunFlag
24+
* @param {Object} app Probot app object
25+
* @param {Object} context Github event context
26+
* @param {Object} configuration Contains data (i.e regex for PR and Commits) from config.yml file
27+
* @param {Boolean} updateCheckRunFlag Update existing check run
28+
* @param {Boolean} createCheckRunFlag Create existing check run
2829
*/
29-
module.exports.commitAndTitleValidator = async (app, context, configuration, updateCheckRunFlag) => {
30+
module.exports.commitAndTitleValidator = async (app, context, configuration, updateCheckRunFlag, createCheckRunFlag) => {
3031
try {
3132
let { prTitleRegex, commitTitleRegex } = regexExtractor(configuration);
3233
let { owner, repository, pullRequestTitle, pullNumber } = prDetailsExtractor(context);
33-
// find commits
34+
/**
35+
* Find all commits for a pull request
36+
*/
3437
let commits = await listCommitsOfPullRequest(context, owner, repository, pullNumber);
35-
if(updateCheckRunFlag) {
38+
/**
39+
* If `PR title` is not present in `context`
40+
*/
41+
if (!pullRequestTitle) {
3642
/**
37-
* In case of check re-run and check suite re-run or Re-run all checks, get pull request data
43+
* In case of new check suite requested, check re-run and check suite re-run or Re-run all checks, get
44+
* pull request data
3845
*/
3946
const pullRequestDetails = await getPullRequest(context, owner, repository, pullNumber);
40-
if(pullRequestDetails && pullRequestDetails.data && pullRequestDetails.data.title) {
47+
/**
48+
* Get PR title
49+
*/
50+
if (pullRequestDetails && pullRequestDetails.data && pullRequestDetails.data.title) {
4151
pullRequestTitle = pullRequestDetails.data.title;
4252
}
4353
}
4454
let result = checkMessagesFormat(pullRequestTitle, commits.data, prTitleRegex, commitTitleRegex);
45-
await createOrUpdateCheckRun(context, owner, repository, result, updateCheckRunFlag);
55+
await createOrUpdateCheckRun(context, owner, repository, result, updateCheckRunFlag, createCheckRunFlag);
4656
} catch (error) {
4757
app.log(error);
4858
}
@@ -70,7 +80,9 @@ function checkMessagesFormat(pullRequestTitle, commits, prTitleRegex, commitMsgR
7080
};
7181
checkPrTitle(pullRequestTitle, prTitleRegex, flags);
7282
if (commits && Array.isArray(commits) && commits.length) {
73-
// check all commit messages
83+
/**
84+
* Check all commit messages
85+
*/
7486
checkCommitMessages(commits, commitIds, commitMsgRegex, mergeCommitRegex, flags);
7587
result = concludeCheckRunParams(prTitleRegex, commitMsgRegex, commitIds, flags);
7688
}
@@ -87,12 +99,16 @@ function checkMessagesFormat(pullRequestTitle, commits, prTitleRegex, commitMsgR
8799
* @param {Object} flags
88100
*/
89101
function checkPrTitle(pullRequestTitle, prTitleRegex, flags) {
90-
// pull request title format
102+
/**
103+
* Check pull request title format
104+
*/
91105
if (checkRegex(pullRequestTitle, prTitleRegex)) {
92106
flags.pullReqTitleStatus = true;
93107
flags.pullReqTitleStatusMsg = messages.valid_pull_request_message;
94108
} else {
95-
// invalid pull Request title
109+
/**
110+
* Invalid pull Request title
111+
*/
96112
flags.pullReqTitleStatus = false;
97113
flags.pullReqTitleStatusMsg = messages.invalid_pull_request_message;
98114
}
@@ -107,7 +123,9 @@ function checkPrTitle(pullRequestTitle, prTitleRegex, flags) {
107123
* @param {Object} flags
108124
*/
109125
function checkCommitMessages(commits, commitIds, commitMsgRegex, mergeCommitRegex, flags) {
110-
// check all commit messages
126+
/**
127+
* Check all commit messages
128+
*/
111129
for (let index = 0; index < commits.length; index++) {
112130
const element = commits[index];
113131
const commitMessage = element.commit.message;
@@ -157,19 +175,27 @@ function concludeCheckRunParams(prTitleRegex, commitMsgRegex, commitIds, flags)
157175
};
158176
let status = checkRunStatusCompleted;
159177
if (!prTitleRegex && !commitMsgRegex) {
160-
// pull request and commit message configration regex not set
178+
/**
179+
* Pull request and commit message configration regex not set
180+
*/
161181
output.title = `${messages.pr_and_commit_message_configuration_not_set}`;
162182
output.summary = `${messages.pr_and_commit_message_configuration_not_set}<br/>`;
163183
} else if (!commitMsgRegex) {
164-
// commit message configration regex not set
184+
/**
185+
* Commit message configration regex not set
186+
*/
165187
output.title = `${messages.commit_message_configuration_not_set}`;
166188
output.summary = `${flags.pullReqTitleStatusMsg}<br/>${messages.commit_message_configuration_not_set}<br/>`;
167189
} else if (!prTitleRegex) {
168-
// pull request configration regex not set
190+
/**
191+
* Pull request configration regex not set
192+
*/
169193
output.title = `${messages.pr_configuration_not_set}`;
170194
output.summary = `${messages.pr_configuration_not_set}<br/>${flags.commitMsgStatusMsg}<br/>${flags.invalidCommits}<br/>`;
171195
}
172-
// set invalid commit messages and count
196+
/**
197+
* Set invalid commit messages and count
198+
*/
173199
if (flags.invalidCommitsCount && flags.invalidCommitsCount >= constants.INVALID_COMMIT_LIMIT) {
174200
output.summary += `${flags.invalidCommitsCount} ${flags.otherInvalidCommitMessages}`;
175201
}
@@ -194,29 +220,29 @@ function prDetailsExtractor(context) {
194220
pullRequestTitle: '',
195221
pullNumber: 0
196222
};
197-
if(context.payload) {
223+
if (context.payload) {
198224
/**
199225
* Extract repository details
200226
*/
201-
if(context.payload.repository) {
202-
if(context.payload.repository.owner && context.payload.repository.owner.login) {
227+
if (context.payload.repository) {
228+
if (context.payload.repository.owner && context.payload.repository.owner.login) {
203229
result.owner = context.payload.repository.owner.login;
204230
}
205-
if(context.payload.repository.name) {
231+
if (context.payload.repository.name) {
206232
result.repository = context.payload.repository.name;
207233
}
208234
}
209235
/**
210-
* Extract pr title and pull number
236+
* Extract PR title and pull number
211237
*/
212-
if(context.payload.pull_request && context.payload.pull_request.title) {
238+
if (context.payload.pull_request && context.payload.pull_request.title) {
213239
result.pullRequestTitle = context.payload.pull_request.title;
214240
}
215-
if(context.payload.number) {
241+
if (context.payload.number) {
216242
result.pullNumber = context.payload.number;
217-
} else if(context.payload.check_run && context.payload.check_run.check_suite && context.payload.check_run.check_suite.pull_requests && context.payload.check_run.check_suite.pull_requests.length && context.payload.check_run.check_suite.pull_requests[0].number) {
243+
} else if (context.payload.check_run && context.payload.check_run.check_suite && context.payload.check_run.check_suite.pull_requests && context.payload.check_run.check_suite.pull_requests.length && context.payload.check_run.check_suite.pull_requests[0].number) {
218244
result.pullNumber = context.payload.check_run.check_suite.pull_requests[0].number;
219-
} else if(context.payload.check_suite && context.payload.check_suite.pull_requests.length && context.payload.check_suite.pull_requests[0].number) {
245+
} else if (context.payload.check_suite && context.payload.check_suite.pull_requests.length && context.payload.check_suite.pull_requests[0].number) {
220246
result.pullNumber = context.payload.check_suite.pull_requests[0].number;
221247
}
222248
}
@@ -232,7 +258,7 @@ function regexExtractor(configuration) {
232258
prTitleRegex: '',
233259
commitTitleRegex: ''
234260
};
235-
result.prTitleRegex = (configuration && configuration.PR_TITLE_REGEX) ? configuration.PR_TITLE_REGEX: '';
261+
result.prTitleRegex = (configuration && configuration.PR_TITLE_REGEX) ? configuration.PR_TITLE_REGEX : '';
236262
result.commitTitleRegex = (configuration && configuration.COMMIT_MESSAGE_REGEX) ? configuration.COMMIT_MESSAGE_REGEX : '';
237263
return result;
238264
}
@@ -243,32 +269,37 @@ function regexExtractor(configuration) {
243269
* @param {String} owner
244270
* @param {String} repository
245271
* @param {Object} result
246-
* @param {boolean} updateCheckRunFlag
272+
* @param {boolean} updateCheckRunFlag
273+
* @param {boolean} createCheckRunFlag
247274
*/
248-
async function createOrUpdateCheckRun(context, owner, repository, result, updateCheckRunFlag) {
275+
async function createOrUpdateCheckRun(context, owner, repository, result, updateCheckRunFlag, createCheckRunFlag) {
249276
if (result && result.commitIds && Array.isArray(result.commitIds) && result.commitIds.length) {
250277
for (let index = 0; index < result.commitIds.length; index++) {
251278
const commitId = result.commitIds[index];
252-
if(updateCheckRunFlag) {
279+
if (updateCheckRunFlag) {
253280
/**
254281
* Update existing check run
255282
*/
256283
const checkRunId = context.payload.check_run.id;
257284
await updateCheckRun(context, owner, repository, commitId, result.status, result.conclusion, result.output, checkRunId);
258-
} else {
285+
} else if (createCheckRunFlag) {
259286
/**
260287
* Create check new run
261288
*/
262289
/**
263290
* check if checkSuite exists or not for the commit
264291
*/
265-
let checkSuiteList = await listCheckSuite(context, owner, repository, commitId);
266-
if (!checkSuiteList || (checkSuiteList && checkSuiteList.data && checkSuiteList.data.total_count && checkSuiteList.data.total_count === 0)) {
267-
// create check suite for a particular commit
268-
await createCheckSuite(context, owner, repository, commitId);
269-
}
270-
// create check run
271-
await createCheckRun(context, owner, repository, commitId, result.status, result.checkRunName, result.conclusion, result.output);
292+
let checkSuiteList = await listCheckSuite(context, owner, repository, commitId);
293+
if (!checkSuiteList || (checkSuiteList && checkSuiteList.data && checkSuiteList.data.total_count && checkSuiteList.data.total_count === 0)) {
294+
/**
295+
* create check suite for a particular commit
296+
*/
297+
await createCheckSuite(context, owner, repository, commitId);
298+
}
299+
/**
300+
* create check run
301+
*/
302+
await createCheckRun(context, owner, repository, commitId, result.status, result.checkRunName, result.conclusion, result.output);
272303
}
273304
}
274305
}

index.js

+14-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ module.exports = async app => {
2828
app.on(events.PULL_REQUEST_OPEN, async (context) => {
2929
try {
3030
const configuration = await context.config(configFileName);
31-
await commitAndTitleValidator(app, context, configuration, false);
31+
await commitAndTitleValidator(app, context, configuration, false, true);
3232
} catch (error) {
3333
app.log(error);
3434
}
@@ -39,7 +39,7 @@ module.exports = async app => {
3939
app.on(events.CHECK_RUN_REREQUESTED, async (context) => {
4040
try {
4141
const configuration = await context.config(configFileName);
42-
await commitAndTitleValidator(app, context, configuration, true);
42+
await commitAndTitleValidator(app, context, configuration, true, false);
4343
} catch (error) {
4444
app.log(error);
4545
}
@@ -54,7 +54,18 @@ module.exports = async app => {
5454
id: listOfCheckRuns.data.check_runs[0].id
5555
};
5656
const configuration = await context.config(configFileName);
57-
await commitAndTitleValidator(app, context, configuration, true);
57+
await commitAndTitleValidator(app, context, configuration, true, false);
58+
} catch (error) {
59+
app.log(error);
60+
}
61+
});
62+
/**
63+
* Run all checks (Check Suite Requested) event listener
64+
*/
65+
app.on(events.CHECK_SUITE_REQUESTED, async (context) => {
66+
try {
67+
const configuration = await context.config(configFileName);
68+
await commitAndTitleValidator(app, context, configuration, false, true);
5869
} catch (error) {
5970
app.log(error);
6071
}

0 commit comments

Comments
 (0)