diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index fce9f576..bcfcaaaa 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -66,40 +66,64 @@ jobs: run: | gcloud auth configure-docker australia-southeast1-docker.pkg.dev - - name: build - run: | - docker build . -f Dockerfile --tag $IMAGE_NAME:${{ github.sha }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 #v3.11.1 - - name: push commit sha tag + - name: Build and push development image + if: ${{ github.ref_name != 'main' && github.ref_name != 'alpha' }} + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0 + with: + context: . + file: ./Dockerfile + push: true + tags: | + ${{ env.DOCKER_DEV }}/${{ env.IMAGE_NAME }}:${{ github.event.pull_request.head.sha }} + cache-from: type=gha + cache-to: type=gha,mode=max + outputs: type=image,name=${{ env.DOCKER_DEV }}/${{ env.IMAGE_NAME }},push-by-digest=false + + - name: Set development image env vars if: ${{ github.ref_name != 'main' && github.ref_name != 'alpha' }} run: | - docker tag $IMAGE_NAME:${{ github.sha }} $DOCKER_DEV/$IMAGE_NAME:${{ github.event.pull_request.head.sha }} - docker push $DOCKER_DEV/$IMAGE_NAME:${{ github.event.pull_request.head.sha }} - DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' $DOCKER_DEV/$IMAGE_NAME:${{ github.event.pull_request.head.sha }} | cut -d'@' -f2) + DIGEST=$(docker buildx imagetools inspect $DOCKER_DEV/$IMAGE_NAME:${{ github.event.pull_request.head.sha }} --format '{{json .}}' | jq -r '.manifest.digest') echo "DOCKER_IMAGE=$DOCKER_DEV/$IMAGE_NAME:${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV echo "DOCKER_DIGEST=$DIGEST" >> $GITHUB_ENV - - name: push production on version bump + - name: Build and push production image + if: ${{ github.event_name == 'push' && (github.ref_name == 'main' || github.ref_name == 'alpha') && startsWith(github.event.head_commit.message, 'bump:') }} + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0 + with: + context: . + file: ./Dockerfile + push: true + tags: ${{ env.DOCKER_MAIN }}/${{ env.IMAGE_NAME }}:${{ env.VERSION }} + # Production builds don't use cache for reproducibility + no-cache: true + + - name: Set production image env vars if: ${{ github.event_name == 'push' && (github.ref_name == 'main' || github.ref_name == 'alpha') && startsWith(github.event.head_commit.message, 'bump:') }} run: | - docker tag $IMAGE_NAME:${{ github.sha }} $DOCKER_MAIN/$IMAGE_NAME:$VERSION - docker push $DOCKER_MAIN/$IMAGE_NAME:$VERSION - DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' $DOCKER_MAIN/$IMAGE_NAME:$VERSION | cut -d'@' -f2) + DIGEST=$(docker buildx imagetools inspect $DOCKER_MAIN/$IMAGE_NAME:$VERSION --format '{{json .}}' | jq -r '.manifest.digest') echo "DOCKER_IMAGE=$DOCKER_MAIN/$IMAGE_NAME:$VERSION" >> $GITHUB_ENV echo "DOCKER_DIGEST=$DIGEST" >> $GITHUB_ENV - - name: manually triggered build + - name: Build and push manually triggered image + if: ${{ github.event_name == 'workflow_dispatch' && github.ref_name != 'main' }} + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0 + with: + context: . + file: ./Dockerfile + push: true + tags: ${{ env.DOCKER_DEV }}/${{ env.IMAGE_NAME }}:${{ github.event.inputs.tag }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Set manually triggered image env vars if: ${{ github.event_name == 'workflow_dispatch' && github.ref_name != 'main' }} env: - IMAGE_NAME: $IMAGE_NAME - DOCKER_DEV: $DOCKER_DEV TAG: ${{ github.event.inputs.tag }} - SHA: ${{ github.sha }} run: | - set -euo pipefail - docker tag "$IMAGE_NAME:$SHA" "$DOCKER_DEV/$IMAGE_NAME:$TAG" - docker push "$DOCKER_DEV/$IMAGE_NAME:$TAG" - DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "$DOCKER_DEV/$IMAGE_NAME:$TAG" | cut -d'@' -f2) + DIGEST=$(docker buildx imagetools inspect $DOCKER_DEV/$IMAGE_NAME:$TAG --format '{{json .}}' | jq -r '.manifest.digest') echo "DOCKER_IMAGE=$DOCKER_DEV/$IMAGE_NAME:$TAG" >> "$GITHUB_ENV" echo "DOCKER_DIGEST=$DIGEST" >> "$GITHUB_ENV" diff --git a/Dockerfile b/Dockerfile index 41a659d4..5c34e0ee 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,19 +11,17 @@ ENV UV_COMPILE_BYTECODE=1 ENV UV_LINK_MODE=copy # Install the project's dependencies using the lockfile and settings -# Copy `pyproject.toml` and `uv.lock` into `/cpg-flow` explicitly -COPY pyproject.toml uv.lock /cpg-flow/ - -# Install the project's dependencies using the lockfile and settings +# Use bind mounts - files are available during RUN but not persisted in layer RUN --mount=type=cache,target=/root/.cache/uv \ --mount=type=bind,source=uv.lock,target=uv.lock \ --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ - uv sync --frozen --no-install-project + uv sync --locked --no-install-project --no-dev -# Add the project source code from src/cpg-flow -ADD . /cpg-flow +# Then, add the rest of the project source code and install it +# Installing separately from its dependencies allows optimal layer caching +COPY . /cpg-flow RUN --mount=type=cache,target=/root/.cache/uv \ - uv sync --frozen + uv sync --locked --no-dev # Place executables in the environment at the front of the path ENV PATH="/cpg-flow/.venv/bin:$PATH"