Improve Docker cache reuse

- Separate cache tags because each architecture can replace a shared
  registry cache and leave the other platform with little useful reuse.
- Pin `homebrew-core` as a build input so its layer can be reused
  across brew-only changes without serving a stale tap after core moves.
- Keep generated Bundler cache files out of the Docker context so local
  development artefacts do not bloat or invalidate image builds.
- Cache apt metadata and downloads because package installs are a
  stable dependency layer and should not repeat avoidable network work.
This commit is contained in:
Mike McQuaid
2026-05-04 09:21:18 +01:00
parent 31d6c6923a
commit 05635369f9
3 changed files with 34 additions and 13 deletions
+9
View File
@@ -1,2 +1,11 @@
Library/Homebrew/vendor/portable-ruby
Library/Homebrew/vendor/bundle/ruby/.homebrew_gem_groups
Library/Homebrew/vendor/bundle/ruby/*/.homebrew_vendor_version
Library/Homebrew/vendor/bundle/ruby/*/bin
Library/Homebrew/vendor/bundle/ruby/*/build_info
Library/Homebrew/vendor/bundle/ruby/*/bundler.lock
Library/Homebrew/vendor/bundle/ruby/*/cache
Library/Homebrew/vendor/bundle/ruby/*/extensions
Library/Homebrew/vendor/bundle/ruby/*/plugins
Library/Homebrew/vendor/bundle/ruby/*/specifications
Library/Taps
+17 -8
View File
@@ -30,6 +30,7 @@ jobs:
labels: ${{ steps.attributes.outputs.labels }}
push: ${{ steps.attributes.outputs.push }}
merge: ${{ steps.attributes.outputs.merge }}
core_revision: ${{ steps.attributes.outputs.core_revision }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -45,6 +46,7 @@ jobs:
run: |
date="$(date --rfc-3339=seconds --utc)"
brew_version="$(git describe --tags --dirty --abbrev=7)"
core_revision="$(git ls-remote https://github.com/Homebrew/homebrew-core refs/heads/main | cut -f1)"
DELIMITER="END_LABELS_$(uuidgen)"
cat <<EOS | tee -a "${GITHUB_OUTPUT}"
@@ -98,9 +100,12 @@ jobs:
fi
done <<<"$(jq --raw-output '.[]' <<<"${VERSIONS}")"
# Transform the `matrix` variable into a JSON array.
echo "matrix=$(jq --null-input --compact-output '$ARGS.positional' --args "${matrix[@]}")" >>"${GITHUB_OUTPUT}"
echo "merge=${merge}" >>"${GITHUB_OUTPUT}"
{
# Transform the `matrix` variable into a JSON array.
echo "matrix=$(jq --null-input --compact-output '$ARGS.positional' --args "${matrix[@]}")"
echo "merge=${merge}"
echo "core_revision=${core_revision}"
} >>"${GITHUB_OUTPUT}"
{
DELIMITER="END_TAGS_$(uuidgen)"
@@ -178,8 +183,10 @@ jobs:
context: .
load: true
tags: brew
cache-from: type=registry,ref=ghcr.io/homebrew/ubuntu${{ matrix.version }}:cache
build-args: version=${{ matrix.version }}
cache-from: type=registry,ref=ghcr.io/homebrew/ubuntu${{ matrix.version }}:cache-${{ matrix.arch }}
build-args: |
version=${{ matrix.version }}
HOMEBREW_CORE_REVISION=${{ needs.generate-tags.outputs.core_revision }}
labels: ${{ needs.generate-tags.outputs.labels }}
- name: Run brew test-bot --only-setup
@@ -199,9 +206,11 @@ jobs:
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
with:
context: .
cache-from: type=registry,ref=ghcr.io/homebrew/ubuntu${{ matrix.version }}:cache
cache-to: type=registry,ref=ghcr.io/homebrew/ubuntu${{ matrix.version }}:cache,mode=max
build-args: version=${{ matrix.version }}
cache-from: type=registry,ref=ghcr.io/homebrew/ubuntu${{ matrix.version }}:cache-${{ matrix.arch }}
cache-to: type=registry,ref=ghcr.io/homebrew/ubuntu${{ matrix.version }}:cache-${{ matrix.arch }},mode=max
build-args: |
version=${{ matrix.version }}
HOMEBREW_CORE_REVISION=${{ needs.generate-tags.outputs.core_revision }}
labels: ${{ needs.generate-tags.outputs.labels }}
outputs: type=image,name=ghcr.io/homebrew/ubuntu${{ matrix.version }},name-canonical=true,push=true,push-by-digest=true
+8 -5
View File
@@ -19,7 +19,9 @@ RUN touch /var/mail/ubuntu && chown ubuntu /var/mail/ubuntu && userdel -r ubuntu
# We need `[` instead of `[[` because the shell is `/bin/sh`.
# `:` below is a no-op that works around a ShellCheck parsing error.
# shellcheck disable=SC1091,SC2154,SC2292
RUN : \
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt/lists,sharing=locked \
: \
&& retry() { bash -c 'for i in {1..5}; do "$@" && exit 0; [[ $((i)) -lt 5 ]] && sleep $((i)); done; exit 1' -- "$@"; } \
&& retry apt-get update --error-on=any \
&& apt-get install -y --no-install-recommends software-properties-common gnupg-agent \
@@ -58,7 +60,6 @@ RUN : \
&& apt-get install -y --no-install-recommends gh \
&& apt-get remove --purge -y software-properties-common \
&& apt-get autoremove --purge -y \
&& rm -rf /var/lib/apt/lists/* \
&& sed -i -E 's/^(USERGROUPS_ENAB\s+)yes$/\1no/' /etc/login.defs \
&& localedef -i en_US -f UTF-8 en_US.UTF-8 \
&& useradd -u "${USER_ID}" --create-home --shell /bin/bash --user-group linuxbrew \
@@ -66,18 +67,20 @@ RUN : \
&& su - linuxbrew -c 'mkdir ~/.linuxbrew'
USER linuxbrew
COPY --chown=linuxbrew:linuxbrew . /home/linuxbrew/.linuxbrew/Homebrew
ENV PATH="/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:${PATH}" \
XDG_CACHE_HOME=/home/linuxbrew/.cache
WORKDIR /home/linuxbrew
ARG HOMEBREW_CORE_REVISION=origin/main
RUN --mount=type=cache,target=/tmp/homebrew-core,uid="${USER_ID}",sharing=locked \
# Clone the homebrew-core repo into /tmp/homebrew-core or pull latest changes if it exists
git clone https://github.com/homebrew/homebrew-core /tmp/homebrew-core || { cd /tmp/homebrew-core && git pull; } \
# Clone the homebrew-core repo into /tmp/homebrew-core or fetch latest changes if it exists
git clone https://github.com/homebrew/homebrew-core /tmp/homebrew-core || git -C /tmp/homebrew-core fetch origin main \
&& git -C /tmp/homebrew-core checkout --force -B main "${HOMEBREW_CORE_REVISION:-origin/main}" \
&& mkdir -p /home/linuxbrew/.linuxbrew/Homebrew/Library/Taps/homebrew/homebrew-core \
&& cp -r /tmp/homebrew-core /home/linuxbrew/.linuxbrew/Homebrew/Library/Taps/homebrew/
COPY --chown=linuxbrew:linuxbrew . /home/linuxbrew/.linuxbrew/Homebrew
RUN --mount=type=cache,target=/home/linuxbrew/.cache,uid="${USER_ID}" \
--mount=type=cache,target=/home/linuxbrew/.bundle,uid="${USER_ID}" \