Files
Forge-Engine/.gitea/workflows/deploy.yml
T
williamandClaude Sonnet 5 bb84b7b377
Build and deploy / test (push) Failing after 13s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Phase 0 : factorise compute_new_value + ajoute pytest/node test à la CI
1. Duplication éliminée avant que la Phase 2 (hasard/opérations
   mathématiques) n'en ajoute 6 de plus aux DEUX fichiers : la chaîne
   d'opérations quasi identique entre screens/data_actions/
   apply_data_action.py (champ d'objet) et apply_variable_action.py
   (variable globale) est factorisée dans un nouveau
   compute_operation.py::compute_new_value(operation, current, raw_value,
   is_decimal), réutilisé par les deux. Nouveau tests/test_compute_operation.py
   verrouille le comportement des 7 opérations existantes (dont les cas
   limites : valeur invalide, type décimal vs entier, opération inconnue)
   avant d'en ajouter d'autres.

2. .gitea/workflows/deploy.yml déployait en prod à chaque push sur main
   sans jamais exécuter la suite de tests — rien ne bloquait
   techniquement un commit cassé. Nouveau job "test" (pytest + node:test
   sur la logique pure de static/js/play/, via des conteneurs officiels
   plutôt que des actions du marketplace, cohérent avec le choix déjà
   fait dans ce fichier) tourne sur CHAQUE push (main ET dev, utile pour
   ce dépôt qui travaille sur dev) ; "build-and-push"/"deploy" gagnent un
   "needs: test" et restent réservés à main (filtre sur gitea.ref) — un
   push sur dev ne redéploie jamais la prod, seulement les tests.

Vérifié : 223 tests passent (8 nouveaux), YAML validé.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 15:00:23 +02:00

105 lines
4.3 KiB
YAML

name: Build and deploy
on:
push:
branches: [main, dev]
# Le job "test" tourne sur CHAQUE push (main et dev) : jusqu'ici aucune
# étape de CI n'exécutait la suite de tests, rien n'empêchait un commit
# cassé d'atteindre la production (voir l'audit qualité de la Phase 0 du
# plan). "build-and-push"/"deploy", eux, restent réservés à main (via le
# filtre "if" sur gitea.ref) — un push sur dev ne doit jamais redéployer
# la prod, seulement faire tourner les tests.
# Secrets à configurer dans Gitea (Paramètres du dépôt > Actions > Secrets) :
# REGISTRY_HOST adresse du registre d'images (ex: gitea.exemple.com)
# REGISTRY_IMAGE chemin complet de l'image (ex: gitea.exemple.com/mon-compte/forge-engine)
# REGISTRY_USER utilisateur pour "docker login" sur ce registre
# REGISTRY_TOKEN jeton d'accès (scope package:write) pour ce registre
# DEPLOY_HOST adresse du serveur de production
# DEPLOY_USER utilisateur SSH sur ce serveur
# DEPLOY_SSH_KEY clé privée SSH (au format PEM) autorisée sur ce serveur
# DEPLOY_PATH dossier sur le serveur où vit docker-compose.prod.yml (ex: /home/deploy/forge-engine)
#
# Utilise directement docker/ssh/scp en ligne de commande plutôt que des
# actions du marketplace, pour ne pas dépendre de la disponibilité de
# github.com / du miroir gitea.com depuis le runner self-hosted.
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Conteneurs officiels plutôt que actions/setup-python|setup-node du
# marketplace — même logique que le reste de ce fichier (éviter une
# dépendance à la disponibilité de github.com/du miroir gitea.com
# depuis le runner self-hosted), et le runner n'a pas besoin
# d'installer quoi que ce soit d'autre que Docker, déjà requis pour
# build-and-push.
- name: Tests Python (pytest)
run: |
docker run --rm -v "$PWD":/app -w /app python:3.13-slim sh -c "
pip install --quiet -r requirements-dev.txt &&
python -m pytest tests/ -q
"
- name: Tests JS (node:test — logique pure de static/js/play/, voir le plan de modularisation)
run: |
docker run --rm -v "$PWD":/app -w /app node:20-slim \
node --test static/js/play/__tests__/*.test.js
build-and-push:
needs: test
if: gitea.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Connexion au registre d'images
run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login "${{ secrets.REGISTRY_HOST }}" -u "${{ secrets.REGISTRY_USER }}" --password-stdin
- name: Build de l'image
run: |
docker build \
-t "${{ secrets.REGISTRY_IMAGE }}:${{ gitea.sha }}" \
-t "${{ secrets.REGISTRY_IMAGE }}:latest" \
.
- name: Publication de l'image
run: |
docker push "${{ secrets.REGISTRY_IMAGE }}:${{ gitea.sha }}"
docker push "${{ secrets.REGISTRY_IMAGE }}:latest"
deploy:
needs: build-and-push
if: gitea.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Préparation de la clé SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key
ssh-keyscan -H "${{ secrets.DEPLOY_HOST }}" >> ~/.ssh/known_hosts
- name: Envoi du docker-compose.prod.yml sur le serveur
run: |
scp -i ~/.ssh/deploy_key docker-compose.prod.yml \
"${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}:${{ secrets.DEPLOY_PATH }}/docker-compose.prod.yml"
- name: Pull et redémarrage sur le serveur
run: |
ssh -i ~/.ssh/deploy_key "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" '
set -e
cd "${{ secrets.DEPLOY_PATH }}"
echo "REGISTRY_IMAGE=${{ secrets.REGISTRY_IMAGE }}" > .env
echo "IMAGE_TAG=${{ gitea.sha }}" >> .env
docker login "${{ secrets.REGISTRY_HOST }}" -u "${{ secrets.REGISTRY_USER }}" -p "${{ secrets.REGISTRY_TOKEN }}"
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d
docker image prune -f
'