Skip to content

Commit

Permalink
Automatically remove stale build label after the PR has been updated (#…
Browse files Browse the repository at this point in the history
…173)

* automatically remove stale build label after the PR has been updated

* address review comments

* move from synchronize to push
  • Loading branch information
jameesjohn authored Dec 20, 2020
1 parent 5b64723 commit 750df37
Show file tree
Hide file tree
Showing 9 changed files with 574 additions and 347 deletions.
8 changes: 5 additions & 3 deletions constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,11 @@ const issuesLabelCheck = 'issues-labeled-check';
const issuesAssignedCheck = 'issues-assigned-check';
const forcePushCheck = 'force-push-check';
const pullRequestReviewCheck = 'pr-review-check';
const codeOwnerCheck = 'code-owner-check'
const codeOwnerCheck = 'code-owner-check';
const ciFailureCheck = 'ci-failure-check';
const updateWithDevelopCheck = 'update-with-develop-check';
const respondToReviewCheck = 'respond-to-review-check';
const oldBuildLabelCheck = 'old-build-label-check';

const checksWhitelist = {
'oppia-android': {
Expand Down Expand Up @@ -92,7 +93,7 @@ const checksWhitelist = {
[issuesLabelEvent]: [issuesLabelCheck],
[issuesAssignedEvent]: [issuesAssignedCheck],
[unlabelEvent]: [datastoreLabelCheck],
[pushEvent]: [forcePushCheck],
[pushEvent]: [forcePushCheck, oldBuildLabelCheck],
[periodicCheckEvent]: [periodicCheck],
[pullRequestReviewEvent]: [pullRequestReviewCheck],
[checkCompletedEvent]: [ciFailureCheck],
Expand Down Expand Up @@ -147,7 +148,8 @@ module.exports.pullRequestReviewCheck = pullRequestReviewCheck;
module.exports.codeOwnerCheck = codeOwnerCheck;
module.exports.ciFailureCheck = ciFailureCheck;
module.exports.updateWithDevelopCheck = updateWithDevelopCheck;
module.exports.respondToReviewCheck = respondToReviewCheck
module.exports.respondToReviewCheck = respondToReviewCheck;
module.exports.oldBuildLabelCheck = oldBuildLabelCheck;

module.exports.getBlacklistedAuthors = function() {
return blacklistedAuthors;
Expand Down
6 changes: 5 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const periodicCheckModule = require('./lib/periodicChecks');

const constants = require('./constants');
const checkIssueAssigneeModule = require('./lib/checkIssueAssignee');
const staleBuildModule = require('./lib/staleBuildChecks');

const whitelistedAccounts = (process.env.WHITELISTED_ACCOUNTS || '')
.toLowerCase()
Expand Down Expand Up @@ -128,12 +129,15 @@ const runChecks = async (context, checkEvent) => {
await Promise.all([
periodicCheckModule.ensureAllPullRequestsAreAssigned(context),
periodicCheckModule.ensureAllIssuesHaveProjects(context),
periodicCheckModule.checkAndTagPRsWithOldBuilds(context)
staleBuildModule.checkAndTagPRsWithOldBuilds(context)
]);
break;
case constants.respondToReviewCheck:
await checkPullRequestReviewModule.handleResponseToReview(context);
break;
case constants.oldBuildLabelCheck:
await staleBuildModule.removeOldBuildLabel(context);
break;
}
}
}
Expand Down
53 changes: 1 addition & 52 deletions lib/periodicChecks.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ const {
pingAndAssignUsers,
getAllOpenIssues,
getAllProjectCards,
hasPendingReviews
hasPendingReviews,
} = require('./utils');
const utilityModule = require('./utils');
const mergeConflictModule = require('./checkMergeConflicts');
const pullRequestReviewModule = require('./checkPullRequestReview');
const { teamLeads, oppiaMaintainers } = require('../userWhitelist.json');
Expand Down Expand Up @@ -175,57 +174,7 @@ const ensureAllIssuesHaveProjects = async (context) => {
});
};

/**
* This function comments on and tags pull requests in which the last
* commit was created 2 days ago
* @param {import('probot').Context} context
*/
const checkAndTagPRsWithOldBuilds = async (context) => {
const OLD_BUILD_LABEL = "PR: don't merge - STALE BUILD";

const allOpenPullRequests = await getAllOpenPullRequests(context);

allOpenPullRequests.forEach(async (pullRequest) => {
const containsOldBuildLabel = pullRequest.labels.some(
label => label.name === OLD_BUILD_LABEL
);
// If label has already been added, do nothing.
if (containsOldBuildLabel) {
return;
}
// Get last commit for pull request.
const {data: lastCommit} = await context.github.repos.getCommit(
context.repo({
ref: pullRequest.head.sha
})
);

const lastCommitDate = new Date(lastCommit.commit.author.date);
// Commit is older than 2 days
if (utilityModule.MIN_BUILD_DATE > lastCommitDate) {
const labelParams = context.repo({
issue_number: pullRequest.number,
labels: [OLD_BUILD_LABEL],
});
context.github.issues.addLabels(labelParams);

// Ping PR author.
const commentParams = context.repo({
issue_number: pullRequest.number,
body:
'Hi @' + pullRequest.user.login + ', the build of this PR is ' +
'stale and this could result in tests failing in develop. Please ' +
'update this pull request with the latest changes from develop. ' +
'Thanks!',
});
context.github.issues.createComment(commentParams);
}
}
);
};

