Files
dice-counter/.gitea/workflows/image.yml
T
gitea-actions 9283a87a1e
binárka / linux (pull_request) Successful in 10s
image / image (pull_request) Failing after 2s
testy / pytest (3.11) (pull_request) Successful in 1s
testy / pytest (3.12) (pull_request) Successful in 1s
testy / pytest (3.13) (pull_request) Successful in 1s
testy / pytest (3.14) (pull_request) Successful in 1s
Ověřit emulaci dřív, než se do stavby pustíme
První běh na runneru odhalil dvě věci.

Rouru do `head` shodil pipefail: head zavřel rouru po dvaceti řádcích, docker
dostal EPIPE a krok skončil na 255, přestože se builder založil v pořádku.

Horší je, že binfmt se sice nainstaloval (installing: arm64 OK), ale buildkit
pak arm64 mezi platformami nenabídl. Emulace musí být registrovaná s příznakem
F, aby si na ni buildkit ve svém kontejneru sáhl bez interpretu v souborovém
systému; jinak vidí jen nativní platformy. Doma to tak mám z qemu-user-static
a proto tam multiarch stavba prošla.

Builder se teď staví načisto — ten z minulého běhu by si pamatoval platformy
z doby před registrací — a hned po něm se ověří, že arm64 v seznamu opravdu
je. Bez toho by stavba spadla až na konci s hláškou, ze které se nic nepozná.
2026-08-23 20:14:17 +02:00

143 lines
6.0 KiB
YAML

