From fb7412370272bc35c973217e51604ad985559128 Mon Sep 17 00:00:00 2001 From: "Rossi, Tommaso (Bip Group)" Date: Thu, 25 Jul 2024 11:14:23 +0000 Subject: [PATCH] Merged PR 127: chore: Add GitHub deploy workflow (WIP) Add a GitHub workflow for deploying on Azure app-service with a blue-green deployment using slots --- .github/workflows/app_service_deploy.yaml | 135 ++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 .github/workflows/app_service_deploy.yaml diff --git a/.github/workflows/app_service_deploy.yaml b/.github/workflows/app_service_deploy.yaml new file mode 100644 index 0000000..8390ceb --- /dev/null +++ b/.github/workflows/app_service_deploy.yaml @@ -0,0 +1,135 @@ +name: Publish Docker image and deploy on App Service + +on: + workflow_dispatch: + inputs: + deploy: + type: boolean + description: Whether to deploy + use-staging-slot: + type: boolean + description: Whether to perform a blue-green deployment using a staging slot + +# TODO: (keep disabled for the moment) +# on: +# push: +# tags: +# - '*' + +env: + # use github packages as container registry + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + + build-and-push-image: + name: Build and push image + runs-on: ubuntu-22.04 + permissions: + contents: read + packages: write + attestations: write + id-token: write + outputs: + image-tags: ${{ steps.meta.outputs.tags }} + + steps: + + - name: Checkout + uses: actions/checkout@v4 + + - name: Log in to the Container Registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 # v3.3.0 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # for TAG github event, it generates two image tags: the git tag itself and 'latest' + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 # v5.5.1 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + id: push + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 # v6.5.0 + with: + context: . + # TODO put in standard {{context}}/Dockerfile ? + file: src/Presentation/PortaleFatture.BE.Api/Dockerfile + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + - name: Generate artifact attestation + uses: actions/attest-build-provenance@5e9cb68e95676991667494a6a4e59b8a2f13e1d0 # v1.3.3 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: true + + deploy: + name: Deploy + if: ${{ github.event.inputs.deploy == 'true' }} + needs: [build-and-push-image] + # self-hosted is needed to ping the health endpoint in subnet + runs-on: self-hosted + environment: prod + permissions: + id-token: write + contents: read + env: + ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }} + ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }} + ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }} + ARM_USE_OIDC: true + RESOURCE_GROUP_NAME: fat-p-app-rg + APP_NAME: fat-p-app-api-container + HEALTH_CHECK_PATH: /health + + steps: + + - name: Azure Login + uses: azure/login@6c251865b4e6290e7b78be643ea2d005bc51f69a # v2.1.1 + with: + client-id: ${{ env.ARM_CLIENT_ID }} + tenant-id: ${{ env.ARM_TENANT_ID }} + subscription-id: ${{ env.ARM_SUBSCRIPTION_ID }} + + - name: Deploy + uses: azure/webapps-deploy@de617f46172a906d0617bb0e50d81e9e3aec24c8 # v3.0.1 + if: ${{ github.event.inputs.use-staging-slot == 'false' }} + with: + resource-group-name: ${{ env.RESOURCE_GROUP_NAME }} + app-name: ${{ env.FUNCTION_APP_NAME }} + images: ${{ jobs.build-and-push-image.outputs.image-tags }} + + - name: Deploy to Staging Slot + uses: azure/webapps-deploy@de617f46172a906d0617bb0e50d81e9e3aec24c8 # v3.0.1 + if: ${{ github.event.inputs.use-staging-slot == 'true' }} + with: + resource-group-name: ${{ env.RESOURCE_GROUP_NAME }} + app-name: ${{ env.FUNCTION_APP_NAME }} + images: ${{ jobs.build-and-push-image.outputs.image-tags }} + slot-name: staging + + - name: Ping Staging Health + if: ${{ github.event.inputs.use-staging-slot == 'true' }} + run: | + curl \ + --retry 5 \ + --retry-max-time 120 \ + --retry-all-errors \ + -f 'https://${{ env.APP_NAME }}-staging.azurewebsites.net${{ env.HEALTH_CHECK_PATH }}' + + - name: Swap Staging and Production Slots + if: ${{ github.event.inputs.use-staging-slot == 'true' }} + run: | + az webapp deployment slot swap \ + -g ${{ env.RESOURCE_GROUP_NAME }} \ + -n ${{ env.APP_NAME }} \ + --slot staging \ + --target-slot production