Deploy Web Vault to USDEV from main #604
This file contains 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 Web Vault | |
run-name: Deploy Web Vault to ${{ inputs.environment }} from ${{ inputs.branch-or-tag }} | |
on: | |
workflow_dispatch: | |
inputs: | |
environment: | |
description: 'Environment' | |
default: 'QA' | |
type: choice | |
options: | |
- USQA | |
- EUQA | |
- USPROD | |
- EUPROD | |
- USDEV | |
branch-or-tag: | |
description: "Branch or Tag name to deploy (examples: 'main', 'feature/sm', 'web-v2023.12.0')" | |
type: string | |
default: main | |
invert-default-sync-delete-destination-files-value: | |
description: "Invert the default sync-delete-destination-files value" | |
type: boolean | |
default: false | |
debug: | |
description: "Debug mode" | |
type: boolean | |
default: false | |
workflow_call: | |
inputs: | |
environment: | |
description: 'Environment' | |
default: 'USQA' | |
type: string | |
branch-or-tag: | |
description: "Branch or Tag name to deploy (examples: 'main', 'feature/sm', 'web-v2023.12.0')" | |
type: string | |
default: main | |
invert-default-sync-delete-destination-files-value: | |
description: "Invert the default sync-delete-destination-files value" | |
type: boolean | |
default: false | |
debug: | |
description: "Debug mode" | |
type: boolean | |
default: true | |
permissions: | |
deployments: write | |
jobs: | |
setup: | |
name: Setup | |
runs-on: ubuntu-22.04 | |
outputs: | |
environment: ${{ steps.config.outputs.environment }} | |
environment-url: ${{ steps.config.outputs.environment-url }} | |
environment-name: ${{ steps.config.outputs.environment-name }} | |
environment-artifact: ${{ steps.config.outputs.environment-artifact }} | |
azure-login-creds: ${{ steps.config.outputs.azure-login-creds }} | |
retrieve-secrets-keyvault: ${{ steps.config.outputs.retrieve-secrets-keyvault }} | |
sync-utility: ${{ steps.config.outputs.sync-utility }} | |
sync-delete-destination-files: ${{ steps.config.outputs.sync-delete-destination-files }} | |
steps: | |
- name: Configure | |
id: config | |
run: | | |
ENV_NAME_LOWER=$(echo "${{ inputs.environment }}" | awk '{print tolower($0)}') | |
echo "configuring the Web deploy for ${{ inputs.environment }}" | |
echo "environment=${{ inputs.environment }}" >> $GITHUB_OUTPUT | |
# Invert the default value for sync-delete-destination-files | |
if [ ${{ inputs.invert-default-sync-delete-destination-files-value }} ]; then | |
echo "sync-delete-destination-files=true" >> $GITHUB_OUTPUT | |
else | |
# This is the default value for USQA, EUQA, USPROD, and EUPROD | |
echo "sync-delete-destination-files=false" >> $GITHUB_OUTPUT | |
fi | |
case ${{ inputs.environment }} in | |
"USQA") | |
echo "azure-login-creds=AZURE_KV_US_QA_SERVICE_PRINCIPAL" >> $GITHUB_OUTPUT | |
echo "retrieve-secrets-keyvault=bw-webvault-rlktusqa-kv" >> $GITHUB_OUTPUT | |
echo "environment-artifact=web-*-cloud-QA.zip" >> $GITHUB_OUTPUT | |
echo "environment-name=Web Vault - US QA Cloud" >> $GITHUB_OUTPUT | |
echo "environment-url=http://vault.$ENV_NAME_LOWER.bitwarden.pw" >> $GITHUB_OUTPUT | |
;; | |
"EUQA") | |
echo "azure-login-creds=AZURE_KV_EU_QA_SERVICE_PRINCIPAL" >> $GITHUB_OUTPUT | |
echo "retrieve-secrets-keyvault=webvaulteu-westeurope-qa" >> $GITHUB_OUTPUT | |
echo "environment-artifact=web-*-cloud-euqa.zip" >> $GITHUB_OUTPUT | |
echo "environment-name=Web Vault - EU QA Cloud" >> $GITHUB_OUTPUT | |
echo "environment-url=http://vault.$ENV_NAME_LOWER.bitwarden.pw" >> $GITHUB_OUTPUT | |
;; | |
"USPROD") | |
echo "azure-login-creds=AZURE_KV_US_PROD_SERVICE_PRINCIPAL" >> $GITHUB_OUTPUT | |
echo "retrieve-secrets-keyvault=bw-webvault-klrt-kv" >> $GITHUB_OUTPUT | |
echo "environment-artifact=web-*-cloud-COMMERCIAL.zip" >> $GITHUB_OUTPUT | |
echo "environment-name=Web Vault - US Production Cloud" >> $GITHUB_OUTPUT | |
echo "environment-url=http://vault.bitwarden.com" >> $GITHUB_OUTPUT | |
;; | |
"EUPROD") | |
echo "azure-login-creds=AZURE_KV_EU_PRD_SERVICE_PRINCIPAL" >> $GITHUB_OUTPUT | |
echo "retrieve-secrets-keyvault=webvault-westeurope-prod" >> $GITHUB_OUTPUT | |
echo "environment-artifact=web-*-cloud-euprd.zip" >> $GITHUB_OUTPUT | |
echo "environment-name=Web Vault - EU Production Cloud" >> $GITHUB_OUTPUT | |
echo "environment-url=http://vault.bitwarden.eu" >> $GITHUB_OUTPUT | |
;; | |
"USDEV") | |
echo "azure-login-creds=AZURE_KV_US_DEV_SERVICE_PRINCIPAL" >> $GITHUB_OUTPUT | |
echo "retrieve-secrets-keyvault=webvault-eastus-dev" >> $GITHUB_OUTPUT | |
echo "environment-artifact=web-*-cloud-usdev.zip" >> $GITHUB_OUTPUT | |
echo "environment-name=Web Vault - US Development Cloud" >> $GITHUB_OUTPUT | |
echo "environment-url=http://vault.$ENV_NAME_LOWER.bitwarden.pw" >> $GITHUB_OUTPUT | |
if [ ${{ inputs.invert-default-sync-delete-destination-files-value }} ]; then | |
echo "sync-delete-destination-files=false" >> $GITHUB_OUTPUT | |
else | |
# This is the default value for USDEV | |
echo "sync-delete-destination-files=true" >> $GITHUB_OUTPUT | |
fi | |
;; | |
esac | |
# Set the sync utility to use for deployment to the environment (az-sync or azcopy) | |
echo "sync-utility=azcopy" >> $GITHUB_OUTPUT | |
approval: | |
name: Approval for Deployment to ${{ needs.setup.outputs.environment-name }} | |
needs: setup | |
runs-on: ubuntu-22.04 | |
environment: ${{ needs.setup.outputs.environment-name }} | |
steps: | |
- name: Success Code | |
run: exit 0 | |
get-branch-or-tag-sha: | |
name: Get Branch or Tag SHA | |
runs-on: ubuntu-22.04 | |
outputs: | |
branch-or-tag-sha: ${{ steps.get-branch-or-tag-sha.outputs.sha }} | |
steps: | |
- name: Checkout Branch | |
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | |
with: | |
ref: ${{ inputs.branch-or-tag }} | |
fetch-depth: 0 | |
- name: Get Branch or Tag SHA | |
id: get-branch-or-tag-sha | |
run: | | |
echo "sha=$(git rev-parse origin/${{ inputs.branch-or-tag }})" >> $GITHUB_OUTPUT | |
notify-start: | |
name: Notify Slack with start message | |
needs: | |
- approval | |
- setup | |
- get-branch-or-tag-sha | |
runs-on: ubuntu-22.04 | |
if: ${{ always() && contains( inputs.environment , 'QA' ) }} | |
outputs: | |
channel_id: ${{ steps.slack-message.outputs.channel_id }} | |
ts: ${{ steps.slack-message.outputs.ts }} | |
steps: | |
- uses: bitwarden/gh-actions/report-deployment-status-to-slack@main | |
id: slack-message | |
with: | |
project: Clients | |
environment: ${{ needs.setup.outputs.environment-name }} | |
tag: ${{ inputs.branch-or-tag }} | |
slack-channel: team-eng-qa-devops | |
event: 'start' | |
commit-sha: ${{ needs.get-branch-or-tag-sha.outputs.branch-or-tag-sha }} | |
url: https://github.com/bitwarden/clients/actions/runs/${{ github.run_id }} | |
AZURE_KV_CI_SERVICE_PRINCIPAL: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} | |
artifact-check: | |
name: Check if Web artifact is present | |
runs-on: ubuntu-22.04 | |
needs: setup | |
env: | |
_ENVIRONMENT_ARTIFACT: ${{ needs.setup.outputs.environment-artifact }} | |
steps: | |
- name: 'Download latest cloud asset from branch/tag: ${{ inputs.branch-or-tag }}' | |
uses: bitwarden/gh-actions/download-artifacts@main | |
id: download-artifacts | |
continue-on-error: true | |
with: | |
workflow: build-web.yml | |
path: apps/web | |
workflow_conclusion: success | |
branch: ${{ inputs.branch-or-tag }} | |
artifacts: ${{ env._ENVIRONMENT_ARTIFACT }} | |
- name: Login to Azure | |
if: ${{ steps.download-artifacts.outcome == 'failure' }} | |
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 | |
with: | |
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} | |
- name: Retrieve secrets for Build trigger | |
if: ${{ steps.download-artifacts.outcome == 'failure' }} | |
id: retrieve-secret | |
uses: bitwarden/gh-actions/get-keyvault-secrets@main | |
with: | |
keyvault: "bitwarden-ci" | |
secrets: "github-pat-bitwarden-devops-bot-repo-scope" | |
- name: 'Trigger build web for missing branch/tag ${{ inputs.branch-or-tag }}' | |
if: ${{ steps.download-artifacts.outcome == 'failure' }} | |
uses: convictional/trigger-workflow-and-wait@f69fa9eedd3c62a599220f4d5745230e237904be # v1.6.5 | |
with: | |
owner: bitwarden | |
repo: clients | |
github_token: ${{ steps.retrieve-secret.outputs.github-pat-bitwarden-devops-bot-repo-scope }} | |
workflow_file_name: build-web.yml | |
ref: ${{ inputs.branch-or-tag }} | |
wait_interval: 100 | |
azure-deploy: | |
name: Deploy Web Vault to ${{ inputs.environment }} Storage Account | |
needs: | |
- setup | |
- artifact-check | |
- approval | |
runs-on: ubuntu-22.04 | |
env: | |
_ENVIRONMENT: ${{ needs.setup.outputs.environment }} | |
_ENVIRONMENT_URL: ${{ needs.setup.outputs.environment-url }} | |
_ENVIRONMENT_NAME: ${{ needs.setup.outputs.environment-name }} | |
_ENVIRONMENT_ARTIFACT: ${{ needs.setup.outputs.environment-artifact }} | |
steps: | |
- name: Create GitHub deployment | |
uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7 | |
id: deployment | |
with: | |
token: '${{ secrets.GITHUB_TOKEN }}' | |
initial-status: 'in_progress' | |
environment-url: ${{ env._ENVIRONMENT_URL }} | |
environment: ${{ env._ENVIRONMENT_NAME }} | |
task: 'deploy' | |
description: 'Deployment from branch/tag: ${{ inputs.branch-or-tag }}' | |
- name: Login to Azure | |
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 | |
with: | |
creds: ${{ secrets[needs.setup.outputs.azure-login-creds] }} | |
- name: Retrieve Storage Account connection string for az sync | |
if: ${{ needs.setup.outputs.sync-utility == 'az-sync' }} | |
id: retrieve-secrets-az-sync | |
uses: bitwarden/gh-actions/get-keyvault-secrets@main | |
with: | |
keyvault: ${{ needs.setup.outputs.retrieve-secrets-keyvault }} | |
secrets: "sa-bitwarden-web-vault-dev-key-temp" | |
- name: Retrieve Storage Account name and SPN credentials for azcopy | |
if: ${{ needs.setup.outputs.sync-utility == 'azcopy' }} | |
id: retrieve-secrets-azcopy | |
uses: bitwarden/gh-actions/get-keyvault-secrets@main | |
with: | |
keyvault: ${{ needs.setup.outputs.retrieve-secrets-keyvault }} | |
secrets: "sa-bitwarden-web-vault-name,sp-bitwarden-web-vault-password,sp-bitwarden-web-vault-appid,sp-bitwarden-web-vault-tenant" | |
- name: 'Download cloud asset from branch/tag: ${{ inputs.branch-or-tag }}' | |
uses: bitwarden/gh-actions/download-artifacts@main | |
with: | |
workflow: build-web.yml | |
path: apps/web | |
workflow_conclusion: success | |
branch: ${{ inputs.branch-or-tag }} | |
artifacts: ${{ env._ENVIRONMENT_ARTIFACT }} | |
- name: Unzip build asset | |
working-directory: apps/web | |
run: unzip ${{ env._ENVIRONMENT_ARTIFACT }} | |
- name: Sync to Azure Storage Account using az storage blob sync | |
if: ${{ needs.setup.outputs.sync-utility == 'az-sync' }} | |
working-directory: apps/web | |
run: | | |
az storage blob sync \ | |
--source "./build" \ | |
--container '$web' \ | |
--connection-string "${{ steps.retrieve-secrets-az-sync.outputs.sa-bitwarden-web-vault-dev-key-temp }}" \ | |
--delete-destination=${{ needs.setup.outputs.sync-delete-destination-files }} | |
- name: Sync to Azure Storage Account using azcopy | |
if: ${{ needs.setup.outputs.sync-utility == 'azcopy' }} | |
working-directory: apps/web | |
env: | |
AZCOPY_AUTO_LOGIN_TYPE: SPN | |
AZCOPY_SPA_APPLICATION_ID: ${{ steps.retrieve-secrets-azcopy.outputs.sp-bitwarden-web-vault-appid }} | |
AZCOPY_SPA_CLIENT_SECRET: ${{ steps.retrieve-secrets-azcopy.outputs.sp-bitwarden-web-vault-password }} | |
AZCOPY_TENANT_ID: ${{ steps.retrieve-secrets-azcopy.outputs.sp-bitwarden-web-vault-tenant }} | |
run: | | |
azcopy sync ./build 'https://${{ steps.retrieve-secrets-azcopy.outputs.sa-bitwarden-web-vault-name }}.blob.core.windows.net/$web/' \ | |
--delete-destination=${{ needs.setup.outputs.sync-delete-destination-files }} --compare-hash="MD5" | |
- name: Debug sync logs | |
if: ${{ inputs.debug }} | |
run: cat /home/runner/.azcopy/*.log | |
- name: Debug index.html | |
if: ${{ inputs.debug }} | |
run: cat apps/web/build/index.html | |
- name: Update deployment status to Success | |
if: success() | |
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1 | |
with: | |
token: '${{ secrets.GITHUB_TOKEN }}' | |
environment-url: ${{ env._ENVIRONMENT_URL }} | |
state: 'success' | |
deployment-id: ${{ steps.deployment.outputs.deployment_id }} | |
- name: Update deployment status to Failure | |
if: failure() | |
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1 | |
with: | |
token: '${{ secrets.GITHUB_TOKEN }}' | |
environment-url: ${{ env._ENVIRONMENT_URL }} | |
state: 'failure' | |
deployment-id: ${{ steps.deployment.outputs.deployment_id }} | |
notify: | |
name: Notify Slack with result | |
runs-on: ubuntu-22.04 | |
if: ${{ always() && contains( inputs.environment , 'QA' ) }} | |
needs: | |
- notify-start | |
- azure-deploy | |
- setup | |
- get-branch-or-tag-sha | |
steps: | |
- uses: bitwarden/gh-actions/report-deployment-status-to-slack@main | |
with: | |
project: Clients | |
environment: ${{ needs.setup.outputs.environment-name }} | |
tag: ${{ inputs.branch-or-tag }} | |
slack-channel: ${{ needs.notify-start.outputs.channel_id }} | |
event: ${{ needs.azure-deploy.result }} | |
url: https://github.com/bitwarden/clients/actions/runs/${{ github.run_id }} | |
commit-sha: ${{ needs.get-branch-or-tag-sha.outputs.branch-or-tag-sha }} | |
update-ts: ${{ needs.notify-start.outputs.ts }} | |
AZURE_KV_CI_SERVICE_PRINCIPAL: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} |