Aller au contenu

Forgejo

perfshop-forgejo est le serveur Git auto-hébergé embarqué dans PerfShop. Il joue trois rôles :

  1. Source unique des scripts de test — les scripts Robot Framework et pytest utilisés par la stack QA sont versionnés dans un dépôt Forgejo (perfshop-tests), pas copiés en dur dans les images Docker.
  2. SCM pour Squash TM — Squash TM pointe vers Forgejo pour rapatrier les scripts au moment de l'exécution via son plugin SCM Git.
  3. Backend de l'éditeur Scripts UI — toutes les opérations d'édition de fichiers depuis perfshop-scripts-ui sont des appels à l'API REST Forgejo.

Forgejo est un fork communautaire de Gitea, piloté par une communauté indépendante depuis 2022. PerfShop utilise la version 14, configurée en mode single-node avec une base SQLite — suffisant pour l'usage pédagogique et nettement plus léger qu'une installation PostgreSQL complète.

Source de vérité

Cette page est tirée du bloc perfshop-forgejo (et perfshop-forgejo-seed) des fichiers docker-compose.desktop.yml / docker-compose.build.yml, du Dockerfile et du script seed.py du dossier forgejo-seed/.

Configuration Docker Compose

perfshop-forgejo — serveur Git

Clé Valeur
Image codeberg.org/forgejo/forgejo:14
container_name perfshop-forgejo
Port exposé 3009 (hôte) → 3000 (container), variable FORGEJO_HTTP_PORT
Volume forgejo-data:/data (volume nommé, contient la DB SQLite et le stockage Git)
Réseau perfshop-network

Variables d'environnement

La configuration de Forgejo suit la convention FORGEJO__<section>__<clé> qui est convertie en interne vers les sections [section] du fichier app.ini officiel.

