diff --git a/.github/workflows/rollback-web.yml b/.github/workflows/rollback-web.yml new file mode 100644 index 00000000000..7f904af79e2 --- /dev/null +++ b/.github/workflows/rollback-web.yml @@ -0,0 +1,304 @@ +name: Rollback Web Vault + +run-name: 'Rollback ${{ inputs.environment }} web to v${{ inputs.release_version }}' + +on: + workflow_dispatch: + inputs: + release_version: + description: 'Version to rollback to (e.g., 2024.11.0)' + required: true + type: string + environment: + description: 'Target environment' + required: true + type: choice + options: + - USPROD + - EUPROD + - USQA + - EUQA + jira_card: + description: 'Jira card key (e.g., WEB-123)' + required: false + type: string + +jobs: + rollback-web: + name: Rollback Web Vault for ${{ inputs.environment }} + runs-on: ubuntu-24.04 + permissions: + contents: read + pull-requests: write + id-token: write + env: + _RELEASE_VERSION: ${{ inputs.release_version }} + _ENVIRONMENT: ${{ inputs.environment }} + _DEPLOYMENT_TYPE: web + _JIRA_CARD: ${{ inputs.jira_card }} + + steps: + - name: Display rollback parameters + run: | + echo "===========================================================" + echo "WEB ROLLBACK PREPARATION" + echo "===========================================================" + echo "" + echo "Parameters:" + echo " Release Version: ${_RELEASE_VERSION}" + echo " Environment: ${_ENVIRONMENT}" + echo " Deployment Type: ${_DEPLOYMENT_TYPE}" + echo " Jira Card: ${_JIRA_CARD}" + echo "" + + - name: Check for existing rollback PR + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + echo "Checking for existing rollback PR..." + echo "Search query: Rollback ${_ENVIRONMENT} to v${_RELEASE_VERSION}" + echo "" + + # Search for PRs with matching title (checks both open and closed) + EXISTING_PRS=$(gh pr list \ + --repo ${{ github.repository }} \ + --state all \ + --search "Rollback ${_ENVIRONMENT} to v${_RELEASE_VERSION}" \ + --json number,state,url \ + --jq 'length') + + if [ "$EXISTING_PRS" -gt 0 ]; then + echo "ERROR: Rollback PR already exists for ${_ENVIRONMENT} v${_RELEASE_VERSION}" + echo "" + echo "Existing PR(s):" + gh pr list \ + --repo ${{ github.repository }} \ + --state all \ + --search "Rollback ${_ENVIRONMENT} to v${_RELEASE_VERSION}" \ + --json number,state,url,title \ + --jq '.[] | " PR #\(.number) (\(.state)): \(.url)"' + echo "" + echo "This is a duplicate. Please check the existing PR above." + exit 1 + fi + + echo "No existing rollback PR found - proceeding with rollback" + echo "" + + - name: Trigger deploy-web workflow for rollback + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + id: trigger_deploy + with: + script: | + const environment = process.env._ENVIRONMENT; + const releaseVersion = process.env._RELEASE_VERSION; + const jiraCard = process.env._JIRA_CARD; + + // Construct the web release tag + const webTag = `web-v${releaseVersion}`; + + core.info(`Triggering deploy-web workflow to rollback ${environment} to ${webTag}`); + + // Trigger deploy-web workflow with the rollback version tag + const response = await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: 'deploy-web.yml', + ref: 'main', + inputs: { + environment: environment, + 'branch-or-tag': webTag, + 'force-delete-destination': 'false', + debug: 'true' + } + }); + + core.info(`Deploy workflow triggered for rollback to ${webTag}`); + core.setOutput('web_tag', webTag); + + - name: Create rollback tracking PR + id: create_pr + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + script: | + const environment = process.env._ENVIRONMENT; + const releaseVersion = process.env._RELEASE_VERSION; + const deploymentType = process.env._DEPLOYMENT_TYPE; + const jiraCard = process.env._JIRA_CARD; + const webTag = `web-v${releaseVersion}`; + + const title = `Rollback ${environment} to v${releaseVersion}`; + + const body = `## Rollback Request + + **Environment:** ${environment} + **Target Version:** v${releaseVersion} + **Deployment Type:** ${deploymentType} + **Web Tag:** ${webTag} + ${jiraCard ? `**Jira Card:** ${jiraCard}` : ''} + + --- + + ## Rollback Process + + This PR tracks the rollback of Web Vault to version ${releaseVersion}. + + The \`deploy-web.yml\` workflow has been triggered to redeploy tag \`${webTag}\` to ${environment}. + + ## Review Checklist + + - [ ] Verify the deploy-web workflow completed successfully + - [ ] Confirm ${environment} is serving the correct version + - [ ] Verify application health post-rollback + - [ ] Update Jira card status + + ## What Happens After Merge + + This is a tracking PR only. The actual rollback deployment is performed by the \`deploy-web.yml\` workflow. + Merging this PR simply closes the rollback tracking issue. + + --- + + **Automated rollback PR created by delivery-automation-service** + `; + + // Create a branch for the tracking PR + const branchName = `rollback/${environment.toLowerCase()}-v${releaseVersion}`.replace(/ /g, '-'); + + // Get the default branch ref + const { data: ref } = await github.rest.git.getRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: 'heads/main' + }); + + // Create new branch + await github.rest.git.createRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: `refs/heads/${branchName}`, + sha: ref.object.sha + }); + + // Create PR + const { data: pr } = await github.rest.pulls.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: title, + body: body, + head: branchName, + base: 'main' + }); + + core.info(`Tracking PR created: ${pr.html_url}`); + core.setOutput('pr_number', pr.number); + core.setOutput('pr_url', pr.html_url); + + // Add automated-rollback label + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + labels: ['automated-rollback'] + }); + + core.info('Added automated-rollback label to PR'); + + - name: Azure Login + uses: bitwarden/gh-actions/azure-login@main + with: + subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + tenant_id: ${{ secrets.AZURE_TENANT_ID }} + client_id: ${{ secrets.AZURE_CLIENT_ID }} + + - name: Get Slack webhook from Key Vault + id: get-kv-secrets + uses: bitwarden/gh-actions/get-keyvault-secrets@main + with: + keyvault: gh-org-bitwarden + secrets: "SLACK-WEBHOOK-BRE-ALERTS" + + - name: Log out from Azure + uses: bitwarden/gh-actions/azure-logout@main + + - name: Post rollback notification to Slack + uses: slackapi/slack-github-action@37ebaef184d7626c5f204ab8d3baff4262dd30f0 # v2.0.0 + env: + SLACK_WEBHOOK_URL: ${{ steps.get-kv-secrets.outputs.SLACK-WEBHOOK-BRE-ALERTS }} + _PR_URL: ${{ steps.create_pr.outputs.pr_url }} + _PR_NUMBER: ${{ steps.create_pr.outputs.pr_number }} + _WEB_TAG: ${{ steps.trigger_deploy.outputs.web_tag }} + with: + webhook-type: incoming-webhook + payload: | + { + "text": "Web Rollback Initiated", + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "Web Rollback Initiated" + } + }, + { + "type": "section", + "fields": [ + { + "type": "mrkdwn", + "text": "*Environment:*\n${{ env._ENVIRONMENT }}" + }, + { + "type": "mrkdwn", + "text": "*Target Version:*\nv${{ env._RELEASE_VERSION }}" + }, + { + "type": "mrkdwn", + "text": "*Deployment Type:*\n${{ env._DEPLOYMENT_TYPE }}" + }, + { + "type": "mrkdwn", + "text": "*Web Tag:*\n${_WEB_TAG}" + }${{ env._JIRA_CARD && format(',{{"type":"mrkdwn","text":"*Jira Card:*\\n"}}', env._JIRA_CARD) || '' }} + ] + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "The deploy-web workflow has been triggered to redeploy version v${{ env._RELEASE_VERSION }}.\n\n<${_PR_URL}|View Tracking PR #${_PR_NUMBER}>" + } + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "Next steps: Monitor the deploy-web workflow and verify application health post-deployment." + } + ] + } + ] + } + + - name: Rollback initiated + env: + _PR_URL: ${{ steps.create_pr.outputs.pr_url }} + _WEB_TAG: ${{ steps.trigger_deploy.outputs.web_tag }} + run: | + echo "===========================================================" + echo "WEB ROLLBACK INITIATED" + echo "===========================================================" + echo "" + echo "Summary:" + echo " - Environment: ${_ENVIRONMENT}" + echo " - Target Version: v${_RELEASE_VERSION}" + echo " - Web Tag: ${_WEB_TAG}" + echo " - Tracking PR: ${_PR_URL}" + echo "" + echo "Next steps:" + echo " 1. Monitor the deploy-web workflow" + echo " 2. Verify ${_ENVIRONMENT} is serving v${_RELEASE_VERSION}" + echo " 3. Confirm application health" + echo " 4. Update Jira card status" + echo ""