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 actions: read 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 in-progress rollback workflows env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | echo "Checking for in-progress rollback workflows..." echo "Searching for: deploy-web.yml runs deploying web-v${_RELEASE_VERSION} to ${_ENVIRONMENT}" echo "" # Check for in-progress or queued deploy-web workflows with matching parameters # Note: Only checks in_progress and queued to allow re-rollbacks after completion IN_PROGRESS_RUNS=$(gh run list \ --repo ${{ github.repository }} \ --workflow=deploy-web.yml \ --status=in_progress,queued \ --json displayTitle,databaseId,status,url \ --jq "[.[] | select(.displayTitle | contains(\"${_ENVIRONMENT}\"))] | length") if [ "$IN_PROGRESS_RUNS" -gt 0 ]; then echo "WARNING: Found in-progress or queued deploy-web workflow(s) for ${_ENVIRONMENT}" echo "" echo "Existing workflow run(s):" gh run list \ --repo ${{ github.repository }} \ --workflow=deploy-web.yml \ --status=in_progress,queued \ --json displayTitle,databaseId,status,url \ --jq ".[] | select(.displayTitle | contains(\"${_ENVIRONMENT}\")) | \" Run #\(.databaseId) (\(.status)): \(.url)\"" echo "" echo "This may be a duplicate rollback or deployment." echo "Please verify the existing workflow is not already deploying v${_RELEASE_VERSION}." exit 1 fi echo "No in-progress rollback workflows 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 // Note: deploy-web.yml has built-in approval gates that will pause before deployment 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.info(`The workflow will pause for approval before deploying`); core.setOutput('web_tag', webTag); // Get the workflow run URL (we need to wait a moment for it to be created) await new Promise(resolve => setTimeout(resolve, 2000)); const runs = await github.rest.actions.listWorkflowRuns({ owner: context.repo.owner, repo: context.repo.repo, workflow_id: 'deploy-web.yml', per_page: 1 }); if (runs.data.workflow_runs.length > 0) { const workflowUrl = runs.data.workflow_runs[0].html_url; core.setOutput('workflow_url', workflowUrl); core.info(`Workflow URL: ${workflowUrl}`); } - 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 }} _WORKFLOW_URL: ${{ steps.trigger_deploy.outputs.workflow_url }} _WEB_TAG: ${{ steps.trigger_deploy.outputs.web_tag }} with: webhook-type: incoming-webhook payload: | { "text": "Web Rollback - Approval Required", "blocks": [ { "type": "header", "text": { "type": "plain_text", "text": "Web Rollback - Approval Required" } }, { "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": "A rollback workflow has been triggered to redeploy version v${{ env._RELEASE_VERSION }} to ${{ env._ENVIRONMENT }}.\n\n*The deployment is paused and awaiting manual approval.*\n\n<${_WORKFLOW_URL}|View Deploy Workflow & Approve>" } }, { "type": "context", "elements": [ { "type": "mrkdwn", "text": "Action required: Review the workflow run and approve the deployment to proceed with the rollback." } ] } ] } - name: Rollback initiated env: _WORKFLOW_URL: ${{ steps.trigger_deploy.outputs.workflow_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 " - Deploy Workflow: ${_WORKFLOW_URL}" echo "" echo "Next steps:" echo " 1. Approve the deploy-web workflow run" echo " 2. Monitor the deployment progress" echo " 3. Verify ${_ENVIRONMENT} is serving v${_RELEASE_VERSION}" echo " 4. Confirm application health" echo " 5. Update Jira card status" echo ""