diff --git a/.github/actions/javascript/awaitStagingDeploys/index.js b/.github/actions/javascript/awaitStagingDeploys/index.js index 728589d2a2b7..7fed9b6634a6 100644 --- a/.github/actions/javascript/awaitStagingDeploys/index.js +++ b/.github/actions/javascript/awaitStagingDeploys/index.js @@ -226,6 +226,7 @@ class GithubUtils { labels: issue.labels, PRList: this.getStagingDeployCashPRList(issue), deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), tag, @@ -260,8 +261,7 @@ class GithubUtils { isAccessible: match[4] === 'x', }), ); - const internalQAPRList = this.getStagingDeployCashInternalQA(issue); - return _.sortBy(_.union(PRList, internalQAPRList), 'number'); + return _.sortBy(PRList, 'number'); } /** @@ -324,6 +324,7 @@ class GithubUtils { * @param {Array} [accessiblePRList] - The list of PR URLs which have passed the accessability check. * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. + * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. * @param {Boolean} [isTimingDashboardChecked] * @param {Boolean} [isFirebaseChecked] * @returns {Promise} @@ -335,6 +336,7 @@ class GithubUtils { accessiblePRList = [], deployBlockers = [], resolvedDeployBlockers = [], + resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, ) { @@ -346,6 +348,11 @@ class GithubUtils { ); console.log('Filtering out the following automated pull requests:', automatedPRs); + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], + // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] + // } const internalQAPRMap = _.reduce( _.filter(data, pr => !_.isEmpty(_.findWhere(pr.labels, {name: INTERNAL_QA_LABEL}))), (map, pr) => { @@ -390,11 +397,13 @@ class GithubUtils { }); } + // Internal QA PR list if (!_.isEmpty(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); issueBody += '\r\n\r\n\r\n**Internal QA:**'; _.each(internalQAPRMap, (assignees, URL) => { const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `\r\n${_.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'} `; + issueBody += `\r\n${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; issueBody += `${URL}`; issueBody += ` -${assigneeMentions}`; }); diff --git a/.github/actions/javascript/checkDeployBlockers/index.js b/.github/actions/javascript/checkDeployBlockers/index.js index 6d7c26639615..849ed857aa1a 100644 --- a/.github/actions/javascript/checkDeployBlockers/index.js +++ b/.github/actions/javascript/checkDeployBlockers/index.js @@ -196,6 +196,7 @@ class GithubUtils { labels: issue.labels, PRList: this.getStagingDeployCashPRList(issue), deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), tag, @@ -230,8 +231,7 @@ class GithubUtils { isAccessible: match[4] === 'x', }), ); - const internalQAPRList = this.getStagingDeployCashInternalQA(issue); - return _.sortBy(_.union(PRList, internalQAPRList), 'number'); + return _.sortBy(PRList, 'number'); } /** @@ -294,6 +294,7 @@ class GithubUtils { * @param {Array} [accessiblePRList] - The list of PR URLs which have passed the accessability check. * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. + * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. * @param {Boolean} [isTimingDashboardChecked] * @param {Boolean} [isFirebaseChecked] * @returns {Promise} @@ -305,6 +306,7 @@ class GithubUtils { accessiblePRList = [], deployBlockers = [], resolvedDeployBlockers = [], + resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, ) { @@ -316,6 +318,11 @@ class GithubUtils { ); console.log('Filtering out the following automated pull requests:', automatedPRs); + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], + // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] + // } const internalQAPRMap = _.reduce( _.filter(data, pr => !_.isEmpty(_.findWhere(pr.labels, {name: INTERNAL_QA_LABEL}))), (map, pr) => { @@ -360,11 +367,13 @@ class GithubUtils { }); } + // Internal QA PR list if (!_.isEmpty(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); issueBody += '\r\n\r\n\r\n**Internal QA:**'; _.each(internalQAPRMap, (assignees, URL) => { const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `\r\n${_.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'} `; + issueBody += `\r\n${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; issueBody += `${URL}`; issueBody += ` -${assigneeMentions}`; }); diff --git a/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.js b/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.js index 27db22f3ca71..401b2edffd90 100644 --- a/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.js +++ b/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.js @@ -122,6 +122,12 @@ const run = function () { 'number', ); + // Get the internalQA PR list, preserving the previous state of `isResolved` + const internalQAPRList = _.sortBy( + currentStagingDeployCashData.internalQAPRList, + 'number', + ); + return GithubUtils.generateStagingDeployCashBody( newTag, _.pluck(PRList, 'url'), @@ -129,6 +135,7 @@ const run = function () { _.pluck(_.where(PRList, {isAccessible: true}), 'url'), _.pluck(deployBlockers, 'url'), _.pluck(_.where(deployBlockers, {isResolved: true}), 'url'), + _.pluck(_.where(internalQAPRList, {isResolved: true}), 'url'), didVersionChange ? false : currentStagingDeployCashData.isTimingDashboardChecked, didVersionChange ? false : currentStagingDeployCashData.isFirebaseChecked, ); diff --git a/.github/actions/javascript/createOrUpdateStagingDeploy/index.js b/.github/actions/javascript/createOrUpdateStagingDeploy/index.js index 97ea937ef3e9..d5b896adeac4 100644 --- a/.github/actions/javascript/createOrUpdateStagingDeploy/index.js +++ b/.github/actions/javascript/createOrUpdateStagingDeploy/index.js @@ -132,6 +132,12 @@ const run = function () { 'number', ); + // Get the internalQA PR list, preserving the previous state of `isResolved` + const internalQAPRList = _.sortBy( + currentStagingDeployCashData.internalQAPRList, + 'number', + ); + return GithubUtils.generateStagingDeployCashBody( newTag, _.pluck(PRList, 'url'), @@ -139,6 +145,7 @@ const run = function () { _.pluck(_.where(PRList, {isAccessible: true}), 'url'), _.pluck(deployBlockers, 'url'), _.pluck(_.where(deployBlockers, {isResolved: true}), 'url'), + _.pluck(_.where(internalQAPRList, {isResolved: true}), 'url'), didVersionChange ? false : currentStagingDeployCashData.isTimingDashboardChecked, didVersionChange ? false : currentStagingDeployCashData.isFirebaseChecked, ); @@ -418,6 +425,7 @@ class GithubUtils { labels: issue.labels, PRList: this.getStagingDeployCashPRList(issue), deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), tag, @@ -452,8 +460,7 @@ class GithubUtils { isAccessible: match[4] === 'x', }), ); - const internalQAPRList = this.getStagingDeployCashInternalQA(issue); - return _.sortBy(_.union(PRList, internalQAPRList), 'number'); + return _.sortBy(PRList, 'number'); } /** @@ -516,6 +523,7 @@ class GithubUtils { * @param {Array} [accessiblePRList] - The list of PR URLs which have passed the accessability check. * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. + * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. * @param {Boolean} [isTimingDashboardChecked] * @param {Boolean} [isFirebaseChecked] * @returns {Promise} @@ -527,6 +535,7 @@ class GithubUtils { accessiblePRList = [], deployBlockers = [], resolvedDeployBlockers = [], + resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, ) { @@ -538,6 +547,11 @@ class GithubUtils { ); console.log('Filtering out the following automated pull requests:', automatedPRs); + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], + // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] + // } const internalQAPRMap = _.reduce( _.filter(data, pr => !_.isEmpty(_.findWhere(pr.labels, {name: INTERNAL_QA_LABEL}))), (map, pr) => { @@ -582,11 +596,13 @@ class GithubUtils { }); } + // Internal QA PR list if (!_.isEmpty(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); issueBody += '\r\n\r\n\r\n**Internal QA:**'; _.each(internalQAPRMap, (assignees, URL) => { const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `\r\n${_.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'} `; + issueBody += `\r\n${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; issueBody += `${URL}`; issueBody += ` -${assigneeMentions}`; }); diff --git a/.github/actions/javascript/getPullRequestDetails/index.js b/.github/actions/javascript/getPullRequestDetails/index.js index 24262b7e6bd8..8b364f228efe 100644 --- a/.github/actions/javascript/getPullRequestDetails/index.js +++ b/.github/actions/javascript/getPullRequestDetails/index.js @@ -267,6 +267,7 @@ class GithubUtils { labels: issue.labels, PRList: this.getStagingDeployCashPRList(issue), deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), tag, @@ -301,8 +302,7 @@ class GithubUtils { isAccessible: match[4] === 'x', }), ); - const internalQAPRList = this.getStagingDeployCashInternalQA(issue); - return _.sortBy(_.union(PRList, internalQAPRList), 'number'); + return _.sortBy(PRList, 'number'); } /** @@ -365,6 +365,7 @@ class GithubUtils { * @param {Array} [accessiblePRList] - The list of PR URLs which have passed the accessability check. * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. + * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. * @param {Boolean} [isTimingDashboardChecked] * @param {Boolean} [isFirebaseChecked] * @returns {Promise} @@ -376,6 +377,7 @@ class GithubUtils { accessiblePRList = [], deployBlockers = [], resolvedDeployBlockers = [], + resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, ) { @@ -387,6 +389,11 @@ class GithubUtils { ); console.log('Filtering out the following automated pull requests:', automatedPRs); + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], + // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] + // } const internalQAPRMap = _.reduce( _.filter(data, pr => !_.isEmpty(_.findWhere(pr.labels, {name: INTERNAL_QA_LABEL}))), (map, pr) => { @@ -431,11 +438,13 @@ class GithubUtils { }); } + // Internal QA PR list if (!_.isEmpty(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); issueBody += '\r\n\r\n\r\n**Internal QA:**'; _.each(internalQAPRMap, (assignees, URL) => { const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `\r\n${_.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'} `; + issueBody += `\r\n${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; issueBody += `${URL}`; issueBody += ` -${assigneeMentions}`; }); diff --git a/.github/actions/javascript/getReleaseBody/index.js b/.github/actions/javascript/getReleaseBody/index.js index e69746d179bc..14779cdcf7ca 100644 --- a/.github/actions/javascript/getReleaseBody/index.js +++ b/.github/actions/javascript/getReleaseBody/index.js @@ -185,6 +185,7 @@ class GithubUtils { labels: issue.labels, PRList: this.getStagingDeployCashPRList(issue), deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), tag, @@ -219,8 +220,7 @@ class GithubUtils { isAccessible: match[4] === 'x', }), ); - const internalQAPRList = this.getStagingDeployCashInternalQA(issue); - return _.sortBy(_.union(PRList, internalQAPRList), 'number'); + return _.sortBy(PRList, 'number'); } /** @@ -283,6 +283,7 @@ class GithubUtils { * @param {Array} [accessiblePRList] - The list of PR URLs which have passed the accessability check. * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. + * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. * @param {Boolean} [isTimingDashboardChecked] * @param {Boolean} [isFirebaseChecked] * @returns {Promise} @@ -294,6 +295,7 @@ class GithubUtils { accessiblePRList = [], deployBlockers = [], resolvedDeployBlockers = [], + resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, ) { @@ -305,6 +307,11 @@ class GithubUtils { ); console.log('Filtering out the following automated pull requests:', automatedPRs); + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], + // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] + // } const internalQAPRMap = _.reduce( _.filter(data, pr => !_.isEmpty(_.findWhere(pr.labels, {name: INTERNAL_QA_LABEL}))), (map, pr) => { @@ -349,11 +356,13 @@ class GithubUtils { }); } + // Internal QA PR list if (!_.isEmpty(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); issueBody += '\r\n\r\n\r\n**Internal QA:**'; _.each(internalQAPRMap, (assignees, URL) => { const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `\r\n${_.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'} `; + issueBody += `\r\n${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; issueBody += `${URL}`; issueBody += ` -${assigneeMentions}`; }); diff --git a/.github/actions/javascript/isPullRequestMergeable/index.js b/.github/actions/javascript/isPullRequestMergeable/index.js index 6f240ac67571..714c0705137b 100644 --- a/.github/actions/javascript/isPullRequestMergeable/index.js +++ b/.github/actions/javascript/isPullRequestMergeable/index.js @@ -217,6 +217,7 @@ class GithubUtils { labels: issue.labels, PRList: this.getStagingDeployCashPRList(issue), deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), tag, @@ -251,8 +252,7 @@ class GithubUtils { isAccessible: match[4] === 'x', }), ); - const internalQAPRList = this.getStagingDeployCashInternalQA(issue); - return _.sortBy(_.union(PRList, internalQAPRList), 'number'); + return _.sortBy(PRList, 'number'); } /** @@ -315,6 +315,7 @@ class GithubUtils { * @param {Array} [accessiblePRList] - The list of PR URLs which have passed the accessability check. * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. + * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. * @param {Boolean} [isTimingDashboardChecked] * @param {Boolean} [isFirebaseChecked] * @returns {Promise} @@ -326,6 +327,7 @@ class GithubUtils { accessiblePRList = [], deployBlockers = [], resolvedDeployBlockers = [], + resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, ) { @@ -337,6 +339,11 @@ class GithubUtils { ); console.log('Filtering out the following automated pull requests:', automatedPRs); + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], + // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] + // } const internalQAPRMap = _.reduce( _.filter(data, pr => !_.isEmpty(_.findWhere(pr.labels, {name: INTERNAL_QA_LABEL}))), (map, pr) => { @@ -381,11 +388,13 @@ class GithubUtils { }); } + // Internal QA PR list if (!_.isEmpty(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); issueBody += '\r\n\r\n\r\n**Internal QA:**'; _.each(internalQAPRMap, (assignees, URL) => { const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `\r\n${_.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'} `; + issueBody += `\r\n${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; issueBody += `${URL}`; issueBody += ` -${assigneeMentions}`; }); diff --git a/.github/actions/javascript/isStagingDeployLocked/index.js b/.github/actions/javascript/isStagingDeployLocked/index.js index 4e6a8ba62535..993b3287c4a2 100644 --- a/.github/actions/javascript/isStagingDeployLocked/index.js +++ b/.github/actions/javascript/isStagingDeployLocked/index.js @@ -149,6 +149,7 @@ class GithubUtils { labels: issue.labels, PRList: this.getStagingDeployCashPRList(issue), deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), tag, @@ -183,8 +184,7 @@ class GithubUtils { isAccessible: match[4] === 'x', }), ); - const internalQAPRList = this.getStagingDeployCashInternalQA(issue); - return _.sortBy(_.union(PRList, internalQAPRList), 'number'); + return _.sortBy(PRList, 'number'); } /** @@ -247,6 +247,7 @@ class GithubUtils { * @param {Array} [accessiblePRList] - The list of PR URLs which have passed the accessability check. * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. + * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. * @param {Boolean} [isTimingDashboardChecked] * @param {Boolean} [isFirebaseChecked] * @returns {Promise} @@ -258,6 +259,7 @@ class GithubUtils { accessiblePRList = [], deployBlockers = [], resolvedDeployBlockers = [], + resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, ) { @@ -269,6 +271,11 @@ class GithubUtils { ); console.log('Filtering out the following automated pull requests:', automatedPRs); + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], + // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] + // } const internalQAPRMap = _.reduce( _.filter(data, pr => !_.isEmpty(_.findWhere(pr.labels, {name: INTERNAL_QA_LABEL}))), (map, pr) => { @@ -313,11 +320,13 @@ class GithubUtils { }); } + // Internal QA PR list if (!_.isEmpty(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); issueBody += '\r\n\r\n\r\n**Internal QA:**'; _.each(internalQAPRMap, (assignees, URL) => { const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `\r\n${_.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'} `; + issueBody += `\r\n${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; issueBody += `${URL}`; issueBody += ` -${assigneeMentions}`; }); diff --git a/.github/actions/javascript/markPullRequestsAsDeployed/index.js b/.github/actions/javascript/markPullRequestsAsDeployed/index.js index 85d5a9495748..45235d928bd1 100644 --- a/.github/actions/javascript/markPullRequestsAsDeployed/index.js +++ b/.github/actions/javascript/markPullRequestsAsDeployed/index.js @@ -318,6 +318,7 @@ class GithubUtils { labels: issue.labels, PRList: this.getStagingDeployCashPRList(issue), deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), tag, @@ -352,8 +353,7 @@ class GithubUtils { isAccessible: match[4] === 'x', }), ); - const internalQAPRList = this.getStagingDeployCashInternalQA(issue); - return _.sortBy(_.union(PRList, internalQAPRList), 'number'); + return _.sortBy(PRList, 'number'); } /** @@ -416,6 +416,7 @@ class GithubUtils { * @param {Array} [accessiblePRList] - The list of PR URLs which have passed the accessability check. * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. + * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. * @param {Boolean} [isTimingDashboardChecked] * @param {Boolean} [isFirebaseChecked] * @returns {Promise} @@ -427,6 +428,7 @@ class GithubUtils { accessiblePRList = [], deployBlockers = [], resolvedDeployBlockers = [], + resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, ) { @@ -438,6 +440,11 @@ class GithubUtils { ); console.log('Filtering out the following automated pull requests:', automatedPRs); + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], + // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] + // } const internalQAPRMap = _.reduce( _.filter(data, pr => !_.isEmpty(_.findWhere(pr.labels, {name: INTERNAL_QA_LABEL}))), (map, pr) => { @@ -482,11 +489,13 @@ class GithubUtils { }); } + // Internal QA PR list if (!_.isEmpty(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); issueBody += '\r\n\r\n\r\n**Internal QA:**'; _.each(internalQAPRMap, (assignees, URL) => { const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `\r\n${_.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'} `; + issueBody += `\r\n${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; issueBody += `${URL}`; issueBody += ` -${assigneeMentions}`; }); diff --git a/.github/actions/javascript/reopenIssueWithComment/index.js b/.github/actions/javascript/reopenIssueWithComment/index.js index 98793c8e1e65..4572d9a8c7da 100644 --- a/.github/actions/javascript/reopenIssueWithComment/index.js +++ b/.github/actions/javascript/reopenIssueWithComment/index.js @@ -160,6 +160,7 @@ class GithubUtils { labels: issue.labels, PRList: this.getStagingDeployCashPRList(issue), deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), tag, @@ -194,8 +195,7 @@ class GithubUtils { isAccessible: match[4] === 'x', }), ); - const internalQAPRList = this.getStagingDeployCashInternalQA(issue); - return _.sortBy(_.union(PRList, internalQAPRList), 'number'); + return _.sortBy(PRList, 'number'); } /** @@ -258,6 +258,7 @@ class GithubUtils { * @param {Array} [accessiblePRList] - The list of PR URLs which have passed the accessability check. * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. + * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. * @param {Boolean} [isTimingDashboardChecked] * @param {Boolean} [isFirebaseChecked] * @returns {Promise} @@ -269,6 +270,7 @@ class GithubUtils { accessiblePRList = [], deployBlockers = [], resolvedDeployBlockers = [], + resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, ) { @@ -280,6 +282,11 @@ class GithubUtils { ); console.log('Filtering out the following automated pull requests:', automatedPRs); + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], + // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] + // } const internalQAPRMap = _.reduce( _.filter(data, pr => !_.isEmpty(_.findWhere(pr.labels, {name: INTERNAL_QA_LABEL}))), (map, pr) => { @@ -324,11 +331,13 @@ class GithubUtils { }); } + // Internal QA PR list if (!_.isEmpty(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); issueBody += '\r\n\r\n\r\n**Internal QA:**'; _.each(internalQAPRMap, (assignees, URL) => { const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `\r\n${_.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'} `; + issueBody += `\r\n${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; issueBody += `${URL}`; issueBody += ` -${assigneeMentions}`; }); diff --git a/.github/actions/javascript/triggerWorkflowAndWait/index.js b/.github/actions/javascript/triggerWorkflowAndWait/index.js index d0b91a87baa9..6dfc1726dffe 100644 --- a/.github/actions/javascript/triggerWorkflowAndWait/index.js +++ b/.github/actions/javascript/triggerWorkflowAndWait/index.js @@ -329,6 +329,7 @@ class GithubUtils { labels: issue.labels, PRList: this.getStagingDeployCashPRList(issue), deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), tag, @@ -363,8 +364,7 @@ class GithubUtils { isAccessible: match[4] === 'x', }), ); - const internalQAPRList = this.getStagingDeployCashInternalQA(issue); - return _.sortBy(_.union(PRList, internalQAPRList), 'number'); + return _.sortBy(PRList, 'number'); } /** @@ -427,6 +427,7 @@ class GithubUtils { * @param {Array} [accessiblePRList] - The list of PR URLs which have passed the accessability check. * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. + * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. * @param {Boolean} [isTimingDashboardChecked] * @param {Boolean} [isFirebaseChecked] * @returns {Promise} @@ -438,6 +439,7 @@ class GithubUtils { accessiblePRList = [], deployBlockers = [], resolvedDeployBlockers = [], + resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, ) { @@ -449,6 +451,11 @@ class GithubUtils { ); console.log('Filtering out the following automated pull requests:', automatedPRs); + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], + // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] + // } const internalQAPRMap = _.reduce( _.filter(data, pr => !_.isEmpty(_.findWhere(pr.labels, {name: INTERNAL_QA_LABEL}))), (map, pr) => { @@ -493,11 +500,13 @@ class GithubUtils { }); } + // Internal QA PR list if (!_.isEmpty(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); issueBody += '\r\n\r\n\r\n**Internal QA:**'; _.each(internalQAPRMap, (assignees, URL) => { const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `\r\n${_.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'} `; + issueBody += `\r\n${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; issueBody += `${URL}`; issueBody += ` -${assigneeMentions}`; }); diff --git a/.github/actions/javascript/verifySignedCommits/index.js b/.github/actions/javascript/verifySignedCommits/index.js index 48ad52700165..a4243f8c2960 100644 --- a/.github/actions/javascript/verifySignedCommits/index.js +++ b/.github/actions/javascript/verifySignedCommits/index.js @@ -149,6 +149,7 @@ class GithubUtils { labels: issue.labels, PRList: this.getStagingDeployCashPRList(issue), deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), tag, @@ -183,8 +184,7 @@ class GithubUtils { isAccessible: match[4] === 'x', }), ); - const internalQAPRList = this.getStagingDeployCashInternalQA(issue); - return _.sortBy(_.union(PRList, internalQAPRList), 'number'); + return _.sortBy(PRList, 'number'); } /** @@ -247,6 +247,7 @@ class GithubUtils { * @param {Array} [accessiblePRList] - The list of PR URLs which have passed the accessability check. * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. + * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. * @param {Boolean} [isTimingDashboardChecked] * @param {Boolean} [isFirebaseChecked] * @returns {Promise} @@ -258,6 +259,7 @@ class GithubUtils { accessiblePRList = [], deployBlockers = [], resolvedDeployBlockers = [], + resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, ) { @@ -269,6 +271,11 @@ class GithubUtils { ); console.log('Filtering out the following automated pull requests:', automatedPRs); + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], + // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] + // } const internalQAPRMap = _.reduce( _.filter(data, pr => !_.isEmpty(_.findWhere(pr.labels, {name: INTERNAL_QA_LABEL}))), (map, pr) => { @@ -313,11 +320,13 @@ class GithubUtils { }); } + // Internal QA PR list if (!_.isEmpty(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); issueBody += '\r\n\r\n\r\n**Internal QA:**'; _.each(internalQAPRMap, (assignees, URL) => { const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `\r\n${_.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'} `; + issueBody += `\r\n${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; issueBody += `${URL}`; issueBody += ` -${assigneeMentions}`; }); diff --git a/.github/libs/GithubUtils.js b/.github/libs/GithubUtils.js index b1b77249baf6..09f84a36a232 100644 --- a/.github/libs/GithubUtils.js +++ b/.github/libs/GithubUtils.js @@ -109,6 +109,7 @@ class GithubUtils { labels: issue.labels, PRList: this.getStagingDeployCashPRList(issue), deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), tag, @@ -143,8 +144,7 @@ class GithubUtils { isAccessible: match[4] === 'x', }), ); - const internalQAPRList = this.getStagingDeployCashInternalQA(issue); - return _.sortBy(_.union(PRList, internalQAPRList), 'number'); + return _.sortBy(PRList, 'number'); } /** @@ -207,6 +207,7 @@ class GithubUtils { * @param {Array} [accessiblePRList] - The list of PR URLs which have passed the accessability check. * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. + * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. * @param {Boolean} [isTimingDashboardChecked] * @param {Boolean} [isFirebaseChecked] * @returns {Promise} @@ -218,6 +219,7 @@ class GithubUtils { accessiblePRList = [], deployBlockers = [], resolvedDeployBlockers = [], + resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, ) { @@ -229,6 +231,11 @@ class GithubUtils { ); console.log('Filtering out the following automated pull requests:', automatedPRs); + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], + // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] + // } const internalQAPRMap = _.reduce( _.filter(data, pr => !_.isEmpty(_.findWhere(pr.labels, {name: INTERNAL_QA_LABEL}))), (map, pr) => { @@ -273,11 +280,13 @@ class GithubUtils { }); } + // Internal QA PR list if (!_.isEmpty(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); issueBody += '\r\n\r\n\r\n**Internal QA:**'; _.each(internalQAPRMap, (assignees, URL) => { const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `\r\n${_.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'} `; + issueBody += `\r\n${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; issueBody += `${URL}`; issueBody += ` -${assigneeMentions}`; }); diff --git a/tests/unit/GithubUtilsTest.js b/tests/unit/GithubUtilsTest.js index a5c8e8a2687f..1c671161d7dd 100644 --- a/tests/unit/GithubUtilsTest.js +++ b/tests/unit/GithubUtilsTest.js @@ -68,6 +68,7 @@ describe('GithubUtils', () => { url: 'https://api.github.com/repos/Andrew-Test-Org/Public-Test-Repo/issues/29', number: 29, deployBlockers: [], + internalQAPRList: [], isTimingDashboardChecked: false, isFirebaseChecked: false, }; @@ -533,7 +534,7 @@ describe('GithubUtils', () => { )); test('Test some verified internalQA PRs', () => ( - githubUtils.generateStagingDeployCashBody(tag, [...basePRList, ...internalQAPRList], [internalQAPRList[0]]) + githubUtils.generateStagingDeployCashBody(tag, [...basePRList, ...internalQAPRList], [], [], [], [], [internalQAPRList[0]]) .then((issueBody) => { expect(issueBody).toBe( `${baseExpectedOutput}`