# CI Setup — Gitea Actions pour RPA Vision V3 Ce document décrit la CI minimale mise en place sur `gitea.localhost:3100` pour prévenir les régressions silencieuses sur `main` et les PR. ## Vue d'ensemble Deux workflows Gitea Actions (syntaxe compatible GitHub Actions) : | Workflow | Fichier | Déclencheur | Bloquant | |----------------------------------|---------------------------------------|------------------------------|----------| | Tests | `.gitea/workflows/tests.yml` | push + PR (toutes branches) | Oui (unit + security) | | Audit sécurité | `.gitea/workflows/security-audit.yml` | push main + cron hebdo | Non | ### Jobs du workflow `tests` 1. **lint** (non bloquant) — `ruff` + `black --check` sur `core/`, `agent_v0/`, `tests/`. 2. **unit-tests** (bloquant) — `pytest tests/unit/` avec `-m "not slow and not gpu and not integration and not performance and not visual"`. 3. **security-tests** (bloquant) — `pytest tests/unit/test_security_*.py` en mode verbose. Dépend de `unit-tests`. ### Jobs du workflow `security-audit` 1. **bandit** — scan statique sur `core/` (asserts ignorés). 2. **pip-audit** — détection CVE sur `requirements-ci.txt` et `requirements.txt`. 3. **secrets-scan** — `grep` pour patterns `sk-ant-`, `sk-proj-`, `AIzaSy`, `AKIA`, `hf_`. Aucun de ces jobs ne casse la CI — ils produisent des artefacts consultables. ## Activation de Gitea Actions Gitea Actions n'est pas actif par défaut. Deux étapes : ### 1. Activer Actions dans Gitea Sur `http://localhost:3100`, éditer `/home/dom/Install_base/docker-compose.yml` (ou le `app.ini` monté dans le conteneur Gitea) et ajouter : ```ini [actions] ENABLED = true DEFAULT_ACTIONS_URL = https://github.com ``` Puis redémarrer Gitea : ```bash cd /home/dom/Install_base docker compose restart gitea ``` Vérifier : dans l'UI Gitea → `Site Administration` → `Configuration Summary` → la section `[actions]` doit afficher `enabled: true`. Côté dépôt : `Settings` → `Advanced Settings` → cocher **"Enable Repository Actions"**. ### 2. Installer et enregistrer un runner local Gitea a besoin d'un `act_runner` (fork de nektos/act) pour exécuter les jobs. ```bash # Téléchargement du runner (Linux amd64) cd /home/dom/Install_base mkdir -p gitea_runner && cd gitea_runner wget https://dl.gitea.com/act_runner/0.2.11/act_runner-0.2.11-linux-amd64 -O act_runner chmod +x act_runner # Génération de la config ./act_runner generate-config > config.yaml # Récupération du token d'enregistrement # Site Administration → Actions → Runners → Create new Runner # (ou pour un runner par-dépôt : Settings du dépôt → Actions → Runners) # Enregistrement (interactif) ./act_runner register --no-interactive \ --instance http://localhost:3100 \ --token \ --name "runner-local-cpu" \ --labels "ubuntu-latest:docker://catthehacker/ubuntu:act-22.04" # Lancement en daemon nohup ./act_runner daemon --config config.yaml > runner.log 2>&1 & ``` Pour persister au reboot : créer un service systemd (cf. `~/ai/rpa_vision_v3/deploy/systemd/` pour un modèle). **Note** : le label `ubuntu-latest` pointe sur une image Docker légère (`catthehacker/ubuntu:act-22.04`, ~300 Mo) qui suffit pour nos jobs Python. ### 3. Premier test ```bash cd /home/dom/ai/rpa_vision_v3 # Modification triviale echo "" >> README.md git add README.md git commit -m "chore: trigger CI" git push gitea main ``` Dans l'UI Gitea → onglet `Actions` du dépôt, le workflow doit apparaître et passer en ~2 minutes. ## Lancer les tests localement avant push Identique à la CI : ```bash cd /home/dom/ai/rpa_vision_v3 source .venv/bin/activate # Tests unitaires (hors slow/gpu/integration) — ~60s pytest tests/unit/ -m "not slow and not gpu and not integration and not performance and not visual" -q # Tests sécurité seulement — ~5s pytest tests/unit/test_security_*.py -v # Lint (si installé) ruff check --select=E9,F63,F7,F82 core/ agent_v0/ tests/ black --check core/ agent_v0/ tests/ ``` Ou via Makefile : ```bash make test-fast # équivalent à "not slow" make check # validate-imports + test-fast ``` ## Désactiver temporairement la CI (merge urgent) Trois options, de la plus propre à la plus brutale : ### Option 1 — Skip via message de commit (recommandé) Préfixer le message avec `[skip ci]` ou `[ci skip]` : ```bash git commit -m "fix: hotfix prod [skip ci]" ``` Gitea Actions respecte cette convention. ### Option 2 — Désactiver le workflow côté dépôt Dans l'UI Gitea → dépôt → `Actions` → sélectionner le workflow → bouton **"Disable workflow"**. Réactivable au même endroit. ### Option 3 — Renommer le fichier ```bash mv .gitea/workflows/tests.yml .gitea/workflows/tests.yml.disabled git commit -am "chore: disable CI temporarily" ``` Ne **jamais** supprimer le fichier — ça rend le rollback pénible. ## Limitations connues - **Pas de tests `slow` / `gpu` / `integration`** en CI. Ces tests nécessitent CUDA, Ollama (port 11434), ou des captures d'écran réelles. Ils doivent être lancés manuellement sur la machine de dev avant un tag de release. - **Pas de tests E2E `smoke`** (`tests/smoke/`) — nécessitent le serveur complet (ports 5005, 5001, 5002, 3002). - **Pas de tests `visual`** (`tests/visual/`) — nécessitent le serveur GPU. - **Runner unique** : tant qu'il n'y a qu'un `act_runner` enregistré, les jobs s'exécutent en série. Acceptable pour < 10 builds/jour. - **Pas de `torch` en CI** : si un test unitaire importe `torch` directement (sans lazy import), il échouera. Convention : les imports GPU doivent être dans `try/except ImportError` + marqueur `@pytest.mark.gpu`. - **`requirements-ci.txt` à resynchroniser** : quand une dépendance est ajoutée à `requirements.txt` et utilisée par un test unitaire, penser à l'ajouter aussi à `requirements-ci.txt`. ## Temps d'exécution estimé | Job | Cold (sans cache pip) | Warm (cache pip) | |-----------------|----------------------|------------------| | lint | ~40s | ~15s | | unit-tests | ~2m30 | ~1m15 | | security-tests | ~1m | ~30s | | **Total CI** | **~3m** | **~1m30** | Le cache pip est géré automatiquement par `actions/setup-python@v5` via la clé `requirements-ci.txt` + `requirements.txt`. ## Troubleshooting ### Le workflow ne se déclenche pas 1. Vérifier que `[actions]` est actif dans `app.ini` Gitea. 2. Vérifier que le runner est bien enregistré : `Site Administration` → `Actions` → `Runners`. 3. Le runner doit être `Online` (point vert). 4. Le dépôt doit avoir Actions activées dans ses paramètres. ### Erreur "No runner available" Le runner est stoppé ou a un label incompatible. Relancer : ```bash cd /home/dom/Install_base/gitea_runner ps aux | grep act_runner # vérifier s'il tourne tail -f runner.log # voir les erreurs ``` ### Timeout sur `pip install` `requirements.txt` contient torch + CUDA (~3 Go). Si la CI tombe sur `requirements.txt` au lieu de `requirements-ci.txt`, vérifier que le fichier léger est bien committé à la racine du repo. ### Tests passent en local mais échouent en CI Diff le plus fréquent : - Variables d'environnement (`.env.local` absent en CI → tester avec `unset` en local). - Ports déjà pris par `svc.sh` en local mais libres en CI (→ OK). - Paths absolus hardcodés (`/home/dom/...`) → utiliser `pathlib` + fixtures. ## Évolutions possibles - Ajouter un job `type-check` avec `mypy core/` (actuellement dans `requirements.txt` mais pas en CI — choix délibéré : trop lent et 200+ erreurs à nettoyer d'abord). - Ajouter un job `coverage` avec seuil minimum (ex: 60%). - Brancher les résultats sur un badge README via `gitea-actions-status`. - Pour les PR : bloquer le merge tant que `unit-tests` + `security-tests` ne passent pas (réglable dans `Settings` → `Branches` → `Branch protection rules`).