169 lines
6.4 KiB
YAML
169 lines
6.4 KiB
YAML
# CI/CD Gitea Actions : tests à chaque push, puis sur `main` seulement,
|
|
# build des images (registre de conteneurs intégré à Gitea) et déploiement
|
|
# SSH sur le VPS.
|
|
#
|
|
# Nécessite un runner Gitea Actions (act_runner, exécuteur "docker") attaché
|
|
# au dépôt ou à l'organisation.
|
|
#
|
|
# Secrets à définir (Paramètres du dépôt → Actions → Secrets) :
|
|
# REGISTRY_TOKEN jeton d'accès (scope "write:package") pour pousser sur
|
|
# le registre de conteneurs de cette instance Gitea
|
|
# SSH_KEY clé privée SSH (format OpenSSH) pour se connecter au VPS
|
|
#
|
|
# Variables à définir (Paramètres du dépôt → Actions → Variables) :
|
|
# REGISTRY_HOST hôte du registre (ex. gitea.mon-domaine.fr)
|
|
# REGISTRY_NAMESPACE espace du registre (ex. <organisation>/<depot>)
|
|
# REGISTRY_USER utilisateur associé à REGISTRY_TOKEN
|
|
# SSH_HOST hôte du VPS
|
|
# SSH_USER utilisateur SSH
|
|
# DEPLOY_PATH dossier du projet sur le VPS (ex. /opt/benevoles)
|
|
# VITE_EDITION_ID UUID de l'édition de production, à renseigner APRÈS
|
|
# la toute première mise en service (voir deploy/README.md)
|
|
|
|
name: ci-cd
|
|
|
|
on:
|
|
push:
|
|
branches: ['**']
|
|
|
|
jobs:
|
|
backend-test:
|
|
runs-on: ubuntu-latest
|
|
container: python:3.12-slim
|
|
services:
|
|
postgres:
|
|
image: postgres:16-alpine
|
|
env:
|
|
POSTGRES_USER: benevoles
|
|
POSTGRES_PASSWORD: benevoles
|
|
POSTGRES_DB: benevoles_test
|
|
ports:
|
|
- 5432:5432
|
|
env:
|
|
TEST_DATABASE_URL: postgresql+psycopg://benevoles:benevoles@postgres:5432/benevoles_test
|
|
DATABASE_URL: postgresql+psycopg://benevoles:benevoles@postgres:5432/benevoles_test
|
|
steps:
|
|
- name: Installer git et node
|
|
run: apt-get update && apt-get install -y --no-install-recommends git nodejs
|
|
- uses: actions/checkout@v4
|
|
- name: Installer uv
|
|
run: pip install --no-cache-dir uv
|
|
- name: Installer les dépendances
|
|
working-directory: backend
|
|
run: uv sync
|
|
- name: Lint
|
|
working-directory: backend
|
|
run: uv run ruff check .
|
|
- name: Migrer la base de test
|
|
working-directory: backend
|
|
run: uv run alembic upgrade head
|
|
- name: Vérifier migration ↔ modèle
|
|
working-directory: backend
|
|
run: uv run alembic check
|
|
- name: Tests
|
|
working-directory: backend
|
|
run: uv run pytest -q
|
|
|
|
frontend-test:
|
|
runs-on: ubuntu-latest
|
|
container: node:20-alpine
|
|
steps:
|
|
- name: Installer git et node
|
|
run: apk add --no-cache git nodejs
|
|
- uses: actions/checkout@v4
|
|
- name: Installer les dépendances
|
|
working-directory: frontend
|
|
run: npm ci
|
|
- name: Typecheck
|
|
working-directory: frontend
|
|
run: npm run typecheck
|
|
- name: Lint
|
|
working-directory: frontend
|
|
run: npm run lint
|
|
- name: Build
|
|
working-directory: frontend
|
|
run: npm run build
|
|
- name: Smoke test
|
|
working-directory: frontend
|
|
run: npm run smoke
|
|
|
|
build-backend:
|
|
needs: backend-test
|
|
if: gitea.ref == 'refs/heads/main'
|
|
runs-on: ubuntu-latest
|
|
container: docker:27
|
|
services:
|
|
docker:
|
|
image: docker:27-dind
|
|
env:
|
|
DOCKER_HOST: tcp://docker:2375
|
|
DOCKER_TLS_CERTDIR: ""
|
|
steps:
|
|
- name: Installer git et node
|
|
run: apk add --no-cache git nodejs
|
|
- uses: actions/checkout@v4
|
|
- name: Connexion au registre
|
|
run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login "${{ vars.REGISTRY_HOST }}" -u "${{ vars.REGISTRY_USER }}" --password-stdin
|
|
- name: Build & push
|
|
run: |
|
|
IMAGE="${{ vars.REGISTRY_HOST }}/${{ vars.REGISTRY_NAMESPACE }}/backend"
|
|
docker build -t "$IMAGE:${{ gitea.sha }}" -t "$IMAGE:latest" backend
|
|
docker push "$IMAGE:${{ gitea.sha }}"
|
|
docker push "$IMAGE:latest"
|
|
|
|
build-frontend:
|
|
needs: frontend-test
|
|
if: gitea.ref == 'refs/heads/main'
|
|
runs-on: ubuntu-latest
|
|
container: docker:27
|
|
services:
|
|
docker:
|
|
image: docker:27-dind
|
|
env:
|
|
DOCKER_HOST: tcp://docker:2375
|
|
DOCKER_TLS_CERTDIR: ""
|
|
steps:
|
|
- name: Installer git et node
|
|
run: apk add --no-cache git nodejs
|
|
- uses: actions/checkout@v4
|
|
- name: Connexion au registre
|
|
run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login "${{ vars.REGISTRY_HOST }}" -u "${{ vars.REGISTRY_USER }}" --password-stdin
|
|
- name: Build & push
|
|
run: |
|
|
IMAGE="${{ vars.REGISTRY_HOST }}/${{ vars.REGISTRY_NAMESPACE }}/frontend"
|
|
docker build \
|
|
--build-arg VITE_API_MODE=http \
|
|
--build-arg VITE_EDITION_ID="${{ vars.VITE_EDITION_ID }}" \
|
|
-f frontend/Dockerfile.prod \
|
|
-t "$IMAGE:${{ gitea.sha }}" -t "$IMAGE:latest" frontend
|
|
docker push "$IMAGE:${{ gitea.sha }}"
|
|
docker push "$IMAGE:latest"
|
|
|
|
deploy:
|
|
needs: [build-backend, build-frontend]
|
|
if: gitea.ref == 'refs/heads/main'
|
|
runs-on: ubuntu-latest
|
|
container: alpine:3.20
|
|
steps:
|
|
- name: Installer les outils
|
|
run: apk add --no-cache git nodejs openssh-client rsync
|
|
- uses: actions/checkout@v4
|
|
- name: Déployer par SSH
|
|
run: |
|
|
mkdir -p ~/.ssh && chmod 700 ~/.ssh
|
|
echo "${{ secrets.SSH_KEY }}" | tr -d '\r' > ~/.ssh/id_ed25519
|
|
chmod 600 ~/.ssh/id_ed25519
|
|
ssh-keyscan -H "${{ vars.SSH_HOST }}" >> ~/.ssh/known_hosts
|
|
rsync -az -e "ssh -i ~/.ssh/id_ed25519" deploy/docker-compose.prod.yml "${{ vars.SSH_USER }}@${{ vars.SSH_HOST }}:${{ vars.DEPLOY_PATH }}/docker-compose.prod.yml"
|
|
ssh -i ~/.ssh/id_ed25519 "${{ vars.SSH_USER }}@${{ vars.SSH_HOST }}" sh -s <<EOF
|
|
set -e
|
|
cd "${{ vars.DEPLOY_PATH }}"
|
|
echo "${{ secrets.REGISTRY_TOKEN }}" | docker login "${{ vars.REGISTRY_HOST }}" -u "${{ vars.REGISTRY_USER }}" --password-stdin
|
|
export BACKEND_IMAGE="${{ vars.REGISTRY_HOST }}/${{ vars.REGISTRY_NAMESPACE }}/backend:${{ gitea.sha }}"
|
|
export FRONTEND_IMAGE="${{ vars.REGISTRY_HOST }}/${{ vars.REGISTRY_NAMESPACE }}/frontend:${{ gitea.sha }}"
|
|
docker compose -f docker-compose.prod.yml pull
|
|
docker compose -f docker-compose.prod.yml run --rm backend uv run alembic upgrade head
|
|
docker compose -f docker-compose.prod.yml up -d
|
|
docker image prune -f
|
|
EOF
|