# CI/CD : tests à chaque push, puis sur `main` seulement, build des images # (registre de conteneurs GitLab) et déploiement SSH sur le VPS. # # Variables CI/CD à définir (Paramètres → CI/CD → Variables du projet) : # SSH_HOST hôte du VPS # SSH_USER utilisateur SSH # SSH_KEY clé privée SSH (format OpenSSH), variable « protégée » # + « masquée », type fichier ou variable multi-lignes # 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) — # le frontend fige cette valeur au moment du build. # # `CI_REGISTRY`, `CI_REGISTRY_USER`, `CI_REGISTRY_PASSWORD` et # `CI_REGISTRY_IMAGE` sont fournis automatiquement par GitLab. stages: - test - build - deploy variables: BACKEND_IMAGE: $CI_REGISTRY_IMAGE/backend FRONTEND_IMAGE: $CI_REGISTRY_IMAGE/frontend backend-test: stage: test image: python:3.12-slim services: - name: postgres:16-alpine alias: postgres variables: POSTGRES_USER: benevoles POSTGRES_PASSWORD: benevoles POSTGRES_DB: benevoles_test TEST_DATABASE_URL: postgresql+psycopg://benevoles:benevoles@postgres:5432/benevoles_test DATABASE_URL: postgresql+psycopg://benevoles:benevoles@postgres:5432/benevoles_test before_script: - pip install --no-cache-dir uv - cd backend - uv sync script: - uv run ruff check . - uv run alembic upgrade head - uv run alembic check - uv run pytest -q frontend-test: stage: test image: node:20-alpine before_script: - cd frontend - npm ci script: - npm run typecheck - npm run lint - npm run build - npm run smoke build-backend: stage: build image: docker:27 services: - docker:27-dind rules: - if: '$CI_COMMIT_BRANCH == "main"' script: - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY" - docker build -t "$BACKEND_IMAGE:$CI_COMMIT_SHORT_SHA" -t "$BACKEND_IMAGE:latest" backend - docker push "$BACKEND_IMAGE:$CI_COMMIT_SHORT_SHA" - docker push "$BACKEND_IMAGE:latest" build-frontend: stage: build image: docker:27 services: - docker:27-dind rules: - if: '$CI_COMMIT_BRANCH == "main"' script: - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY" - > docker build --build-arg VITE_API_MODE=http --build-arg VITE_EDITION_ID="$VITE_EDITION_ID" -f frontend/Dockerfile.prod -t "$FRONTEND_IMAGE:$CI_COMMIT_SHORT_SHA" -t "$FRONTEND_IMAGE:latest" frontend - docker push "$FRONTEND_IMAGE:$CI_COMMIT_SHORT_SHA" - docker push "$FRONTEND_IMAGE:latest" deploy: stage: deploy image: alpine:3.20 rules: - if: '$CI_COMMIT_BRANCH == "main"' before_script: - apk add --no-cache openssh-client rsync - eval "$(ssh-agent -s)" - echo "$SSH_KEY" | tr -d '\r' | ssh-add - - mkdir -p ~/.ssh && chmod 700 ~/.ssh - ssh-keyscan -H "$SSH_HOST" >> ~/.ssh/known_hosts script: - rsync -az deploy/docker-compose.prod.yml "$SSH_USER@$SSH_HOST:$DEPLOY_PATH/docker-compose.prod.yml" - | ssh "$SSH_USER@$SSH_HOST" sh -s <