Skip to content

Commit

Permalink
feat: lint pr with regexp rules
Browse files Browse the repository at this point in the history
  • Loading branch information
christophehurpeau committed Jan 27, 2019
1 parent 8512872 commit aec6d86
Show file tree
Hide file tree
Showing 12 changed files with 194 additions and 75 deletions.
14 changes: 14 additions & 0 deletions lib/actions/autoAssignPRToCreator.js
@@ -0,0 +1,14 @@
'use strict';

exports.autoAssignPRToCreator = (repoContext, context) => {
if (!repoContext.config.autoAssignToCreator) return;

const pr = context.payload.pull_request;
if (pr.assignees.length !== 0) return;

return context.github.issues.addAssignees(
context.issue({
assignees: [pr.user.login],
})
);
};
19 changes: 19 additions & 0 deletions lib/actions/editOpenedPR.js
@@ -0,0 +1,19 @@
'use strict';

const cleanTitle = require('../utils/cleanTitle');

exports.editOpenedPR = (repoContext, context) => {
if (!repoContext.config.trimTitle) return;

const pr = context.payload.pull_request;
const title = cleanTitle(pr.title);

if (pr.title !== title) {
pr.title = title;
context.github.issues.update(
context.issue({
title,
})
);
}
};
34 changes: 34 additions & 0 deletions lib/actions/lintPR.js
@@ -0,0 +1,34 @@
'use strict';

exports.lintPR = (repoContext, context) => {
if (!repoContext.config.prLint) return;

const repo = context.payload.repository;
const pr = context.payload.pull_request;

// do not lint pr from forks
if (pr.head.repo.id !== repo.id) return;

const errorRule = repoContext.config.prLint.title.find(
(rule) => !rule.regExp.test(pr.title)
);

const date = new Date();

return context.github.checks.create(
context.repo({
name: 'reviewflow/lint-pr',
head_sha: pr.head.sha,
status: 'completed',
conclusion: errorRule ? 'failure' : 'success',
started_at: date,
completed_at: date,
output: errorRule
? errorRule.error
: {
title: '✓ Your PR is valid',
summary: '',
},
})
);
};
2 changes: 2 additions & 0 deletions lib/context/initTeamSlack.js
Expand Up @@ -3,6 +3,8 @@
const { WebClient } = require('@slack/client');

