diff --git a/.github/workflows/preDeploy.yml b/.github/workflows/preDeploy.yml index 619ef7b3d43b..5c1257b85f41 100644 --- a/.github/workflows/preDeploy.yml +++ b/.github/workflows/preDeploy.yml @@ -38,9 +38,9 @@ jobs: needs: confirmPassingBuild outputs: MERGED_PR: ${{ steps.getMergedPullRequest.outputs.number }} - IS_AUTOMATED_PR: ${{ steps.isAutomatedPullRequest.outputs.IS_AUTOMATED_PR }} - SHOULD_DEPLOY: ${{ steps.shouldDeploy.outputs.SHOULD_DEPLOY }} - SHOULD_CP: ${{ steps.isStagingDeployLocked.outputs.IS_LOCKED && steps.hasCherryPickLabel.outputs.HAS_CP_LABEL }} + IS_AUTOMATED_PR: ${{ fromJSON(steps.isAutomatedPullRequest.outputs.IS_AUTOMATED_PR) }} + SHOULD_DEPLOY: ${{ fromJSON(steps.shouldDeploy.outputs.SHOULD_DEPLOY) }} + SHOULD_CP: ${{ fromJSON(steps.isStagingDeployLocked.outputs.IS_LOCKED) && fromJSON(steps.hasCherryPickLabel.outputs.HAS_CP_LABEL) }} steps: - name: Get merged pull request @@ -85,8 +85,11 @@ jobs: needs: chooseDeployActions if: ${{ fromJSON(needs.chooseDeployActions.outputs.SHOULD_DEPLOY) }} secrets: inherit + outputs: + NEW_VERSION: ${{ steps.createNewVersion.outputs.NEW_VERSION }} steps: - name: Create new version + id: createNewVersion uses: Expensify/App/.github/workflows/createNewVersion.yml@main updateStaging: diff --git a/workflow_tests/assertions/preDeployAssertions.js b/workflow_tests/assertions/preDeployAssertions.js index 2de86d0dcb5b..4ba684d0982c 100644 --- a/workflow_tests/assertions/preDeployAssertions.js +++ b/workflow_tests/assertions/preDeployAssertions.js @@ -360,7 +360,7 @@ const assertCreateNewVersionJobExecuted = (workflowResult, didExecute = true) => } }; -const assertUpdateStagingJobExecuted = (workflowResult, didExecute = true) => { +const assertUpdateStagingJobExecuted = (workflowResult, didExecute = true, shouldCp = false) => { const steps = [ utils.getStepAssertion( 'Run turnstyle', @@ -370,19 +370,38 @@ const assertUpdateStagingJobExecuted = (workflowResult, didExecute = true) => { 'Running turnstyle', [{key: 'poll-interval-seconds', value: '10'}, {key: 'GITHUB_TOKEN', value: '***'}], ), - utils.getStepAssertion( - 'Cherry-pick PR to staging', - true, - null, - 'UPDATE_STAGING', - 'Cherry picking', - ), + ]; + if (shouldCp) { + steps.push( + utils.getStepAssertion( + 'Cherry-pick PR to staging', + true, + null, + 'UPDATE_STAGING', + 'Cherry picking', + [{key: 'GITHUB_TOKEN', value: '***'}, {key: 'WORKFLOW', value: 'cherryPick.yml'}, {key: 'INPUTS', value: '{ PULL_REQUEST_NUMBER: 123, NEW_VERSION: 1.2.3 }'}], + ), + ); + } else { + steps.push( + utils.getStepAssertion( + 'Update staging branch from main', + true, + null, + 'UPDATE_STAGING', + 'Updating staging branch', + [{key: 'TARGET_BRANCH', value: 'staging'}, {key: 'OS_BOTIFY_TOKEN', value: '***'}, {key: 'GPG_PASSPHRASE', value: '***'}], + ), + ); + } + steps.push( utils.getStepAssertion( 'Checkout staging', true, null, 'UPDATE_STAGING', 'Checking out staging', + [{key: 'ref', value: 'staging'}, {key: 'fetch-depth', value: '0'}], ), utils.getStepAssertion( 'Tag staging', @@ -397,6 +416,7 @@ const assertUpdateStagingJobExecuted = (workflowResult, didExecute = true) => { null, 'UPDATE_STAGING', 'Updating StagingDeployCash', + [{key: 'GITHUB_TOKEN', value: '***'}, {key: 'NPM_VERSION', value: '1.2.3'}], ), utils.getStepAssertion( 'Find open StagingDeployCash', @@ -404,29 +424,40 @@ const assertUpdateStagingJobExecuted = (workflowResult, didExecute = true) => { null, 'UPDATE_STAGING', 'Finding open StagingDeployCash', - ), - utils.getStepAssertion( - 'Comment in StagingDeployCash to alert Applause that a new pull request has been cherry-picked', - true, null, - 'UPDATE_STAGING', - 'Commenting in StagingDeployCash', - ), - utils.getStepAssertion( - 'Wait for staging deploys to finish', - true, - null, - 'UPDATE_STAGING', - 'Waiting for staging deploy to finish', - ), - utils.getStepAssertion( - 'Comment in StagingDeployCash to alert Applause that cherry-picked pull request has been deployed.', - true, - null, - 'UPDATE_STAGING', - 'Commenting in StagingDeployCash', + [{key: 'GITHUB_TOKEN', value: '***'}], ), - ]; + ); + if (shouldCp) { + steps.push( + utils.getStepAssertion( + 'Comment in StagingDeployCash to alert Applause that a new pull request has been cherry-picked', + true, + null, + 'UPDATE_STAGING', + 'Commenting in StagingDeployCash', + null, + [{key: 'GITHUB_TOKEN', value: '***'}], + ), + utils.getStepAssertion( + 'Wait for staging deploys to finish', + true, + null, + 'UPDATE_STAGING', + 'Waiting for staging deploy to finish', + [{key: 'GITHUB_TOKEN', value: '***'}, {key: 'TAG', value: '1.2.3'}], + ), + utils.getStepAssertion( + 'Comment in StagingDeployCash to alert Applause that cherry-picked pull request has been deployed.', + true, + null, + 'UPDATE_STAGING', + 'Commenting in StagingDeployCash', + null, + [{key: 'GITHUB_TOKEN', value: '***'}], + ), + ); + } if (didExecute) { expect(workflowResult).toEqual(expect.arrayContaining(steps)); } else { diff --git a/workflow_tests/mocks/preDeployMocks.js b/workflow_tests/mocks/preDeployMocks.js index f96f190fd42f..1c42607523cf 100644 --- a/workflow_tests/mocks/preDeployMocks.js +++ b/workflow_tests/mocks/preDeployMocks.js @@ -34,7 +34,7 @@ const CONFIRM_PASSING_BUILD_JOB_MOCK_STEPS = [ ]; // choose_deploy_actions -const GET_MERGED_PULL_REQUEST_MOCK_STEP__CHOOSE_DEPLOY = utils.getMockStep( +const GET_MERGED_PULL_REQUEST_MOCK_STEP__CHOOSE_DEPLOY__CP_LABEL = utils.getMockStep( 'Get merged pull request', 'Getting merged pull request', 'CHOOSE_DEPLOY_ACTIONS', @@ -42,17 +42,51 @@ const GET_MERGED_PULL_REQUEST_MOCK_STEP__CHOOSE_DEPLOY = utils.getMockStep( null, {number: '123', labels: '[\'CP Staging\']'}, ); -const CHECK_IF_STAGINGDEPLOYCASH_IS_LOCKED_MOCK_STEP = utils.getMockStep( +const GET_MERGED_PULL_REQUEST_MOCK_STEP__CHOOSE_DEPLOY = utils.getMockStep( + 'Get merged pull request', + 'Getting merged pull request', + 'CHOOSE_DEPLOY_ACTIONS', + ['github_token'], + null, + {number: '123', labels: '[]'}, +); +const CHECK_IF_STAGINGDEPLOYCASH_IS_LOCKED_MOCK_STEP__LOCKED = utils.getMockStep( 'Check if StagingDeployCash is locked', 'Checking StagingDeployCash', 'CHOOSE_DEPLOY_ACTIONS', ['GITHUB_TOKEN'], null, - {IS_LOCKED: 'true'}, + {IS_LOCKED: true}, ); -const CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS = [ +const CHECK_IF_STAGINGDEPLOYCASH_IS_LOCKED_MOCK_STEP__UNLOCKED = utils.getMockStep( + 'Check if StagingDeployCash is locked', + 'Checking StagingDeployCash', + 'CHOOSE_DEPLOY_ACTIONS', + ['GITHUB_TOKEN'], + null, + {IS_LOCKED: false}, +); +const CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__STAGING_LOCKED = [ + GET_MERGED_PULL_REQUEST_MOCK_STEP__CHOOSE_DEPLOY, + CHECK_IF_STAGINGDEPLOYCASH_IS_LOCKED_MOCK_STEP__LOCKED, + + // steps 3-5 run normally +]; +const CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__CP_LABEL__STAGING_LOCKED = [ + GET_MERGED_PULL_REQUEST_MOCK_STEP__CHOOSE_DEPLOY__CP_LABEL, + CHECK_IF_STAGINGDEPLOYCASH_IS_LOCKED_MOCK_STEP__LOCKED, + + // steps 3-5 run normally +]; +const CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__STAGING_UNLOCKED = [ GET_MERGED_PULL_REQUEST_MOCK_STEP__CHOOSE_DEPLOY, - CHECK_IF_STAGINGDEPLOYCASH_IS_LOCKED_MOCK_STEP, + CHECK_IF_STAGINGDEPLOYCASH_IS_LOCKED_MOCK_STEP__UNLOCKED, + + // steps 3-5 run normally +]; +const CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__CP_LABEL__STAGING_UNLOCKED = [ + GET_MERGED_PULL_REQUEST_MOCK_STEP__CHOOSE_DEPLOY__CP_LABEL, + CHECK_IF_STAGINGDEPLOYCASH_IS_LOCKED_MOCK_STEP__UNLOCKED, // steps 3-5 run normally ]; @@ -73,6 +107,9 @@ const CREATE_NEW_VERSION_MOCK_STEP = utils.getMockStep( 'Create new version', 'Creating new version', 'CREATE_NEW_VERSION', + null, + null, + {NEW_VERSION: '1.2.3'}, ); const CREATE_NEW_VERSION_JOB_MOCK_STEPS = [ CREATE_NEW_VERSION_MOCK_STEP, @@ -90,16 +127,19 @@ const UPDATE_STAGING_BRANCH_MOCK_STEP = utils.getMockStep( 'Update staging branch from main', 'Updating staging branch', 'UPDATE_STAGING', + ['TARGET_BRANCH', 'OS_BOTIFY_TOKEN', 'GPG_PASSPHRASE'], ); const CHERRYPICK_PR_MOCK_STEP = utils.getMockStep( 'Cherry-pick PR to staging', 'Cherry picking', 'UPDATE_STAGING', + ['GITHUB_TOKEN', 'WORKFLOW', 'INPUTS'], ); const CHECKOUT_STAGING_MOCK_STEP = utils.getMockStep( 'Checkout staging', 'Checking out staging', 'UPDATE_STAGING', + ['ref', 'fetch-depth'], ); const TAG_STAGING_MOCK_STEP = utils.getMockStep( 'Tag staging', @@ -110,29 +150,35 @@ const UPDATE_STAGINGDEPLOYCASH_MOCK_STEP = utils.getMockStep( 'Update StagingDeployCash', 'Updating StagingDeployCash', 'UPDATE_STAGING', + ['GITHUB_TOKEN', 'NPM_VERSION'], ); const FIND_OPEN_STAGINGDEPLOYCASH_MOCK_STEP = utils.getMockStep( 'Find open StagingDeployCash', 'Finding open StagingDeployCash', 'UPDATE_STAGING', null, - null, + ['GITHUB_TOKEN'], {STAGING_DEPLOY_CASH: '1234'}, ); const COMMENT_TO_ALERT_APPLAUSE_CHERRYPICK_MOCK_STEP = utils.getMockStep( 'Comment in StagingDeployCash to alert Applause that a new pull request has been cherry-picked', 'Commenting in StagingDeployCash', 'UPDATE_STAGING', + null, + ['GITHUB_TOKEN'], ); const WAIT_FOR_STAGING_DEPLOYS_MOCK_STEP = utils.getMockStep( 'Wait for staging deploys to finish', 'Waiting for staging deploy to finish', 'UPDATE_STAGING', + ['GITHUB_TOKEN', 'TAG'], ); const COMMENT_TO_ALERT_APPLAUSE_DEPLOY_MOCK_STEP = utils.getMockStep( 'Comment in StagingDeployCash to alert Applause that cherry-picked pull request has been deployed.', 'Commenting in StagingDeployCash', 'UPDATE_STAGING', + null, + ['GITHUB_TOKEN'], ); const ANNOUNCE_FAILED_WORKFLOW_IN_SLACK_MOCK_STEP = utils.getMockStep( 'Announce failed workflow in Slack', @@ -168,7 +214,7 @@ const CHECK_TEAM_MEMBERSHIP_MOCK_STEP__TRUE = utils.getMockStep( 'IS_EXPENSIFY_EMPLOYEE', ['GITHUB_TOKEN', 'username', 'team'], null, - {isTeamMember: 'true'}, + {isTeamMember: true}, ); const IS_EXPENSIFY_EMPLOYEE_JOB_MOCK_STEPS__TRUE = [ GET_MERGED_PULL_REQUEST_MOCK_STEP__IS_EXPENSIFY_EMPLOYEE, @@ -180,7 +226,7 @@ const CHECK_TEAM_MEMBERSHIP_MOCK_STEP__FALSE = utils.getMockStep( 'IS_EXPENSIFY_EMPLOYEE', ['GITHUB_TOKEN', 'username', 'team'], null, - {isTeamMember: 'false'}, + {isTeamMember: false}, ); const IS_EXPENSIFY_EMPLOYEE_JOB_MOCK_STEPS__FALSE = [ GET_MERGED_PULL_REQUEST_MOCK_STEP__IS_EXPENSIFY_EMPLOYEE, @@ -411,7 +457,10 @@ module.exports = { LINT_JOB_MOCK_STEPS, TEST_JOB_MOCK_STEPS, CONFIRM_PASSING_BUILD_JOB_MOCK_STEPS, - CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS, + CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__STAGING_LOCKED, + CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__CP_LABEL__STAGING_LOCKED, + CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__STAGING_UNLOCKED, + CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__CP_LABEL__STAGING_UNLOCKED, SKIP_DEPLOY_JOB_MOCK_STEPS, CREATE_NEW_VERSION_JOB_MOCK_STEPS, UPDATE_STAGING_JOB_MOCK_STEPS, diff --git a/workflow_tests/preDeploy.test.js b/workflow_tests/preDeploy.test.js index 3f70ffb8428b..f491832a82b2 100644 --- a/workflow_tests/preDeploy.test.js +++ b/workflow_tests/preDeploy.test.js @@ -66,7 +66,9 @@ describe('test workflow preDeploy', () => { act, 'pull_request', {head: {ref: 'main'}}, - {OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'Dummy Tester', SLACK_WEBHOOK: 'dummy_slack_webhook'}, + { + OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'Dummy Tester', SLACK_WEBHOOK: 'dummy_slack_webhook', LARGE_SECRET_PASSPHRASE: '3xtr3m3ly_s3cr3t_p455word', + }, 'dummy_github_token', ); @@ -75,7 +77,7 @@ describe('test workflow preDeploy', () => { lint: mocks.LINT_JOB_MOCK_STEPS, test: mocks.TEST_JOB_MOCK_STEPS, confirmPassingBuild: mocks.CONFIRM_PASSING_BUILD_JOB_MOCK_STEPS, - chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS, + chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__CP_LABEL__STAGING_UNLOCKED, skipDeploy: mocks.SKIP_DEPLOY_JOB_MOCK_STEPS, createNewVersion: mocks.CREATE_NEW_VERSION_JOB_MOCK_STEPS, updateStaging: mocks.UPDATE_STAGING_JOB_MOCK_STEPS, @@ -112,7 +114,9 @@ describe('test workflow preDeploy', () => { act, 'pull_request', {head: {ref: 'main'}}, - {OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'Dummy Tester', SLACK_WEBHOOK: 'dummy_slack_webhook'}, + { + OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'Dummy Tester', SLACK_WEBHOOK: 'dummy_slack_webhook', LARGE_SECRET_PASSPHRASE: '3xtr3m3ly_s3cr3t_p455word', + }, 'dummy_github_token', ); const testMockSteps = { @@ -130,7 +134,7 @@ describe('test workflow preDeploy', () => { ], test: mocks.TEST_JOB_MOCK_STEPS, confirmPassingBuild: mocks.CONFIRM_PASSING_BUILD_JOB_MOCK_STEPS, - chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS, + chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__CP_LABEL__STAGING_UNLOCKED, skipDeploy: mocks.SKIP_DEPLOY_JOB_MOCK_STEPS, createNewVersion: mocks.CREATE_NEW_VERSION_JOB_MOCK_STEPS, updateStaging: mocks.UPDATE_STAGING_JOB_MOCK_STEPS, @@ -188,7 +192,9 @@ describe('test workflow preDeploy', () => { act, 'pull_request', {head: {ref: 'main'}}, - {OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'Dummy Tester', SLACK_WEBHOOK: 'dummy_slack_webhook'}, + { + OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'Dummy Tester', SLACK_WEBHOOK: 'dummy_slack_webhook', LARGE_SECRET_PASSPHRASE: '3xtr3m3ly_s3cr3t_p455word', + }, 'dummy_github_token', ); const testMockSteps = { @@ -206,7 +212,7 @@ describe('test workflow preDeploy', () => { ), ], confirmPassingBuild: mocks.CONFIRM_PASSING_BUILD_JOB_MOCK_STEPS, - chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS, + chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__CP_LABEL__STAGING_UNLOCKED, skipDeploy: mocks.SKIP_DEPLOY_JOB_MOCK_STEPS, createNewVersion: mocks.CREATE_NEW_VERSION_JOB_MOCK_STEPS, updateStaging: mocks.UPDATE_STAGING_JOB_MOCK_STEPS, @@ -264,14 +270,16 @@ describe('test workflow preDeploy', () => { act, 'pull_request', {head: {ref: 'main'}}, - {OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'Dummy Tester', SLACK_WEBHOOK: 'dummy_slack_webhook'}, + { + OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'Dummy Tester', SLACK_WEBHOOK: 'dummy_slack_webhook', LARGE_SECRET_PASSPHRASE: '3xtr3m3ly_s3cr3t_p455word', + }, 'dummy_github_token', ); const testMockSteps = { lint: mocks.LINT_JOB_MOCK_STEPS, test: mocks.TEST_JOB_MOCK_STEPS, confirmPassingBuild: mocks.CONFIRM_PASSING_BUILD_JOB_MOCK_STEPS, - chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS, + chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__CP_LABEL__STAGING_UNLOCKED, skipDeploy: mocks.SKIP_DEPLOY_JOB_MOCK_STEPS, createNewVersion: mocks.CREATE_NEW_VERSION_JOB_MOCK_STEPS, updateStaging: mocks.UPDATE_STAGING_JOB_MOCK_STEPS, @@ -304,14 +312,16 @@ describe('test workflow preDeploy', () => { act, 'pull_request', {head: {ref: 'main'}}, - {OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'OSBotify', SLACK_WEBHOOK: 'dummy_slack_webhook'}, + { + OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'OSBotify', SLACK_WEBHOOK: 'dummy_slack_webhook', LARGE_SECRET_PASSPHRASE: '3xtr3m3ly_s3cr3t_p455word', + }, 'dummy_github_token', ); const testMockSteps = { lint: mocks.LINT_JOB_MOCK_STEPS, test: mocks.TEST_JOB_MOCK_STEPS, confirmPassingBuild: mocks.CONFIRM_PASSING_BUILD_JOB_MOCK_STEPS, - chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS, + chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__CP_LABEL__STAGING_UNLOCKED, skipDeploy: mocks.SKIP_DEPLOY_JOB_MOCK_STEPS, createNewVersion: mocks.CREATE_NEW_VERSION_JOB_MOCK_STEPS, updateStaging: mocks.UPDATE_STAGING_JOB_MOCK_STEPS, @@ -340,14 +350,16 @@ describe('test workflow preDeploy', () => { act, 'pull_request', {head: {ref: 'main'}}, - {OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'Dummy Tester', SLACK_WEBHOOK: 'dummy_slack_webhook'}, + { + OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'Dummy Tester', SLACK_WEBHOOK: 'dummy_slack_webhook', LARGE_SECRET_PASSPHRASE: '3xtr3m3ly_s3cr3t_p455word', + }, 'dummy_github_token', ); const testMockSteps = { lint: mocks.LINT_JOB_MOCK_STEPS, test: mocks.TEST_JOB_MOCK_STEPS, confirmPassingBuild: mocks.CONFIRM_PASSING_BUILD_JOB_MOCK_STEPS, - chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS, + chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__CP_LABEL__STAGING_UNLOCKED, skipDeploy: mocks.SKIP_DEPLOY_JOB_MOCK_STEPS, createNewVersion: mocks.CREATE_NEW_VERSION_JOB_MOCK_STEPS, updateStaging: mocks.UPDATE_STAGING_JOB_MOCK_STEPS, @@ -376,14 +388,16 @@ describe('test workflow preDeploy', () => { act, 'pull_request', {head: {ref: 'main'}}, - {OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'Dummy Tester', SLACK_WEBHOOK: 'dummy_slack_webhook'}, + { + OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'Dummy Tester', SLACK_WEBHOOK: 'dummy_slack_webhook', LARGE_SECRET_PASSPHRASE: '3xtr3m3ly_s3cr3t_p455word', + }, 'dummy_github_token', ); const testMockSteps = { lint: mocks.LINT_JOB_MOCK_STEPS, test: mocks.TEST_JOB_MOCK_STEPS, confirmPassingBuild: mocks.CONFIRM_PASSING_BUILD_JOB_MOCK_STEPS, - chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS, + chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__CP_LABEL__STAGING_UNLOCKED, skipDeploy: mocks.SKIP_DEPLOY_JOB_MOCK_STEPS, createNewVersion: mocks.CREATE_NEW_VERSION_JOB_MOCK_STEPS, updateStaging: mocks.UPDATE_STAGING_JOB_MOCK_STEPS, @@ -412,14 +426,16 @@ describe('test workflow preDeploy', () => { act, 'pull_request', {head: {ref: 'main'}}, - {OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'Dummy Tester', SLACK_WEBHOOK: 'dummy_slack_webhook'}, + { + OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'Dummy Tester', SLACK_WEBHOOK: 'dummy_slack_webhook', LARGE_SECRET_PASSPHRASE: '3xtr3m3ly_s3cr3t_p455word', + }, 'dummy_github_token', ); const testMockSteps = { lint: mocks.LINT_JOB_MOCK_STEPS, test: mocks.TEST_JOB_MOCK_STEPS, confirmPassingBuild: mocks.CONFIRM_PASSING_BUILD_JOB_MOCK_STEPS, - chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS, + chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__CP_LABEL__STAGING_UNLOCKED, skipDeploy: mocks.SKIP_DEPLOY_JOB_MOCK_STEPS, createNewVersion: mocks.CREATE_NEW_VERSION_JOB_MOCK_STEPS, updateStaging: mocks.UPDATE_STAGING_JOB_MOCK_STEPS, @@ -440,4 +456,320 @@ describe('test workflow preDeploy', () => { assertions.assertNewContributorWelcomeMessageJobExecuted(result, true, false, true); }, 60000); }); + + describe('skip deploy', () => { + test('no CP label, staging locked, not automated PR - deploy skipped and comment left', async () => { + const repoPath = mockGithub.repo.getPath('testWorkflowsRepo') || ''; + const workflowPath = path.join(repoPath, '.github', 'workflows', 'preDeploy.yml'); + let act = new kieActJs.Act(repoPath, workflowPath); + act = utils.setUpActParams( + act, + 'pull_request', + {head: {ref: 'main'}}, + {OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'Dummy Tester', SLACK_WEBHOOK: 'dummy_slack_webhook'}, + 'dummy_github_token', + ); + const testMockSteps = { + lint: mocks.LINT_JOB_MOCK_STEPS, + test: mocks.TEST_JOB_MOCK_STEPS, + confirmPassingBuild: mocks.CONFIRM_PASSING_BUILD_JOB_MOCK_STEPS, + chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__STAGING_LOCKED, + skipDeploy: mocks.SKIP_DEPLOY_JOB_MOCK_STEPS, + createNewVersion: mocks.CREATE_NEW_VERSION_JOB_MOCK_STEPS, + updateStaging: mocks.UPDATE_STAGING_JOB_MOCK_STEPS, + isExpensifyEmployee: mocks.IS_EXPENSIFY_EMPLOYEE_JOB_MOCK_STEPS__TRUE, + newContributorWelcomeMessage: mocks.NEW_CONTRIBUTOR_WELCOME_MESSAGE_JOB_MOCK_STEPS__MANY_PRS, + 'e2e-tests': mocks.E2E_TESTS_JOB_MOCK_STEPS, + }; + const result = await act + .runEvent('push', { + workflowFile: path.join(repoPath, '.github', 'workflows'), + mockSteps: testMockSteps, + }); + assertions.assertLintJobExecuted(result); + assertions.assertTestJobExecuted(result); + assertions.assertIsExpensifyEmployeeJobExecuted(result); + assertions.assertE2ETestsJobExecuted(result, false); // Act does not support ubuntu-20.04-64core runner and omits the job + assertions.assertChooseDeployActionsJobExecuted(result); + assertions.assertSkipDeployJobExecuted(result); + assertions.assertCreateNewVersionJobExecuted(result, false); + assertions.assertUpdateStagingJobExecuted(result, false, false); + }, 60000); + + test('no CP label, staging locked, automated PR - deploy skipped, but no comment left', async () => { + const repoPath = mockGithub.repo.getPath('testWorkflowsRepo') || ''; + const workflowPath = path.join(repoPath, '.github', 'workflows', 'preDeploy.yml'); + let act = new kieActJs.Act(repoPath, workflowPath); + act = utils.setUpActParams( + act, + 'pull_request', + {head: {ref: 'main'}}, + {OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'OSBotify', SLACK_WEBHOOK: 'dummy_slack_webhook'}, + 'dummy_github_token', + ); + const testMockSteps = { + lint: mocks.LINT_JOB_MOCK_STEPS, + test: mocks.TEST_JOB_MOCK_STEPS, + confirmPassingBuild: mocks.CONFIRM_PASSING_BUILD_JOB_MOCK_STEPS, + chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__STAGING_LOCKED, + skipDeploy: mocks.SKIP_DEPLOY_JOB_MOCK_STEPS, + createNewVersion: mocks.CREATE_NEW_VERSION_JOB_MOCK_STEPS, + updateStaging: mocks.UPDATE_STAGING_JOB_MOCK_STEPS, + isExpensifyEmployee: mocks.IS_EXPENSIFY_EMPLOYEE_JOB_MOCK_STEPS__TRUE, + newContributorWelcomeMessage: mocks.NEW_CONTRIBUTOR_WELCOME_MESSAGE_JOB_MOCK_STEPS__MANY_PRS, + 'e2e-tests': mocks.E2E_TESTS_JOB_MOCK_STEPS, + }; + const result = await act + .runEvent('push', { + workflowFile: path.join(repoPath, '.github', 'workflows'), + mockSteps: testMockSteps, + }); + assertions.assertLintJobExecuted(result); + assertions.assertTestJobExecuted(result); + assertions.assertIsExpensifyEmployeeJobExecuted(result); + assertions.assertE2ETestsJobExecuted(result, false); // Act does not support ubuntu-20.04-64core runner and omits the job + assertions.assertChooseDeployActionsJobExecuted(result); + assertions.assertSkipDeployJobExecuted(result, false); + assertions.assertCreateNewVersionJobExecuted(result, false); + assertions.assertUpdateStagingJobExecuted(result, false, false); + }, 60000); + + test('no CP label, staging not locked, not automated PR - proceed with deploy', async () => { + const repoPath = mockGithub.repo.getPath('testWorkflowsRepo') || ''; + const workflowPath = path.join(repoPath, '.github', 'workflows', 'preDeploy.yml'); + let act = new kieActJs.Act(repoPath, workflowPath); + act = utils.setUpActParams( + act, + 'pull_request', + {head: {ref: 'main'}}, + { + OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'Dummy Tester', SLACK_WEBHOOK: 'dummy_slack_webhook', LARGE_SECRET_PASSPHRASE: '3xtr3m3ly_s3cr3t_p455word', + }, + 'dummy_github_token', + ); + const testMockSteps = { + lint: mocks.LINT_JOB_MOCK_STEPS, + test: mocks.TEST_JOB_MOCK_STEPS, + confirmPassingBuild: mocks.CONFIRM_PASSING_BUILD_JOB_MOCK_STEPS, + chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__STAGING_UNLOCKED, + skipDeploy: mocks.SKIP_DEPLOY_JOB_MOCK_STEPS, + createNewVersion: mocks.CREATE_NEW_VERSION_JOB_MOCK_STEPS, + updateStaging: mocks.UPDATE_STAGING_JOB_MOCK_STEPS, + isExpensifyEmployee: mocks.IS_EXPENSIFY_EMPLOYEE_JOB_MOCK_STEPS__TRUE, + newContributorWelcomeMessage: mocks.NEW_CONTRIBUTOR_WELCOME_MESSAGE_JOB_MOCK_STEPS__MANY_PRS, + 'e2e-tests': mocks.E2E_TESTS_JOB_MOCK_STEPS, + }; + const result = await act + .runEvent('push', { + workflowFile: path.join(repoPath, '.github', 'workflows'), + mockSteps: testMockSteps, + }); + assertions.assertLintJobExecuted(result); + assertions.assertTestJobExecuted(result); + assertions.assertIsExpensifyEmployeeJobExecuted(result); + assertions.assertE2ETestsJobExecuted(result, false); // Act does not support ubuntu-20.04-64core runner and omits the job + assertions.assertChooseDeployActionsJobExecuted(result); + assertions.assertSkipDeployJobExecuted(result, false); + assertions.assertCreateNewVersionJobExecuted(result); + assertions.assertUpdateStagingJobExecuted(result, true, false); + }, 60000); + + test('no CP label, staging not locked, automated PR - deploy skipped, but no comment left', async () => { + const repoPath = mockGithub.repo.getPath('testWorkflowsRepo') || ''; + const workflowPath = path.join(repoPath, '.github', 'workflows', 'preDeploy.yml'); + let act = new kieActJs.Act(repoPath, workflowPath); + act = utils.setUpActParams( + act, + 'pull_request', + {head: {ref: 'main'}}, + {OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'OSBotify', SLACK_WEBHOOK: 'dummy_slack_webhook'}, + 'dummy_github_token', + ); + const testMockSteps = { + lint: mocks.LINT_JOB_MOCK_STEPS, + test: mocks.TEST_JOB_MOCK_STEPS, + confirmPassingBuild: mocks.CONFIRM_PASSING_BUILD_JOB_MOCK_STEPS, + chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__STAGING_UNLOCKED, + skipDeploy: mocks.SKIP_DEPLOY_JOB_MOCK_STEPS, + createNewVersion: mocks.CREATE_NEW_VERSION_JOB_MOCK_STEPS, + updateStaging: mocks.UPDATE_STAGING_JOB_MOCK_STEPS, + isExpensifyEmployee: mocks.IS_EXPENSIFY_EMPLOYEE_JOB_MOCK_STEPS__TRUE, + newContributorWelcomeMessage: mocks.NEW_CONTRIBUTOR_WELCOME_MESSAGE_JOB_MOCK_STEPS__MANY_PRS, + 'e2e-tests': mocks.E2E_TESTS_JOB_MOCK_STEPS, + }; + const result = await act + .runEvent('push', { + workflowFile: path.join(repoPath, '.github', 'workflows'), + mockSteps: testMockSteps, + }); + assertions.assertLintJobExecuted(result); + assertions.assertTestJobExecuted(result); + assertions.assertIsExpensifyEmployeeJobExecuted(result); + assertions.assertE2ETestsJobExecuted(result, false); // Act does not support ubuntu-20.04-64core runner and omits the job + assertions.assertChooseDeployActionsJobExecuted(result); + assertions.assertSkipDeployJobExecuted(result, false); + assertions.assertCreateNewVersionJobExecuted(result, false); + assertions.assertUpdateStagingJobExecuted(result, false, false); + }, 60000); + + test('CP label, staging locked, not automated PR - proceed with deploy', async () => { + const repoPath = mockGithub.repo.getPath('testWorkflowsRepo') || ''; + const workflowPath = path.join(repoPath, '.github', 'workflows', 'preDeploy.yml'); + let act = new kieActJs.Act(repoPath, workflowPath); + act = utils.setUpActParams( + act, + 'pull_request', + {head: {ref: 'main'}}, + { + OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'Dummy Tester', SLACK_WEBHOOK: 'dummy_slack_webhook', LARGE_SECRET_PASSPHRASE: '3xtr3m3ly_s3cr3t_p455word', + }, + 'dummy_github_token', + ); + const testMockSteps = { + lint: mocks.LINT_JOB_MOCK_STEPS, + test: mocks.TEST_JOB_MOCK_STEPS, + confirmPassingBuild: mocks.CONFIRM_PASSING_BUILD_JOB_MOCK_STEPS, + chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__CP_LABEL__STAGING_LOCKED, + skipDeploy: mocks.SKIP_DEPLOY_JOB_MOCK_STEPS, + createNewVersion: mocks.CREATE_NEW_VERSION_JOB_MOCK_STEPS, + updateStaging: mocks.UPDATE_STAGING_JOB_MOCK_STEPS, + isExpensifyEmployee: mocks.IS_EXPENSIFY_EMPLOYEE_JOB_MOCK_STEPS__TRUE, + newContributorWelcomeMessage: mocks.NEW_CONTRIBUTOR_WELCOME_MESSAGE_JOB_MOCK_STEPS__MANY_PRS, + 'e2e-tests': mocks.E2E_TESTS_JOB_MOCK_STEPS, + }; + const result = await act + .runEvent('push', { + workflowFile: path.join(repoPath, '.github', 'workflows'), + mockSteps: testMockSteps, + }); + assertions.assertLintJobExecuted(result); + assertions.assertTestJobExecuted(result); + assertions.assertIsExpensifyEmployeeJobExecuted(result); + assertions.assertE2ETestsJobExecuted(result, false); // Act does not support ubuntu-20.04-64core runner and omits the job + assertions.assertChooseDeployActionsJobExecuted(result); + assertions.assertSkipDeployJobExecuted(result, false); + assertions.assertCreateNewVersionJobExecuted(result); + assertions.assertUpdateStagingJobExecuted(result, true, true); + }, 60000); + + test('CP label, staging locked, automated PR - proceed with deploy', async () => { + const repoPath = mockGithub.repo.getPath('testWorkflowsRepo') || ''; + const workflowPath = path.join(repoPath, '.github', 'workflows', 'preDeploy.yml'); + let act = new kieActJs.Act(repoPath, workflowPath); + act = utils.setUpActParams( + act, + 'pull_request', + {head: {ref: 'main'}}, + { + OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'OSBotify', SLACK_WEBHOOK: 'dummy_slack_webhook', LARGE_SECRET_PASSPHRASE: '3xtr3m3ly_s3cr3t_p455word', + }, + 'dummy_github_token', + ); + const testMockSteps = { + lint: mocks.LINT_JOB_MOCK_STEPS, + test: mocks.TEST_JOB_MOCK_STEPS, + confirmPassingBuild: mocks.CONFIRM_PASSING_BUILD_JOB_MOCK_STEPS, + chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__CP_LABEL__STAGING_LOCKED, + skipDeploy: mocks.SKIP_DEPLOY_JOB_MOCK_STEPS, + createNewVersion: mocks.CREATE_NEW_VERSION_JOB_MOCK_STEPS, + updateStaging: mocks.UPDATE_STAGING_JOB_MOCK_STEPS, + isExpensifyEmployee: mocks.IS_EXPENSIFY_EMPLOYEE_JOB_MOCK_STEPS__TRUE, + newContributorWelcomeMessage: mocks.NEW_CONTRIBUTOR_WELCOME_MESSAGE_JOB_MOCK_STEPS__MANY_PRS, + 'e2e-tests': mocks.E2E_TESTS_JOB_MOCK_STEPS, + }; + const result = await act + .runEvent('push', { + workflowFile: path.join(repoPath, '.github', 'workflows'), + mockSteps: testMockSteps, + }); + assertions.assertLintJobExecuted(result); + assertions.assertTestJobExecuted(result); + assertions.assertIsExpensifyEmployeeJobExecuted(result); + assertions.assertE2ETestsJobExecuted(result, false); // Act does not support ubuntu-20.04-64core runner and omits the job + assertions.assertChooseDeployActionsJobExecuted(result); + assertions.assertSkipDeployJobExecuted(result, false); + assertions.assertCreateNewVersionJobExecuted(result); + assertions.assertUpdateStagingJobExecuted(result, true, true); + }, 60000); + + test('CP label, staging not locked, not automated PR - proceed with deploy', async () => { + const repoPath = mockGithub.repo.getPath('testWorkflowsRepo') || ''; + const workflowPath = path.join(repoPath, '.github', 'workflows', 'preDeploy.yml'); + let act = new kieActJs.Act(repoPath, workflowPath); + act = utils.setUpActParams( + act, + 'pull_request', + {head: {ref: 'main'}}, + { + OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'Dummy Tester', SLACK_WEBHOOK: 'dummy_slack_webhook', LARGE_SECRET_PASSPHRASE: '3xtr3m3ly_s3cr3t_p455word', + }, + 'dummy_github_token', + ); + const testMockSteps = { + lint: mocks.LINT_JOB_MOCK_STEPS, + test: mocks.TEST_JOB_MOCK_STEPS, + confirmPassingBuild: mocks.CONFIRM_PASSING_BUILD_JOB_MOCK_STEPS, + chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__CP_LABEL__STAGING_UNLOCKED, + skipDeploy: mocks.SKIP_DEPLOY_JOB_MOCK_STEPS, + createNewVersion: mocks.CREATE_NEW_VERSION_JOB_MOCK_STEPS, + updateStaging: mocks.UPDATE_STAGING_JOB_MOCK_STEPS, + isExpensifyEmployee: mocks.IS_EXPENSIFY_EMPLOYEE_JOB_MOCK_STEPS__TRUE, + newContributorWelcomeMessage: mocks.NEW_CONTRIBUTOR_WELCOME_MESSAGE_JOB_MOCK_STEPS__MANY_PRS, + 'e2e-tests': mocks.E2E_TESTS_JOB_MOCK_STEPS, + }; + const result = await act + .runEvent('push', { + workflowFile: path.join(repoPath, '.github', 'workflows'), + mockSteps: testMockSteps, + }); + assertions.assertLintJobExecuted(result); + assertions.assertTestJobExecuted(result); + assertions.assertIsExpensifyEmployeeJobExecuted(result); + assertions.assertE2ETestsJobExecuted(result, false); // Act does not support ubuntu-20.04-64core runner and omits the job + assertions.assertChooseDeployActionsJobExecuted(result); + assertions.assertSkipDeployJobExecuted(result, false); + assertions.assertCreateNewVersionJobExecuted(result); + assertions.assertUpdateStagingJobExecuted(result, true, false); + }, 60000); + + test('CP label, staging not locked, automated PR - proceed with deploy', async () => { + const repoPath = mockGithub.repo.getPath('testWorkflowsRepo') || ''; + const workflowPath = path.join(repoPath, '.github', 'workflows', 'preDeploy.yml'); + let act = new kieActJs.Act(repoPath, workflowPath); + act = utils.setUpActParams( + act, + 'pull_request', + {head: {ref: 'main'}}, + { + OS_BOTIFY_TOKEN: 'dummy_token', GITHUB_ACTOR: 'OSBotify', SLACK_WEBHOOK: 'dummy_slack_webhook', LARGE_SECRET_PASSPHRASE: '3xtr3m3ly_s3cr3t_p455word', + }, + 'dummy_github_token', + ); + const testMockSteps = { + lint: mocks.LINT_JOB_MOCK_STEPS, + test: mocks.TEST_JOB_MOCK_STEPS, + confirmPassingBuild: mocks.CONFIRM_PASSING_BUILD_JOB_MOCK_STEPS, + chooseDeployActions: mocks.CHOOSE_DEPLOY_ACTIONS_JOB_MOCK_STEPS__CP_LABEL__STAGING_UNLOCKED, + skipDeploy: mocks.SKIP_DEPLOY_JOB_MOCK_STEPS, + createNewVersion: mocks.CREATE_NEW_VERSION_JOB_MOCK_STEPS, + updateStaging: mocks.UPDATE_STAGING_JOB_MOCK_STEPS, + isExpensifyEmployee: mocks.IS_EXPENSIFY_EMPLOYEE_JOB_MOCK_STEPS__TRUE, + newContributorWelcomeMessage: mocks.NEW_CONTRIBUTOR_WELCOME_MESSAGE_JOB_MOCK_STEPS__MANY_PRS, + 'e2e-tests': mocks.E2E_TESTS_JOB_MOCK_STEPS, + }; + const result = await act + .runEvent('push', { + workflowFile: path.join(repoPath, '.github', 'workflows'), + mockSteps: testMockSteps, + }); + assertions.assertLintJobExecuted(result); + assertions.assertTestJobExecuted(result); + assertions.assertIsExpensifyEmployeeJobExecuted(result); + assertions.assertE2ETestsJobExecuted(result, false); // Act does not support ubuntu-20.04-64core runner and omits the job + assertions.assertChooseDeployActionsJobExecuted(result); + assertions.assertSkipDeployJobExecuted(result, false); + assertions.assertCreateNewVersionJobExecuted(result); + assertions.assertUpdateStagingJobExecuted(result, true, false); + }, 60000); + }); });