Environnements de déploiement
Les environnements sont des cibles de déploiement nommées (par ex. staging, production, eu-west) dotées de contrôles de sécurité combinables. Un job de workflow qui déclare environment: production est évalué au regard de TOUS les contrôles configurés avant que fremforge ne provisionne la VM du runner ; si un contrôle échoue, le déploiement est refusé avec un motif structuré. Les administrateurs de l’organisation font le tri via l’interface d’administration ; le workflow peut être relancé une fois la condition sous-jacente levée.
Démarrage rapide
Allez dans administration fremforge → Environnements (
https://frem.sh/<org>/_admin/environments).Sous Nouvel environnement, saisissez un nom et cliquez sur Créer.
Ouvrez la page de détail du nouvel environnement, descendez jusqu’à Politiques de déploiement, configurez les politiques souhaitées, puis cliquez sur Enregistrer les politiques.
Faites référence à l’environnement dans n’importe quel job de workflow :
jobs: deploy: runs-on: fremforge environment: production steps: - run: ./deploy.sh
Le prochain déploiement qui cible cet environnement sera évalué au regard de vos contrôles.
Les 9 contrôles
Tous les contrôles sont indépendants et combinables. TOUS les contrôles configurés doivent RÉUSSIR pour qu’un déploiement ait lieu. Un contrôle sans configuration est ignoré (considéré comme réussi).
A. Approbateurs requis
Bloque le lancement jusqu’à ce que N personnes cliquent sur Approuver pour le déploiement en attente.
- Quand l’utiliser : déploiements en production, environnements réglementés, tout ce pour quoi un second regard est le filet de sécurité.
- Configuration : Required reviewers sur la page de détail de l’environnement. 0 = pas d’approbation ; 1 à 6 = N approbateurs requis.
- Où approuver : administration fremforge → Déploiements (
/<org>/_admin/deployments), section « Approbations en attente ». - Remarques : l’utilisateur qui a déclenché le workflow (la personne qui a poussé le commit ou ouvert la pull request) ne peut pas approuver son propre déploiement. La plateforme rejette l’auto-approbation à la fois au niveau de la route et au niveau de l’évaluateur.
- Révocation : les approbateurs peuvent révoquer leur propre approbation avant le lancement du déploiement (par ex. si vous avez repéré un problème après avoir cliqué sur Approuver). Une fois le déploiement lancé, l’approbation est immuable.
B. Références autorisées (motifs de branches / tags)
Restreint les références git autorisées à déployer vers cet environnement.
- Quand l’utiliser : « seule
maindéploie en production » ; « seuls les tagsrelease/*déploient en canary ». - Configuration : Branches et étiquettes de déploiement sur la page de détail de l’environnement. Motifs génériques à la GitHub :
main,release/*,**/hotfix-*,refs/tags/v[0-9]+.*. Vide = toute référence autorisée.
C. Plage horaire
Limite les déploiements à certaines heures ouvrées, ou les bloque pendant les gels.
Quand l’utiliser : « déploiements uniquement du lundi au jeudi, 09:00–17:00 CET » ; « bloquer tous les déploiements du 22 décembre au 2 janvier (gel des fêtes) ».
Configuration : Time-window JSON sur la page de détail de l’environnement. Forme :
{ "tz": "Europe/Copenhagen", "allowed": [ { "days": ["Mon", "Tue", "Wed", "Thu"], "from": "09:00", "to": "17:00" } ], "blackouts": [ { "from": "2026-12-22T00:00Z", "to": "2027-01-02T00:00Z", "reason": "holiday freeze" } ] }tz: fuseau horaire IANA. UTC par défaut.allowed: tableau des plages autorisées. Les jours s’écrivent en 3 lettres (Mon..Sun). Les heures sont au format 24 hHH:MMdanstz.blackouts: tableau de plages UTC absolues pendant lesquelles les déploiements sont interdits, quel que soitallowed.
Remarques : les
blackoutsl’emportent surallowed. Vide = aucune restriction horaire.
D. Budget SLO sain
Refuse les déploiements tant que le budget d’erreur SLO est en train d’être consommé.
- Quand l’utiliser : « ne pas déployer tant que la latence ou le taux d’erreur visibles par les clients sont dans le rouge ; corrigez d’abord la régression. »
- Configuration : Block when these alarms are firing : noms d’alarmes CES/LTS séparés par des virgules, entretenus par vos watchdogs de vitesse de consommation. Exemple :
my-api-latency-sev1, my-api-error-budget-sev2. - Fonctionnement : fremforge suit le dernier état de chaque alarme listée. Dès qu’une alarme listée est à l’état
firing, ce contrôle refuse le lancement. - Échec en mode fermé : si fremforge ne dispose d’aucun état récent pour une alarme listée, le contrôle échoue en mode fermé : mieux vaut enquêter que contourner en silence.
E. Vérifications de statut requises
Exige que des contextes de statut de commit Forgejo nommés soient à success sur le commit déployé.
- Quand l’utiliser : « les déploiements doivent attendre que dep-scan, SAST et image-scan réussissent tous sur ce commit. »
- Configuration : Required check contexts : un par ligne. Exemples :
dep-scan,sast,sha-pin-scan,image-scan-trivy. - Fonctionnement : fremforge lit
GET /api/v1/repos/<o>/<r>/statuses/<sha>lors de la vérification préalable. Chaque contexte requis doit avoir l’étatsuccess. Un état manquant OU différent de success fait échouer le contrôle.
F. Verrou de concurrence
Plafonne le nombre de déploiements en cours vers cet environnement.
- Quand l’utiliser : « un seul déploiement en production à la fois » : évite les situations de concurrence où deux déploiements s’écrasent mutuellement.
- Configuration : Max in-flight deploys : entier de 0 à 100. 0 = pas de plafond.
- Comptabilisés : les états
pending_gates,pending_approvaletdispatched. Une tentativecompletedoufailedn’est plus comptée.
G. Délai de carence après un rollback
Après un rollback, bloque les déploiements pendant N minutes pour laisser l’équipe enquêter.
- Quand l’utiliser : « après un rollback, imposer une pause de 60 minutes avant de redéployer » : évite de redéclencher par mégarde la même régression.
- Configuration : Cooldown after rollback (minutes) : entier de 0 à 1440 (24 h). 0 = pas de délai de carence.
H. Ticket lié obligatoire
Exige que le corps de la pull request déployée fasse référence à un ticket ou à un incident.
- Quand l’utiliser : exigence de conformité / de piste d’audit : chaque déploiement en production doit avoir un « pourquoi » attaché.
- Configuration : cochez Exiger une référence de ticket dans le corps de la pull request. Expression régulière Ticket pattern facultative pour remplacer le motif par défaut.
- Motif par défaut :
(?i)(JIRA|FF|INC|FIX)-[0-9]+|fixes? #[0-9]+|closes? #[0-9]+|resolves? #[0-9]+: reconnaît JIRA-1234, FF-99,fixes #42,Closes #99, etc. Le préfixe(?i)le rend insensible à la casse. - Remplacement par organisation : toute expression régulière JavaScript valide. Le préfixe
(?i)est pris en compte.
I. Indicateur de pause
Un interrupteur par environnement pour arrêter tous les déploiements.
- Quand l’utiliser : pendant un incident. Activez une pause ; enquêtez ; levez-la.
- Configuration : Par environnement (administration de l’organisation) :
<org>/_admin/deployments→ section « Indicateurs de pause ». fremforge peut aussi appliquer une pause à l’échelle de la plateforme pendant un incident ; toute pause active qui couvre votre environnement bloque le déploiement. - Résolution : la portée la plus spécifique l’emporte pour le champ de motif, mais N’IMPORTE QUELLE portée active bloque le déploiement.
Déroulement d’une évaluation
Lorsqu’un workflow avec environment: <name> est pris en charge par la plateforme :
- Vérification préalable : fremforge recherche l’environnement de l’organisation. Aucun environnement configuré = aucun contrôle ne s’applique (adoption progressive ; les workflows des nouveaux clients ne sont pas bloqués avant qu’ils aient configuré des environnements).
- Création ou récupération d’une tentative de déploiement, identifiée par
(env, ref, commit_sha). Les relances du même workflow sur le même commit partagent la même tentative : un processus d’approbation survit donc aux nouvelles tentatives. - Résolution des informations annexes : l’adresse e-mail de l’acteur et le corps de la pull request sont lus dans Forgejo. Au mieux ; repli sur des valeurs synthétiques si Forgejo est dégradé.
- Évaluation des 9 contrôles en parallèle : chaque contrôle est indépendant et lit son propre signal.
- Composition : si TOUS les contrôles configurés réussissent, l’état passe à
dispatchedet la VM du runner est provisionnée. Si SEUL le contrôle A (approbateurs) échoue, l’état passe àpending_approval: les administrateurs peuvent cliquer sur Approuver, et la nouvelle tentative suivante réévalue. Si un autre contrôle échoue, l’état passe àgates_failed. - Audit : le détail complet des résultats des contrôles est enregistré et un événement d’audit est émis.
À quoi ressemble un déploiement refusé
Le client voit : l’exécution du workflow annulée, avec une vérification de statut de commit indiquant le motif du refus (par ex. deploy_gate_C_time_window — outside allowed windows).
L’administrateur de l’organisation voit : une ligne dans Pending deployments avec le détail complet de l’évaluation (quels contrôles ont réussi, lesquels ont échoué), avec la chaîne reason propre à chaque contrôle.
Ce qui est déployé dans chaque environnement
Administration fremforge → Déploiements (https://frem.sh/<org>/_admin/deployments) commence par Déployé par environnement. Pour chaque environnement, vous voyez le déploiement actuellement en place et celui d’avant, qui est votre cible de retour arrière :
- le dépôt, la ref (branche ou tag) et le commit, avec un lien ;
- les tags qui pointent vers ce commit, par exemple
prd-2026-11-01ourc-81; - qui l’a approuvé, et quand ;
- quand le déploiement s’est terminé, et un lien vers son exécution de workflow.
Un déploiement n’est considéré comme en place que si son exécution a été lancée et s’est terminée avec succès. Les tentatives échouées, annulées, refusées ou encore en attente ne comptent jamais : après un déploiement échoué, le précédent reste affiché comme en place. Un environnement sans déploiement réussi affiche Jamais déployé.
Les outils de release peuvent lire les mêmes données via l’API, avec un token qui porte deployments:read, sans avoir à analyser la page :
curl -fsS "https://frem.sh/_app/api/v1/orgs/acme/deployments/live?environment=production" \
-H "Authorization: Bearer $FREMFORGE_TOKEN"Chaque environnement de la réponse a live et previous, tous deux null tant que rien n’y a été déployé. Chacun contient repo_full_name, ref, commit_sha, commit_url, tags, approvals, deployed_at, run_number et run_url. Sans ?environment=, vous obtenez tous les environnements. tags provient des 150 tags les plus récents du dépôt et peut dater d’une minute au plus. Il vaut null (et non []) quand les tags n’ont pas pu être lus à ce moment.
Combiner les contrôles
L’échelle est volontairement combinable : la plupart des clients configurent 2 ou 3 contrôles par environnement, pas les 9. Quelques points de départ suggérés :
| Profil | Contrôles configurés | Justification |
|---|---|---|
| Développeur seul, un environnement | aucun | Aucun contrôle nécessaire à l’échelle d’une personne seule ; par défaut, fremforge autorise toutes les branches. |
| Petite équipe, environnement de production | B (refs=main) + I (indicateur de pause disponible) | Évite les déploiements accidentels de branches de fonctionnalité en production ; l’astreinte dispose de l’interrupteur d’arrêt. |
| Équipe moyenne, secteur réglementé | A (2 approbateurs) + B (refs=main, release/*) + H (ticket lié) + I | Approbation + piste d’audit + interrupteur d’arrêt commun aux équipes. |
| Grande entreprise, plusieurs étapes | A (3 approbateurs) + B + C (heures ouvrées) + D (SLO sain) + E (dep-scan + sast) + F (concurrence=1) + G (délai de carence de 60 min) + H + I | Échelle complète ; chaque contrôle a du sens à cette échelle. |
Commencez petit, et ajoutez des contrôles à mesure que vous grandissez.
Secrets et variables par environnement
Indépendamment des contrôles, les environnements portent leurs propres secrets et variables, injectés uniquement dans les jobs qui déclarent environment: <name>. Voir Secrets pour la gestion des secrets.
Gérer les environnements via l’API
Tout ce que fait l’interface d’administration, l’API REST le fait aussi. Les environnements se trouvent dans l’espace de noms des extensions fremforge : l’URL de base est donc https://frem.sh/_app/api/v1, et non /api/v1 seul, qui est l’API propre à Forgejo et rejettera l’appel.
| Méthode | Chemin | Scope |
|---|---|---|
GET | /orgs/<org>/environments | environments:read |
POST | /orgs/<org>/environments | environments:write |
GET | /orgs/<org>/environments/<name> | environments:read |
DELETE | /orgs/<org>/environments/<name> | environments:write |
PUT DELETE | /orgs/<org>/environments/<name>/variables/<VAR> | environments:write |
GET | /orgs/<org>/environments/<name>/secrets | environments:read |
PUT | /orgs/<org>/environments/<name>/secrets/<NAME> | environments:write |
DELETE | /orgs/<org>/environments/<name>/secrets/<id> | environments:write |
PUT | /orgs/<org>/environments/<name>/gates | environments:write |
PUT | /orgs/<org>/environments/<name>/branches | environments:write |
GET | /orgs/<org>/deployments/live | deployments:read |
Les noms d’environnements correspondent à [A-Za-z0-9_.-]+ (pas de /). Les noms de variables correspondent à [A-Z][A-Z0-9_]*, avec des valeurs jusqu’à 64 Kio. Les valeurs des secrets sont chiffrées au repos et jamais renvoyées : les points de terminaison de liste ne donnent que les noms et les métadonnées.
# Create an environment, then give it a variable and a secret.
curl -fsS -X POST https://frem.sh/_app/api/v1/orgs/acme/environments \
-H "Authorization: Bearer $FREMFORGE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"name":"staging"}'
curl -fsS -X PUT https://frem.sh/_app/api/v1/orgs/acme/environments/staging/variables/REGION \
-H "Authorization: Bearer $FREMFORGE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"value":"eu-de"}'
curl -fsS -X PUT https://frem.sh/_app/api/v1/orgs/acme/environments/staging/secrets/DEPLOY_KEY \
-H "Authorization: Bearer $FREMFORGE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"value":"…"}'{"value": "…"}. Les secrets au niveau de l’organisation (PUT /orgs/<org>/secrets/<NAME>) sont documentés avec {"data": "…"} et acceptent aussi value comme alias : les deux orthographes fonctionnent. Si vous envoyez les deux, data l’emporte.Si vous obtenez une erreur 403
403 Token lacks required scope 'environments:…' signifie que le point de terminaison existe et que votre jeton ne porte pas le scope ; ce n’est pas une fonctionnalité manquante. Vérifiez les scopes que détient réellement votre identifiant. Un PAT que vous avez créé vous-même porte exactement les scopes que vous avez cochés ; un banc de développement porte un ensemble créé par la plateforme, volontairement plus restreint, qui se renouvelle au réveil du banc.
Claim OIDC d’environnement
Les workflows qui déclarent environment: <name> reçoivent un claim OIDC supplémentaire : sub devient repo:<owner>/<repo>:environment:<name>. C’est sur ce claim que s’appuient les politiques de confiance des clouds pour la fédération de courte durée (AWS STS AssumeRoleWithWebIdentity, Azure WIF, GCP Workload Identity Federation). Voir Fédération OIDC pour la forme des politiques de confiance.
Dépannage
Le workflow est bloqué sur « Review pending » et aucune notification n’a été envoyée. → Vérifiez le nombre de Required reviewers de l’environnement. Les approbations se font sur la page d’administration Pending deployments ; fremforge n’envoie pas (encore) d’e-mail aux approbateurs. Ajoutez cette page au point quotidien de votre équipe.
Un déploiement a été refusé avec deploy_gate_D_slo_burn alors que je n’ai pas configuré le contrôle D.
→ Le contrôle D échoue en mode fermé lorsque fremforge ne dispose d’aucun état récent pour une alarme listée. Si vous avez LISTÉ un nom d’alarme qui n’a jamais remonté d’état, le contrôle refuse automatiquement. Retirez ce nom d’alarme de la configuration du contrôle, ou assurez-vous que l’alarme est raccordée de sorte que son état soit remonté.
Le corps de la pull request correspond à un motif de ticket, mais le contrôle H échoue quand même. → La tentative de déploiement a été créée AVANT l’ouverture de la pull request. fremforge capture le corps de la pull request lors de la première évaluation et ne le récupère pas à nouveau. Poussez un commit vide pour déclencher une nouvelle évaluation.
Je veux contourner temporairement les contrôles. → Il n’existe pas encore d’interface de contournement par organisation. Contactez support@frem.sh pour contourner temporairement un contrôle. Les portées des indicateurs de pause ne sont que des bascules levée/active.
Événements d’audit
Chaque décision d’un contrôle émet des événements d’audit structurés :
| Événement | Quand |
|---|---|
environment.gates.update | Un administrateur de l’organisation modifie la configuration des contrôles |
tenant.deploy.approval_granted | Un approbateur clique sur Approuver |
tenant.deploy.approval_rejected | Un approbateur clique sur Rejeter (avec un motif) |
tenant.deploy.approval_revoked | Un approbateur révoque sa propre approbation |
tenant.deploy.pause_set / _cleared | Indicateur de pause par environnement basculé (administration de l’organisation) |
platform.deploy.pause_set / _cleared | Indicateur de pause à l’échelle de la plateforme basculé |