# Postaví kontejnerový image a při vydání ho pošle do registru Gitey.
#
# Runner běží v host módu, takže tu nejsou hotové akce z marketplace a všechno
# je obyčejný shell — stejně jako v ostatních workflow tady. Docker na
# hostiteli být musí, ten se tu neinstaluje.
#
# Nad pull requesty se image staví a zkouší, ale nikam se neposílá. Dockerfile
# by se jinak rozbil až ve chvíli, kdy se tagne release.
name: image
on:
push:
tags: ["v*"]
pull_request:
workflow_dispatch:
env:
REGISTRY: gitea.spacilovi.eu
IMAGE: david-spacil/dice-counter
PLATFORMS: linux/amd64,linux/arm64
ZKOUSKA_PORT: "18000"
jobs:
image:
runs-on: homelab
steps:
- name: Zdrojáky
env:
TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git init -q .
git remote remove origin 2>/dev/null || true
git remote add origin "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git"
git config http.extraheader "Authorization: token ${TOKEN}"
git fetch -q --depth 1 origin "${GITHUB_REF}"
git config --unset http.extraheader
git checkout -qf FETCH_HEAD
git clean -qfd
- name: Předpoklady
run: |
command -v docker >/dev/null \
|| { echo "Docker na runneru není." >&2; exit 1; }
docker buildx version >/dev/null 2>&1 \
|| { echo "Chybí docker buildx — bez něj multiarch nejde." >&2; exit 1; }
docker version --format '{{.Server.Version}}'
- name: QEMU pro cizí architektury
run: |
# Registruje binfmt, aby šlo na x86 stroji stavět i arm64. Všechny
# závislosti jsou čistě pythonní, takže se pod emulací nic
# nekompiluje a stavba tím prakticky netrpí.
docker run --privileged --rm tonistiigi/binfmt --install arm64
- name: Builder
run: |
# Výchozí ovladač Dockeru multiplatformní stavbu neumí, je potřeba
# docker-container. Staví se pokaždé načisto — builder z minulého
# běhu by si pamatoval platformy z doby před registrací emulace.
#
# Bez roury do `head`: pod pipefail by zavřená roura shodila celý
# krok dřív, než docker dopíše výstup.
docker buildx rm kostky >/dev/null 2>&1 || true
docker buildx create --name kostky --driver docker-container --use
docker buildx inspect --bootstrap
# Kdyby arm64 v seznamu chybělo, stavba spadne až na konci a hláška
# nic neřekne. Radši to zkontrolujeme hned.
PLATFORMY=$(docker buildx inspect)
echo "$PLATFORMY" | grep -q "linux/arm64" || {
echo "Buildkit nevidí linux/arm64, i když se binfmt nainstaloval." >&2
echo "Emulace musí být registrovaná s příznakem F, jinak si na ni" >&2
echo "buildkit ze svého kontejneru nesáhne. Na runneru to natrvalo" >&2
echo "vyřeší balíček qemu-user-static." >&2
echo "--- současná registrace ---" >&2
cat /proc/sys/fs/binfmt_misc/qemu-aarch64 >&2 2>/dev/null || echo "(žádná)" >&2
exit 1; }
- name: Zkouška
run: |
# Zkouší se nativní amd64: --load umí do místního Dockeru uložit jen
# jednu platformu a spustit stejně nic jiného nejde.
docker buildx build --platform linux/amd64 --load \
-f deploy/Dockerfile \
--build-arg VERSION="zkouska-${GITHUB_SHA:0:7}" \
-t kostky:zkouska .
trap 'docker rm -f kostky-zkouska >/dev/null 2>&1 || true' EXIT
# Adresa se vnucuje, ať zkouška nezávisí na síti běhounu a dá se
# ověřit, co přesně tabule nabídne.
docker run -d --name kostky-zkouska --init \
-p "${ZKOUSKA_PORT}:${ZKOUSKA_PORT}" -e DICE_HOST=127.0.0.1 \
-e DICE_PORT="${ZKOUSKA_PORT}" kostky:zkouska
for _ in $(seq 30); do
curl -sf -o /dev/null "http://127.0.0.1:${ZKOUSKA_PORT}/" && break
sleep 1
done
curl -sf -o /dev/null "http://127.0.0.1:${ZKOUSKA_PORT}/" || {
echo "Kontejner se nerozeběhl." >&2
docker logs kostky-zkouska >&2
exit 1; }
curl -sf -o /dev/null "http://127.0.0.1:${ZKOUSKA_PORT}/static/style.css"
curl -sf "http://127.0.0.1:${ZKOUSKA_PORT}/board" | grep -q "127.0.0.1:${ZKOUSKA_PORT}"
curl -sf -o /dev/null "http://127.0.0.1:${ZKOUSKA_PORT}/export"
# Verze se musí do image opravdu dostat, ne se hlásit jako neznámá.
docker run --rm kostky:zkouska python web.py --version
! docker run --rm kostky:zkouska python web.py --version | grep -q "neznámá"
docker logs kostky-zkouska
echo "Image jede."
- name: Publikace
if: startsWith(github.ref, 'refs/tags/')
env:
TOKEN: ${{ secrets.PACKAGE_TOKEN }}
VLASTNIK: ${{ github.repository_owner }}
run: |
# Automatický token Actions na balíčky nestačí — Gitea to zatím
# neumí a sama v dokumentaci odkazuje na osobní token. Ten je
# v secrets pod PACKAGE_TOKEN; jméno nesmí začínat na GITEA_,
# ten prefix si Gitea vyhrazuje.
[ -n "$TOKEN" ] || { echo "Chybí secret PACKAGE_TOKEN." >&2; exit 1; }
echo "$TOKEN" | docker login "$REGISTRY" -u "$VLASTNIK" --password-stdin
trap 'docker logout "$REGISTRY" >/dev/null 2>&1 || true' EXIT
# Značka bez počátečního "v": v repozitáři je v1.2.0, u image se
# čekají 1.2.0.
VERZE="${GITHUB_REF_NAME#v}"
docker buildx build --platform "$PLATFORMS" --push \
-f deploy/Dockerfile \
--build-arg VERSION="${GITHUB_REF_NAME}" \
-t "$REGISTRY/$IMAGE:$VERZE" \
-t "$REGISTRY/$IMAGE:latest" .
echo "Publikováno: $REGISTRY/$IMAGE:$VERZE a :latest"
docker buildx imagetools inspect "$REGISTRY/$IMAGE:$VERZE"