From a38b35c62b6becc8f817f070c537e509966d59f9 Mon Sep 17 00:00:00 2001 From: Levi McDonough Date: Sat, 14 Dec 2024 19:01:47 -0500 Subject: [PATCH] Enhance GitHub Actions workflow for building and deploying containers with updated actions, improved environment variable handling, and added artifact attestations for images. --- .../workflows/build_and_deploy_containers.yml | 115 ++++++++++-------- 1 file changed, 65 insertions(+), 50 deletions(-) diff --git a/.github/workflows/build_and_deploy_containers.yml b/.github/workflows/build_and_deploy_containers.yml index 91bb7bb..968cb6e 100644 --- a/.github/workflows/build_and_deploy_containers.yml +++ b/.github/workflows/build_and_deploy_containers.yml @@ -10,19 +10,26 @@ on: workflow_dispatch: # Allow manual triggering env: - CARGO_TERM_COLOR: always REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BACKEND_IMAGE_NAME: rust-backend + FRONTEND_IMAGE_NAME: nextjs-frontend jobs: build_test_run: name: Build and Test runs-on: ubuntu-22.04 + permissions: + contents: read + packages: write + attestations: write + id-token: write steps: # Checkout the repository - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Set environment variables from secrets - name: Set environment variables @@ -34,7 +41,6 @@ jobs: echo "POSTGRES_SCHEMA=${{ secrets.POSTGRES_SCHEMA }}" >> $GITHUB_ENV echo "POSTGRES_HOST=${{ secrets.POSTGRES_HOST }}" >> $GITHUB_ENV echo "DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}" >> $GITHUB_ENV - echo "BACKEND_PORT=${{ secrets.BACKEND_PORT }}" >> $GITHUB_ENV echo "BACKEND_INTERFACE=${{ secrets.BACKEND_INTERFACE }}" >> $GITHUB_ENV echo "PLATFORM=${{ secrets.PLATFORM }}" >> $GITHUB_ENV @@ -79,41 +85,19 @@ jobs: steps: # Checkout the repository - name: Checkout - uses: actions/checkout@v3 - - # Set environment variables from secrets - - name: Set environment variables - run: | - echo "POSTGRES_USER=${{ secrets.POSTGRES_USER }}" >> $GITHUB_ENV - echo "POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }}" >> $GITHUB_ENV - echo "POSTGRES_DB=${{ secrets.POSTGRES_DB }}" >> $GITHUB_ENV - echo "POSTGRES_PORT=${{ secrets.POSTGRES_PORT }}" >> $GITHUB_ENV - echo "POSTGRES_SCHEMA=${{ secrets.POSTGRES_SCHEMA }}" >> $GITHUB_ENV - echo "POSTGRES_HOST=${{ secrets.POSTGRES_HOST }}" >> $GITHUB_ENV - echo "DATABASE_URL=${{ secrets.DATABASE_URL }}" >> $GITHUB_ENV - echo "BACKEND_PORT=${{ secrets.BACKEND_PORT }}" >> $GITHUB_ENV - echo "BACKEND_INTERFACE=${{ secrets.BACKEND_INTERFACE }}" >> $GITHUB_ENV - echo "PLATFORM=${{ secrets.PLATFORM }}" >> $GITHUB_ENV - echo "CONTAINER_NAME=${{ secrets.CONTAINER_NAME }}" >> $GITHUB_ENV - echo "FRONTEND_CONTAINER_NAME=${{ secrets.FRONTEND_CONTAINER_NAME }}" >> $GITHUB_ENV - echo "FRONTEND_PORT=${{ secrets.FRONTEND_PORT }}" >> $GITHUB_ENV - echo "DB_DNS_ALIAS=${{ secrets.DB_DNS_ALIAS }}" >> $GITHUB_ENV - echo "BACKEND_DNS_ALIAS=${{ secrets.BACKEND_DNS_ALIAS }}" >> $GITHUB_ENV - echo "FRONTEND_DNS_ALIAS=${{ secrets.FRONTEND_DNS_ALIAS }}" >> $GITHUB_ENV - echo "BACKEND_ALLOWED_ORIGINS=${{ secrets.BACKEND_ALLOWED_ORIGINS }}" >> $GITHUB_ENV - echo "BACKEND_LOG_FILTER_LEVEL=${{ secrets.BACKEND_LOG_FILTER_LEVEL }}" >> $GITHUB_ENV + uses: actions/checkout@v4 # Log in to GitHub Container Registry - - name: Log in to GitHub Container Registry + - name: Log in to the Container registry uses: docker/login-action@v2 with: - registry: ghcr.io + registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} # Set up Docker Buildx - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 # Cache Docker layers - name: Cache Docker layers @@ -124,32 +108,63 @@ jobs: restore-keys: | ${{ runner.os }}-buildx- + # Extract metadata (tags, labels) for Docker + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY }}/${{ env.BACKEND_IMAGE_NAME }}-${{ github.actor }}:${{ github.sha }}, ${{ env.REGISTRY }}/${{ env.FRONTEND_IMAGE_NAME }}-${{ github.actor }}:${{ github.sha }} + # Build and push Rust backend image - name: Build and Push Rust Backend Image - run: | - BRANCH_NAME=$(echo ${{ github.ref_name }} | cut -c1-10) - IMAGE_TAG=$(echo ${{ github.sha }} | cut -c1-10) - echo "Building and pushing Rust backend image with tag: ${BRANCH_NAME}-rust-backend-${IMAGE_TAG}" - docker buildx build --platform linux/amd64,linux/arm64 \ - --cache-from type=local,src=/tmp/.buildx-cache \ - --cache-to type=local,dest=/tmp/.buildx-cache-new \ - -t ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${BRANCH_NAME}-rust-backend-${IMAGE_TAG} \ - -f Dockerfile \ - --push . + id: push_backend + uses: docker/build-push-action@v6 + with: + platforms: linux/amd64,linux/arm64 + context: . + push: true + tags: | + ${{ env.REGISTRY }}/${{ env.BACKEND_IMAGE_NAME }}-${{ github.actor }}:${{ github.sha }} + ${{ steps.meta.outputs.tags }}-${{ github.sha }} + ${{ github.actor }}/${{ env.BACKEND_IMAGE_NAME }}:${{ github.sha }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache-new + file: Dockerfile # Build and push Next.js frontend image - name: Build and Push Next.js Frontend Image - run: | - BRANCH_NAME=$(echo ${{ github.ref_name }} | cut -c1-10) - IMAGE_TAG=$(echo ${{ github.sha }} | cut -c1-10) - echo "Building and pushing Next.js frontend image with tag: ${BRANCH_NAME}-nextjs-frontend-${IMAGE_TAG}" - docker buildx build --platform linux/amd64,linux/arm64 \ - --cache-from type=local,src=/tmp/.buildx-cache \ - --cache-to type=local,dest=/tmp/.buildx-cache-new \ - -t ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${BRANCH_NAME}-nextjs-frontend-${IMAGE_TAG} \ - -f web/Dockerfile \ - --push . + id: push_frontend + uses: docker/build-push-action@v6 + with: + platforms: linux/amd64,linux/arm64 + context: web + push: true + tags: | + ${{ env.REGISTRY }}/${{ env.FRONTEND_IMAGE_NAME }}-${{ github.actor }}:${{ github.sha }} + ${{ steps.meta.outputs.tags }}-${{ github.sha }} + ${{ github.actor }}/${{ env.FRONTEND_IMAGE_NAME }}:${{ github.sha }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache-new + file: web/Dockerfile # Move new cache to the original location - name: Move new cache - run: mv /tmp/.buildx-cache-new /tmp/.buildx-cache \ No newline at end of file + run: mv /tmp/.buildx-cache-new /tmp/.buildx-cache + + # Generate artifact attestation for Rust backend image + - name: Generate artifact attestation for Rust Backend Image + uses: actions/attest-build-provenance@v2 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.BACKEND_IMAGE_NAME }}-rust-backend + subject-digest: ${{ steps.push_backend.outputs.digest }} + push-to-registry: true + + # Generate artifact attestation for Next.js frontend image + - name: Generate artifact attestation for Next.js Frontend Image + uses: actions/attest-build-provenance@v2 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.FRONTEND_IMAGE_NAME }}-nextjs-frontend + subject-digest: ${{ steps.push_frontend.outputs.digest }} + push-to-registry: true \ No newline at end of file