const initTeamSlack = async (context, config) => {
if (!config.slackToken) return;

const githubLoginToSlackEmail = { ...config.dev, ...config.design };

const slackClient = new WebClient(config.slackToken);
Expand Down
13 changes: 4 additions & 9 deletions lib/context/repoContext.js
@@ -1,6 +1,6 @@
'use strict';

const config = require('../teamconfig');
const teamConfigs = require('../teamconfigs');
const { obtainTeamContext } = require('./teamContext');
const initRepoLabels = require('./initRepoLabels');

Expand All @@ -26,11 +26,6 @@ const initRepoContext = async (context, config) => {
const addStatusCheck = (context, statusInfo) => {
const pr = context.payload.pull_request;

context.log.info('addStatusCheck', {
head_sha: pr.head.sha,
statusInfo,
});

return context.github.checks.create(
context.repo({
name: 'reviewflow',
Expand Down Expand Up @@ -163,8 +158,8 @@ const repoContexts = new Map();

exports.obtainRepoContext = (context) => {
const owner = context.payload.repository.owner;
if (owner.login !== 'ornikar') {
console.warn(owner.login);
if (!teamConfigs[owner.login]) {
console.warn(owner.login, Object.keys(teamConfigs));
return null;
}
const key = context.payload.repository.id;
Expand All @@ -175,7 +170,7 @@ exports.obtainRepoContext = (context) => {
const existingPromise = repoContextsPromise.get(key);
if (existingPromise) return Promise.resolve(existingPromise);

const promise = initRepoContext(context, config);
const promise = initRepoContext(context, teamConfigs[owner.login]);
repoContextsPromise.set(key, promise);

return promise.then((repoContext) => {
Expand Down
4 changes: 0 additions & 4 deletions lib/context/teamContext.js
Expand Up @@ -67,10 +67,6 @@ const teamContexts = new Map();

exports.obtainTeamContext = (context, config) => {
const owner = context.payload.repository.owner;
if (owner.login !== 'ornikar') {
console.warn(owner.login);
return null;
}

const existingTeamContext = teamContexts.get(owner.login);
if (existingTeamContext) return existingTeamContext;
Expand Down
53 changes: 15 additions & 38 deletions lib/index.js
Expand Up @@ -3,8 +3,9 @@
'use strict';

const { obtainRepoContext } = require('./context/repoContext');
const cleanTitle = require('./utils/cleanTitle');
const config = require('./teamconfig');
const { autoAssignPRToCreator } = require('./actions/autoAssignPRToCreator');
const { editOpenedPR } = require('./actions/editOpenedPR');
const { lintPR } = require('./actions/lintPR');

// const getConfig = require('probot-config')
// const { MongoClient } = require('mongodb');
Expand All @@ -19,41 +20,14 @@ const config = require('./teamconfig');
* @param {import('probot').Application} app - Probot's Application class.
*/
module.exports = (app) => {
const autoAssignToCreator = (repoContext, context) => {
if (!repoContext.config.autoAssignToCreator) return;

const pr = context.payload.pull_request;
if (pr.assignees.length !== 0) return;

return context.github.issues.addAssignees(
context.issue({
assignees: [pr.user.login],
})
);
};

const editOpenedPr = (repoContext, context) => {
if (!repoContext.config.trimTitle) return;

const pr = context.payload.pull_request;
const title = cleanTitle(pr.title);

if (pr.title !== title) {
context.github.issues.update(
context.issue({
title,
})
);
}
};

app.on('pull_request.opened', async (context) => {
const repoContext = await obtainRepoContext(context);
if (!repoContext) return;

await Promise.all([
autoAssignToCreator(repoContext, context),
editOpenedPr(repoContext, context),
autoAssignPRToCreator(repoContext, context),
editOpenedPR(repoContext, context),
lintPR(repoContext, context),
]);
});

Expand All @@ -72,7 +46,7 @@ module.exports = (app) => {
const shouldWait = false;
// repoContext.reviewShouldWait(reviewerGroup, pr.requested_reviewers, { includesWaitForGroups: true });

if (config.labels.review[reviewerGroup]) {
if (repoContext.config.labels.review[reviewerGroup]) {
const { data: reviews } = await context.github.pullRequests.listReviews(
context.issue({ per_page: 50 })
);
Expand Down Expand Up @@ -121,7 +95,7 @@ module.exports = (app) => {
}
);

if (config.labels.review[reviewerGroup]) {
if (repoContext.config.labels.review[reviewerGroup]) {
const { data: reviews } = await context.github.pullRequests.listReviews(
context.issue({ per_page: 50 })
);
Expand Down Expand Up @@ -186,7 +160,7 @@ module.exports = (app) => {

const reviewerGroup = repoContext.getReviewerGroup(reviewer.login);

if (reviewerGroup && config.labels.review[reviewerGroup]) {
if (reviewerGroup && repoContext.config.labels.review[reviewerGroup]) {
const hasRequestedReviewsForGroup = repoContext.reviewShouldWait(
reviewerGroup,
pr.requested_reviewers,
Expand Down Expand Up @@ -251,7 +225,7 @@ module.exports = (app) => {

const reviewerGroup = repoContext.getReviewerGroup(reviewer.login);

if (reviewerGroup && config.labels.review[reviewerGroup]) {
if (reviewerGroup && repoContext.config.labels.review[reviewerGroup]) {
const { data: reviews } = await context.github.pullRequests.listReviews(
context.issue({ per_page: 50 })
);
Expand Down Expand Up @@ -311,7 +285,7 @@ module.exports = (app) => {
if (!repoContext) return;

await Promise.all([
editOpenedPr(repoContext, context),
editOpenedPR(repoContext, context),
repoContext.addStatusCheckToLatestCommit(context),
]);
});
Expand All @@ -320,6 +294,9 @@ module.exports = (app) => {
const repoContext = await obtainRepoContext(context);
if (!repoContext) return;

await editOpenedPr(repoContext, context);
await Promise.all([
editOpenedPR(repoContext, context),
lintPR(repoContext, context),
]);
});
};
67 changes: 67 additions & 0 deletions lib/teamconfigs/christophehurpeau.js
@@ -0,0 +1,67 @@
'use strict';

module.exports = {
autoAssignToCreator: true,
trimTitle: true,
prLint: {
title: [
{
regExp:
// eslint-disable-next-line unicorn/no-unsafe-regex
/^(revert: )?(build|chore|ci|docs|feat|fix|perf|refactor|style|test)(\(([a-z\-/]*)\))?:\s/,
error: {
title: 'Title does not match commitlint conventional',
summary:
'https://github.com/marionebl/commitlint/tree/master/%40commitlint/config-conventional',
},
},
],
},
dev: {
christophehurpeau: 'christophe@hurpeau.com',
},
waitForGroups: {
dev: [],
design: ['devs'],
},
labels: {
list: {
// /* ci */
// 'ci/in-progress': { name: ':green_heart: ci/in-progress', color: '#0052cc' },
// 'ci/fail': { name: ':green_heart: ci/fail', color: '#e11d21' },
// 'ci/passed': { name: ':green_heart: ci/passed', color: '#86f9b4' },

/* code */
'code/needs-review': {
name: ':ok_hand: code/needs-review',
color: '#FFD57F',
},
'code/review-requested': {
name: ':ok_hand: code/review-requested',
color: '#B2E1FF',
},
'code/changes-requested': {
name: ':ok_hand: code/changes-requested',
color: '#e11d21',
},
'code/approved': {
name: ':ok_hand: code/approved',
color: '#64DD17',
},
},

review: {
ci: {
inProgress: 'ci/in-progress',
succeeded: 'ci/success',
failed: 'ci/fail',
},
dev: {
needsReview: 'code/needs-review',
requested: 'code/review-requested',
changesRequested: 'code/changes-requested',
approved: 'code/approved',
},
},
},
};
4 changes: 4 additions & 0 deletions lib/teamconfigs/index.js
@@ -0,0 +1,4 @@
'use strict';

exports.ornikar = require('./ornikar');
exports.christophehurpeau = require('./christophehurpeau');
21 changes: 21 additions & 0 deletions lib/teamconfig.js → lib/teamconfigs/ornikar.js
Expand Up @@ -4,6 +4,27 @@ module.exports = {
slackToken: process.env.ORNIKAR_SLACK_TOKEN,
autoAssignToCreator: true,
trimTitle: true,
prLint: {
title: [
{
regExp:
// eslint-disable-next-line unicorn/no-unsafe-regex
/^(revert: )?(build|chore|ci|docs|feat|fix|perf|refactor|style|test)(\(([a-z\-/]*)\))?:\s/,
error: {
title: 'Title does not match commitlint conventional',
summary:
'https://github.com/marionebl/commitlint/tree/master/%40commitlint/config-conventional',
},
},
{
regExp: /\s(ONK-(\d+)|\[no issue])$/,
error: {
title: 'Title does not have JIRA issue',
summary: 'The PR title should end with ONK-0000, or [no issue]',
},
},
],
},
dev: {
abarreir: `alexandre${process.env.ORNIKAR_EMAIL_DOMAIN}`,
christophehurpeau: `christophe${process.env.ORNIKAR_EMAIL_DOMAIN}`,
Expand Down
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -9,7 +9,7 @@
"repository": "git@github.com:christophehurpeau/reviewflow.git",
"homepage": "https://github.com/christophehurpeau/reviewflow",
"engines": {
"node": ">=10.6.0 < 11.0.0"
"node": ">=10.6.0"
},
"main": "./lib/index.js",
"scripts": {
Expand Down Expand Up @@ -71,7 +71,7 @@
"jest": "^23.6.0",
"lint-staged": "8.1.0",
"localtunnel": "1.9.1",
"nodemon": "1.18.6",
"nodemon": "1.18.9",
"pob-release": "4.6.1",
"prettier": "1.15.2",
"yarnhook": "0.3.0"
Expand Down

0 comments on commit aec6d86

Please sign in to comment.