Refactor build script to actually have a working cache using buildah

The old "docker build" no longer does caching the way it used to, and our cache logic doesn't work.

The new cache logic uses buildah, which is an alternate image build tool.
Buildah comes pre-installed on GHA.

When building, it pushes each layer as it goes to the cache repo.
It queries the repo for layers that are already built, so we don't need to explicitly pull
any specific tags and cache from them.

If caching is not enabled we still use docker as normal, so local development is not affected.
Local automatic caching will still apply.
pull/428/merge
Mike Lang 3 weeks ago committed by Mike Lang
parent 4238ab5d9d
commit bff3fa7800

@ -19,7 +19,7 @@ permissions:
# build components using a job matrix, so they can run in parallel # build components using a job matrix, so they can run in parallel
jobs: jobs:
build: build:
runs-on: ubuntu-20.04 runs-on: ubuntu-24.04
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@ -65,4 +65,4 @@ jobs:
run: | run: |
export PUSH=true export PUSH=true
if [ "$GITHUB_EVENT_NAME" != "pull_request" ] && [ "$GITHUB_REF" == "refs/heads/master" ]; then export PUSH=latest; fi if [ "$GITHUB_EVENT_NAME" != "pull_request" ] && [ "$GITHUB_REF" == "refs/heads/master" ]; then export PUSH=latest; fi
CACHE_FROM="latest" ./build ${{ matrix.component }} CACHE=true ./build ${{ matrix.component }}

47
build

@ -34,6 +34,9 @@ PUSH=${PUSH:-}
# Base is the repository namespace information, not including the wubloader-component part. # Base is the repository namespace information, not including the wubloader-component part.
BASE="ghcr.io/dbvideostriketeam" BASE="ghcr.io/dbvideostriketeam"
# cache name is the name of the repository we store shared layer cache in
CACHE_NAME="$BASE/wubloader-cache"
# The docker image tag, derived from the git commit + whether working tree is clean # The docker image tag, derived from the git commit + whether working tree is clean
TAG=$(./get-build-tag) TAG=$(./get-build-tag)
@ -41,34 +44,30 @@ if [ "$#" -gt 0 ]; then
COMPONENTS=("$@") COMPONENTS=("$@")
fi fi
# If CACHE_FROM is set, explicitly pull and re-use specified image versions # If CACHE is set, image layers will be pushed to the registry during the build,
CACHE_IMAGES=() # and re-use any layers from this cache instead of rebuilding them.
# You can set CACHE=readonly to only use the cache and not write to it (eg. due to permissions)
# Setting CACHE requires buildah be installed and configured, as this is used for the build instead of docker.
case "${CACHE:-}" in
"")
CACHE_ARGS=() CACHE_ARGS=()
if [ -n "${CACHE_FROM:-}" ]; then BUILD_CMD="docker"
# Note lack of quotes here - we want to word split ;;
for commit in $CACHE_FROM; do readonly)
if [ "$commit" == "latest" ]; then CACHE_ARGS+=("--cache-from" "$CACHE_NAME")
tag="latest" BUILD_CMD="buildah"
else ;;
tag=$(git rev-parse --short "$commit") *)
fi CACHE_ARGS+=("--layers" "--cache-to" "$CACHE_NAME" "--cache-from" "$CACHE_NAME")
for component in "${COMPONENTS[@]}"; do BUILD_CMD="buildah"
CACHE_IMAGES+=("$BASE/wubloader-$component:$tag") ;;
CACHE_ARGS+=("--cache-from" "$BASE/wubloader-$component:$tag") esac
done
done
echo "Trying to pull images for commits $CACHE_FROM if they exist, to re-use layers if possible"
for image in "${CACHE_IMAGES[@]}"; do
echo "Pulling $image"
docker pull "$image" || true # don't exit on failure
done
fi
for component in "${COMPONENTS[@]}"; do for component in "${COMPONENTS[@]}"; do
echo "Building image for $component" echo "Building image for $component"
latest="$BASE/wubloader-$component:latest" latest="$BASE/wubloader-$component:latest"
specific="$BASE/wubloader-$component:$TAG" specific="$BASE/wubloader-$component:$TAG"
docker build \ "$BUILD_CMD" build \
-f "$component/Dockerfile" \ -f "$component/Dockerfile" \
-t "$latest" \ -t "$latest" \
-t "$specific" \ -t "$specific" \
@ -77,10 +76,10 @@ for component in "${COMPONENTS[@]}"; do
echo "Built image wubloader-$component:$TAG" echo "Built image wubloader-$component:$TAG"
if [ -n "$PUSH" ]; then if [ -n "$PUSH" ]; then
echo "Pushing tag $specific" echo "Pushing tag $specific"
docker push "$specific" "$BUILD_CMD" push "$specific"
fi fi
if [ "$PUSH" == "latest" ]; then if [ "$PUSH" == "latest" ]; then
echo "Pushing tag $latest" echo "Pushing tag $latest"
docker push "$latest" "$BUILD_CMD" push "$latest"
fi fi
done done

Loading…
Cancel
Save