ci: buduj tylko zmienione usługi i sprzątaj po sobie na runnerze #82

Merged
gitea merged 1 commits from fix/ci-buduj-tylko-zmienione into master 2026-08-26 18:21:16 +00:00
2 changed files with 90 additions and 4 deletions
+11
View File
@@ -32,3 +32,14 @@ jobs:
docker push $IMG:$TAG
docker push $IMG:latest
echo "Zbudowano i wypchnieto: $IMG:$TAG (+ latest)"
# Sprzątanie ZAWSZE, także po nieudanym budowaniu. Ten obraz dźwiga TeX Live
# i to właśnie na nim runner zatkał się kiedyś na „no space left on device" —
# a po nieudanym buildzie zostaje najwięcej śmieci.
- name: Sprzątanie po budowaniu
if: always()
run: |
docker system df || true
docker system prune -af --filter "until=168h" || true
docker builder prune -f --filter "until=168h" || true
docker system df || true
+79 -4
View File
@@ -1,21 +1,96 @@
name: build
# Buduje obrazy usług, które dzielą warstwę logiczną i łącze: data, logic,
# presentation, astrodemo. Render i silnik B mają własne pipeline'y, bo są ciężkie
# i rzadko się zmieniają (build-render.yaml, build-swisseph.yaml).
on:
push:
branches: [master]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# Dwa commity, bo porównujemy z poprzednim. Domyślny płytki klon ma
# jeden i `HEAD^` w nim nie istnieje.
fetch-depth: 2
- name: Login
run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login gitea.czernobog.pl -u gitea --password-stdin
# astrodemo dołącza do tej samej pętli: dzieli warstwę logiczną i łącze,
# więc jego obraz ma powstawać z tego samego commita co reszta produktu.
- name: Build & push (data, logic, presentation, astrodemo)
- name: Build & push (tylko usługi, które się zmieniły)
run: |
set -eu
TAG=${GITHUB_SHA::8}
for SVC in data logic presentation astrodemo; do
USLUGI="data logic presentation astrodemo"
# Usługi z własnym pipeline'em — celowo poza tą pętlą.
OSOBNE="render engine-swisseph"
# Usługa, której nie ma na żadnej z list, nigdy się nie zbuduje i NIKT
# tego nie zauważy: brak obrazu wygląda potem na problem z rejestrem.
# Ten sam mechanizm już nas kosztował przy liście obserwowanych obrazów
# w image-updaterze. Lepiej zatrzymać budowanie i powiedzieć wprost.
for KATALOG in services/*/; do
NAZWA=$(basename "$KATALOG")
case " $USLUGI $OSOBNE " in
*" $NAZWA "*) ;;
*) echo "BŁĄD: usługa '$NAZWA' nie jest na żadnej liście budowania."
echo "Dopisz ją do USLUGI w tym pliku albo daj jej własny workflow"
echo "(jak render i engine-swisseph), zależnie od tego, czy ma"
echo "powstawać z każdego commita produktu."
exit 1 ;;
esac
done
# Kontekstem budowania każdego obrazu jest WYŁĄCZNIE ./services/<nazwa>,
# więc zmiana poza tym katalogiem nie może wpłynąć na jego zawartość.
# Dzięki temu porównanie ścieżek jest dokładne, a nie przybliżone.
if POPRZEDNI=$(git rev-parse --verify HEAD^ 2>/dev/null); then
ZMIENIONE=$(git diff --name-only "$POPRZEDNI" HEAD)
else
# Pierwszy commit albo przepisana historia — nie ma z czym porównać,
# więc budujemy wszystko. Lepiej zbudować za dużo niż wypuścić obraz
# ze starym kodem pod nowym tagiem.
echo "Brak poprzedniego commita — buduję komplet."
ZMIENIONE=""
fi
# Zmiana w samym pliku workflow dotyczy wszystkich obrazów naraz.
if [ -z "$ZMIENIONE" ] || echo "$ZMIENIONE" | grep -q '^\.gitea/workflows/build\.yaml$'; then
DO_BUDOWY="$USLUGI"
else
DO_BUDOWY=""
for SVC in $USLUGI; do
if echo "$ZMIENIONE" | grep -q "^services/$SVC/"; then
DO_BUDOWY="$DO_BUDOWY $SVC"
fi
done
fi
if [ -z "$(echo "$DO_BUDOWY" | tr -d ' ')" ]; then
echo "Żadna z usług się nie zmieniła — nie ma czego budować."
echo "Wdrożone tagi zostają na poprzednich wersjach, i tak ma być."
exit 0
fi
echo "Buduję:$DO_BUDOWY (tag $TAG)"
for SVC in $DO_BUDOWY; do
docker build -t gitea.czernobog.pl/gitea/astrololo-$SVC:$TAG ./services/$SVC
docker push gitea.czernobog.pl/gitea/astrololo-$SVC:$TAG
done
echo "Tag: $TAG"
# Sprzątanie ZAWSZE, także po nieudanym budowaniu — to właśnie po awarii
# zostaje najwięcej śmieci, a kolejny przebieg zaczyna od mniejszego zapasu
# miejsca niż poprzedni. Tak zatkał się dysk przy budowaniu rendera.
- name: Sprzątanie po budowaniu
if: always()
run: |
docker system df || true
# `until=168h` zostawia tydzień: warstwy bazowe i cache z ostatnich dni
# przeżywają, więc kolejny build nie zaczyna od zera, a stare znikają.
docker system prune -af --filter "until=168h" || true
docker builder prune -f --filter "until=168h" || true
docker system df || true