Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/actions/checkDeployBlockers/checkDeployBlockers.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ const run = function () {
console.log('Checking for unverified PRs or unresolved deploy blockers', data);

// Check the issue description to see if there are any unfinished/un-QAed items in the checklist.
const uncheckedBoxRegex = /-\s\[\s]/g;
const matches = uncheckedBoxRegex.exec(data.body);
if (matches !== null) {
const uncheckedBoxRegex = new RegExp(`-\\s\\[\\s]\\s(?:QA|${GithubUtils.ISSUE_OR_PULL_REQUEST_REGEX.source})`);
if (uncheckedBoxRegex.test(data.body)) {
console.log('An unverified PR or unresolved deploy blocker was found.');
core.setOutput('HAS_DEPLOY_BLOCKERS', true);
return;
Expand Down
6 changes: 3 additions & 3 deletions .github/actions/checkDeployBlockers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ const run = function () {
console.log('Checking for unverified PRs or unresolved deploy blockers', data);

// Check the issue description to see if there are any unfinished/un-QAed items in the checklist.
const uncheckedBoxRegex = /-\s\[\s]/g;
const matches = uncheckedBoxRegex.exec(data.body);
if (matches !== null) {
const uncheckedBoxRegex = new RegExp(`-\\s\\[\\s]\\s(?:QA|${GithubUtils.ISSUE_OR_PULL_REQUEST_REGEX.source})`);
if (uncheckedBoxRegex.test(data.body)) {
console.log('An unverified PR or unresolved deploy blocker was found.');
core.setOutput('HAS_DEPLOY_BLOCKERS', true);
return;
Expand Down Expand Up @@ -512,6 +511,7 @@ module.exports.EXPENSIFY_CASH_REPO = EXPENSIFY_CASH_REPO;
module.exports.STAGING_DEPLOY_CASH_LABEL = STAGING_DEPLOY_CASH_LABEL;
module.exports.DEPLOY_BLOCKER_CASH_LABEL = DEPLOY_BLOCKER_CASH_LABEL;
module.exports.APPLAUSE_BOT = APPLAUSE_BOT;
module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX;


/***/ }),
Expand Down
1 change: 1 addition & 0 deletions .github/actions/createOrUpdateStagingDeploy/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,7 @@ module.exports.EXPENSIFY_CASH_REPO = EXPENSIFY_CASH_REPO;
module.exports.STAGING_DEPLOY_CASH_LABEL = STAGING_DEPLOY_CASH_LABEL;
module.exports.DEPLOY_BLOCKER_CASH_LABEL = DEPLOY_BLOCKER_CASH_LABEL;
module.exports.APPLAUSE_BOT = APPLAUSE_BOT;
module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX;


/***/ }),
Expand Down
1 change: 1 addition & 0 deletions .github/actions/getPullRequestDetails/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@ module.exports.EXPENSIFY_CASH_REPO = EXPENSIFY_CASH_REPO;
module.exports.STAGING_DEPLOY_CASH_LABEL = STAGING_DEPLOY_CASH_LABEL;
module.exports.DEPLOY_BLOCKER_CASH_LABEL = DEPLOY_BLOCKER_CASH_LABEL;
module.exports.APPLAUSE_BOT = APPLAUSE_BOT;
module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX;


/***/ }),
Expand Down
1 change: 1 addition & 0 deletions .github/actions/getReleaseBody/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@ module.exports.EXPENSIFY_CASH_REPO = EXPENSIFY_CASH_REPO;
module.exports.STAGING_DEPLOY_CASH_LABEL = STAGING_DEPLOY_CASH_LABEL;
module.exports.DEPLOY_BLOCKER_CASH_LABEL = DEPLOY_BLOCKER_CASH_LABEL;
module.exports.APPLAUSE_BOT = APPLAUSE_BOT;
module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX;


/***/ }),
Expand Down
1 change: 1 addition & 0 deletions .github/actions/isPullRequestMergeable/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ module.exports.EXPENSIFY_CASH_REPO = EXPENSIFY_CASH_REPO;
module.exports.STAGING_DEPLOY_CASH_LABEL = STAGING_DEPLOY_CASH_LABEL;
module.exports.DEPLOY_BLOCKER_CASH_LABEL = DEPLOY_BLOCKER_CASH_LABEL;
module.exports.APPLAUSE_BOT = APPLAUSE_BOT;
module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX;