Variable Valeur Rôle
FORGEJO__server__DOMAIN ${FORGEJO_DOMAIN:-localhost} Domaine Git (apparaît dans les URLs clone)
FORGEJO__server__ROOT_URL ${PUBLIC_FORGEJO_URL:-http://localhost:3009} URL publique complète (utilisée pour les liens UI)
FORGEJO__server__HTTP_PORT 3000 Port d'écoute interne
FORGEJO__database__DB_TYPE sqlite3 Base SQLite (pas de service DB dédié)
FORGEJO__database__PATH /data/gitea/forgejo.db Fichier SQLite persisté dans le volume
FORGEJO__security__INSTALL_LOCK true Verrouille l'écran d'installation initial (pas d'assistant web)
FORGEJO__service__DISABLE_REGISTRATION false Autorise la création de comptes depuis l'UI (usage pédagogique)
FORGEJO__security__PASSWORD_CHECK_PWN false Désactive la vérification HaveIBeenPwned (évite les appels sortants)
FORGEJO__oauth2__ENABLE false Pas d'OAuth2 — seulement l'auth locale et les tokens
FORGEJO__api__ENABLE_SWAGGER true Expose la documentation Swagger à /api/swagger
FORGEJO__api__MAX_RESPONSE_ITEMS 50 Limite de pagination pour l'API REST
FORGEJO__http__ENABLE_PPROF false Désactive l'endpoint de profiling Go (attaque de surface réduite)
FORGEJO__security__DISABLE_GIT_HOOKS false Autorise les hooks Git serveur (utilisés par Squash TM)
FORGEJO__git__DISABLE_DIFF_HIGHLIGHT false Active la coloration syntaxique des diffs
FORGEJO__admin__DEFAULT_EMAIL_NOTIFICATIONS disabled Pas d'envoi d'emails (pas de SMTP configuré)

Healthcheck

Paramètre Valeur
Test curl -f http://localhost:3000/api/v1/version
interval 10 s
timeout 5 s
retries 10
start_period 30 s

Le start_period de 30 secondes laisse à Forgejo le temps d'initialiser sa base SQLite et de charger ses modules Go au premier démarrage.

perfshop-forgejo-seed — initialisation one-shot

Clé Valeur
Build forgejo-seed/Dockerfile
container_name perfshop-forgejo-seed
Volumes forgejo-token-data:/token (écriture du token), /var/run/docker.sock:/var/run/docker.sock
depends_on perfshop-forgejo avec condition: service_healthy
restart "no" (one-shot)

Variables d'env critiques :

Variable Défaut Rôle
FORGEJO_URL http://perfshop-forgejo:3000 URL interne pour les appels API
FORGEJO_ADMIN_USER forgejo-admin Compte admin bootstrappé
FORGEJO_ADMIN_PASSWORD perfshop Mot de passe admin (à changer en prod)
FORGEJO_CI_USER perfshop-ci Compte CI utilisé par Squash TM et Scripts UI
FORGEJO_CI_PASSWORD perfshop Mot de passe CI
FORGEJO_CI_EMAIL ci@perfshop.fr Email CI
FORGEJO_REPO perfshop-tests Nom du dépôt cible
FORGEJO_CONTAINER perfshop-forgejo Nom du container Forgejo (active le mode CLI via docker exec)
PERFSHOP_LANG fr Filtre les scripts à pousser selon la langue

Le script de seed seed.py

Le script forgejo-seed/seed.py est idempotent : on peut le relancer sans casser un déploiement existant. Chaque étape vérifie l'état courant avant d'agir (HTTP 200 = existe déjà, HTTP 404 = à créer).

Les 9 fonctions du script

Fonction Ligne Rôle
log(msg, error=False) 24 Logging stdout/stderr préfixé [forgejo-seed]
wait_for_forgejo(max_retries, delay) 28 Attend que GET /api/v1/version réponde 200, puis crée le compte admin
ensure_ci_user() 94 Crée le compte CI via l'API (idempotent)
ensure_token() 111 Génère un token API pour le compte CI et l'écrit dans /token/forgejo_token
ensure_squash_token() 149 Génère un second token pour Squash TM (plugin SCM Git)
ensure_repo() 171 Crée le dépôt perfshop-tests vide
ensure_source_repo() 190 Crée un second dépôt perfshop (miroir du code source applicatif)
collect_scripts() 210 Parcourt /scripts et filtre les fichiers selon PERFSHOP_LANG
push_script(rel_path, token) 239 Pousse un fichier via l'API REST (PUT /repos/{owner}/{repo}/contents/{path})

Flux complet du seed

sequenceDiagram
  autonumber
  participant SD as perfshop-forgejo-seed
  participant FG as perfshop-forgejo<br/>(healthy)
  participant FTD as volume forgejo-token-data
  participant SUI as perfshop-scripts-ui<br/>(démarrage décalé)
  participant STM as perfshop-squash-seed<br/>(depends_on ok)

  Note over SD,FG: Étape 1 — Attendre que Forgejo réponde
  SD->>FG: GET /api/v1/version
  FG-->>SD: 200 {version: "14.x.x"}

  Note over SD,FG: Étape 2 — Créer compte admin
  alt Mode CLI (FORGEJO_CONTAINER défini)
    SD->>SD: docker exec --user git perfshop-forgejo<br/>forgejo admin user create --admin
  else Mode API REST
    SD->>FG: POST /api/v1/admin/users<br/>Authorization: Basic (GITEA_ADMIN_*)
  end
  FG-->>SD: 201 / 422 (existe déjà)

  Note over SD,FG: Étape 3 — Créer compte CI
  SD->>FG: GET /api/v1/users/perfshop-ci
  FG-->>SD: 404
  SD->>FG: POST /api/v1/admin/users<br/>{username: "perfshop-ci", password, email}
  FG-->>SD: 201

  Note over SD,FG: Étape 4 — Générer token API pour le compte CI
  SD->>FG: POST /api/v1/users/perfshop-ci/tokens<br/>{name: "scripts-ui"}
  FG-->>SD: 201 {sha1: "xxxxx"}
  SD->>FTD: écrit /token/forgejo_token

  Note over SD,FG: Étape 5 — Générer token pour Squash TM
  SD->>FG: POST /api/v1/users/perfshop-ci/tokens<br/>{name: "squash-tm"}
  FG-->>SD: 201 {sha1: "yyyyy"}
  SD->>FTD: écrit /token/squash_forgejo_token

  Note over SD,FG: Étape 6 — Créer les dépôts
  SD->>FG: POST /api/v1/user/repos<br/>{name: "perfshop-tests"}
  SD->>FG: POST /api/v1/user/repos<br/>{name: "perfshop"}

  Note over SD,FG: Étape 7 — Pousser les scripts initiaux
  SD->>SD: Parcourt /scripts, filtre par PERFSHOP_LANG
  loop Pour chaque script
    SD->>FG: PUT /api/v1/repos/perfshop-ci/perfshop-tests/contents/{path}<br/>{content: base64, message: "initial push"}
  end

  SD-->>SD: exit 0 (restart: "no")

  Note over SUI,FTD: scripts-ui démarre après le seed
  SUI->>FTD: lit /token/forgejo_token au boot
  STM->>FTD: lit /token/squash_forgejo_token via squash-seed

Deux modes d'amorçage de l'admin

Le script seed.py supporte deux stratégies pour créer le compte admin initial :

Mode A — CLI via docker exec

Déclenché quand la variable FORGEJO_CONTAINER est définie (ce qui est le cas dans les deux fichiers compose PerfShop). Le seed utilise le socket Docker monté en bind mount pour exécuter :

docker exec --user git perfshop-forgejo \
    forgejo admin user create --admin \
    --username <user> --password <pass> --email <email>

C'est la méthode privilégiée dans PerfShop car elle fonctionne même quand aucun compte n'existe encore (la création initiale par API REST nécessiterait des credentials admin préexistants, ce qui est un problème de poule et d'œuf).

Mode B — API REST avec GITEA_ADMIN_*

Fallback si FORGEJO_CONTAINER est absent. Utilise les variables GITEA_ADMIN_USERNAME, GITEA_ADMIN_PASSWORD et GITEA_ADMIN_EMAIL passées à Forgejo au démarrage, qui créent automatiquement le compte admin au premier boot. Le seed peut alors appeler l'API avec ces credentials.

Ce mode est conservé dans le code pour portabilité, mais n'est pas activé dans les configurations PerfShop livrées.

Les deux tokens générés

Token scripts-ui

Fichier /token/forgejo_token
Volume forgejo-token-data (nommé)
Consommateur perfshop-scripts-ui (monte en RO)
Usage Appels API Forgejo depuis le module forgejo.js de Scripts UI

Token squash-tm

Fichier /token/squash_forgejo_token
Volume forgejo-token-data (nommé)
Consommateur perfshop-squash-seed (relais vers Squash TM via son API)
Usage Configuration du plugin SCM Git côté Squash TM

Le second token est créé spécifiquement pour éviter que le même token soit utilisé par deux consommateurs différents — si on doit révoquer l'un, l'autre reste valide.

Les deux dépôts créés

perfshop-tests

Le dépôt principal pour les tests. C'est lui qui est édité depuis Scripts UI et consommé par Squash TM.

Structure typique après le seed initial :

perfshop-tests/
├── tests/
│   ├── smoke/
│   │   ├── login.robot
│   │   └── checkout.robot
│   ├── api/
│   │   ├── products.robot
│   │   └── cart.robot
│   └── e2e/
│       └── full_journey.robot
├── resources/
│   ├── variables.robot
│   └── keywords.robot
└── pytest/
    ├── test_api.py
    └── conftest.py

Les fichiers réellement poussés dépendent de PERFSHOP_LANG : la fonction collect_scripts() filtre les fichiers selon leur suffixe ou leur dossier parent pour ne pousser que les scripts dans la bonne langue (ex: login_fr.robot vs login_en.robot).

perfshop

Un second dépôt qui héberge (optionnellement) une copie du code source applicatif de PerfShop lui-même. Son usage est plus limité : il permet à un formateur de faire un commit pédagogique (ex: « ajoutez cette ligne pour corriger le bug de validation du code postal ») sans toucher au code réel déployé.

Usage par les consommateurs

flowchart TB
  subgraph seed["perfshop-forgejo-seed (one-shot)"]
    S1["1. Bootstrap admin<br/>(docker exec CLI)"]
    S2["2. Créer compte perfshop-ci"]
    S3["3. Générer 2 tokens"]
    S4["4. Créer dépôts"]
    S5["5. Push scripts initiaux"]
    S1 --> S2 --> S3 --> S4 --> S5
  end

  subgraph fg["perfshop-forgejo (service permanent)"]
    GIT["Dépôt perfshop-tests<br/>+ dépôt perfshop"]
  end

  subgraph vol["forgejo-token-data (volume nommé)"]
    T1["forgejo_token"]
    T2["squash_forgejo_token"]
  end

  subgraph consumers["Consommateurs"]
    SUI["perfshop-scripts-ui<br/>(édition interactive)"]
    STM["perfshop-testmgmt<br/>(SCM Git plugin)"]
    TR["perfshop-test-runner<br/>(git pull au lancement<br/>d'un run)"]
  end

  seed --> fg
  seed --> vol

  SUI -->|HTTP API + Bearer token| fg
  STM -->|HTTP API + Bearer token| fg
  TR -->|git clone / git pull| fg

  SUI -.->|lit| T1
  STM -.->|lit via squash-seed| T2

Sécurité et exposition

Usage pédagogique

Par défaut, la configuration livrée est orientée démonstration :

  • Mot de passe admin par défaut perfshop (à changer impérativement en déploiement exposé)
  • FORGEJO__service__DISABLE_REGISTRATION=false — n'importe qui peut créer un compte depuis l'UI (utile en formation pour donner à chaque étudiant son propre accès)
  • FORGEJO__security__PASSWORD_CHECK_PWN=false — pas de vérification HaveIBeenPwned
  • Pas de SMTP configuré — aucun email de vérification ou de notification

Recommandations pour exposition publique

Avant exposition sur internet

  • Changer FORGEJO_ADMIN_PASSWORD et FORGEJO_CI_PASSWORD
  • Passer FORGEJO__service__DISABLE_REGISTRATION=true pour bloquer l'inscription libre
  • Ajouter un reverse proxy avec HTTPS et rate limiting
  • Activer FORGEJO__security__PASSWORD_CHECK_PWN=true (nécessite une connexion sortante vers api.pwnedpasswords.com)
  • Configurer SMTP pour les emails de vérification et reset de mot de passe
  • Passer en base PostgreSQL dédiée si la volumétrie des dépôts dépasse quelques Go (SQLite reste performant en-dessous)

Pour aller plus loin