stavba bez kontejneru, proti Pythonu od uv
binárka / linux (pull_request) Failing after 4s

Runner běží v host módu, bez dockeru, takže se v něm kontejner na AlmaLinux
spustit nedá. Ukázalo se ale, že kontejner potřeba není: stačí stavět proti
samostatnému CPythonu od uv. Ten je slinkovaný s glibc 2.17 a nic
z hostitele se do binárky nedostane — změřeno objdumpem přes všechno, co
se z ní rozbaluje. Výsledek je tedy přenositelnější než přes AlmaLinux 8
(2.28) a build.sh je o polovinu kratší.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
gitea-actionsandClaude Opus 5 committed 2026-08-21 17:23:09 +02:00
1 parent cb39036724
commit 8aa54dc7a0
4 files changed
+47 -55

No files matched your search

+28 -29
View File
@@ -1,9 +1,8 @@
# Postaví binárku a pověsí ji na release. # Postaví binárku a pověsí ji na release.
# #
# Běží v kontejneru na AlmaLinux 8, ne na runneru: binárka slinkovaná proti # Runner běží v host módu, takže tu není kontejner ani hotové akce
# novější glibc by nešla spustit na starších systémech. Záměrně bez hotových # z marketplace — nic se nespoléhá na to, co má hostitel nainstalováno.
# akcí z marketplace — na vlastním runneru odpadá starost, jestli v kontejneru # O starou glibc se stará build.sh přes samostatný CPython od uv.
# je node.
name: binárka name: binárka
on: on:
@@ -15,50 +14,50 @@ on:
jobs: jobs:
linux: linux:
runs-on: homelab runs-on: homelab
container: almalinux:8
steps: steps:
- name: Nástroje
run: dnf install -y -q git python3.11 binutils
- name: Zdrojáky - name: Zdrojáky
env: env:
TOKEN: ${{ secrets.GITHUB_TOKEN }} TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: | run: |
git init -q . git init -q .
git remote remove origin 2>/dev/null || true
git remote add origin "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git" git remote add origin "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git"
git config http.extraheader "Authorization: token ${TOKEN}" git config http.extraheader "Authorization: token ${TOKEN}"
git fetch -q --depth 1 origin "${GITHUB_REF}" git fetch -q --depth 1 origin "${GITHUB_REF}"
git checkout -q FETCH_HEAD
git config --unset http.extraheader git config --unset http.extraheader
git checkout -qf FETCH_HEAD
git clean -qfd
- name: Prostředí - name: uv
run: | run: |
python3.11 -m venv /tmp/build echo "$HOME/.local/bin" >> "$GITHUB_PATH"
/tmp/build/bin/pip install --quiet --upgrade pip export PATH="$HOME/.local/bin:$PATH"
/tmp/build/bin/pip install --quiet -r requirements.txt pyinstaller command -v uv >/dev/null || curl -LsSf https://astral.sh/uv/install.sh | sh
uv --version
- name: Testy - name: Testy
run: /tmp/build/bin/pytest -q run: uv run --with-requirements requirements.txt --no-project pytest -q
- name: Binárka - name: Binárka
run: | run: ./build.sh
/tmp/build/bin/pyinstaller --clean --noconfirm \
--distpath dist --workpath /tmp/work kostky.spec
ls -lh dist/kostky
- name: Zkouška - name: Zkouška
run: | run: |
XDG_DATA_HOME=/tmp/data DICE_PORT=8321 DICE_HOST=127.0.0.1 \ XDG_DATA_HOME=/tmp/zkouska DICE_PORT=8321 DICE_HOST=127.0.0.1 \
./dist/kostky > /tmp/server.log 2>&1 & ./dist/kostky > /tmp/server.log 2>&1 &
server=$!
trap 'kill $server 2>/dev/null || true' EXIT
for _ in $(seq 30); do for _ in $(seq 30); do
curl -sf -o /dev/null http://127.0.0.1:8321/ && break curl -sf -o /dev/null http://127.0.0.1:8321/ && break
sleep 1 sleep 1
done done
curl -sf -o /dev/null http://127.0.0.1:8321/ curl -sf -o /dev/null http://127.0.0.1:8321/
curl -sf -o /dev/null http://127.0.0.1:8321/static/style.css curl -sf -o /dev/null http://127.0.0.1:8321/static/style.css
curl -sf -o /dev/null http://127.0.0.1:8321/board curl -sf -o /dev/null http://127.0.0.1:8321/board
test -f /tmp/data/kostky/dice.db test -f /tmp/zkouska/kostky/dice.db
cat /tmp/server.log cat /tmp/server.log
- name: Na release - name: Na release
@@ -70,24 +69,24 @@ jobs:
api="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}" api="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}"
auth="Authorization: token ${TOKEN}" auth="Authorization: token ${TOKEN}"
# Release může, ale nemusí existovat — na tag se dá kliknout ručně. # Release u tagu být může, ale nemusí — dá se založit i ručně.
release=$(curl -s -H "$auth" "$api/releases/tags/${GITHUB_REF_NAME}") id=$(curl -s -H "$auth" "$api/releases/tags/${GITHUB_REF_NAME}" \
id=$(printf '%s' "$release" | python3.11 -c \ | python3 -c 'import json,sys; print(json.load(sys.stdin).get("id",""))' || true)
'import json,sys; print(json.load(sys.stdin).get("id",""))' || true)
if [ -z "$id" ]; then if [ -z "$id" ]; then
id=$(curl -sf -X POST -H "$auth" -H "Content-Type: application/json" \ id=$(curl -sf -X POST -H "$auth" -H "Content-Type: application/json" \
-d "{\"tag_name\":\"${GITHUB_REF_NAME}\",\"name\":\"${GITHUB_REF_NAME}\"}" \ -d "{\"tag_name\":\"${GITHUB_REF_NAME}\",\"name\":\"${GITHUB_REF_NAME}\"}" \
"$api/releases" | python3.11 -c \ "$api/releases" \
'import json,sys; print(json.load(sys.stdin)["id"])') | python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])')
fi fi
# Aby se dal build zopakovat, stará příloha stejného jména jde pryč. # Aby se dal build zopakovat, stará příloha stejného jména jde pryč.
curl -s -H "$auth" "$api/releases/$id/assets" | python3.11 -c \ curl -s -H "$auth" "$api/releases/$id/assets" \
'import json,os,sys; [print(a["id"]) for a in json.load(sys.stdin) if a["name"] == os.environ["ASSET"]]' \ | python3 -c 'import json,os,sys; [print(a["id"]) for a in json.load(sys.stdin) if a["name"] == os.environ["ASSET"]]' \
| while read -r old; do | while read -r old; do
curl -sf -X DELETE -H "$auth" "$api/releases/$id/assets/$old" curl -sf -X DELETE -H "$auth" "$api/releases/$id/assets/$old"
done done
curl -sf -X POST -H "$auth" -F "attachment=@dist/kostky" \ curl -sf -o /dev/null -X POST -H "$auth" -F "attachment=@dist/kostky" \
"$api/releases/$id/assets?name=${ASSET}" "$api/releases/$id/assets?name=${ASSET}"
echo "$ASSET pověšen na ${GITHUB_REF_NAME}"
+1
View File
@@ -4,3 +4,4 @@ __pycache__/
.pytest_cache/ .pytest_cache/
dist/ dist/
build/ build/
.build/
+6 -6
View File
@@ -17,8 +17,7 @@ chmod +x kostky
``` ```
Nic se neinstaluje — Python, Flask i šablony jsou uvnitř. Zatím jen pro Linux Nic se neinstaluje — Python, Flask i šablony jsou uvnitř. Zatím jen pro Linux
na x86-64; postavené proti glibc 2.28, takže jede na všem od RHEL 8, na x86-64; postavené proti glibc 2.17, takže jede prakticky všude.
Debianu 10 a Ubuntu 20.04 výš.
Ze zdrojáků to je stejně krátké: Ze zdrojáků to je stejně krátké:
@@ -132,10 +131,11 @@ python3 web.py
./build.sh ./build.sh
``` ```
Staví se v kontejneru (podman nebo docker) na AlmaLinux 8, ne na hostiteli. Staví se proti samostatnému CPythonu od `uv`, ne proti systémovému. Ten je
Binárka slinkovaná proti glibc z Fedory 44 by nešla spustit nikde se starším slinkovaný s glibc 2.17; postavené proti Pythonu z Fedory 44 by to chtělo
systémem — glibc drží zpětnou kompatibilitu, ne dopřednou. Výsledek je glibc 2.43 a nešlo by spustit skoro nikde — glibc drží zpětnou kompatibilitu,
v `dist/kostky`. ne dopřednou. Nic z hostitele se do binárky nedostane, takže kontejner k tomu
potřeba není. Výsledek je v `dist/kostky`.
Terminálová verze součástí binárky není; ta se pouští ze zdrojáků. Terminálová verze součástí binárky není; ta se pouští ze zdrojáků.
+12 -20
View File
@@ -1,30 +1,22 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Postaví jednosouborovou binárku pro Linux do dist/kostky. # Postaví jednosouborovou binárku pro Linux do dist/kostky.
# #
# Staví se v kontejneru s glibc 2.28 (AlmaLinux 8), ne na hostiteli. Binárka # Staví se proti samostatnému CPythonu od uv, ne proti systémovému. Ten je
# slinkovaná proti glibc z Fedory 44 by nešla spustit nikde se starším # slinkovaný s glibc 2.17, takže binárka jede i na letitých systémech.
# systémem — glibc drží zpětnou kompatibilitu, ne dopřednou. Postavené na # Postavená proti Pythonu z Fedory 44 by chtěla glibc 2.43 a nešla by
# staré glibc poběží i na nové. # spustit skoro nikde — glibc drží zpětnou kompatibilitu, ne dopřednou.
# Nic z hostitele se do ní nedostane, takže kontejner k tomu není potřeba.
set -euo pipefail set -euo pipefail
IMAGE=${IMAGE:-docker.io/library/almalinux:8} VERSION=${VERSION:-3.11}
PYTHON=${PYTHON:-python3.11} BUILD=${BUILD:-.build}
ENGINE=${ENGINE:-$(command -v podman || command -v docker)}
# Rootless podman mapuje roota v kontejneru na tebe, docker ne — tam by uv python install "$VERSION"
# dist/ zůstalo cizí. uv venv --quiet --managed-python --python "$VERSION" "$BUILD"
FIXUP=":" uv pip install --quiet --python "$BUILD/bin/python" -r requirements.txt pyinstaller
[[ "$ENGINE" == *docker ]] && FIXUP="chown -R $(id -u):$(id -g) dist"
"$ENGINE" run --rm -v "$PWD:/src:z" -w /src "$IMAGE" bash -euc " "$BUILD/bin/pyinstaller" --clean --noconfirm \
dnf install -y -q python3.11 binutils --distpath dist --workpath "$BUILD/work" kostky.spec
$PYTHON -m venv /tmp/build
/tmp/build/bin/pip install --quiet --upgrade pip
/tmp/build/bin/pip install --quiet flask qrcode pyinstaller
/tmp/build/bin/pyinstaller --clean --noconfirm \
--distpath dist --workpath /tmp/work kostky.spec
$FIXUP
"
echo echo
ls -lh dist/kostky ls -lh dist/kostky