/***/ }),
Expand Down
1 change: 1 addition & 0 deletions .github/actions/isStagingDeployLocked/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,7 @@ module.exports.EXPENSIFY_CASH_REPO = EXPENSIFY_CASH_REPO;
module.exports.STAGING_DEPLOY_CASH_LABEL = STAGING_DEPLOY_CASH_LABEL;
module.exports.DEPLOY_BLOCKER_CASH_LABEL = DEPLOY_BLOCKER_CASH_LABEL;
module.exports.APPLAUSE_BOT = APPLAUSE_BOT;
module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX;


/***/ }),
Expand Down
1 change: 1 addition & 0 deletions .github/actions/markPullRequestsAsDeployed/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,7 @@ module.exports.EXPENSIFY_CASH_REPO = EXPENSIFY_CASH_REPO;
module.exports.STAGING_DEPLOY_CASH_LABEL = STAGING_DEPLOY_CASH_LABEL;
module.exports.DEPLOY_BLOCKER_CASH_LABEL = DEPLOY_BLOCKER_CASH_LABEL;
module.exports.APPLAUSE_BOT = APPLAUSE_BOT;
module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX;


/***/ }),
Expand Down
1 change: 1 addition & 0 deletions .github/actions/reopenIssueWithComment/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,7 @@ module.exports.EXPENSIFY_CASH_REPO = EXPENSIFY_CASH_REPO;
module.exports.STAGING_DEPLOY_CASH_LABEL = STAGING_DEPLOY_CASH_LABEL;
module.exports.DEPLOY_BLOCKER_CASH_LABEL = DEPLOY_BLOCKER_CASH_LABEL;
module.exports.APPLAUSE_BOT = APPLAUSE_BOT;
module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX;


/***/ }),
Expand Down
1 change: 1 addition & 0 deletions .github/actions/triggerWorkflowAndWait/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,7 @@ module.exports.EXPENSIFY_CASH_REPO = EXPENSIFY_CASH_REPO;
module.exports.STAGING_DEPLOY_CASH_LABEL = STAGING_DEPLOY_CASH_LABEL;
module.exports.DEPLOY_BLOCKER_CASH_LABEL = DEPLOY_BLOCKER_CASH_LABEL;
module.exports.APPLAUSE_BOT = APPLAUSE_BOT;
module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX;


/***/ }),
Expand Down
1 change: 1 addition & 0 deletions .github/libs/GithubUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -424,3 +424,4 @@ module.exports.EXPENSIFY_CASH_REPO = EXPENSIFY_CASH_REPO;
module.exports.STAGING_DEPLOY_CASH_LABEL = STAGING_DEPLOY_CASH_LABEL;
module.exports.DEPLOY_BLOCKER_CASH_LABEL = DEPLOY_BLOCKER_CASH_LABEL;
module.exports.APPLAUSE_BOT = APPLAUSE_BOT;
module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX;
122 changes: 85 additions & 37 deletions tests/unit/checkDeployBlockersTest.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
* @jest-environment node
*/
const _ = require('underscore');
const core = require('@actions/core');
const GithubUtils = require('../../.github/libs/GithubUtils');
const run = require('../../.github/actions/checkDeployBlockers/checkDeployBlockers');
Expand Down Expand Up @@ -35,6 +36,23 @@ beforeAll(() => {
GithubUtils.octokitInternal = mocktokit;
});

let baseComments = [];
beforeEach(() => {
baseComments = {
data: [
{
body: 'foo',
},
{
body: 'bar',
},
{
body: ':shipit:',
},
],
};
});