module.exports = {
ensureAllPullRequestsAreAssigned,
ensureAllIssuesHaveProjects,
checkAndTagPRsWithOldBuilds
};
104 changes: 104 additions & 0 deletions lib/staleBuildChecks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
const utils = require('./utils');

/**
* This function comments on and tags pull requests in which the last
* commit was created 2 days ago
* @param {import('probot').Context} context
*/
const checkAndTagPRsWithOldBuilds = async (context) => {
const allOpenPullRequests = await utils.getAllOpenPullRequests(
context
);

allOpenPullRequests.forEach(async (pullRequest) => {
const containsOldBuildLabel = pullRequest.labels.some(
label => label.name === utils.OLD_BUILD_LABEL
);
// If label has already been added, do nothing.
if (containsOldBuildLabel) {
return;
}
// Get last commit for pull request.
const {data: lastCommit} = await context.github.repos.getCommit(
context.repo({
ref: pullRequest.head.sha
})
);

const lastCommitDate = new Date(lastCommit.commit.author.date);
// Commit is older than 2 days
if (utils.MIN_BUILD_DATE > lastCommitDate) {
const labelParams = context.repo({
issue_number: pullRequest.number,
labels: [utils.OLD_BUILD_LABEL],
});
context.github.issues.addLabels(labelParams);

// Ping PR author.
const commentParams = context.repo({
issue_number: pullRequest.number,
body:
'Hi @' + pullRequest.user.login + ', the build of this PR is ' +
'stale and this could result in tests failing in develop. Please ' +
'update this pull request with the latest changes from develop. ' +
'Thanks!',
});
context.github.issues.createComment(commentParams);
}
}
);
};

/**
* This function removes the old build label when a PR has a new commit.
* @param {import('probot').Context} context
*/
const removeOldBuildLabel = async (context) => {
// Get the commit SHA after the push.
const sha = context.payload.after;
const maxWaitTime = 10000;
const waitTime = 2000;
/**
* @type {import('probot').Octokit.PullsGetResponse} pullRequest
*/
let pullRequest;
let totalWaitTime = 0;

do {
// Wait for 2 seconds before searching so that the pull request
// would have been synchronized with the new commit.
await utils.sleep(waitTime);
totalWaitTime += waitTime;
if (totalWaitTime >= maxWaitTime) {
return;
}

const pullRequestData = await context.github.search.issuesAndPullRequests(
{
q: `${sha} repo:${context.payload.repository.full_name}`,
}
);
// Since we are searching via the sha, only one PR will be found,
// which is the PR that we are looking for.
pullRequest = pullRequestData.data.items[0];
} while (pullRequest === undefined);

const containsOldBuildLabel = pullRequest.labels.some(
label => label.name === utils.OLD_BUILD_LABEL
);

if (!containsOldBuildLabel) {
return;
}

context.github.issues.removeLabel(
context.repo({
issue_number: pullRequest.number,
name: utils.OLD_BUILD_LABEL,
})
);
};
module.exports = {
checkAndTagPRsWithOldBuilds,
removeOldBuildLabel
};
2 changes: 2 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const SUCCESS_STATUS = 204;
const THREE_MINUTES = 60 * 1000 * 3;
let MIN_BUILD_DATE = new Date();
MIN_BUILD_DATE.setDate(MIN_BUILD_DATE.getDate() - 2); // 2 days prior.
const OLD_BUILD_LABEL = "PR: don't merge - STALE BUILD";

/**
* Gets all the changed files in the repo
Expand Down Expand Up @@ -419,6 +420,7 @@ module.exports = {
THREE_MINUTES,
LABELS_EXCLUDED_FROM_CODEOWNER_ASSIGNMENT,
DATASTORE_LABEL,
OLD_BUILD_LABEL,
getAllChangedFiles,
getNameString,
getNewItemsFromFileByRegex,
Expand Down
2 changes: 2 additions & 0 deletions spec/checkBranchPushSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const scheduler = require('../lib/scheduler');
const pushPayload = require('../fixtures/push.json');
const pullRequestPayload = require('../fixtures/pullRequestPayload.json');
const checkBranchPushModule = require('../lib/checkBranchPush');
const staleBuildModule = require('../lib/staleBuildChecks');

describe('Force Push Check', () => {
/**
Expand All @@ -39,6 +40,7 @@ describe('Force Push Check', () => {

beforeEach(() => {
spyOn(scheduler, 'createScheduler').and.callFake(() => {});
spyOn(staleBuildModule, 'removeOldBuildLabel').and.callFake(() => {});
github = {
issues: {
createComment: jasmine.createSpy('createComment').and.returnValue({}),
Expand Down
2 changes: 1 addition & 1 deletion spec/checkForNewCodeownerSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ describe('check for new code owner', () => {
/core/templates/google-analytics.initializer.ts @jameesjohn @vojtechjelinek
/core/templates/base-components/ @jameesjohn @vojtechjelinek
/core/templates/pages/Base.ts @jameesjohn @vojtechjelinek
/core/templates/pages/oppia_footer_directive.html
/core/templates/pages/oppia_footer_directive.html
@jameesjohn @vojtechjelinek
/core/templates/pages/OppiaFooterDirective.ts @jameesjohn @vojtechjelinek
/core/templates/pages/footer_js_libs.html @jameesjohn @vojtechjelinek
Expand Down
Loading

0 comments on commit 750df37

Please sign in to comment.