server-up/.forgejo/workflows/deploy.yml
Ramon 342b2ee9e5
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 1m38s
ci: tests in een container draaien in plaats van een venv op de runner
De testsstap die ik in v0.5.00 toevoegde blokkeerde de deploy: de runner heeft
geen python3-venv, dus `python3 -m venv` faalde en alle volgende stappen werden
overgeslagen.

- Tests draaien nu in python:3.12-slim via docker, dat de runner sowieso heeft.
  Bijkomend voordeel: dezelfde Python-versie als waarop de app in productie
  draait, in plaats van wat er toevallig op de runner staat.
- PYTHONDONTWRITEBYTECODE en -p no:cacheprovider voorkomen dat de container
  root-eigen __pycache__/.pytest_cache in de werkmap achterlaat, wat de
  rsync-stap en volgende checkouts zou kunnen hinderen.
- Pip-cache in een named volume, zodat een herhaalde run niet opnieuw downloadt.

Toegepast in deploy.yml, deploy-prod.yml en build.yml.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-26 22:34:14 +02:00

115 lines
No EOL
3.7 KiB
YAML

name: Deploy server-up (dev)
on:
push:
branches: [dev]
workflow_dispatch:
concurrency:
group: server-up-deploy-dev
cancel-in-progress: false
jobs:
deploy:
runs-on: [self-hosted, dev]
timeout-minutes: 20
env:
DEPLOY_DIR: /opt/docker/server-up
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Bepaal versie
id: version
run: |
set -euo pipefail
BASE="$(tr -d '[:space:]' < VERSION 2>/dev/null || echo 0.0.0)"
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
VERSION="${GITHUB_REF_NAME#v}"
CHANNEL="release"
else
VERSION="${BASE}"
CHANNEL="dev"
fi
echo "VERSION=${VERSION}" >> "$GITHUB_ENV"
echo "CHANNEL=${CHANNEL}" >> "$GITHUB_ENV"
# SU_VERSION wordt door docker compose gebruikt als build-arg
echo "SU_VERSION=${VERSION}" >> "$GITHUB_ENV"
echo "Deploying version: ${VERSION} (${CHANNEL})"
- name: Tests draaien
run: |
set -euo pipefail
# In een container in plaats van een venv op de runner: die heeft
# geen python3-venv, en zo draaien de tests bovendien op exact de
# Python-versie waarop de app in productie draait.
# PYTHONDONTWRITEBYTECODE + no:cacheprovider voorkomen dat er
# root-eigen bestanden in de werkmap achterblijven.
docker run --rm \
-v "$PWD:/w" -w /w \
-v su-pip-cache:/root/.cache/pip \
-e PYTHONDONTWRITEBYTECODE=1 \
python:3.12-slim \
sh -c "pip install -q -r server-up/requirements.txt pytest \
&& python -m pytest tests -q -p no:cacheprovider"
- name: Sync code naar deploy-directory
run: |
set -euo pipefail
rsync -a --no-group --delete \
--exclude='.git/' \
--exclude='.forgejo/' \
./ "$DEPLOY_DIR/"
- name: Schrijf VERSION-bestand
working-directory: ${{ env.DEPLOY_DIR }}
run: echo "${VERSION}" > VERSION
- name: Build image
working-directory: ${{ env.DEPLOY_DIR }}
run: |
set -euo pipefail
# De dev-server bouwt altijd zelf vanaf de dev-branch. SU_TAG vastleggen
# zodat compose exact het zojuist gebouwde image start.
touch .env
sed -i '/^SU_TAG=/d' .env
echo "SU_TAG=${VERSION}" >> .env
docker compose build --pull
docker tag "server-up:${VERSION}" "server-up:${CHANNEL}" || true
- name: Deploy
working-directory: ${{ env.DEPLOY_DIR }}
run: |
set -euo pipefail
docker compose up -d --remove-orphans
docker compose ps
- name: Wachten op healthcheck
run: |
set -euo pipefail
for i in {1..40}; do
status=$(docker inspect --format '{{.State.Health.Status}}' server-up 2>/dev/null || echo "starting")
echo "poll $i: $status"
if [ "$status" = "healthy" ]; then
echo "server-up is healthy als versie ${VERSION}"
exit 0
fi
sleep 3
done
echo "server-up werd niet healthy in tijd — logs:"
cd "$DEPLOY_DIR" && docker compose logs --tail=200
exit 1
- name: Oude images opruimen (behoud laatste 5)
if: success()
run: |
docker images server-up --format '{{.Tag}} {{.ID}}' \
| grep -vE '^(latest|release|dev) ' \
| tail -n +6 \
| awk '{print $2}' \
| xargs -r docker rmi -f || true
docker image prune -f