From a6265885ada74009ed799452b5e34db2acd1c888 Mon Sep 17 00:00:00 2001 From: Joseph Flinn <58369717+joseph-flinn@users.noreply.github.com> Date: Tue, 4 May 2021 13:41:49 -0700 Subject: [PATCH] Automating Server Release/Deploy for QA Env (#1281) * initial success caching test * updating status testing * fixing the fail check * fixing bash if syntax * changing the way of testing since you can't change workflow inputs between re-runs * trying out different bash syntax * removing the export to env * adding in last run status check * switching up the last_run_status file handling since it doesn't look like it is working correctly * adding push trigger * fixing typo * adding date to the cache key and adding a bit more logging * fixing restore key * trying a different way of logging both successes and failures * fixing typo * reorganizing the random success/fail * trying different bash * fixing binary operator * adding in success flag checks * increasing the odds of success * trying to fix weird problem * changing dquotes to squotes * testing failure and always() flow * adding in a release pipeline * adding in the manual trigger for the release pipeline * fixing the bash for loop for tagging and switching to the rc image for release * adding docker trust to the pull task * fixing bash array typo * removing build task * adding the dotnet tool restore back in to hopefully restore swagger * adding an Api build to build the swagger docs * working on build workflow * testing cache between jobs * Adding in steps * fixing the last line * updating the build workflow * adding manual trigger for build workflow * moving the matrix values to the env section of the task * changing the envs * using env template replacement * removing the unique id since I don't think I need it * testing the cache * commenting out the docker push * adding the env vars back to the cache task * adding envs to test * fixing the path issue * resetting the build workflow back to serial build/docker * Adding in the qa release workflow * removing unneccessary dependency * parameterizing the project file names * forcing gulp install * installing gulp globally * reorganizing to see if gulp works * removing the awkward paths * fixing typo * commenting out all non-api matrix for easier testing * trying to zip the build for deploy * adding in the base path for the test * replacing the web app name * adding a specific slotname * adding the env into the package path for the deployment * trying to fix the zip * setting up all of the other deploys * switching the secrets over to be environment secrets * adding in production automation with the deploys commented out * removing the master branch from the QA deploy * adding in the dependancy on the setup * changing the tag * trying a different ref * renaming the deployment slot to staging * trying a different slot name * resetting the qa deploy to the original * moving the secrets * updating the qa deploy with the db reset/update stubs * updating the deploy task dependencies * adding missing update-db command placeholder * trying a string for the inputs * moving the input check into the steps instead of the job level so that the job completes * testing azure kv * fixing typo * Change id to retrieve-secrets * Fix typo * testing the rest of the QA app service deployments * updating the name of the QA AZ creds secret and migrating the disabled prod deploy jobs to use the prod AZ secrets * adding in the additional key vault secrets and fixing some other mistakes * fixing one of the other preview versions * removing newline for testing commit * fixing typo * fixing a secret name typo * moving the secrets to the env to test their outputs * adding missing k * Update build workflow with environment variables for Docker Trust * removing the unneeded env vars * Update build and release workflow using Azure secrets as env variables * Clean up output of NuGet version * Fix capitalization * Fix variable names for Docker Trust Setup * fixing the dashes in the env ids * switching the dev tag for qa when pushing * commenting out the test for the pipeline testing * removing all of the testing code and blockers Co-authored-by: Vince Grassia <593223+vgrassia@users.noreply.github.com> --- .github/workflows/build.yml | 395 +++++++++++++++--------------- .github/workflows/prod-deploy.yml | 380 ++++++++++++++++++++++++++++ .github/workflows/qa-deploy.yml | 360 +++++++++++++++++++++++++++ .github/workflows/release.yml | 284 +++++++++++++++++++++ 4 files changed, 1218 insertions(+), 201 deletions(-) create mode 100644 .github/workflows/prod-deploy.yml create mode 100644 .github/workflows/qa-deploy.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f41979e4c..69e68c5b3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,15 +5,12 @@ on: branches-ignore: - 'l10n_master' - 'gh-pages' - release: - types: - - published + workflow_dispatch: + inputs: {} jobs: - cloc: runs-on: ubuntu-latest - steps: - name: Checkout repo uses: actions/checkout@v2 @@ -26,202 +23,8 @@ jobs: - name: Print lines of code run: cloc --include-lang C#,SQL,Razor,"Bourne Shell",PowerShell,HTML,CSS,Sass,JavaScript,TypeScript --vcs git - ubuntu: - runs-on: ubuntu-latest - - steps: - - name: Set up Node - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - - name: Set up gulp - run: npm i -g gulp - - - name: Print environment - run: | - whoami - dotnet --info - node --version - npm --version - gulp --version - docker --version - Write-Output "GitHub ref: $env:GITHUB_REF" - Write-Output "GitHub event: $env:GITHUB_EVENT" - shell: pwsh - env: - GITHUB_REF: ${{ github.ref }} - GITHUB_EVENT: ${{ github.event_name }} - - - name: Log into docker - if: github.ref == 'refs/heads/master' || github.event_name == 'release' || github.ref == 'refs/heads/rc' - run: echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - - name: Setup Docker Trust - if: github.ref == 'refs/heads/master' || github.event_name == 'release' || github.ref == 'refs/heads/rc' - run: | - mkdir -p ~/.docker/trust/private - - echo "${{ secrets.DOCKER_DELEGATION_KEY }}" > ~/.docker/trust/private/$DOCKER_DELEGATION_KEY_ID.key - echo "${{ secrets.DOCKER_REPO_API_KEY }}" > ~/.docker/trust/private/$DOCKER_REPO_API_ID.key - echo "${{ secrets.DOCKER_REPO_IDENTITY_KEY }}" > ~/.docker/trust/private/$DOCKER_REPO_IDENTITY_ID.key - echo "${{ secrets.DOCKER_REPO_SERVER_KEY }}" > ~/.docker/trust/private/$DOCKER_REPO_SERVER_ID.key - echo "${{ secrets.DOCKER_REPO_ATTACHMENTS_KEY }}" > ~/.docker/trust/private/$DOCKER_REPO_ATTACHMENTS_ID.key - echo "${{ secrets.DOCKER_REPO_ICONS_KEY }}" > ~/.docker/trust/private/$DOCKER_REPO_ICONS_ID.key - echo "${{ secrets.DOCKER_REPO_NOTIFICATIONS_KEY }}" > ~/.docker/trust/private/$DOCKER_REPO_NOTIFICATIONS_ID.key - echo "${{ secrets.DOCKER_REPO_EVENTS_KEY }}" > ~/.docker/trust/private/$DOCKER_REPO_EVENTS_ID.key - echo "${{ secrets.DOCKER_REPO_ADMIN_KEY }}" > ~/.docker/trust/private/$DOCKER_REPO_ADMIN_ID.key - echo "${{ secrets.DOCKER_REPO_NGINX_KEY }}" > ~/.docker/trust/private/$DOCKER_REPO_NGINX_ID.key - echo "${{ secrets.DOCKER_REPO_K8SPROXY_KEY }}" > ~/.docker/trust/private/$DOCKER_REPO_K8SPROXY_ID.key - echo "${{ secrets.DOCKER_REPO_SSO_KEY }}" > ~/.docker/trust/private/$DOCKER_REPO_SSO_ID.key - echo "${{ secrets.DOCKER_REPO_PORTAL_KEY }}" > ~/.docker/trust/private/$DOCKER_REPO_PORTAL_ID.key - echo "${{ secrets.DOCKER_REPO_MSSQL_KEY }}" > ~/.docker/trust/private/$DOCKER_REPO_MSSQL_ID.key - echo "${{ secrets.DOCKER_REPO_SETUP_KEY }}" > ~/.docker/trust/private/$DOCKER_REPO_SETUP_ID.key - env: - DOCKER_DELEGATION_KEY_ID: "5702b22123e058cbd96a7a43000cb981ae98ef3f2f4aa34138ab3dc1d011e446" - DOCKER_REPO_API_ID: "525fa3e70b84669c9fe489c5a3d0974898d14c0807b19447242c60ed8d4ca766" - DOCKER_REPO_IDENTITY_ID: "084da6ea47ba1c4f34c2870a78a17739cd5df50359d2c2c7616822632df726d3" - DOCKER_REPO_SERVER_ID: "ffbee21a1a71854a1c1310df4f5aded41726dd90d61050a6256168cd9268b1ee" - DOCKER_REPO_ATTACHMENTS_ID: "e40fbcb5b273ad601c00ea905ca326ab68b395f17a46a8530e0ddd7d12bd4240" - DOCKER_REPO_ICONS_ID: "0d3f5c6854610bd3d9b9c0a6851fe525b057976b46cb0f47de3942cf3b0be394" - DOCKER_REPO_NOTIFICATIONS_ID: "1bf8d22352ec65a6c9b9282c454462240e0a1eb78bff03b65b5a4b7887599ab2" - DOCKER_REPO_EVENTS_ID: "1020320052e6247f3c5fbfc2a3bfb0efc7e247f8a5a187dc03f60848359ac7c9" - DOCKER_REPO_ADMIN_ID: "c5d80db8745fcd7a1510c3fba5c65582cfc2453d2b1eeb292abe79eb1351cf5c" - DOCKER_REPO_NGINX_ID: "bf3d3247f5c2be73bbe830cddbae445c29e4fcc9e2fb4b4d39abf86a2740098b" - DOCKER_REPO_K8SPROXY_ID: "bdad34c1202b2bbf8a460b66da08b2c1c1eea5864b29508782c00da145eb1fcd" - DOCKER_REPO_SSO_ID: "97a5f6d29b255ff709ec63faad27c2f76246f006563bf3ecbb71547325c05815" - DOCKER_REPO_PORTAL_ID: "4f358aa0a41c9a6650f5d2f907c2de418df34ddf3ee45e0994be7cc2dcd0b56e" - DOCKER_REPO_MSSQL_ID: "30a44d7efbe48d30ed06abef003d2d8990205dad6a034617cddc03548f8c084e" - DOCKER_REPO_SETUP_ID: "2932fb9c39b7eacf4418c7c9ee4c823f973c426412ddd64d7f9f0b6f940b8428" - - - name: Checkout repo - uses: actions/checkout@v2 - - - name: Restore - run: dotnet tool restore - - - name: Build - run: | - chmod +x ./build.sh - ./build.sh - - - name: tag rc branch - if: github.ref == 'refs/heads/rc' - run: ./build.sh tag rc - - - name: Tag dev - if: github.ref == 'refs/heads/master' || github.event_name == 'release' - run: ./build.sh tag dev - - - name: Tag beta - if: github.event_name == 'release' - run: ./build.sh tag beta - - - name: Tag version - if: github.event_name == 'release' - run: ./build.sh tag $($env:RELEASE_TAG_NAME.TrimStart('v')) - shell: pwsh - env: - RELEASE_TAG_NAME: ${{ github.event.release.tag_name }} - - - name: List docker images - if: github.ref == 'refs/heads/master' || github.event_name == 'release' || github.ref == 'refs/heads/rc' - run: docker images - - - name: Push rc images - if: github.ref == 'refs/heads/rc' - run: ./build.sh push rc - env: - DOCKER_CONTENT_TRUST: 1 - DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE }} - - - name: Push dev images - if: github.ref == 'refs/heads/master' || github.event_name == 'release' - run: ./build.sh push dev - env: - DOCKER_CONTENT_TRUST: 1 - DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE }} - - - name: Push beta images - if: github.event_name == 'release' - run: ./build.sh push beta - env: - DOCKER_CONTENT_TRUST: 1 - DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE }} - - - name: Push latest images - if: github.event_name == 'release' - run: ./build.sh push latest - env: - DOCKER_CONTENT_TRUST: 1 - DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE }} - - - name: Push version images - if: github.event_name == 'release' - run: ./build.sh push $($env:RELEASE_TAG_NAME.TrimStart('v')) - shell: pwsh - env: - RELEASE_TAG_NAME: ${{ github.event.release.tag_name }} - DOCKER_CONTENT_TRUST: 1 - DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE }} - - - name: Make docker stub - run: | - STUB_OUTPUT=$(pwd)/docker-stub - docker run -i --rm --name setup -v $STUB_OUTPUT:/bitwarden bitwarden/setup:dev \ - dotnet Setup.dll -stub 1 -install 1 -domain bitwarden.example.com -os lin - sudo chown -R $(whoami):$(whoami) $STUB_OUTPUT - rm -rf $STUB_OUTPUT/letsencrypt - rm $STUB_OUTPUT/env/uid.env $STUB_OUTPUT/config.yml - touch $STUB_OUTPUT/env/uid.env - cd docker-stub; zip -r ../docker-stub.zip *; cd .. - - - name: Upload docker stub artifact - uses: actions/upload-artifact@v2-preview - with: - name: docker-stub.zip - path: ./docker-stub.zip - - - name: Build swagger - run: | - cd ./src/Api - dotnet swagger tofile --output ../../swagger.json --host https://api.bitwarden.com ` - ./obj/Docker/publish/Api/Api.dll public - cd ../.. - shell: pwsh - env: - ASPNETCORE_ENVIRONMENT: Production - swaggerGen: 'True' - - - name: Upload swagger artifact - uses: actions/upload-artifact@v2-preview - with: - name: swagger.json - path: ./swagger.json - - - name: Log out of docker - if: github.ref == 'refs/heads/master' || github.event_name == 'release' || github.ref == 'refs/heads/rc' - run: docker logout - - - name: Upload release assets - if: github.event_name == 'release' - run: | - hub release edit ` - -a ./swagger.json ` - -a ./docker-stub.zip ` - -m "Version $($env:RELEASE_TAG_NAME.TrimStart('v'))" ` - $env:RELEASE_TAG_NAME - shell: pwsh - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - RELEASE_TAG_NAME: ${{ github.event.release.tag_name }} - - windows: + testing: runs-on: windows-latest - steps: - name: Set up NuGet uses: nuget/setup-nuget@v1 @@ -238,7 +41,7 @@ jobs: - name: Print environment run: | - nuget help + nuget help | grep "Version" msbuild -version dotnet --info node --version @@ -264,3 +67,193 @@ jobs: - name: Test solution run: dotnet test .\test\Core.Test\Core.Test.csproj --configuration Debug --no-build shell: pwsh + + build: + runs-on: ubuntu-latest + needs: testing + steps: + - name: Set up Node + uses: actions/setup-node@v1 + with: + node-version: '10.x' + + - name: Set up gulp + run: npm i -g gulp + + - name: Print environment + run: | + whoami + dotnet --info + node --version + npm --version + gulp --version + docker --version + Write-Output "GitHub ref: $env:GITHUB_REF" + Write-Output "GitHub event: $env:GITHUB_EVENT" + shell: pwsh + env: + GITHUB_REF: ${{ github.ref }} + GITHUB_EVENT: ${{ github.event_name }} + + - name: Login to Azure + uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a + with: + creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }} + + - name: Retrieve secrets + id: retrieve-secrets + uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403 + with: + keyvault: "bitwarden-prod-kv" + secrets: "docker-password, + docker-username, + dct-delegate-repo-passphrase, + dct-delegate-key, + dct-repo-server-key, + dct-repo-attachments-key, + dct-repo-admin-key, + dct-repo-nginx-key, + dct-repo-k8sproxy-key, + dct-repo-sso-key, + dct-repo-api-key, + dct-repo-portal-key, + dct-repo-setup-key, + dct-repo-notifications-key, + dct-repo-events-key, + dct-repo-web-key, + dct-repo-icons-key, + dct-repo-identity-key" + + - name: Log into docker + if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/rc' + run: echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin + env: + DOCKER_USERNAME: ${{ steps.retrieve-secrets.outputs.docker-username }} + DOCKER_PASSWORD: ${{ steps.retrieve-secrets.outputs.docker-password }} + + - name: Setup Docker Trust + if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/rc' + run: | + mkdir -p ~/.docker/trust/private + + echo "$DCT_DELEGATE_KEY" > ~/.docker/trust/private/$DCT_DELEGATION_KEY_ID.key + echo "$DCT_REPO_API_KEY" > ~/.docker/trust/private/$DCT_REPO_API_ID.key + echo "$DCT_REPO_IDENTITY_KEY" > ~/.docker/trust/private/$DCT_REPO_IDENTITY_ID.key + echo "$DCT_REPO_SERVER_KEY" > ~/.docker/trust/private/$DCT_REPO_SERVER_ID.key + echo "$DCT_REPO_ATTACHMENTS_KEY" > ~/.docker/trust/private/$DCT_REPO_ATTACHMENTS_ID.key + echo "$DCT_REPO_ICONS_KEY" > ~/.docker/trust/private/$DCT_REPO_ICONS_ID.key + echo "$DCT_REPO_NOTIFICATIONS_KEY" > ~/.docker/trust/private/$DCT_REPO_NOTIFICATIONS_ID.key + echo "$DCT_REPO_EVENTS_KEY" > ~/.docker/trust/private/$DCT_REPO_EVENTS_ID.key + echo "$DCT_REPO_ADMIN_KEY" > ~/.docker/trust/private/$DCT_REPO_ADMIN_ID.key + echo "$DCT_REPO_NGINX_KEY" > ~/.docker/trust/private/$DCT_REPO_NGINX_ID.key + echo "$DCT_REPO_K8SPROXY_KEY" > ~/.docker/trust/private/$DCT_REPO_K8SPROXY_ID.key + echo "$DCT_REPO_SSO_KEY" > ~/.docker/trust/private/$DCT_REPO_SSO_ID.key + echo "$DCT_REPO_PORTAL_KEY" > ~/.docker/trust/private/$DCT_REPO_PORTAL_ID.key + echo "$DCT_REPO_MSSQL_KEY" > ~/.docker/trust/private/$DCT_REPO_MSSQL_ID.key + echo "$DCT_REPO_SETUP_KEY" > ~/.docker/trust/private/$DCT_REPO_SETUP_ID.key + env: + DCT_DELEGATION_KEY_ID: "5702b22123e058cbd96a7a43000cb981ae98ef3f2f4aa34138ab3dc1d011e446" + DCT_REPO_API_ID: "525fa3e70b84669c9fe489c5a3d0974898d14c0807b19447242c60ed8d4ca766" + DCT_REPO_IDENTITY_ID: "084da6ea47ba1c4f34c2870a78a17739cd5df50359d2c2c7616822632df726d3" + DCT_REPO_SERVER_ID: "ffbee21a1a71854a1c1310df4f5aded41726dd90d61050a6256168cd9268b1ee" + DCT_REPO_ATTACHMENTS_ID: "e40fbcb5b273ad601c00ea905ca326ab68b395f17a46a8530e0ddd7d12bd4240" + DCT_REPO_ICONS_ID: "0d3f5c6854610bd3d9b9c0a6851fe525b057976b46cb0f47de3942cf3b0be394" + DCT_REPO_NOTIFICATIONS_ID: "1bf8d22352ec65a6c9b9282c454462240e0a1eb78bff03b65b5a4b7887599ab2" + DCT_REPO_EVENTS_ID: "1020320052e6247f3c5fbfc2a3bfb0efc7e247f8a5a187dc03f60848359ac7c9" + DCT_REPO_ADMIN_ID: "c5d80db8745fcd7a1510c3fba5c65582cfc2453d2b1eeb292abe79eb1351cf5c" + DCT_REPO_NGINX_ID: "bf3d3247f5c2be73bbe830cddbae445c29e4fcc9e2fb4b4d39abf86a2740098b" + DCT_REPO_K8SPROXY_ID: "bdad34c1202b2bbf8a460b66da08b2c1c1eea5864b29508782c00da145eb1fcd" + DCT_REPO_SSO_ID: "97a5f6d29b255ff709ec63faad27c2f76246f006563bf3ecbb71547325c05815" + DCT_REPO_PORTAL_ID: "4f358aa0a41c9a6650f5d2f907c2de418df34ddf3ee45e0994be7cc2dcd0b56e" + DCT_REPO_MSSQL_ID: "30a44d7efbe48d30ed06abef003d2d8990205dad6a034617cddc03548f8c084e" + DCT_REPO_SETUP_ID: "2932fb9c39b7eacf4418c7c9ee4c823f973c426412ddd64d7f9f0b6f940b8428" + DCT_DELEGATE_KEY: ${{ steps.retrieve-secrets.outputs.dct-delegate-key }} + DCT_REPO_API_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-api-key }} + DCT_REPO_IDENTITY_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-identity-key }} + DCT_REPO_SERVER_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-server-key }} + DCT_REPO_ATTACHMENTS_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-attachments-key }} + DCT_REPO_ICONS_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-icons-key }} + DCT_REPO_NOTIFICATIONS_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-notifications-key }} + DCT_REPO_EVENTS_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-events-key }} + DCT_REPO_ADMIN_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-admin-key }} + DCT_REPO_NGINX_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-nginx-key }} + DCT_REPO_K8SPROXY_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-k8sproxy-key }} + DCT_REPO_SSO_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-sso-key }} + DCT_REPO_PORTAL_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-portal-key }} + DCT_REPO_MSSQL_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-mssql-key }} + DCT_REPO_SETUP_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-setup-key }} + + - name: Checkout repo + uses: actions/checkout@v2 + + - name: Restore + run: dotnet tool restore + + - name: Build + run: | + chmod +x ./build.sh + ./build.sh + + - name: Tag rc branch + if: github.ref == 'refs/heads/rc' + run: ./build.sh tag rc + + - name: Tag dev + if: github.ref == 'refs/heads/master' + run: ./build.sh tag dev + + - name: List docker images + if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/rc' + run: docker images + + - name: Push rc images + if: github.ref == 'refs/heads/rc' + run: ./build.sh push rc + env: + DOCKER_CONTENT_TRUST: 1 + DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE: ${{ steps.retrieve-secrets.outputs.dct-delegate-repo-passphrase }} + + - name: Push dev images + if: github.ref == 'refs/heads/master' + run: ./build.sh push dev + env: + DOCKER_CONTENT_TRUST: 1 + DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE: ${{ steps.retrieve-secrets.outputs.dct-delegate-repo-passphrase }} + + - name: Make docker stub + run: | + STUB_OUTPUT=$(pwd)/docker-stub + docker run -i --rm --name setup -v $STUB_OUTPUT:/bitwarden bitwarden/setup:dev \ + dotnet Setup.dll -stub 1 -install 1 -domain bitwarden.example.com -os lin + sudo chown -R $(whoami):$(whoami) $STUB_OUTPUT + rm -rf $STUB_OUTPUT/letsencrypt + rm $STUB_OUTPUT/env/uid.env $STUB_OUTPUT/config.yml + touch $STUB_OUTPUT/env/uid.env + cd docker-stub; zip -r ../docker-stub.zip *; cd .. + + - name: Upload docker stub artifact + uses: actions/upload-artifact@v2 + with: + name: docker-stub.zip + path: ./docker-stub.zip + + - name: Build swagger + run: | + cd ./src/Api + dotnet swagger tofile --output ../../swagger.json --host https://api.bitwarden.com ` + ./obj/Docker/publish/Api/Api.dll public + cd ../.. + shell: pwsh + env: + ASPNETCORE_ENVIRONMENT: Production + swaggerGen: 'True' + + - name: Upload swagger artifact + uses: actions/upload-artifact@v2 + with: + name: swagger.json + path: ./swagger.json + + - name: Log out of docker + if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/rc' + run: docker logout diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml new file mode 100644 index 000000000..9a917d8cc --- /dev/null +++ b/.github/workflows/prod-deploy.yml @@ -0,0 +1,380 @@ +name: Prod Deploy + +on: + workflow_dispatch: + inputs: + release_tag_name_input: + description: "Release Tag Name " + required: true + release: + types: + - published + +jobs: + setup: + runs-on: ubuntu-latest + outputs: + package_version: ${{ steps.create_tags.outputs.package_version }} + tag_version: ${{ steps.create_tags.outputs.tag_version }} + steps: + - name: Checkout Repo + uses: actions/checkout@v2 + + - name: Create Deploy version vars + id: create_tags + run: | + if [ "${{ github.event_name }}" != "release" ]; then + case "${RELEASE_TAG_NAME_INPUT:0:1}" in + v) + echo "RELEASE_NAME=${RELEASE_TAG_NAME_INPUT:1}" >> $GITHUB_ENV + echo "RELEASE_TAG_NAME=$RELEASE_TAG_NAME_INPUT" >> $GITHUB_ENV + echo "::set-output name=package_version::${RELEASE_TAG_NAME_INPUT:1}" + echo "::set-output name=tag_version::$RELEASE_TAG_NAME_INPUT" + ;; + [0-9]) + echo "RELEASE_NAME=$RELEASE_TAG_NAME_INPUT" >> $GITHUB_ENV + echo "RELEASE_TAG_NAME=v$RELEASE_TAG_NAME_INPUT" >> $GITHUB_ENV + echo "::set-output name=package_version::$RELEASE_TAG_NAME_INPUT" + echo "::set-output name=tag_version::v$RELEASE_TAG_NAME_INPUT" + ;; + *) + exit 1 + ;; + esac + else + TAG_VERSION=$(echo ${{ github.ref }} | cut -d "/" -f 3) + PKG_VERSION=${TAG_VERSION:1} + + echo "::set-output name=package_version::$PKG_VERSION" + echo "::set-output name=tag_version::$TAG_VERSION" + fi + env: + RELEASE_TAG_NAME_INPUT: ${{ github.event.inputs.release_tag_name_input }} + + - name: test outputs + run: | + echo "Package Version: ${{ steps.create_tags.outputs.package_version }}" + echo "Tag Version: ${{ steps.create_tags.outputs.tag_version }}" + + build: + runs-on: ubuntu-latest + needs: setup + 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: . + env: + PKG_VERSION: ${{ needs.setup.outputs.package_version }} + TAG_VERSION: ${{ needs.setup.outputs.tag_version }} + steps: + - name: Checkout repo + uses: actions/checkout@v2 + with: + ref: ${{ env.TAG_VERSION }} + + - name: Set up Node + uses: actions/setup-node@v1 + with: + node-version: '10.x' + + - 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/Azure/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/Azure/publish + + cd obj/Azure/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@v2 + 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 }} + + + deploy-identity: + runs-on: ubuntu-latest + needs: build + environment: Production + steps: + - name: Download aritifacts + uses: actions/download-artifact@v2 + with: + name: Identity.zip + + - name: Login to Azure + uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a + with: + creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }} + + - name: Retrieve secrets + id: retrieve-secrets + uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403 + with: + keyvault: "bitwarden-prod-kv" + secrets: "appservices-identity-webapp-name, + appservices-identity-webapp-publish-profile" + + - name: Deploy Identity + uses: azure/webapps-deploy@v2 + with: + app-name: ${{ steps.retrieve-secrets.outputs.appservices-identity-webapp-name }} + slot-name: "staging" + publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-identity-webapp-publish-profile }} + package: ./Identity.zip + + + deploy-api: + runs-on: ubuntu-latest + needs: build + environment: Production + steps: + - name: Download aritifacts + uses: actions/download-artifact@v2 + with: + name: Api.zip + + - name: Login to Azure + uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a + with: + creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }} + + - name: Retrieve secrets + id: retrieve-secrets + uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403 + with: + keyvault: "bitwarden-prod-kv" + secrets: "appservices-api-webapp-name, + appservices-api-webapp-publish-profile" + + - name: Deploy Api + uses: azure/webapps-deploy@v2 + with: + app-name: ${{ steps.retrieve-secrets.outputs.appservices-api-webapp-name }} + slot-name: "staging" + publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-api-webapp-publish-profile }} + package: ./Api.zip + + + deploy-billing: + runs-on: ubuntu-latest + needs: build + environment: Production + steps: + - name: Download aritifacts + uses: actions/download-artifact@v2 + with: + name: Billing.zip + + - name: Login to Azure + uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a + with: + creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }} + + - name: Retrieve secrets + id: retrieve-secrets + uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403 + with: + keyvault: "bitwarden-prod-kv" + secrets: "appservices-billing-webapp-name, + appservices-billing-webapp-publish-profile" + + - name: Deploy Billing + uses: azure/webapps-deploy@v2 + with: + app-name: ${{ steps.retrieve-secrets.outputs.appservices-billing-webapp-name }} + slot-name: "staging" + publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-billing-webapp-publish-profile }} + package: ./Billing.zip + + + deploy-events: + runs-on: ubuntu-latest + needs: build + environment: Production + steps: + - name: Download aritifacts + uses: actions/download-artifact@v2 + with: + name: Events.zip + + - name: Login to Azure + uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a + with: + creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }} + + - name: Retrieve secrets + id: retrieve-secrets + uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403 + with: + keyvault: "bitwarden-prod-kv" + secrets: "appservices-events-webapp-name, + appservices-events-webapp-publish-profile" + + - name: Deploy Events + uses: azure/webapps-deploy@v2 + with: + app-name: ${{ steps.retrieve-secrets.outputs.appservices-events-webapp-name }} + slot-name: "staging" + publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-events-webapp-publish-profile }} + package: ./Events.zip + + + deploy-sso: + runs-on: ubuntu-latest + needs: build + environment: Production + steps: + - name: Download aritifacts + uses: actions/download-artifact@v2 + with: + name: Sso.zip + + - name: Login to Azure + uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a + with: + creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }} + + - name: Retrieve secrets + id: retrieve-secrets + uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403 + with: + keyvault: "bitwarden-prod-kv" + secrets: "appservices-sso-webapp-name, + appservices-sso-webapp-publish-profile" + + - name: Deploy SSO + uses: azure/webapps-deploy@v2 + with: + app-name: ${{ steps.retrieve-secrets.outputs.appservices-sso-webapp-name }} + slot-name: "staging" + publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-sso-webapp-publish-profile }} + package: ./Sso.zip + + + deploy-portal: + runs-on: ubuntu-latest + needs: build + environment: Production + steps: + - name: Download aritifacts + uses: actions/download-artifact@v2 + with: + name: Portal.zip + + - name: Login to Azure + uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a + with: + creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }} + + - name: Retrieve secrets + id: retrieve-secrets + uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403 + with: + keyvault: "bitwarden-prod-kv" + secrets: "appservices-portal-webapp-name, + appservices-portal-webapp-publish-profile" + + - name: Deploy Portal + uses: azure/webapps-deploy@v2 + with: + app-name: ${{ steps.retrieve-secrets.outputs.appservices-portal-webapp-name }} + slot-name: "staging" + publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-portal-webapp-publish-profile }} + package: ./Portal.zip + + + deploy-admin: + runs-on: ubuntu-latest + needs: build + environment: Production + steps: + - name: Download aritifacts + uses: actions/download-artifact@v2 + with: + name: Admin.zip + + - name: Login to Azure + uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a + with: + creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }} + + - name: Retrieve secrets + id: retrieve-secrets + uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403 + with: + keyvault: "bitwarden-prod-kv" + secrets: "appservices-admin-webapp-name, + appservices-admin-webapp-publish-profile" + + - name: Deploy Admin + uses: azure/webapps-deploy@v2 + with: + app-name: ${{ steps.retrieve-secrets.outputs.appservices-admin-webapp-name }} + slot-name: "staging" + publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-admin-webapp-publish-profile }} + package: ./Admin.zip + diff --git a/.github/workflows/qa-deploy.yml b/.github/workflows/qa-deploy.yml new file mode 100644 index 000000000..225a976c4 --- /dev/null +++ b/.github/workflows/qa-deploy.yml @@ -0,0 +1,360 @@ +name: QA Deploy + +on: + push: + branches: + - 'rc' + 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@v2 + + - name: Set up Node + uses: actions/setup-node@v1 + with: + node-version: '10.x' + + - 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/Azure/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/Azure/publish + + cd obj/Azure/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@v2 + 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: + runs-on: ubuntu-latest + needs: build + steps: + - name: Reset Test Data - Stub + if: ${{ github.events.inputs.resetDb }} == "true" + run: | + echo "placeholder for cleaning DB" + echo "placeholder for loading test dataset" + + update-db: + if: ${{ github.events.inputs.migrateDb }} == "true" + runs-on: ubuntu-latest + needs: build + steps: + - name: migrate db + if: ${{ github.events.inputs.resetDb }} == "true" + run: | + echo "placeholder for updateing DB" + + + deploy-identity: + runs-on: ubuntu-latest + needs: + - reset-db + - update-db + steps: + - name: Download aritifacts + uses: actions/download-artifact@v2 + with: + name: Identity.zip + + - 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: "appservices-identity-webapp-name, + appservices-identity-webapp-publish-profile" + + - name: Deploy Identity + uses: azure/webapps-deploy@v2 + with: + app-name: ${{ steps.retrieve-secrets.outputs.appservices-identity-webapp-name }} + slot-name: "staging" + publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-identity-webapp-publish-profile }} + package: ./Identity.zip + + + deploy-api: + runs-on: ubuntu-latest + needs: + - reset-db + - update-db + steps: + - name: Download aritifacts + uses: actions/download-artifact@v2 + with: + name: Api.zip + + - 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: "appservices-api-webapp-name, + appservices-api-webapp-publish-profile" + + - name: Deploy Api + uses: azure/webapps-deploy@v2 + with: + app-name: ${{ steps.retrieve-secrets.outputs.appservices-api-webapp-name }} + slot-name: "staging" + publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-api-webapp-publish-profile }} + package: ./Api.zip + + + deploy-billing: + runs-on: ubuntu-latest + needs: + - reset-db + - update-db + steps: + - name: Download aritifacts + uses: actions/download-artifact@v2 + with: + name: Billing.zip + + - 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: "appservices-billing-webapp-name, + appservices-billing-webapp-publish-profile" + + - name: Deploy Billing + uses: azure/webapps-deploy@v2 + with: + app-name: ${{ steps.retrieve-secrets.outputs.appservices-billing-webapp-name }} + slot-name: "staging" + publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-billing-webapp-publish-profile }} + package: ./Billing.zip + + + deploy-events: + runs-on: ubuntu-latest + needs: + - reset-db + - update-db + steps: + - name: Download aritifacts + uses: actions/download-artifact@v2 + with: + name: Events.zip + + - 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: "appservices-events-webapp-name, + appservices-events-webapp-publish-profile" + + - name: Deploy Events + uses: azure/webapps-deploy@v2 + with: + app-name: ${{ steps.retrieve-secrets.outputs.appservices-events-webapp-name }} + slot-name: "staging" + publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-events-webapp-publish-profile }} + package: ./Events.zip + + + deploy-sso: + runs-on: ubuntu-latest + needs: + - reset-db + - update-db + steps: + - name: Download aritifacts + uses: actions/download-artifact@v2 + with: + name: Sso.zip + + - 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: "appservices-sso-webapp-name, + appservices-sso-webapp-publish-profile" + + - name: Deploy SSO + uses: azure/webapps-deploy@v2 + with: + app-name: ${{ steps.retrieve-secrets.outputs.appservices-sso-webapp-name }} + slot-name: "staging" + publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-sso-webapp-publish-profile }} + package: ./Sso.zip + + + deploy-portal: + runs-on: ubuntu-latest + needs: + - reset-db + - update-db + steps: + - name: Download aritifacts + uses: actions/download-artifact@v2 + with: + name: Portal.zip + + - 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: "appservices-portal-webapp-name, + appservices-portal-webapp-publish-profile" + + - name: Deploy Portal + uses: azure/webapps-deploy@v2 + with: + app-name: ${{ steps.retrieve-secrets.outputs.appservices-portal-webapp-name }} + slot-name: "staging" + publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-portal-webapp-publish-profile }} + package: ./Portal.zip + + + deploy-admin: + runs-on: ubuntu-latest + needs: + - reset-db + - update-db + steps: + - name: Download aritifacts + uses: actions/download-artifact@v2 + with: + name: Admin.zip + + - 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: "appservices-admin-webapp-name, + appservices-admin-webapp-publish-profile" + + - name: Deploy Admin + uses: azure/webapps-deploy@v2 + with: + app-name: ${{ steps.retrieve-secrets.outputs.appservices-admin-webapp-name }} + slot-name: "staging" + publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-admin-webapp-publish-profile }} + package: ./Admin.zip + diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..fe50f65dd --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,284 @@ +name: Release + +on: + workflow_dispatch: + inputs: + release_tag_name_input: + description: "Release Tag Name " + required: true + +jobs: + setup: + runs-on: ubuntu-latest + outputs: + release_upload_url: ${{ steps.create_release.outputs.upload_url }} + release_version: ${{ steps.create_tags.outputs.package_version }} + tag_version: ${{ steps.create_tags.outputs.tag_version }} + steps: + - name: Checkout repo + uses: actions/checkout@v2 + + - name: Create Release Vars + id: create_tags + run: | + case "${RELEASE_TAG_NAME_INPUT:0:1}" in + v) + echo "RELEASE_NAME=${RELEASE_TAG_NAME_INPUT:1}" >> $GITHUB_ENV + echo "RELEASE_TAG_NAME=$RELEASE_TAG_NAME_INPUT" >> $GITHUB_ENV + echo "::set-output name=package_version::${RELEASE_TAG_NAME_INPUT:1}" + echo "::set-output name=tag_version::$RELEASE_TAG_NAME_INPUT" + ;; + [0-9]) + echo "RELEASE_NAME=$RELEASE_TAG_NAME_INPUT" >> $GITHUB_ENV + echo "RELEASE_TAG_NAME=v$RELEASE_TAG_NAME_INPUT" >> $GITHUB_ENV + echo "::set-output name=package_version::$RELEASE_TAG_NAME_INPUT" + echo "::set-output name=tag_version::v$RELEASE_TAG_NAME_INPUT" + ;; + *) + exit 1 + ;; + esac + env: + RELEASE_TAG_NAME_INPUT: ${{ github.event.inputs.release_tag_name_input }} + + - name: Create Draft Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ env.RELEASE_TAG_NAME }} + release_name: ${{ env.RELEASE_NAME }} + draft: true + prerelease: false + + release: + runs-on: ubuntu-latest + needs: setup + env: + RELEASE_VERSION: ${{ needs.setup.outputs.release_version }} + TAG_VERSION: ${{ needs.setup.outputs.tag_version }} + steps: + - name: Print environment + run: | + whoami + docker --version + Write-Output "GitHub ref: $env:GITHUB_REF" + Write-Output "GitHub event: $env:GITHUB_EVENT" + shell: pwsh + env: + GITHUB_REF: ${{ github.ref }} + GITHUB_EVENT: ${{ github.event_name }} + + - name: Login to Azure + uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a + with: + creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }} + + - name: Retrieve secrets + id: retrieve-secrets + uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403 + with: + keyvault: "bitwarden-prod-kv" + secrets: "docker-password, + docker-username, + dct-delegate-repo-passphrase, + dct-delegate-key, + dct-repo-server-key, + dct-repo-attachments-key, + dct-repo-admin-key, + dct-repo-nginx-key, + dct-repo-k8sproxy-key, + dct-repo-sso-key, + dct-repo-api-key, + dct-repo-portal-key, + dct-repo-setup-key, + dct-repo-notifications-key, + dct-repo-events-key, + dct-repo-web-key, + dct-repo-icons-key, + dct-repo-identity-key" + + - name: Log into docker + if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/rc' + run: echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin + env: + DOCKER_USERNAME: ${{ steps.retrieve-secrets.outputs.docker-username }} + DOCKER_PASSWORD: ${{ steps.retrieve-secrets.outputs.docker-password }} + + - name: Setup Docker Trust + run: | + mkdir -p ~/.docker/trust/private + + echo "$DCT_DELEGATE_KEY" > ~/.docker/trust/private/$DCT_DELEGATION_KEY_ID.key + echo "$DCT_REPO_API_KEY" > ~/.docker/trust/private/$DCT_REPO_API_ID.key + echo "$DCT_REPO_IDENTITY_KEY" > ~/.docker/trust/private/$DCT_REPO_IDENTITY_ID.key + echo "$DCT_REPO_SERVER_KEY" > ~/.docker/trust/private/$DCT_REPO_SERVER_ID.key + echo "$DCT_REPO_ATTACHMENTS_KEY" > ~/.docker/trust/private/$DCT_REPO_ATTACHMENTS_ID.key + echo "$DCT_REPO_ICONS_KEY" > ~/.docker/trust/private/$DCT_REPO_ICONS_ID.key + echo "$DCT_REPO_NOTIFICATIONS_KEY" > ~/.docker/trust/private/$DCT_REPO_NOTIFICATIONS_ID.key + echo "$DCT_REPO_EVENTS_KEY" > ~/.docker/trust/private/$DCT_REPO_EVENTS_ID.key + echo "$DCT_REPO_ADMIN_KEY" > ~/.docker/trust/private/$DCT_REPO_ADMIN_ID.key + echo "$DCT_REPO_NGINX_KEY" > ~/.docker/trust/private/$DCT_REPO_NGINX_ID.key + echo "$DCT_REPO_K8SPROXY_KEY" > ~/.docker/trust/private/$DCT_REPO_K8SPROXY_ID.key + echo "$DCT_REPO_SSO_KEY" > ~/.docker/trust/private/$DCT_REPO_SSO_ID.key + echo "$DCT_REPO_PORTAL_KEY" > ~/.docker/trust/private/$DCT_REPO_PORTAL_ID.key + echo "$DCT_REPO_MSSQL_KEY" > ~/.docker/trust/private/$DCT_REPO_MSSQL_ID.key + echo "$DCT_REPO_SETUP_KEY" > ~/.docker/trust/private/$DCT_REPO_SETUP_ID.key + env: + DCT_DELEGATION_KEY_ID: "5702b22123e058cbd96a7a43000cb981ae98ef3f2f4aa34138ab3dc1d011e446" + DCT_REPO_API_ID: "525fa3e70b84669c9fe489c5a3d0974898d14c0807b19447242c60ed8d4ca766" + DCT_REPO_IDENTITY_ID: "084da6ea47ba1c4f34c2870a78a17739cd5df50359d2c2c7616822632df726d3" + DCT_REPO_SERVER_ID: "ffbee21a1a71854a1c1310df4f5aded41726dd90d61050a6256168cd9268b1ee" + DCT_REPO_ATTACHMENTS_ID: "e40fbcb5b273ad601c00ea905ca326ab68b395f17a46a8530e0ddd7d12bd4240" + DCT_REPO_ICONS_ID: "0d3f5c6854610bd3d9b9c0a6851fe525b057976b46cb0f47de3942cf3b0be394" + DCT_REPO_NOTIFICATIONS_ID: "1bf8d22352ec65a6c9b9282c454462240e0a1eb78bff03b65b5a4b7887599ab2" + DCT_REPO_EVENTS_ID: "1020320052e6247f3c5fbfc2a3bfb0efc7e247f8a5a187dc03f60848359ac7c9" + DCT_REPO_ADMIN_ID: "c5d80db8745fcd7a1510c3fba5c65582cfc2453d2b1eeb292abe79eb1351cf5c" + DCT_REPO_NGINX_ID: "bf3d3247f5c2be73bbe830cddbae445c29e4fcc9e2fb4b4d39abf86a2740098b" + DCT_REPO_K8SPROXY_ID: "bdad34c1202b2bbf8a460b66da08b2c1c1eea5864b29508782c00da145eb1fcd" + DCT_REPO_SSO_ID: "97a5f6d29b255ff709ec63faad27c2f76246f006563bf3ecbb71547325c05815" + DCT_REPO_PORTAL_ID: "4f358aa0a41c9a6650f5d2f907c2de418df34ddf3ee45e0994be7cc2dcd0b56e" + DCT_REPO_MSSQL_ID: "30a44d7efbe48d30ed06abef003d2d8990205dad6a034617cddc03548f8c084e" + DCT_REPO_SETUP_ID: "2932fb9c39b7eacf4418c7c9ee4c823f973c426412ddd64d7f9f0b6f940b8428" + DCT_DELEGATE_KEY: ${{ steps.retrieve-secrets.outputs.dct-delegate-key }} + DCT_REPO_API_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-api-key }} + DCT_REPO_IDENTITY_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-identity-key }} + DCT_REPO_SERVER_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-server-key }} + DCT_REPO_ATTACHMENTS_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-attachments-key }} + DCT_REPO_ICONS_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-icons-key }} + DCT_REPO_NOTIFICATIONS_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-notifications-key }} + DCT_REPO_EVENTS_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-events-key }} + DCT_REPO_ADMIN_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-admin-key }} + DCT_REPO_NGINX_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-nginx-key }} + DCT_REPO_K8SPROXY_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-k8sproxy-key }} + DCT_REPO_SSO_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-sso-key }} + DCT_REPO_PORTAL_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-portal-key }} + DCT_REPO_MSSQL_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-mssql-key }} + DCT_REPO_SETUP_KEY: ${{ steps.retrieve-secrets.outputs.dct-repo-setup-key }} + + - name: Checkout repo + uses: actions/checkout@v2 + + - name: Restore + run: dotnet tool restore + + - name: pull docker images + run: | + docker pull bitwarden/api:rc + docker pull bitwarden/identity:rc + docker pull bitwarden/server:rc + docker pull bitwarden/attachments:rc + docker pull bitwarden/icons:rc + docker pull bitwarden/notifications:rc + docker pull bitwarden/events:rc + docker pull bitwarden/admin:rc + docker pull bitwarden/nginx:rc + docker pull bitwarden/nginx:rc + docker pull bitwarden/sso:rc + docker pull bitwarden/portal:rc + docker pull bitwarden/mssql:rc + docker pull bitwarden/setup:rc + env: + DOCKER_CONTENT_TRUST: 1 + + + - name: re-tag docker images + run: | + tags=( latest beta ${RELEASE_VERSION} ) + for TAG in "${tags[@]}" + do + docker tag bitwarden/api:rc bitwarden/api:$TAG + docker tag bitwarden/identity:rc bitwarden/identity:$TAG + docker tag bitwarden/server:rc bitwarden/server:$TAG + docker tag bitwarden/attachments:rc bitwarden/attachments:$TAG + docker tag bitwarden/icons:rc bitwarden/icons:$TAG + docker tag bitwarden/notifications:rc bitwarden/notifications:$TAG + docker tag bitwarden/events:rc bitwarden/events:$TAG + docker tag bitwarden/admin:rc bitwarden/admin:$TAG + docker tag bitwarden/nginx:rc bitwarden/nginx:$TAG + docker tag bitwarden/nginx:rc bitwarden/k8s-proxy:$TAG + docker tag bitwarden/sso:rc bitwarden/sso:$TAG + docker tag bitwarden/portal:rc bitwarden/portal:$TAG + docker tag bitwarden/mssql:rc bitwarden/mssql:$TAG + docker tag bitwarden/setup:rc bitwarden/setup:$TAG + done + + - name: List docker images + run: docker images + + - name: Push beta images + run: ./build.sh push beta + env: + DOCKER_CONTENT_TRUST: 1 + DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE: ${{ steps.retrieve-secrets.outputs.dct-delegate-repo-passphrase }} + + - name: Push latest images + run: ./build.sh push latest + env: + DOCKER_CONTENT_TRUST: 1 + DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE: ${{ steps.retrieve-secrets.outputs.dct-delegate-repo-passphrase }} + + - name: Push version images + run: ./build.sh push $($env:$RELEASE_VERSION) + shell: pwsh + env: + DOCKER_CONTENT_TRUST: 1 + DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE: ${{ steps.retrieve-secrets.outputs.dct-delegate-repo-passphrase }} + + - name: Make docker stub + run: | + STUB_OUTPUT=$(pwd)/docker-stub + docker run -i --rm --name setup -v $STUB_OUTPUT:/bitwarden bitwarden/setup:dev \ + dotnet Setup.dll -stub 1 -install 1 -domain bitwarden.example.com -os lin + sudo chown -R $(whoami):$(whoami) $STUB_OUTPUT + rm -rf $STUB_OUTPUT/letsencrypt + rm $STUB_OUTPUT/env/uid.env $STUB_OUTPUT/config.yml + touch $STUB_OUTPUT/env/uid.env + cd docker-stub; zip -r ../docker-stub.zip *; cd .. + + - name: Upload docker stub artifact + uses: actions/upload-artifact@v2 + with: + name: docker-stub.zip + path: ./docker-stub.zip + + - name: Build swagger + run: | + cd ./src/Api + echo "Restore" + dotnet restore "Api.csproj" + echo "Clean" + dotnet clean "Api.csproj" -c "Release" -o "obj/Docker/publish/Api" + echo "Publish" + dotnet publish "Api.csproj" -c "Release" -o "obj/Docker/publish/Api" + + dotnet swagger tofile --output ../../swagger.json --host https://api.bitwarden.com ` + ./obj/Docker/publish/Api/Api.dll public + cd ../.. + shell: pwsh + env: + ASPNETCORE_ENVIRONMENT: Production + swaggerGen: 'True' + + - name: Upload swagger artifact + uses: actions/upload-artifact@v2 + with: + name: swagger.json + path: ./swagger.json + + - name: Log out of docker + run: docker logout + + - name: Upload release assets + if: github.event_name == 'release' + run: | + hub release edit ` + -a ./swagger.json ` + -a ./docker-stub.zip ` + -m "Version $($env:RELEASE_VERSION)" ` + $env:RELEASE_TAG_NAME + shell: pwsh + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +