diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 000000000..6995e9175 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,182 @@ +--- +name: Publish +run-name: Publish ${{ inputs.publish_type }} + +on: + workflow_dispatch: + inputs: + publish_type: + description: "Publish Options" + required: true + default: "Initial Publish" + type: choice + options: + - Initial Publish + - Redeploy + - Dry Run + version: + description: 'Version to publish (default: latest release)' + required: true + type: string + default: latest + +env: + _AZ_REGISTRY: "bitwardenprod.azurecr.io" + +jobs: + setup: + name: Setup + runs-on: ubuntu-22.04 + outputs: + branch-name: ${{ steps.branch.outputs.branch-name }} + deployment-id: ${{ steps.deployment.outputs.deployment-id }} + release-version: ${{ steps.version-output.outputs.version }} + steps: + - name: Version output + id: version-output + run: | + if [[ "${{ inputs.version }}" == "latest" || "${{ inputs.version }}" == "" ]]; then + VERSION=$(curl "https://api.github.com/repos/bitwarden/server/releases" | jq -c '.[] | select(.tag_name) | .tag_name' | head -1 | grep -ohE '20[0-9]{2}\.([1-9]|1[0-2])\.[0-9]+') + echo "Latest Released Version: $VERSION" + echo "version=$VERSION" >> $GITHUB_OUTPUT + else + echo "Release Version: ${{ inputs.version }}" + echo "version=${{ inputs.version }}" >> $GITHUB_OUTPUT + fi + + - name: Get branch name + id: branch + run: | + BRANCH_NAME=$(basename ${{ github.ref }}) + echo "branch-name=$BRANCH_NAME" >> $GITHUB_OUTPUT + + - name: Create GitHub deployment + uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7 + id: deployment + with: + token: '${{ secrets.GITHUB_TOKEN }}' + initial-status: 'in_progress' + environment: 'production' + description: 'Deployment ${{ steps.version-output.outputs.release-version }} from branch ${{ github.ref_name }}' + task: release + + publish-docker: + name: Publish Docker images + runs-on: ubuntu-22.04 + needs: setup + env: + _RELEASE_VERSION: ${{ needs.setup.outputs.release-version }} + _BRANCH_NAME: ${{ needs.setup.outputs.branch-name }} + strategy: + fail-fast: false + matrix: + include: + - project_name: Admin + - project_name: Api + - project_name: Attachments + - project_name: Billing + - project_name: Events + - project_name: EventsProcessor + - project_name: Icons + - project_name: Identity + - project_name: MsSql + - project_name: MsSqlMigratorUtility + - project_name: Nginx + - project_name: Notifications + - project_name: Scim + - project_name: Server + - project_name: Setup + - project_name: Sso + steps: + - name: Print environment + env: + RELEASE_OPTION: ${{ inputs.publish_type }} + run: | + whoami + docker --version + echo "GitHub ref: $GITHUB_REF" + echo "GitHub event: $GITHUB_EVENT" + echo "Github Release Option: $RELEASE_OPTION" + + - name: Check out repo + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + + - name: Set up project name + id: setup + run: | + PROJECT_NAME=$(echo "${{ matrix.project_name }}" | awk '{print tolower($0)}') + echo "Matrix name: ${{ matrix.project_name }}" + echo "PROJECT_NAME: $PROJECT_NAME" + echo "project_name=$PROJECT_NAME" >> $GITHUB_OUTPUT + + ########## ACR PROD ########## + - name: Log in to Azure - production subscription + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 + with: + creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }} + + - name: Log in to Azure ACR + run: az acr login -n $_AZ_REGISTRY --only-show-errors + + - name: Pull latest project image + env: + PROJECT_NAME: ${{ steps.setup.outputs.project_name }} + run: | + if [[ "${{ inputs.publish_type }}" == "Dry Run" ]]; then + docker pull $_AZ_REGISTRY/$PROJECT_NAME:latest + else + docker pull $_AZ_REGISTRY/$PROJECT_NAME:$_BRANCH_NAME + fi + + - name: Tag version and latest + env: + PROJECT_NAME: ${{ steps.setup.outputs.project_name }} + run: | + if [[ "${{ inputs.publish_type }}" == "Dry Run" ]]; then + docker tag $_AZ_REGISTRY/$PROJECT_NAME:latest $_AZ_REGISTRY/$PROJECT_NAME:dryrun + else + docker tag $_AZ_REGISTRY/$PROJECT_NAME:$_BRANCH_NAME $_AZ_REGISTRY/$PROJECT_NAME:$_RELEASE_VERSION + docker tag $_AZ_REGISTRY/$PROJECT_NAME:$_BRANCH_NAME $_AZ_REGISTRY/$PROJECT_NAME:latest + fi + + - name: Push version and latest image + env: + PROJECT_NAME: ${{ steps.setup.outputs.project_name }} + run: | + if [[ "${{ inputs.publish_type }}" == "Dry Run" ]]; then + docker push $_AZ_REGISTRY/$PROJECT_NAME:dryrun + else + docker push $_AZ_REGISTRY/$PROJECT_NAME:$_RELEASE_VERSION + docker push $_AZ_REGISTRY/$PROJECT_NAME:latest + fi + + - name: Log out of Docker + run: docker logout + + update-deployment: + name: Update Deployment Status + runs-on: ubuntu-22.04 + needs: + - setup + - publish-docker + if: ${{ always() && inputs.publish_type != 'Dry Run' }} + steps: + - name: Check if any job failed + if: contains(needs.*.result, 'failure') + run: exit 1 + + - name: Update deployment status to Success + if: ${{ inputs.publish_type != 'Dry Run' && success() }} + uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3 + with: + token: '${{ secrets.GITHUB_TOKEN }}' + state: 'success' + deployment-id: ${{ needs.setup.outputs.deployment-id }} + + - name: Update deployment status to Failure + if: ${{ inputs.publish_type != 'Dry Run' && failure() }} + uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3 + with: + token: '${{ secrets.GITHUB_TOKEN }}' + state: 'failure' + deployment-id: ${{ needs.setup.outputs.deployment-id }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 35940bc53..7e0e8ae26 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -53,99 +53,6 @@ jobs: BRANCH_NAME=$(basename ${{ github.ref }}) echo "branch-name=$BRANCH_NAME" >> $GITHUB_OUTPUT - release-docker: - name: Build Docker images - runs-on: ubuntu-22.04 - needs: setup - env: - _RELEASE_VERSION: ${{ needs.setup.outputs.release_version }} - _BRANCH_NAME: ${{ needs.setup.outputs.branch-name }} - strategy: - fail-fast: false - matrix: - include: - - project_name: Admin - - project_name: Api - - project_name: Attachments - - project_name: Billing - - project_name: Events - - project_name: EventsProcessor - - project_name: Icons - - project_name: Identity - - project_name: MsSql - - project_name: MsSqlMigratorUtility - - project_name: Nginx - - project_name: Notifications - - project_name: Scim - - project_name: Server - - project_name: Setup - - project_name: Sso - steps: - - name: Print environment - env: - RELEASE_OPTION: ${{ inputs.release_type }} - run: | - whoami - docker --version - echo "GitHub ref: $GITHUB_REF" - echo "GitHub event: $GITHUB_EVENT" - echo "Github Release Option: $RELEASE_OPTION" - - - name: Check out repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - - name: Set up project name - id: setup - run: | - PROJECT_NAME=$(echo "${{ matrix.project_name }}" | awk '{print tolower($0)}') - echo "Matrix name: ${{ matrix.project_name }}" - echo "PROJECT_NAME: $PROJECT_NAME" - echo "project_name=$PROJECT_NAME" >> $GITHUB_OUTPUT - - ########## ACR PROD ########## - - name: Log in to Azure - production subscription - uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 - with: - creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }} - - - name: Log in to Azure ACR - run: az acr login -n $_AZ_REGISTRY --only-show-errors - - - name: Pull latest project image - env: - PROJECT_NAME: ${{ steps.setup.outputs.project_name }} - run: | - if [[ "${{ inputs.release_type }}" == "Dry Run" ]]; then - docker pull $_AZ_REGISTRY/$PROJECT_NAME:latest - else - docker pull $_AZ_REGISTRY/$PROJECT_NAME:$_BRANCH_NAME - fi - - - name: Tag version and latest - env: - PROJECT_NAME: ${{ steps.setup.outputs.project_name }} - run: | - if [[ "${{ inputs.release_type }}" == "Dry Run" ]]; then - docker tag $_AZ_REGISTRY/$PROJECT_NAME:latest $_AZ_REGISTRY/$PROJECT_NAME:dryrun - else - docker tag $_AZ_REGISTRY/$PROJECT_NAME:$_BRANCH_NAME $_AZ_REGISTRY/$PROJECT_NAME:$_RELEASE_VERSION - docker tag $_AZ_REGISTRY/$PROJECT_NAME:$_BRANCH_NAME $_AZ_REGISTRY/$PROJECT_NAME:latest - fi - - - name: Push version and latest image - env: - PROJECT_NAME: ${{ steps.setup.outputs.project_name }} - run: | - if [[ "${{ inputs.release_type }}" == "Dry Run" ]]; then - docker push $_AZ_REGISTRY/$PROJECT_NAME:dryrun - else - docker push $_AZ_REGISTRY/$PROJECT_NAME:$_RELEASE_VERSION - docker push $_AZ_REGISTRY/$PROJECT_NAME:latest - fi - - - name: Log out of Docker - run: docker logout - release: name: Create GitHub release runs-on: ubuntu-22.04