Build and Deploy to Dev #23
This file contains hidden or 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
| # Build and Deploy to Dev Environment | |
| # | |
| # This workflow is designed for testing feature branches in the dev environment. | |
| # It builds Docker images from the current branch and deploys them to dev only. | |
| # | |
| # When to use: | |
| # - Testing feature branches before merging to master | |
| # - Manual testing of changes in a controlled environment | |
| # - Debugging issues that need to be tested in dev | |
| # | |
| # What it does: | |
| # - Builds backend, frontend, and Airflow images from current branch | |
| # - Tags images with branch name (e.g., feat-897-change-release-pattern) | |
| # - Deploys all services to dev environment only | |
| # - Does NOT deploy to test or production environments | |
| # | |
| # Security: This workflow can only deploy to dev environment due to the 'environment: dev' | |
| # restriction in the job configuration. | |
| name: Build and Deploy to Dev | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| image_tag: | |
| description: 'Image tag to build and deploy (defaults to branch name)' | |
| required: false | |
| default: '' | |
| env: | |
| app-name: carrot | |
| repo-owner: health-informatics-uon | |
| registry: ghcr.io | |
| permissions: | |
| contents: read | |
| packages: write | |
| jobs: | |
| # Single job that builds and deploys everything to dev environment | |
| build-and-deploy: | |
| runs-on: ubuntu-latest | |
| # Security: This restricts the job to only use dev environment secrets and variables | |
| environment: dev | |
| steps: | |
| - name: Check out the repo | |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 | |
| - name: Docker Login | |
| uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 | |
| with: | |
| registry: ${{ env.registry }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Set timestamp env var | |
| run: echo "RUN_TIMESTAMP=$(TZ="Etc/UTC" date +'%Y%m%d%H%M%S')" >> $GITHUB_ENV | |
| # Set the image tag - either from user input or derived from branch name | |
| - name: Set default image tag | |
| run: | | |
| if [ -z "${{ github.event.inputs.image_tag }}" ]; then | |
| # Use branch name, replacing slashes with dashes for valid Docker tag format | |
| # e.g., feat/897/change-release-pattern -> feat-897-change-release-pattern | |
| BRANCH_TAG=$(echo "${{ github.ref_name }}" | sed 's/\//-/g') | |
| echo "IMAGE_TAG=$BRANCH_TAG" >> $GITHUB_ENV | |
| else | |
| echo "IMAGE_TAG=${{ github.event.inputs.image_tag }}" >> $GITHUB_ENV | |
| fi | |
| # Build and push backend | |
| - name: Extract backend Docker metadata | |
| id: backend_meta | |
| uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0 | |
| with: | |
| images: ${{ env.registry }}/${{ env.repo-owner }}/${{ env.app-name }}/backend | |
| tags: | | |
| type=raw,value=${{ env.IMAGE_TAG }} | |
| type=raw,value=${{ github.sha }} | |
| type=raw,value=${{ env.RUN_TIMESTAMP }} | |
| - name: Build and push backend image | |
| uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0 | |
| with: | |
| context: ./app | |
| file: ./app/api/Dockerfile | |
| push: true | |
| platforms: linux/amd64,linux/arm64 | |
| tags: ${{ steps.backend_meta.outputs.tags }} | |
| # Build and push frontend | |
| - name: Extract frontend Docker metadata | |
| id: frontend_meta | |
| uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0 | |
| with: | |
| images: ${{ env.registry }}/${{ env.repo-owner }}/${{ env.app-name }}/frontend | |
| tags: | | |
| type=raw,value=${{ env.IMAGE_TAG }} | |
| type=raw,value=${{ github.sha }} | |
| type=raw,value=${{ env.RUN_TIMESTAMP }} | |
| - name: Build and push frontend image | |
| uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0 | |
| with: | |
| context: ./app/next-client-app | |
| file: ./app/next-client-app/Dockerfile | |
| push: true | |
| platforms: linux/amd64,linux/arm64 | |
| tags: ${{ steps.frontend_meta.outputs.tags }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| # Build and push Airflow webserver | |
| - name: Extract Airflow webserver Docker metadata | |
| id: airflow_webserver_meta | |
| uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0 | |
| with: | |
| images: ${{ env.registry }}/${{ env.repo-owner }}/${{ env.app-name }}/airflow-webserver | |
| tags: | | |
| type=raw,value=${{ env.IMAGE_TAG }} | |
| type=raw,value=${{ github.sha }} | |
| type=raw,value=${{ env.RUN_TIMESTAMP }} | |
| - name: Build and push Airflow webserver image | |
| uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0 | |
| with: | |
| context: ./app/airflow | |
| file: ./app/airflow/Dockerfile | |
| build-args: AIRFLOW_COMPONENT=webserver | |
| push: true | |
| platforms: linux/amd64,linux/arm64 | |
| tags: ${{ steps.airflow_webserver_meta.outputs.tags }} | |
| # Build and push Airflow scheduler | |
| - name: Extract Airflow scheduler Docker metadata | |
| id: airflow_scheduler_meta | |
| uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0 | |
| with: | |
| images: ${{ env.registry }}/${{ env.repo-owner }}/${{ env.app-name }}/airflow-scheduler | |
| tags: | | |
| type=raw,value=${{ env.IMAGE_TAG }} | |
| type=raw,value=${{ github.sha }} | |
| type=raw,value=${{ env.RUN_TIMESTAMP }} | |
| - name: Build and push Airflow scheduler image | |
| uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0 | |
| with: | |
| context: ./app/airflow | |
| file: ./app/airflow/Dockerfile | |
| build-args: AIRFLOW_COMPONENT=scheduler | |
| push: true | |
| platforms: linux/amd64,linux/arm64 | |
| tags: ${{ steps.airflow_scheduler_meta.outputs.tags }} | |
| # ============================================================================= | |
| # DEPLOY TO DEV ENVIRONMENT | |
| # ============================================================================= | |
| # All deployments are restricted to dev environment only for security | |
| - name: Deploy Backend to Dev | |
| uses: azure/webapps-deploy@2fdd5c3ebb4e540834e86ecc1f6fdcd5539023ee # v3.0.2 | |
| with: | |
| app-name: ${{ vars.AZURE_WEBAPP_NAME }} | |
| publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }} | |
| images: ${{ env.registry }}/${{ env.repo-owner }}/${{ env.app-name }}/backend:${{ env.IMAGE_TAG }} | |
| - name: Deploy Frontend to Dev | |
| uses: azure/webapps-deploy@2fdd5c3ebb4e540834e86ecc1f6fdcd5539023ee # v3.0.2 | |
| with: | |
| app-name: ${{ vars.AZURE_WEBAPP_NEXT_NAME }} | |
| publish-profile: ${{ secrets.AZURE_WEBAPP_NEXT_PUBLISH_PROFILE }} | |
| images: ${{ env.registry }}/${{ env.repo-owner }}/${{ env.app-name }}/frontend:${{ env.IMAGE_TAG }} | |
| - name: Deploy Airflow Webserver to Dev | |
| uses: azure/webapps-deploy@2fdd5c3ebb4e540834e86ecc1f6fdcd5539023ee # v3.0.2 | |
| with: | |
| app-name: ${{ vars.AIRFLOW_WEBSERVER_NAME }} | |
| publish-profile: ${{ secrets.AIRFLOW_WEBSERVER_PUBLISH_PROFILE }} | |
| images: ${{ env.registry }}/${{ env.repo-owner }}/${{ env.app-name }}/airflow-webserver:${{ env.IMAGE_TAG }} | |
| - name: Deploy Airflow Scheduler to Dev | |
| uses: azure/webapps-deploy@2fdd5c3ebb4e540834e86ecc1f6fdcd5539023ee # v3.0.2 | |
| with: | |
| app-name: ${{ vars.AIRFLOW_SCHEDULER_NAME }} | |
| publish-profile: ${{ secrets.AIRFLOW_SCHEDULER_PUBLISH_PROFILE }} | |
| images: ${{ env.registry }}/${{ env.repo-owner }}/${{ env.app-name }}/airflow-scheduler:${{ env.IMAGE_TAG }} |