Deploy to Beta Environment #78
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Deploy to Beta Environment | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| deploy_to_npm: | |
| description: "Deploy to NPM" | |
| type: boolean | |
| default: false | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| id-token: write # allows the JWT to be requested from GitHub's OIDC provider | |
| contents: read # This is required for actions/checkout | |
| pull-requests: read # This is required to get PR information | |
| env: | |
| NODE_OPTIONS: '--no-warnings' | |
| jobs: | |
| validate-actor: | |
| # Allow only to run from branches and not tags | |
| if: ${{ startsWith(github.ref, 'refs/heads/') }} | |
| uses: ./.github/workflows/validate-actor.yml | |
| with: | |
| team_names: 'js-sdk,integrations' | |
| secrets: | |
| PAT: ${{ secrets.PAT }} | |
| get-deploy-inputs: | |
| name: Get Deploy Inputs | |
| needs: validate-actor | |
| runs-on: [self-hosted, Linux, X64] | |
| outputs: | |
| version_suffix: ${{ steps.deploy-inputs.outputs.version_suffix }} | |
| beta_identifier: ${{ steps.deploy-inputs.outputs.beta_identifier }} | |
| beta_identifier_for_automation_tests: ${{ steps.deploy-inputs.outputs.beta_identifier_for_automation_tests }} | |
| trigger_source: ${{ format('Triggered via PR <{0}|#{1}> by <{2}|{3}>', steps.pr-info.outputs.pr_url, steps.pr-info.outputs.pr_number, format('{0}/{1}', github.server_url, github.actor), github.actor) }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Find PR for current branch | |
| id: pr-info | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| const branch = context.ref.replace('refs/heads/', ''); | |
| console.log(`Finding PRs for branch: ${branch}`); | |
| const { data: pullRequests } = await github.rest.pulls.list({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| head: `${context.repo.owner}:${branch}`, | |
| base: 'develop', | |
| state: 'open' | |
| }); | |
| if (pullRequests.length > 0) { | |
| const pr = pullRequests[0]; | |
| const prNumber = pr.number.toString(); | |
| const prUrl = pr.html_url; | |
| console.log(`Found PR #${prNumber} for branch ${branch}: https://github.com/${context.repo.owner}/${context.repo.repo}/pull/${prNumber}`); | |
| // Check if PR is in draft state | |
| if (pr.draft) { | |
| core.setFailed(`PR #${prNumber} is in draft state. Please mark it as ready for review before deploying.`); | |
| return; | |
| } | |
| // Get detailed PR information including mergeable state | |
| const { data: prDetails } = await github.rest.pulls.get({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: prNumber | |
| }); | |
| // Check if PR is mergeable and all requirements are satisfied | |
| if (prDetails.mergeable === false) { | |
| core.setFailed(`PR #${prNumber} is not in a mergeable state. Please resolve conflicts before deploying.`); | |
| return; | |
| } | |
| // The mergeable_state can be one of: clean, dirty, blocked, unstable, or unknown | |
| // Only 'clean' means all requirements are met (checks passed, approvals received, no conflicts) | |
| if (prDetails.mergeable_state !== 'clean') { | |
| // Get more details about why it's not clean | |
| let reason = ''; | |
| if (prDetails.mergeable_state === 'blocked') { | |
| reason = 'required checks or approvals are missing'; | |
| } else if (prDetails.mergeable_state === 'dirty') { | |
| reason = 'there are merge conflicts'; | |
| } else if (prDetails.mergeable_state === 'unstable') { | |
| reason = 'required checks are failing'; | |
| } else { | |
| reason = `the mergeable state is "${prDetails.mergeable_state}"`; | |
| } | |
| core.setFailed(`PR #${prNumber} is not ready to merge: ${reason}. Please resolve all issues before deploying.`); | |
| return; | |
| } | |
| console.log(`PR #${prNumber} is in a clean mergeable state. All requirements satisfied. Proceeding with beta deployment.`); | |
| core.setOutput('pr_number', prNumber); | |
| core.setOutput('pr_url', prUrl); | |
| } else { | |
| core.setFailed(`No open PR found for branch ${branch} targeting develop branch`); | |
| core.setOutput('pr_number', ''); | |
| } | |
| - name: Extract deploy inputs | |
| id: deploy-inputs | |
| shell: bash | |
| run: | | |
| # Suffix the short commit hash with the PR number | |
| SHA_SHORT=$(echo ${{ github.sha }} | cut -c1-7) | |
| # The version_suffix is structured as "beta.pr.<PR_NUMBER>.<SHORT_COMMIT_HASH>". | |
| # - "beta.pr." is a fixed prefix indicating a beta release for a pull request. | |
| # - <PR_NUMBER> is the number of the pull request associated with the branch. | |
| # - <SHORT_COMMIT_HASH> is the first 7 characters of the commit hash for traceability. | |
| echo "version_suffix=beta.pr.${{ steps.pr-info.outputs.pr_number }}.$SHA_SHORT" >> $GITHUB_OUTPUT | |
| echo "beta_identifier=PR-${{ steps.pr-info.outputs.pr_number }}/$SHA_SHORT" >> $GITHUB_OUTPUT | |
| echo "beta_identifier_for_automation_tests=pr-${{ steps.pr-info.outputs.pr_number }}-$SHA_SHORT" >> $GITHUB_OUTPUT | |
| deploy-cdn: | |
| name: Deploy to CDN | |
| uses: ./.github/workflows/deploy.yml | |
| needs: get-deploy-inputs | |
| with: | |
| environment: beta | |
| bugsnag_release_stage: beta | |
| s3_dir_path: beta/${{ needs.get-deploy-inputs.outputs.beta_identifier }}/v3 | |
| s3_dir_path_legacy: beta/${{ needs.get-deploy-inputs.outputs.beta_identifier }}/v1.1 | |
| version_suffix: ${{ needs.get-deploy-inputs.outputs.version_suffix }} | |
| trigger_source: ${{ needs.get-deploy-inputs.outputs.trigger_source }} | |
| secrets: | |
| AWS_ACCOUNT_ID: ${{ secrets.AWS_PROD_ACCOUNT_ID }} | |
| AWS_S3_BUCKET_NAME: ${{ secrets.AWS_PROD_S3_BUCKET_NAME }} | |
| AWS_S3_SYNC_ROLE: ${{ secrets.AWS_PROD_S3_SYNC_ROLE }} | |
| AWS_CF_DISTRIBUTION_ID: ${{ secrets.AWS_PROD_CF_DISTRIBUTION_ID }} | |
| BUGSNAG_API_KEY: ${{ secrets.RS_PROD_BUGSNAG_API_KEY }} | |
| SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} | |
| SLACK_RELEASE_CHANNEL_ID: ${{ secrets.SLACK_RELEASE_CHANNEL_ID_NON_PROD }} | |
| deploy-npm: | |
| name: Deploy to NPM | |
| uses: ./.github/workflows/deploy-npm.yml | |
| needs: get-deploy-inputs | |
| if: ${{ inputs.deploy_to_npm }} | |
| with: | |
| environment: beta | |
| bugsnag_release_stage: beta | |
| version_suffix: ${{ needs.get-deploy-inputs.outputs.version_suffix }} | |
| base_version: develop | |
| head_version: ${{ github.ref_name }} | |
| trigger_source: ${{ needs.get-deploy-inputs.outputs.trigger_source }} | |
| secrets: | |
| RS_PROD_BUGSNAG_API_KEY: ${{ secrets.RS_PROD_BUGSNAG_API_KEY }} | |
| NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} | |
| SLACK_RELEASE_CHANNEL_ID: ${{ secrets.SLACK_RELEASE_CHANNEL_ID_NON_PROD }} | |
| deploy-sanity-suite: | |
| name: Deploy sanity suite | |
| needs: [get-deploy-inputs] | |
| uses: ./.github/workflows/deploy-sanity-suite.yml | |
| with: | |
| environment: 'beta' | |
| beta_identifier: ${{ needs.get-deploy-inputs.outputs.beta_identifier }} | |
| trigger_source: ${{ needs.get-deploy-inputs.outputs.trigger_source }} | |
| secrets: | |
| AWS_ACCOUNT_ID: ${{ secrets.AWS_PROD_ACCOUNT_ID }} | |
| AWS_S3_BUCKET_NAME: ${{ secrets.AWS_PROD_S3_BUCKET_NAME }} | |
| AWS_S3_SYNC_ROLE: ${{ secrets.AWS_PROD_S3_SYNC_ROLE }} | |
| AWS_CF_DISTRIBUTION_ID: ${{ secrets.AWS_PROD_CF_DISTRIBUTION_ID }} | |
| SANITY_SUITE_WRITE_KEY: ${{ secrets.SANITY_SUITE_PROD_WRITE_KEY }} | |
| SANITY_SUITE_DATAPLANE_URL: ${{ secrets.SANITY_SUITE_PROD_DATAPLANE_URL }} | |
| SANITY_SUITE_CONFIG_SERVER_HOST: ${{ secrets.SANITY_SUITE_PROD_CONFIG_SERVER_HOST }} | |
| BUGSNAG_API_KEY: ${{ secrets.RS_PROD_BUGSNAG_API_KEY }} | |
| SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} | |
| SLACK_RELEASE_CHANNEL_ID: ${{ secrets.SLACK_RELEASE_CHANNEL_ID_NON_PROD }} | |
| run-e2e-regression-test-suites: | |
| uses: ./.github/workflows/run-e2e-regression-test-suites.yml | |
| name: Run E2E Regression Test Suites | |
| needs: [get-deploy-inputs, deploy-sanity-suite, deploy-cdn] | |
| with: | |
| environment: beta | |
| sanity_test_suite_url: https://cdn.rudderlabs.com/sanity-suite/beta/${{ needs.get-deploy-inputs.outputs.beta_identifier }} | |
| build_source_id: ${{ needs.get-deploy-inputs.outputs.beta_identifier_for_automation_tests }} | |
| trigger_source: ${{ needs.get-deploy-inputs.outputs.trigger_source }} | |
| secrets: | |
| PAT: ${{ secrets.PAT }} |