Files
cozystack/.github/workflows/build-main.yaml
Myasnikov Daniil 6d04ba5b3d ci(build): warm the main cache on an isolated docker-container builder
`--cache-to type=registry,mode=max` is unsupported on the host's default embedded docker driver unless the daemon runs the containerd image store, so on a classic store the warmer would fail to export any cache. Build the warmer on a docker-container buildx builder, which supports mode=max regardless of the host image store.

It also gives the warmer its own buildkit (separate bbolt), so it never contends with PR builds on the shared embedded buildkit.

Part of #2937.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-06-17 20:50:01 +05:00

88 lines
3.1 KiB
YAML

name: Build cache (main)
# Warms the shared mode=max build cache so PR builds start hot.
#
# PR builds (pull-requests.yaml) read the cache but never write it
# (WRITE_CACHE unset -> 0). Only this serialized main build writes
# CACHE_REGISTRY/<img>:buildcache, so concurrent PR builds never race on the
# cache manifest -- the 409 collisions PR #2711 fixed for image tags would
# otherwise reappear on the cache ref. Cache is mode=max so all multistage
# `builder` stages are cached, not just the final stage as with inline.
#
# This job builds on a docker-container buildx builder, NOT the host's default
# embedded `docker` driver: `--cache-to type=registry,mode=max` is unsupported
# on the docker driver unless the daemon runs the containerd image store, so on
# a classic store the warmer would otherwise fail to export any cache. The
# container driver also gives this build its own buildkit (separate bbolt), so
# the warmer never contends with PR builds on the shared embedded buildkit.
env:
# Same per-CI registry as pull-requests.yaml; the cache is co-located here.
REGISTRY: iad.ocir.io/idyksih5sir9/cozystack
on:
push:
branches: [main]
paths-ignore:
- 'docs/**'
# Only the newest main commit's cache matters; cancel older in-flight warmers.
concurrency:
group: build-main-cache
cancel-in-progress: true
jobs:
warm-cache:
name: Warm build cache
runs-on: [self-hosted]
timeout-minutes: 90
permissions:
contents: read
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Set up Docker config
run: |
if [ -d ~/.docker ]; then
cp -r ~/.docker "${{ runner.temp }}/.docker"
fi
- name: Login to OCIR
uses: docker/login-action@v3
with:
username: ${{ secrets.OCIR_USER }}
password: ${{ secrets.OCIR_TOKEN }}
registry: iad.ocir.io
env:
DOCKER_CONFIG: ${{ runner.temp }}/.docker
# docker-container driver: required for `--cache-to type=registry,mode=max`
# (unsupported on the host's default docker driver) and gives this build an
# isolated buildkit so it never contends with PR builds on the shared one.
- name: Set up Buildx (docker-container driver)
id: buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker-container
- name: Build all images and write mode=max cache
run: make build
env:
DOCKER_CONFIG: ${{ runner.temp }}/.docker
# Build on the docker-container builder created above (BUILDX_ARGS adds
# --builder=$(BUILDER)); buildx forwards the OCIR auth from DOCKER_CONFIG
# to the container builder for cache reads/writes and image pushes.
BUILDER: ${{ steps.buildx.outputs.name }}
# WRITE_CACHE=1 turns on --cache-to (mode=max) for every image.
WRITE_CACHE: '1'
# Publish a floating :main handle; do not move :latest (releases do).
IMAGE_TAG: main
PUBLISH_VERSIONED: '0'
PUBLISH_FLOATING: '0'