diff --git a/.github/workflows/build_deploy.yml b/.github/workflows/build_deploy.yml index 3399800..6c0d203 100644 --- a/.github/workflows/build_deploy.yml +++ b/.github/workflows/build_deploy.yml @@ -13,28 +13,42 @@ jobs: steps: - name: Checkout the repo uses: actions/checkout@v4 + - name: 🏗 Set up yq + uses: frenck/action-setup-yq@v1 - name: Get full and partial repository name id: meta run: | echo "GITHUB_REPOSITORY: ${{ github.repository }}" - if [[ "${{ github.repository }}" == *".git" ]]; then - if [[ "${{ github.repository }}" == "https://"* ]]; then - echo "GITHUB_REPOSITORY ends in .git and is a URL" - REPO=$(echo "${{ github.repository }}" | sed 's/\.git$//' | cut -d'/' -f4-5 | sed 's/[^a-zA-Z0-9\/-]/-/g') - else - echo "GITHUB_REPOSITORY ends in .git and is not a URL" - REPO=$(echo "${{ github.repository }}" | sed 's/\.git$//' | sed 's/[^a-zA-Z0-9\/-]/-/g') - fi + repo_temp="" + + if [[ "${{ github.repository }}" == git@* && "${{ github.repository }}" == *:* && "${{ github.repository }}" == *.git ]]; then + echo "Detected SSH style git remote (e.g. git@host:owner/repo.git)" + # Extracts 'owner/repo' from 'git@host:owner/repo.git' + repo_temp=$(echo "${{ github.repository }}" | sed 's/\.git$//' | awk -F: '{print $2}') + elif [[ "${{ github.repository }}" == "https://"* && "${{ github.repository }}" == *.git ]]; then + echo "Detected HTTPS URL ending in .git (e.g. https://host/owner/repo.git)" + # Extracts 'owner/repo' from 'https://host/owner/repo.git' + repo_temp=$(echo "${{ github.repository }}" | sed 's/\.git$//' | awk -F/ '{print $(NF-1)"/"$(NF)}') + elif [[ "${{ github.repository }}" == *.git ]]; then # Catches other cases ending in .git, like owner/repo.git or other path based .git repos + echo "Detected path-like git repo ending in .git (e.g. owner/repo.git)" + # Extracts 'owner/repo' from 'owner/repo.git' + repo_temp=$(echo "${{ github.repository }}" | sed 's/\.git$//') else - echo "GITHUB_REPOSITORY is not a URL" - REPO=$(echo "${{ github.repository }}" | sed 's/[^a-zA-Z0-9\/-]/-/g') + echo "Assuming owner/repo format (e.g. owner/repo)" + repo_temp="${{ github.repository }}" fi + + # Sanitize and lowercase for Docker image naming conventions + REPO=$(echo "$repo_temp" | tr '[:upper:]' '[:lower:]' | sed -e 's/[^a-z0-9\/-]/-/g' -e 's/--\+/-/g' -e 's/^-//g' -e 's/-$//g') + echo "REPO (image base name): $REPO" echo "REPO=$REPO" >> $GITHUB_OUTPUT REPO_NAME_ONLY=$(echo "$REPO" | cut -d'/' -f2) + echo "REPO_NAME_ONLY (project name): $REPO_NAME_ONLY" echo "REPO_NAME_ONLY=$REPO_NAME_ONLY" >> $GITHUB_OUTPUT REPO_PROJECT_PATH=/srv/$(echo "$REPO_NAME_ONLY") + echo "REPO_PROJECT_PATH: $REPO_PROJECT_PATH" echo "REPO_PROJECT_PATH=$REPO_PROJECT_PATH" >> $GITHUB_OUTPUT - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -176,6 +190,7 @@ jobs: # with: # cache-source: ${{ runner.temp }}/.cache/buildx-cache - name: Build container + id: build_container uses: docker/build-push-action@v6 with: outputs: type=docker,dest=${{ runner.temp }}/${{ steps.meta.outputs.REPO_NAME_ONLY }}-${{ github.ref_name }}_${{ github.sha }}.tar @@ -195,6 +210,45 @@ jobs: # path: ${{ runner.temp }}/${{ steps.meta.outputs.REPO_NAME_ONLY }}-${{ github.ref_name }}_${{ github.sha }}.tar # if-no-files-found: error # compression-level: 0 + - name: Update docker compose and "pin" just built image by adding image digest to tag + env: + IMAGE_DIGEST: ${{ steps.build_container.outputs.DIGEST }} + IMAGE_BASE_NAME: ${{ steps.meta.outputs.REPO }} + run: | + set -eu -o pipefail + echo "PROD_STATUS: ${PROD}" + echo "IMAGE_DIGEST: ${IMAGE_DIGEST}" + echo "IMAGE_BASE_NAME (for compose update): ${IMAGE_BASE_NAME}" + + TARGET_COMPOSE_FILE="" + SERVICE_YQ_PATH="" + IMAGE_TAG="" + + echo "Checking yq version..." + yq --version + + if [ "${PROD}" = "true" ]; then + TARGET_COMPOSE_FILE="./server/docker-compose_web.yml" + SERVICE1_YQ_PATH=".services.web" + SERVICE2_YQ_PATH=".services.celery" + IMAGE_TAG="stable" + + echo "Updating PROD configuration in $TARGET_COMPOSE_FILE for service $SERVICE_YQ_PATH" + yq -i "${SERVICE1_YQ_PATH}.image = \"${IMAGE_BASE_NAME}:${IMAGE_TAG}@${IMAGE_DIGEST}\"" "$TARGET_COMPOSE_FILE" + yq -i "${SERVICE2_YQ_PATH}.image = \"${IMAGE_BASE_NAME}:${IMAGE_TAG}@${IMAGE_DIGEST}\"" "$TARGET_COMPOSE_FILE" + else + TARGET_COMPOSE_FILE="./server/docker-compose_staging.yml" + SERVICE1_YQ_PATH=".services.\"web-staging\"" + SERVICE2_YQ_PATH=".services.\"celery-staging\"" + IMAGE_TAG="staging" + + echo "Updating STAGING configuration in $TARGET_COMPOSE_FILE for service $SERVICE_YQ_PATH" + yq -i "${SERVICE1_YQ_PATH}.image = \"${IMAGE_BASE_NAME}:${IMAGE_TAG}@${IMAGE_DIGEST}\"" "$TARGET_COMPOSE_FILE" + yq -i "${SERVICE2_YQ_PATH}.image = \"${IMAGE_BASE_NAME}:${IMAGE_TAG}@${IMAGE_DIGEST}\"" "$TARGET_COMPOSE_FILE" + fi + + echo "Successfully updated $TARGET_COMPOSE_FILE. Image pinned to:" + yq "${SERVICE_YQ_PATH}.image" "$TARGET_COMPOSE_FILE" - name: Get Deploy Secrets uses: bitwarden/sm-action@v2 with: