Skip to content

Commit

Permalink
Merge pull request #141 from whoan/issue-138
Browse files Browse the repository at this point in the history
Support caching with BuildKit enabled
  • Loading branch information
whoan authored Oct 23, 2023
2 parents 08966d5 + 5f9303f commit 21854c9
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 20 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM docker:20.10.3
FROM docker:24.0.6

LABEL "maintainer"="whoan <[email protected]>"
LABEL "repository"="https://github.com/whoan/docker-build-with-cache-action"
Expand Down
24 changes: 10 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,19 @@ Built-in support for the most known registries:
- Docker Hub
- AWS ECR (private and public)
- GitHub's (old and new registry)
- Google Cloud's
- Google Cloud's (currently not under test)

## :exclamation: New behavior if you force `DOCKER_BUILDKIT=1`
## :star2: Action supercharged

> It only affects multi-stage builds
- Docker updated to 24.0.6
- BuildKit is enabled for faster/parallel builds
- Cache also works with BuildKit enabled except for old GitHub Docker Registry (docker.pkg.github.com). Migrate to ghcr.io or disable BuildKit in the step:

This action relies on old builder output where we could take the hash of each intermediate layer during build and tag it as an image.
When new builder is enabled (`DOCKER_BUILDKIT=1`), this action is not able to push the layers of intermediate stages as it can NOT parse the builder output.
As a workaround, the action now forces `DOCKER_BUILDKIT=0` by default, but if your workflow relies on the new builder, at the temporary price of not using caches for all the stages, you can enable `DOCKER_BUILDKIT` like this in your job step:

- name: Build with DOCKER_BUILDKIT enabled
env:
DOCKER_BUILDKIT: 1
uses: whoan/docker-build-with-cache-action@issue-139
...

For plans to be able to cache all stages with `DOCKER_BUILDKIT=1`, see #138.
- name: Build with DOCKER_BUILDKIT disabled
env:
DOCKER_BUILDKIT: 0
uses: whoan/docker-build-with-cache-action@master
...

## Inputs

Expand Down
51 changes: 46 additions & 5 deletions docker-build.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash

set -e
export DOCKER_BUILDKIT=${DOCKER_BUILDKIT:-0}
export DOCKER_BUILDKIT=${DOCKER_BUILDKIT:-1}

# helper functions
_has_value() {
Expand Down Expand Up @@ -41,6 +41,10 @@ _is_aws_ecr_public() {
[[ "$INPUT_REGISTRY" =~ ^public.ecr.aws$ ]]
}

_buildkit_is_enabled() {
[[ "$DOCKER_BUILDKIT" != 0 ]]
}

_get_aws_region() {
_is_aws_ecr_public && echo "us-east-1" && return
# tied to _is_aws_ecr_private implementation
Expand Down Expand Up @@ -329,6 +333,10 @@ pull_cached_stages() {
if [ "$INPUT_PULL_IMAGE_AND_STAGES" != true ]; then
return
fi
# cache importing/exporting is done in build statement when BuildKit is enabled
if _buildkit_is_enabled; then
return
fi
echo -e "\n[Action Step] Pulling image..."

if _is_aws_ecr_public; then
Expand All @@ -347,7 +355,7 @@ pull_cached_stages() {
fi
}

build_image() {
_build_image_legacy() {
echo -e "\n[Action Step] Building image..."
max_stage=$(_get_max_stage_number)

Expand All @@ -358,10 +366,9 @@ build_image() {

_parse_extra_args

# build image using cache
set -o pipefail
set -x
# shellcheck disable=SC2068,SC2086
# shellcheck disable=SC2086
docker build \
$cache_from \
--tag "$DUMMY_IMAGE_NAME" \
Expand All @@ -372,6 +379,36 @@ build_image() {
set +x
}

_build_image_buildkit() {
echo -e "\n[Action Step] Building image with BuildKit..."

local cache_image
cache_image="$(_get_full_stages_image_name)":latest

_parse_extra_args

set -x
docker buildx create --use
# shellcheck disable=SC2086
docker buildx build \
--load \
--cache-from type=registry,ref="$cache_image" \
--cache-to mode=max,image-manifest=true,type=registry,ref="$cache_image" \
--tag "$DUMMY_IMAGE_NAME" \
--file "${INPUT_CONTEXT}"/"${INPUT_DOCKERFILE}" \
${INPUT_BUILD_EXTRA_ARGS} \
"${extra_args[@]}" \
"${INPUT_CONTEXT}"
}

build_image() {
if _buildkit_is_enabled; then
_build_image_buildkit
else
_build_image_legacy
fi
}

tag_image() {
echo -e "\n[Action Step] Tagging image..."
local tag
Expand All @@ -395,7 +432,9 @@ push_image_and_stages() {
fi

_push_image_tags
_push_image_stages
if ! _buildkit_is_enabled; then
_push_image_stages
fi
}

logout_from_registry() {
Expand All @@ -416,3 +455,5 @@ tag_image
push_image_and_stages

echo "FULL_IMAGE_NAME=$(_get_full_image_name)" >> "$GITHUB_OUTPUT"

echo "End of script"

0 comments on commit 21854c9

Please sign in to comment.