feat: add resolve-buildx-cache as a shared composite action

This commit is contained in:
2026-08-09 15:09:25 +02:00
commit 4dee87df56
3 changed files with 180 additions and 0 deletions
+68
View File
@@ -0,0 +1,68 @@
# resolve-buildx-cache
Zamienia zmienne `DOCKER_CACHE_*` wystawiane przez runnera na opcje buildx.
```yaml
- name: Resolve buildx cache settings
id: cache
uses: https://git.cierzniak.it/gitea-runner/actions/resolve-buildx-cache@v1
with:
cache-image: ${{ github.repository }}/app
- uses: docker/setup-buildx-action@v4
with:
driver-opts: ${{ steps.cache.outputs.driver-opts }}
- uses: docker/build-push-action@v7
with:
cache-from: ${{ steps.cache.outputs.cache-from }}
cache-to: ${{ steps.cache.outputs.cache-to }}
```
## Wejście i wyjście
| Input | Wymagany | Co to |
| --- | --- | --- |
| `cache-image` | tak | Ścieżka obrazu cache'a bez hosta rejestru, np. `org/repo/app`. Ref powstaje jako `<DOCKER_CACHE_SERVER>/<cache-image>:cache` |
| Output | Do czego |
| --- | --- |
| `driver-opts` | `driver-opts` dla `docker/setup-buildx-action` |
| `cache-from` | `cache-from` dla `docker/build-push-action` |
| `cache-to` | `cache-to` dla `docker/build-push-action` |
Każdy job budujący osobny obraz podaje własny `cache-image` — inaczej cztery buildy
nadpisywałyby sobie jeden wpis w rejestrze.
## Zmienne runnera
Czytane jako zwykłe env joba z `runner.envs` w `config.yaml` runnera, **nie** przez kontekst
`vars.*` — ten widzi wyłącznie zmienne zdefiniowane po stronie Gitei. Runnery czytają
`config.yaml` przy starcie, więc po zmianie trzeba je zrestartować.
| Zmienna | Znaczenie |
| --- | --- |
| `DOCKER_CACHE_TYPE` | typ cache'a buildx, w praktyce `registry` |
| `DOCKER_CACHE_SERVER` | host rejestru cache'a, np. `registry:5000` |
| `DOCKER_CACHE_NETWORK` | sieć Compose, do której trzeba podpiąć buildkita, żeby zobaczył rejestr |
## Dlaczego tak
**Puste `DOCKER_CACHE_TYPE`/`DOCKER_CACHE_SERVER` degradują joba do buildu bez cache'a**
(`::warning::` w logu), zamiast go wywalać. Cache jest optymalizacją; brak konfiguracji na
nowej puli runnerów nie ma prawa zatrzymać wdrożenia.
**`DOCKER_CACHE_NETWORK` nie jest wpisany na sztywno.** Buildkit startuje jako osobny
kontener poza siecią stacku runnerów, więc przy rejestrze stojącym w tej sieci trzeba go
podpiąć jawnie. Ale przy flotach w LXC, gdzie rejestr ma własne IP, nie ma do czego się
podpinać, a `network=<nieistniejąca>` wywala joba twardo. Dlatego pusta wartość oznacza
„nie przekazuj `driver-opts` wcale" — repo nie zna topologii runnera i nie ma czego zgadywać.
**`registry.insecure=true` w refach**, bo rejestr cache'a chodzi po HTTP bez TLS-a.
Zastępuje to wcześniejszy `buildkitd-config-inline` z blokiem `[registry."..."]`, który przy
pustej zmiennej generował `[registry.""]` — blok składniowo zepsuty, a nie błąd.
**Wartości jadą z runnera, nie z `vars.*` Gitei**, bo każda pula ma własny rejestr cache'a
i wskazuje na siebie. Gdy siedziały jako zmienne organizacji, po przeniesieniu na runnery
`vars.DOCKER_CACHE_*` rozwiązywało się do pustego stringa — build leciał na zielono bez
cache'a i nikt tego nie zauważył.
+45
View File
@@ -0,0 +1,45 @@
name: Resolve buildx cache settings
description: >-
Turns the DOCKER_CACHE_* variables exported by the runner into buildx driver options and
cache refs. Missing variables degrade the job to a build without cache instead of failing it.
inputs:
cache-image:
description: Cache image path without the registry host (e.g. "org/repo/app").
required: true
outputs:
driver-opts:
description: driver-opts for docker/setup-buildx-action; empty when the cache registry needs no network pinning.
value: ${{ steps.resolve.outputs.driver-opts }}
cache-from:
description: cache-from ref for docker/build-push-action; empty disables cache reads.
value: ${{ steps.resolve.outputs.cache-from }}
cache-to:
description: cache-to ref for docker/build-push-action; empty disables cache writes.
value: ${{ steps.resolve.outputs.cache-to }}
runs:
using: composite
steps:
- id: resolve
shell: bash
env:
CACHE_IMAGE: ${{ inputs.cache-image }}
run: |
if [ -n "${DOCKER_CACHE_NETWORK}" ]; then
echo "driver-opts=network=${DOCKER_CACHE_NETWORK}" >> "$GITHUB_OUTPUT"
else
echo "driver-opts=" >> "$GITHUB_OUTPUT"
fi
if [ -z "${DOCKER_CACHE_TYPE}" ] || [ -z "${DOCKER_CACHE_SERVER}" ]; then
echo "::warning::DOCKER_CACHE_* not set on the runner - building without cache"
echo "cache-from=" >> "$GITHUB_OUTPUT"
echo "cache-to=" >> "$GITHUB_OUTPUT"
exit 0
fi
ref="${DOCKER_CACHE_SERVER}/${CACHE_IMAGE}:cache"
echo "cache-from=type=${DOCKER_CACHE_TYPE},ref=${ref},registry.insecure=true" >> "$GITHUB_OUTPUT"
echo "cache-to=type=${DOCKER_CACHE_TYPE},ref=${ref},registry.insecure=true,mode=max" >> "$GITHUB_OUTPUT"