mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-24 14:17:52 -05:00
Store RHEL8 image layer cache in GHCR instead of the Actions cache
The nightly image build has failed since 2026-07-23 with "failed to solve: not_found" while exporting the BuildKit layer cache, because the repository's GitHub Actions cache is at the 10 GB limit and entries are evicted as fast as they are written (0% cache hit rate on restore). Use a registry cache (ci-rhel8:buildcache in GHCR) instead, which has no size cap, and exclude the buildcache tag from the daily image cleanup. Make the cache effective across nightly rebuilds: key the vcpkg stage on its actual inputs (vcpkg.json, the vcpkg configuration and the vcpkg tool) with a direct manifest install instead of copying the entire build context, and exclude .git from the Docker build context since its internals differ between checkouts of the same commit and invalidated 'COPY . /src' on every run. Nightly builds now reuse the compiled vcpkg ports from the layer cache and only recompile the ResInsight warmup stage.
This commit is contained in:
1 parent
87518f2f2f
commit
4b4bf29dfc
4 files changed
+38
-25
No files matched your search
@@ -3,6 +3,14 @@
|
|||||||
# Docker contexts -- this file is the canonical list of paths excluded from
|
# Docker contexts -- this file is the canonical list of paths excluded from
|
||||||
# `COPY . /src` (used by .github/docker/Dockerfile.rhel8).
|
# `COPY . /src` (used by .github/docker/Dockerfile.rhel8).
|
||||||
|
|
||||||
|
# Git metadata. The in-image build does not need it (the CMake submodule init
|
||||||
|
# is guarded by EXISTS .git, and the submodule working trees are already in
|
||||||
|
# the context), and its internals (index, packfiles, reflogs) differ between
|
||||||
|
# checkouts of the same commit, which would invalidate the BuildKit layer
|
||||||
|
# cache for `COPY . /src` on every nightly image build.
|
||||||
|
.git
|
||||||
|
**/.git
|
||||||
|
|
||||||
# Local CMake build outputs (host-side; can be tens of GB).
|
# Local CMake build outputs (host-side; can be tens of GB).
|
||||||
build/
|
build/
|
||||||
build_*/
|
build_*/
|
||||||
|
|||||||
@@ -104,41 +104,39 @@ FROM base AS vcpkg-builder
|
|||||||
|
|
||||||
ENV VCPKG_DEFAULT_BINARY_CACHE=/opt/vcpkg-cache
|
ENV VCPKG_DEFAULT_BINARY_CACHE=/opt/vcpkg-cache
|
||||||
|
|
||||||
COPY . /src
|
# Copy only the inputs that determine the dependency set instead of the whole
|
||||||
|
# source tree. This keys the expensive vcpkg compile below on just these
|
||||||
|
# paths, so the layer stays valid in the BuildKit registry cache across
|
||||||
|
# ordinary source commits -- nightly rebuilds reuse the previously compiled
|
||||||
|
# vcpkg binaries instead of recompiling every port.
|
||||||
|
COPY ThirdParty/vcpkg /src/ThirdParty/vcpkg
|
||||||
|
COPY vcpkg.json /src/vcpkg.json
|
||||||
|
COPY vcpkg-configuration-rhel8.json /src/vcpkg-configuration.json
|
||||||
|
|
||||||
# Running the ResInsight CMake configure triggers a vcpkg manifest install,
|
# A direct manifest install compiles every dependency into
|
||||||
# which compiles every dependency into VCPKG_DEFAULT_BINARY_CACHE. The same
|
# VCPKG_DEFAULT_BINARY_CACHE. The dependency set has no manifest features or
|
||||||
# toolchain is used here and in the final image, so the vcpkg ABI hashes match
|
# overlay ports, and CC/CXX below match the ResInsight configure in the
|
||||||
# and the cache is reused by CI builds. Later configure steps may fail inside
|
# warmup stage and in CI, so the vcpkg ABI hashes match and the cache is
|
||||||
# the build container; that is tolerated as the dependencies are already built
|
# reused there. x64-linux is the triplet the vcpkg CMake toolchain defaults
|
||||||
# by then.
|
# to on Linux.
|
||||||
#
|
#
|
||||||
# After configure, verify the cache contains a plausible number of entries.
|
# After the install, verify the cache contains a plausible number of entries.
|
||||||
# vcpkg's `files` binary provider stores one .zip per package under
|
# vcpkg's `files` binary provider stores one .zip per package under
|
||||||
# <cache>/<2-hex>/<full-hash>.zip. ResInsight depends on ~30+ packages, so a
|
# <cache>/<2-hex>/<full-hash>.zip. ResInsight depends on ~30+ packages, so a
|
||||||
# threshold of 20 catches the failure mode where the configure dies early
|
# threshold of 20 catches the failure mode where the install dies early
|
||||||
# (e.g. after building only a handful of leaf deps) while staying robust to
|
# (e.g. after building only a handful of leaf deps) while staying robust to
|
||||||
# small manifest churn.
|
# small manifest churn.
|
||||||
RUN git config --global --add safe.directory '*' \
|
RUN git config --global --add safe.directory '*' \
|
||||||
&& cp /src/vcpkg-configuration-rhel8.json /src/vcpkg-configuration.json \
|
|
||||||
&& mkdir -p "${VCPKG_DEFAULT_BINARY_CACHE}" \
|
&& mkdir -p "${VCPKG_DEFAULT_BINARY_CACHE}" \
|
||||||
&& source /opt/rh/gcc-toolset-14/enable \
|
&& source /opt/rh/gcc-toolset-14/enable \
|
||||||
&& ( cd /src/ThirdParty/vcpkg && ./bootstrap-vcpkg.sh ) \
|
&& ( cd /src/ThirdParty/vcpkg && ./bootstrap-vcpkg.sh ) \
|
||||||
&& export CC=/opt/rh/gcc-toolset-14/root/usr/bin/gcc \
|
&& export CC=/opt/rh/gcc-toolset-14/root/usr/bin/gcc \
|
||||||
&& export CXX=/opt/rh/gcc-toolset-14/root/usr/bin/g++ \
|
&& export CXX=/opt/rh/gcc-toolset-14/root/usr/bin/g++ \
|
||||||
&& { cmake -S /src -B /tmp/cfg -G Ninja \
|
&& ( cd /src && ./ThirdParty/vcpkg/vcpkg install --triplet x64-linux ) \
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
|
||||||
-DRESINSIGHT_INCLUDE_APPLICATION_UNIT_TESTS=true \
|
|
||||||
-DRESINSIGHT_ENABLE_UNITY_BUILD=true \
|
|
||||||
-DRESINSIGHT_ENABLE_HDF5=false \
|
|
||||||
-DRESINSIGHT_ENABLE_GRPC=false \
|
|
||||||
-DRESINSIGHT_GCC_STDCPP_EXP_PATH=/opt/libstdcxx-exp/lib \
|
|
||||||
-DCMAKE_TOOLCHAIN_FILE=ThirdParty/vcpkg/scripts/buildsystems/vcpkg.cmake \
|
|
||||||
|| true; } \
|
|
||||||
&& vcpkg_zip_count=$(find "${VCPKG_DEFAULT_BINARY_CACHE}" -type f -name '*.zip' | wc -l) \
|
&& vcpkg_zip_count=$(find "${VCPKG_DEFAULT_BINARY_CACHE}" -type f -name '*.zip' | wc -l) \
|
||||||
&& echo "vcpkg binary cache entries: ${vcpkg_zip_count}" \
|
&& echo "vcpkg binary cache entries: ${vcpkg_zip_count}" \
|
||||||
&& test "${vcpkg_zip_count}" -ge 20 \
|
&& test "${vcpkg_zip_count}" -ge 20 \
|
||||||
&& rm -rf /tmp/cfg /src
|
&& rm -rf /src
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Stage 3: warm the ResInsight buildcache by performing a full compile at
|
# Stage 3: warm the ResInsight buildcache by performing a full compile at
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
- ".github/docker/Dockerfile.rhel8"
|
- ".github/docker/Dockerfile.rhel8"
|
||||||
- ".github/workflows/build-rhel8-image.yml"
|
- ".github/workflows/build-rhel8-image.yml"
|
||||||
|
- ".dockerignore"
|
||||||
- "vcpkg.json"
|
- "vcpkg.json"
|
||||||
- "vcpkg-configuration-rhel8.json"
|
- "vcpkg-configuration-rhel8.json"
|
||||||
- ".gitmodules"
|
- ".gitmodules"
|
||||||
@@ -102,5 +103,10 @@ jobs:
|
|||||||
tags: |
|
tags: |
|
||||||
${{ steps.meta.outputs.image }}:latest
|
${{ steps.meta.outputs.image }}:latest
|
||||||
${{ steps.meta.outputs.image }}:${{ steps.meta.outputs.date }}
|
${{ steps.meta.outputs.image }}:${{ steps.meta.outputs.date }}
|
||||||
cache-from: type=gha
|
# Layer cache lives in GHCR instead of the GitHub Actions cache: the
|
||||||
cache-to: type=gha,mode=max
|
# Actions cache has a 10 GB per-repo limit shared with all other
|
||||||
|
# workflows, so the multi-GB mode=max export was evicted immediately
|
||||||
|
# (0% hit rate) and the export itself started failing with
|
||||||
|
# "not_found" once the repo hit the cap.
|
||||||
|
cache-from: type=registry,ref=${{ steps.meta.outputs.image }}:buildcache
|
||||||
|
cache-to: type=registry,ref=${{ steps.meta.outputs.image }}:buildcache,mode=max,image-manifest=true
|
||||||
@@ -4,7 +4,8 @@ name: Cleanup RHEL8 CI Image Versions
|
|||||||
#
|
#
|
||||||
# Retention rules:
|
# Retention rules:
|
||||||
# * Versions tagged "latest" are always kept (the consumer workflow pulls
|
# * Versions tagged "latest" are always kept (the consumer workflow pulls
|
||||||
# `:latest`, so deleting it would break CI).
|
# `:latest`, so deleting it would break CI). Versions tagged "buildcache"
|
||||||
|
# are always kept too (BuildKit layer cache used by the image build).
|
||||||
# * The most recent MIN_KEEP versions by updated_at are kept regardless of
|
# * The most recent MIN_KEEP versions by updated_at are kept regardless of
|
||||||
# age. This is a safety floor: if the last few nightly builds break, we
|
# age. This is a safety floor: if the last few nightly builds break, we
|
||||||
# can still roll back to a working older image.
|
# can still roll back to a working older image.
|
||||||
@@ -95,14 +96,14 @@ jobs:
|
|||||||
echo "Cutoff (UTC) : $(date -u -d @"$cutoff_epoch" -Iseconds)"
|
echo "Cutoff (UTC) : $(date -u -d @"$cutoff_epoch" -Iseconds)"
|
||||||
|
|
||||||
# jq pipeline:
|
# jq pipeline:
|
||||||
# 1. drop versions whose tags include "latest"
|
# 1. drop versions whose tags include "latest" or "buildcache"
|
||||||
# 2. sort newest-first
|
# 2. sort newest-first
|
||||||
# 3. skip the first MIN_KEEP (safety floor)
|
# 3. skip the first MIN_KEEP (safety floor)
|
||||||
# 4. keep only those older than the cutoff
|
# 4. keep only those older than the cutoff
|
||||||
to_delete=$(jq -c \
|
to_delete=$(jq -c \
|
||||||
--argjson keep "$MIN_KEEP" \
|
--argjson keep "$MIN_KEEP" \
|
||||||
--argjson cutoff "$cutoff_epoch" '
|
--argjson cutoff "$cutoff_epoch" '
|
||||||
[ .[] | select((.metadata.container.tags // []) | index("latest") | not) ]
|
[ .[] | select((.metadata.container.tags // []) | (index("latest") or index("buildcache")) | not) ]
|
||||||
| sort_by(.updated_at) | reverse
|
| sort_by(.updated_at) | reverse
|
||||||
| .[$keep:]
|
| .[$keep:]
|
||||||
| [ .[] | select((.updated_at | fromdateiso8601) < $cutoff) ]
|
| [ .[] | select((.updated_at | fromdateiso8601) < $cutoff) ]
|
||||||
|
|||||||
Reference in new issue
Block a user