afterEach(() => {
mockSetOutput.mockClear();
mockGetIssue.mockClear();
Expand All @@ -45,69 +63,99 @@ afterAll(() => {
jest.clearAllMocks();
});

describe('checkDeployBlockers', () => {
const baseIssue = {
function checkbox(isClosed) {
return isClosed ? '[x]' : '[ ]';
}

function mockIssue(prList, deployBlockerList) {
return {
data: {
number: 1,
title: 'Scott\'s Unfinished QA Checklist',
body: 'Checklist for Deploy #668\r\n'
+ '- [x] @foo https://github.com/Expensify/App/issues/1',
title: 'Scott\'s QA Checklist',
body: `
**Release Version:** \`1.1.31-2\`
**Compare Changes:** https://github.com/Expensify/App/compare/production...staging

**This release contains changes from the following pull requests:**
${_.map(prList, ({url, isQASuccess, isAccessibilitySuccess}) => `
- ${url}
- ${checkbox(isQASuccess)} QA
- ${checkbox(isAccessibilitySuccess)} Accessibility
`)}
${!_.isEmpty(deployBlockerList) ? `

**Deploy Blockers:**` : ''}
${_.map(deployBlockerList, ({url, isQASuccess}) => `
- ${checkbox(isQASuccess)} ${url}
`)}
cc @Expensify/applauseleads
`,
},
};
}

const baseComments = {
data: [
{
body: 'foo',
},
{
body: 'bar',
},
{
body: ':shipit:',
},
],
};
describe('checkDeployBlockers', () => {
const allClearIssue = mockIssue([{url: 'https://github.com/Expensify/App/pull/6882', isQASuccess: true, isAccessibilitySuccess: true}]);

describe('checkDeployBlockers', () => {
test('Test an issue with a checked item and :shipit:', () => {
mockGetIssue.mockResolvedValue(baseIssue);
test('Test an issue with all checked items and :shipit:', () => {
mockGetIssue.mockResolvedValue(allClearIssue);
mockListComments.mockResolvedValue(baseComments);
return run().then(() => {
expect(mockSetOutput).toHaveBeenCalledWith('HAS_DEPLOY_BLOCKERS', false);
});
});

test('Test an issue with an unchecked item and :shipit:', () => {
const uncheckedItemIssue = baseIssue;
uncheckedItemIssue.data.body += '\r\n- [ ] @bar https://github.com/Expensify/App/issues/23';
mockGetIssue.mockResolvedValue(uncheckedItemIssue);
mockListComments.mockResolvedValue(baseComments);
test('Test an issue with all boxes checked but no :shipit:', () => {
mockGetIssue.mockResolvedValue(allClearIssue);
const extraComments = {
data: [
...baseComments.data,
{body: 'This issue either has unchecked QA steps or has not yet been stamped with a :shipit: comment. Reopening!'},
],
};
mockListComments.mockResolvedValue(extraComments);
return run().then(() => {
expect(mockSetOutput).toHaveBeenCalledWith('HAS_DEPLOY_BLOCKERS', true);
});
});

test('Test an issue with all boxes checked but no :shipit:', () => {
const checkedBoxesNoShipitIssue = baseIssue;
checkedBoxesNoShipitIssue.data.body = 'Checklist for Deploy #668:\r\n'
+ '- [x] @bar https://github.com/Expensify/App/issues/23\r\n'
+ '- [x] @baz https://github.com/Expensify/App/issues/42';
mockGetIssue.mockResolvedValue(checkedBoxesNoShipitIssue);
// eslint-disable-next-line max-len
baseComments.data.push({body: 'This issue either has unchecked QA steps or has not yet been stamped with a :shipit: comment. Reopening!'});
mockListComments.mockResolvedValue(baseComments);
test('Test an issue with all boxes checked but no comments', () => {
mockGetIssue.mockResolvedValue(allClearIssue);
mockListComments.mockResolvedValue({data: []});
return run().then(() => {
expect(mockSetOutput).toHaveBeenCalledWith('HAS_DEPLOY_BLOCKERS', true);
});
});

test('Test an issue with all boxes checked but no comments', () => {
mockGetIssue.mockResolvedValue(baseIssue);
mockListComments.mockResolvedValue({data: []});
test('Test an issue with all QA checked but no accessibility', () => {
mockGetIssue.mockResolvedValue(mockIssue([{url: 'https://github.com/Expensify/App/pull/6882', isQASuccess: true, isAccessibilitySuccess: false}]));
mockListComments.mockResolvedValue(baseComments);
return run().then(() => {
expect(mockSetOutput).toHaveBeenCalledWith('HAS_DEPLOY_BLOCKERS', false);
});
});

test('Test an issue with all QA checked but not all deploy blockers', () => {
mockGetIssue.mockResolvedValue(mockIssue(
[{url: 'https://github.com/Expensify/App/pull/6882', isQASuccess: true, isAccessibilitySuccess: false}],
[{url: 'https://github.com/Expensify/App/pull/6883', isQASuccess: false}],
));
mockListComments.mockResolvedValue(baseComments);
return run().then(() => {
expect(mockSetOutput).toHaveBeenCalledWith('HAS_DEPLOY_BLOCKERS', true);
});
});

test('Test an issue with all QA checked and all deploy blockers resolved', () => {
mockGetIssue.mockResolvedValue(mockIssue(
[{url: 'https://github.com/Expensify/App/pull/6882', isQASuccess: true, isAccessibilitySuccess: false}],
[{url: 'https://github.com/Expensify/App/pull/6883', isQASuccess: true}],
));
mockListComments.mockResolvedValue(baseComments);
return run().then(() => {
expect(mockSetOutput).toHaveBeenCalledWith('HAS_DEPLOY_BLOCKERS', false);
});
});
});
});