ci: pipeline backendu dla Gitea Actions
Backend / Lint i formatowanie (pull_request) Successful in 20s
Backend / Testy i kontrakt API (pull_request) Successful in 4m58s
Backend / Testowy build obrazu (pull_request) Successful in 1m34s

Workflow .gitea/workflows/backend.yaml z trzema jobami:

- lint   ruff check oraz ruff format --check --diff
- test   testy jednostkowe i kontrakt API, plus compileall całego pakietu
- image  testowy build obrazu; job czeka na lint i test

Job image nie poprzestaje na zbudowaniu obrazu - uruchamia kontener bez
prawdziwego tokenu Discorda i czeka, aż /api/status odpowie. Panel łączy
się z backendem po sieci, więc sam start procesu niczego nie dowodzi.
Zapytanie leci z wnętrza kontenera, dzięki czemu krok nie zależy od tego,
czy runner ma zainstalowanego curla albo wgeta.

Filtry paths ograniczają uruchomienia do zmian w kodzie Pythona,
zależnościach, konfiguracji lintera, Dockerfile i samym workflow.

Zależności instalują się z gotowych kółek, więc obraz CI nie potrzebuje
kompilatora. ffmpeg i libopus są wymagane dopiero przy odtwarzaniu,
a testy nie dotykają warstwy audio.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
lgooseandClaude Bot committed 2026-08-21 01:25:40 +02:00
1 parent 9ae22704ff
commit fd8d71a80d
1 file changed
+96
+96
View File
@@ -0,0 +1,96 @@
name: Backend
on:
push:
branches: [main]
paths:
- "**.py"
- "requirements*.txt"
- "pyproject.toml"
- "Dockerfile"
- ".gitea/workflows/backend.yaml"
pull_request:
paths:
- "**.py"
- "requirements*.txt"
- "pyproject.toml"
- "Dockerfile"
- ".gitea/workflows/backend.yaml"
workflow_dispatch:
env:
PYTHON_VERSION: "3.13"
RUFF_VERSION: "0.16.4"
jobs:
lint:
name: Lint i formatowanie
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Instalacja ruff
run: pip install --no-cache-dir "ruff==${RUFF_VERSION}"
- name: Reguły lintera
run: ruff check --output-format=github .
- name: Zgodność z formatterem
run: ruff format --check --diff .
test:
name: Testy i kontrakt API
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: pip
# Zależności instalują się z gotowych kółek - kompilator nie jest
# potrzebny. ffmpeg i libopus są wymagane dopiero przy odtwarzaniu,
# a testy nie dotykają warstwy audio.
- name: Instalacja zależności
run: pip install --no-cache-dir -r requirements.txt
- name: Testy jednostkowe
run: python -m unittest discover -s tests -t . -v
- name: Kontrola składni całego pakietu
run: python -m compileall -q zyrarbot main.py
image:
name: Testowy build obrazu
runs-on: ubuntu-latest
needs: [lint, test]
steps:
- uses: actions/checkout@v4
- name: Budowa obrazu backendu
run: docker build --tag zyrarbot-api:ci .
# Sam start procesu to za mało - panel łączy się z API po sieci, więc
# sprawdzamy, że kontener faktycznie odpowiada. Zapytanie leci z jego
# wnętrza, żeby nie zależeć od narzędzi zainstalowanych na runnerze.
- name: Kontener odpowiada na API
run: |
docker run -d --name zyrarbot-ci -e DISCORD_TOKEN=ci-dummy zyrarbot-api:ci
probe="import json,urllib.request;json.load(urllib.request.urlopen('http://localhost:8000/api/status',timeout=2))"
for i in $(seq 1 30); do
if docker exec zyrarbot-ci python -c "$probe" 2>/dev/null; then
echo "API odpowiedziało po ${i}s"
docker rm -f zyrarbot-ci
exit 0
fi
sleep 1
done
echo "::error::API nie odpowiedziało w ciągu 30 sekund"
docker logs zyrarbot-ci
docker rm -f zyrarbot-ci
exit 1