You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
350 lines
11 KiB
350 lines
11 KiB
name: QA Deploy |
|
|
|
on: |
|
workflow_dispatch: |
|
inputs: |
|
migrateDb: |
|
required: true |
|
default: "true" |
|
resetDb: |
|
required: true |
|
default: "false" |
|
|
|
jobs: |
|
build: |
|
runs-on: ubuntu-latest |
|
strategy: |
|
fail-fast: false |
|
matrix: |
|
include: |
|
- name: Api |
|
base_path: . |
|
- name: Admin |
|
base_path: . |
|
gulp: true |
|
- name: Billing |
|
base_path: . |
|
- name: Events |
|
base_path: . |
|
- name: Notifications |
|
base_path: . |
|
- name: Sso |
|
base_path: ./bitwarden_license |
|
gulp: true |
|
- name: Portal |
|
base_path: ./bitwarden_license |
|
gulp: true |
|
- name: Identity |
|
base_path: . |
|
steps: |
|
- name: Checkout repo |
|
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f |
|
|
|
- name: Set up Node |
|
uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea |
|
with: |
|
node-version: '14' |
|
|
|
- name: Update NPM |
|
run: | |
|
npm install -g npm@7 |
|
|
|
- name: Print Environment |
|
run: | |
|
dotnet --info |
|
node --version |
|
npm --version |
|
gulp --version |
|
|
|
- name: Load env vars |
|
run: | |
|
echo "Base Path: ${BASE_PATH}" |
|
echo "Name: ${NAME}" |
|
env: |
|
BASE_PATH: ${{ matrix.base_path }} |
|
NAME: ${{ matrix.name }} |
|
|
|
- name: Build Service |
|
run: | |
|
work_dir=$(pwd) |
|
dir=$BASE_PATH/src/$SERVICE_NAME |
|
|
|
cd $dir |
|
echo "Restore" |
|
dotnet restore $SERVICE_NAME.csproj |
|
echo "Clean" |
|
dotnet clean $SERVICE_NAME.csproj -c "Release" -o obj/build-output/publish |
|
|
|
if [ "$GULP" == "true" ]; then |
|
npm install |
|
npm install gulp |
|
gulp --gulpfile gulpfile.js build |
|
fi |
|
|
|
echo "Publish" |
|
dotnet publish $SERVICE_NAME.csproj -c "Release" -o obj/build-output/publish |
|
|
|
cd obj/build-output/publish |
|
zip -r $SERVICE_NAME.zip . |
|
mv $SERVICE_NAME.zip ../../../ |
|
env: |
|
SERVICE_NAME: ${{ matrix.name }} |
|
BASE_PATH: ${{ matrix.base_path }} |
|
GULP: ${{ matrix.gulp }} |
|
|
|
- name: Upload build artifact |
|
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 |
|
with: |
|
name: ${{ env.SERVICE_NAME }}.zip |
|
path: ${{ env.BASE_PATH }}/src/${{ env.SERVICE_NAME }}/${{ env.SERVICE_NAME }}.zip |
|
env: |
|
BASE_PATH: ${{ matrix.base_path }} |
|
SERVICE_NAME: ${{ matrix.name }} |
|
|
|
- name: Test build dir |
|
run: ls $BASE_PATH/src/$SERVICE_NAME |
|
env: |
|
SERVICE_NAME: ${{ matrix.name }} |
|
BASE_PATH: ${{ matrix.base_path }} |
|
|
|
|
|
reset-db: |
|
name: Reset Database |
|
if: ${{ github.event.inputs.resetDb == 'true' }} |
|
runs-on: ubuntu-latest |
|
needs: build |
|
steps: |
|
- name: Reset Test Data - Stub |
|
run: | |
|
echo "placeholder for cleaning DB" |
|
echo "placeholder for loading test dataset" |
|
|
|
|
|
update-db: |
|
name: Update Database |
|
if: ${{ github.event.inputs.migrateDb == 'true' }} |
|
runs-on: ubuntu-latest |
|
needs: build |
|
steps: |
|
- name: Checkout repo |
|
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f |
|
|
|
- name: Login to Azure |
|
uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a |
|
with: |
|
creds: ${{ secrets.AZURE_QA_KV_CREDENTIALS }} |
|
|
|
- name: Retrieve secrets |
|
id: retrieve-secrets |
|
uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403 |
|
with: |
|
keyvault: "bitwarden-qa-kv" |
|
secrets: "mssql-server-host, |
|
mssql-admin-login, |
|
mssql-admin-login-password" |
|
|
|
- name: Migrate database |
|
env: |
|
MSSQL_HOST: ${{ steps.retrieve-secrets.outputs.mssql-server-host }} |
|
MSSQL_USER: ${{ steps.retrieve-secrets.outputs.mssql-admin-login }} |
|
MSSQL_PASS: ${{ steps.retrieve-secrets.outputs.mssql-admin-login-password }} |
|
working-directory: ./util/Migrator/DbScripts |
|
run: | |
|
echo "Running database migrations..." |
|
for f in `ls -v ./*.sql`; do |
|
sqlcmd -S $MSSQL_HOST -d vault -U $MSSQL_USER -P $MSSQL_PASS -I -i $f |
|
done; |
|
|
|
|
|
deploy: |
|
runs-on: ubuntu-latest |
|
if: always() |
|
needs: |
|
- reset-db |
|
- update-db |
|
strategy: |
|
fail-fast: false |
|
matrix: |
|
include: |
|
- name: Api |
|
- name: Admin |
|
- name: Billing |
|
- name: Events |
|
- name: Sso |
|
- name: Portal |
|
- name: Identity |
|
steps: |
|
- name: Setup |
|
id: setup |
|
run: | |
|
NAME_LOWER=$(echo "${{ matrix.name }}" | awk '{print tolower($0)}') |
|
echo "Matrix name: ${{ matrix.name }}" |
|
echo "NAME_LOWER: $NAME_LOWER" |
|
echo "::set-output name=name_lower::$NAME_LOWER" |
|
|
|
- name: Download aritifacts |
|
uses: actions/download-artifact@158ca71f7c614ae705e79f25522ef4658df18253 |
|
with: |
|
name: ${{ matrix.name }}.zip |
|
|
|
- name: Login to Azure |
|
uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a |
|
with: |
|
creds: ${{ secrets.AZURE_QA_KV_CREDENTIALS }} |
|
|
|
- name: Retrieve secrets |
|
id: retrieve-secrets |
|
env: |
|
VAULT_NAME: "bitwarden-qa-kv" |
|
run: | |
|
webapp_name=$(az keyvault secret show --vault-name $VAULT_NAME --name appservices-${{ steps.setup.outputs.name_lower }}-webapp-name --query value --output tsv) |
|
echo "::add-mask::$webapp_name" |
|
echo "::set-output name=webapp-name::$webapp_name" |
|
|
|
- name: Deploy App |
|
uses: azure/webapps-deploy@798e43877120eda6a2a690a4f212c545e586ae31 |
|
with: |
|
app-name: ${{ steps.retrieve-secrets.outputs.webapp-name }} |
|
slot-name: "staging" |
|
package: ./${{ matrix.name }}.zip |
|
|
|
|
|
swap-identity: |
|
runs-on: ubuntu-latest |
|
needs: deploy |
|
steps: |
|
- name: Login to Azure |
|
uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a |
|
with: |
|
creds: ${{ secrets.AZURE_QA_KV_CREDENTIALS }} |
|
|
|
- name: Retrieve secrets |
|
id: retrieve-secrets |
|
env: |
|
VAULT_NAME: "bitwarden-qa-kv" |
|
run: | |
|
identity_webapp_name=$(az keyvault secret show --vault-name $VAULT_NAME --name appservices-identity-webapp-name --query value --output tsv) |
|
echo "::add-mask::$identity_webapp_name" |
|
echo "::set-output name=identity-webapp-name::$identity_webapp_name" |
|
|
|
- name: Start staging slot |
|
run: az webapp start --name ${{ steps.retrieve-secrets.outputs.identity-webapp-name }} --resource-group bitwarden-qa --slot staging |
|
|
|
- name: Make sure staging endpoint is alive |
|
run: | |
|
SUCCESS="no" |
|
while read OUTPUT |
|
do |
|
STATUS=$( curl -is https://${{ steps.retrieve-secrets.outputs.identity-webapp-name }}-staging.azurewebsites.net/.well-known/openid-configuration/jwks | head -1 ) |
|
if [[ "$STATUS" == *"200 OK"* ]]; then |
|
echo "It is live!" |
|
SUCCESS="yes" |
|
break |
|
fi |
|
echo -e "STAUS=$STATUS\nRetrying: $OUTPUT" |
|
sleep 4; |
|
done < <(seq 15) |
|
|
|
if [[ "$SUCCESS" == "no" ]]; then |
|
exit 1 |
|
fi |
|
|
|
- name: Swap Identity |
|
run: az webapp deployment slot swap -g bitwarden-qa -n ${{ steps.retrieve-secrets.outputs.identity-webapp-name }} --slot staging --target-slot production |
|
|
|
- name: Stop staging slot |
|
run: az webapp stop --name ${{ steps.retrieve-secrets.outputs.identity-webapp-name }} --resource-group bitwarden-qa --slot staging |
|
|
|
|
|
swap-slots: |
|
runs-on: ubuntu-latest |
|
needs: swap-identity |
|
strategy: |
|
fail-fast: false |
|
matrix: |
|
include: |
|
- name: Api |
|
- name: Billing |
|
- name: Events |
|
- name: Sso |
|
- name: Portal |
|
steps: |
|
- name: Setup |
|
id: setup |
|
run: | |
|
NAME_LOWER=$(echo "${{ matrix.name }}" | awk '{print tolower($0)}') |
|
echo "::set-output name=name_lower::$NAME_LOWER" |
|
|
|
- name: Login to Azure |
|
uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a |
|
with: |
|
creds: ${{ secrets.AZURE_QA_KV_CREDENTIALS }} |
|
|
|
- name: Retrieve secrets |
|
id: retrieve-secrets |
|
env: |
|
VAULT_NAME: "bitwarden-qa-kv" |
|
run: | |
|
webapp_name=$(az keyvault secret show --vault-name $VAULT_NAME --name appservices-${{ steps.setup.outputs.name_lower }}-webapp-name --query value --output tsv) |
|
echo "::add-mask::$webapp_name" |
|
echo "::set-output name=webapp-name::$webapp_name" |
|
|
|
- name: Start staging slot |
|
run: az webapp start --name ${{ steps.retrieve-secrets.outputs.webapp-name }} --resource-group bitwarden-qa --slot staging |
|
|
|
- name: Make sure staging endpoint is alive |
|
run: | |
|
SUCCESS="no" |
|
while read OUTPUT |
|
do |
|
STATUS=$( curl -is https://${{ steps.retrieve-secrets.outputs.webapp-name }}-staging.azurewebsites.net/alive | head -1 ) |
|
if [[ "$STATUS" == *"200 OK"* ]]; then |
|
echo "It is live!" |
|
SUCCESS="yes" |
|
break |
|
fi |
|
echo -e "STAUS=$STATUS\nRetrying: $OUTPUT" |
|
sleep 4; |
|
done < <(seq 15) |
|
|
|
if [[ "$SUCCESS" == "no" ]]; then |
|
exit 1 |
|
fi |
|
|
|
- name: Swap slots |
|
run: az webapp deployment slot swap -g bitwarden-qa -n ${{ steps.retrieve-secrets.outputs.webapp-name }} --slot staging --target-slot production |
|
|
|
- name: Stop staging slot |
|
run: az webapp stop --name ${{ steps.retrieve-secrets.outputs.webapp-name }} --resource-group bitwarden-qa --slot staging |
|
|
|
|
|
swap-admin: |
|
runs-on: ubuntu-latest |
|
needs: swap-slots |
|
steps: |
|
- name: Login to Azure |
|
uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a |
|
with: |
|
creds: ${{ secrets.AZURE_QA_KV_CREDENTIALS }} |
|
|
|
- name: Retrieve secrets |
|
id: retrieve-secrets |
|
env: |
|
VAULT_NAME: "bitwarden-qa-kv" |
|
run: | |
|
admin_webapp_name=$(az keyvault secret show --vault-name $VAULT_NAME --name appservices-admin-webapp-name --query value --output tsv) |
|
echo "::add-mask::$admin_webapp_name" |
|
echo "::set-output name=admin-webapp-name::$admin_webapp_name" |
|
|
|
- name: Start staging slot |
|
run: az webapp start --name ${{ steps.retrieve-secrets.outputs.admin-webapp-name }} --resource-group bitwarden-qa --slot staging |
|
|
|
- name: Make sure staging endpoint is alive |
|
run: | |
|
sleep 60 # I don't think the admin portal has an alive endpoint |
|
|
|
- name: Swap Admin |
|
run: az webapp deployment slot swap -g bitwarden-qa -n ${{ steps.retrieve-secrets.outputs.admin-webapp-name }} --slot staging --target-slot production |
|
|
|
- name: Stop staging slot |
|
run: az webapp stop --name ${{ steps.retrieve-secrets.outputs.admin-webapp-name }} --resource-group bitwarden-qa --slot staging
|
|
|