Aller au contenu principal

Gels de fusion

Un gel de fusion bloque les fusions dans une branche, pour une raison donnée, jusqu’à une échéance. Utilisez-en un pour la coupe d’un train de release, un incident ou une migration qui ne doit pas entrer en concurrence avec d’autres modifications. Les trains de release posent et lèvent leurs propres gels (source: train), dont le responsable est celui du train.

Un gel couvre l’un des périmètres suivants :

  • tous les dépôts de l’organisation ;
  • une liste de dépôts (jusqu’à 50) ;
  • un seul dépôt.

Il s’applique toujours à une seule branche : main, sauf si vous en indiquez une autre.

Comment un gel bloque une fusion

fremforge publie un statut de commit, fremforge/hold, sur le commit de tête de chaque pull request ouverte vers une branche gelée :

StatutSignification
pendingUn gel couvre cette pull request. La description indique le responsable, l’échéance et la raison.
successAucun gel ne la couvre, ou un administrateur a laissé passer cette pull request (voir Dérogation administrateur).

Sur une branche où fremforge/hold est un contrôle obligatoire, un gel pending bloque tous les moyens de fusionner :

  • Le bouton de fusion et le point de terminaison de fusion de l’API refusent avec « Not all required status checks successful ».
  • La fusion automatique attend. Lorsque le gel est levé, le statut passe à success et toute pull request programmée pour fusionner fusionne alors. Une pull request programmée pendant un gel est fusionnée après celui-ci.
  • La file de fusion tient la pull request à l’écart des groupes de fusion. Si le gel dure plus longtemps que le délai de contrôle de la file, celle-ci met la pull request de côté et la réintègre une fois, lorsque ses contrôles redeviennent verts.

Pousser sur une pull request soumise à un gel, ou en ouvrir une nouvelle, fait apparaître le statut en quelques secondes. Toutes les 5 minutes, une tâche de réconciliation répare tout statut manquant, obsolète ou publié par quelqu’un d’autre.

Les gels échouent en position fermée. Si fremforge ne peut pas publier le statut, une nouvelle pull request vers une branche où les gels sont appliqués attend jusqu’à ce qu’il le puisse.

Dans la console

Les propriétaires de l’organisation gèrent les gels sous Build et déploiement → Gels des fusions (https://frem.sh/<org>/_admin/merge-holds) : les gels actifs avec leur responsable, leur échéance et les dépôts où le bouton de fusion attend, des boutons pour lever, prolonger ou laisser passer une pull request, un formulaire pour poser un gel, les interrupteurs d’application, et les gels récemment terminés. Tout ce qui figure sur la page est aussi disponible dans l’API ci-dessous.

Activer l’application

Rendre fremforge/hold obligatoire se fait sur option, par dépôt ou pour toute l’organisation, et par branche. Tant que vous ne l’avez pas activé, les gels sont listés et lus par les outils, mais le bouton de fusion ne les attend pas.

curl -X PUT https://frem.sh/_app/api/v1/orgs/<org>/merge-holds/enforcement \
  -H "Authorization: Bearer $FREMFORGE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"repo": "*", "branch": "main"}'

repo est un nom de dépôt, ou * pour tous les dépôts, y compris ceux créés plus tard. Le jeton doit avoir policy:write.

Lorsque vous activez l’option, fremforge publie d’abord fremforge/hold sur chaque pull request ouverte vers la branche. Ce n’est qu’ensuite qu’il ajoute le contrôle à la règle de protection de la branche. Aucune pull request n’attend jamais un contrôle que rien n’a publié.

La réponse indique :

  • required_on : les dépôts où le contrôle est désormais obligatoire.
  • unprotected : les dépôts dont la branche n’a pas de règle de protection. fremforge n’en crée pas ; ajoutez une règle et la tâche de réconciliation rend le contrôle obligatoire dans les 5 minutes.
  • failed : les dépôts dont les pull requests n’ont pas pu être lues. Leur règle reste inchangée et la tâche réessaie.

Pour désactiver l’option, envoyez le même corps avec DELETE. fremforge retire le contrôle partout où aucune autre activation ne couvre encore le dépôt.

Poser un gel

curl -X POST https://frem.sh/_app/api/v1/orgs/<org>/merge-holds \
  -H "Authorization: Bearer $FREMFORGE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "repos": ["platform", "infrastructure-azure"],
        "reason": "Train 42 cut: no merges until the tst probe passes",
        "duration_minutes": 120
      }'
ChampObligatoireRemarques
reasonouiUne ligne, 500 caractères au maximum. Affichée dans le statut de chaque pull request gelée.
expires_at ou duration_minutesexactement un des deuxAu moins 5 minutes et au plus 7 jours dans le futur. expires_at est au format ISO 8601 avec fuseau horaire.
reposnonÀ omettre pour geler tous les dépôts.
branchnonUn nom de branche, sans caractères génériques. main par défaut.
owneruniquement pour un jeton qui n’agit pour aucune personneUn membre de l’organisation.

Le jeton doit avoir deployments:write, la portée qui permet aussi de suspendre les déploiements. La lecture des gels nécessite deployments:read.

Responsable

Chaque gel appartient à une personne. Lorsque vous posez un gel, vous-même ou un agent agissant en votre nom, vous en êtes le responsable. Un jeton qui n’agit pour aucune personne, comme un jeton de CI, doit indiquer owner.

Expiration et alerte

Aucun gel ne bloque indéfiniment. Lorsqu’un gel atteint son échéance, fremforge le lève dans les 5 minutes, consigne merge_hold.expired dans le journal d’audit et envoie un e-mail au responsable. Si les fusions doivent rester gelées, prolongez-le avant :

curl -X PATCH https://frem.sh/_app/api/v1/orgs/<org>/merge-holds/<id> \
  -H "Authorization: Bearer $FREMFORGE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"duration_minutes": 60}'

Lister et lever des gels

# Live holds, and where enforcement is on
curl https://frem.sh/_app/api/v1/orgs/<org>/merge-holds \
  -H "Authorization: Bearer $FREMFORGE_TOKEN"

# Release one
curl -X POST https://frem.sh/_app/api/v1/orgs/<org>/merge-holds/<id>/release \
  -H "Authorization: Bearer $FREMFORGE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"note": "Train 42 is out"}'

Ajoutez ?state=all à la liste pour inclure les gels levés. Les pull requests gelées passent à success quelques secondes après la levée.

La pose et la levée d’un gel apparaissent aussi dans le flux d’événements sous hold.placed et hold.released, avec un événement par dépôt couvert par le gel.

Les assistants IA connectés via le serveur MCP de fremforge peuvent lister les gels avec l’outil list_merge_holds.

Dérogation administrateur

Il existe deux dérogations, toutes deux consignées dans le journal d’audit :

  • Lever le gel de quelqu’un d’autre. Tout propriétaire de l’organisation peut lever n’importe quel gel. Lorsque le responsable le lève, le journal d’audit consigne merge_hold.released. Lorsque quelqu’un d’autre le fait, il consigne merge_hold.override.
  • Laisser passer une pull request. Pour un correctif urgent pendant un gel, exemptez une seule pull request. Son statut passe à success, et le gel reste en place pour tout le reste. Une raison est obligatoire. Le journal d’audit consigne merge_hold.exempted.
curl -X POST https://frem.sh/_app/api/v1/orgs/<org>/merge-holds/<id>/exemptions \
  -H "Authorization: Bearer $FREMFORGE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"repo": "platform", "pr_number": 812, "reason": "INC-7 hotfix"}'

Un administrateur de dépôt peut toujours fusionner manuellement lorsque la règle de branche ne s’applique pas aux administrateurs. C’est la voie de secours (break-glass), et Forgejo l’enregistre comme n’importe quelle fusion.

Gels de release depuis un ticket

Si votre équipe gèle un dépôt en ouvrant un ticket portant l’étiquette release-freeze, cela continue de fonctionner. Dans un dépôt où l’application est activée, fremforge transforme chaque ticket release-freeze ouvert en gel sur ce dépôt :

  • l’auteur du ticket en est le responsable ;
  • sa raison est le titre du ticket ;
  • fermer le ticket, ou retirer l’étiquette, le lève en quelques secondes.

Le bouton de fusion respecte donc désormais aussi ce gel. Un tel gel n’a pas de fin propre : il est donc posé par périodes de 24 heures. Tant que le ticket est ouvert, fremforge renouvelle le gel à son expiration et prévient le responsable par e-mail que le gel est toujours en vigueur.

Ce qu’un gel ne fait pas

  • Il n’empêche pas les push directs sur la branche. Utilisez la protection de branche pour exiger des pull requests.
  • Il n’arrête pas les déploiements. Pour cela, suspendez un environnement de déploiement.
  • Toute personne ayant un accès en écriture à un dépôt peut publier un statut de commit sous n’importe quel nom. fremforge rétablit fremforge/hold et consigne merge_hold.status_foreign dans le journal d’audit lorsque quelqu’un d’autre le publie. Cela referme la brèche en quelques secondes ou minutes, pas instantanément.

Événements d’audit

ÉvénementQuand
merge_hold.createdUn gel a été posé, y compris un gel reflétant un ticket release-freeze.
merge_hold.updatedSon responsable l’a prolongé ou en a modifié la raison.
merge_hold.releasedSon responsable l’a levé, ou son ticket release-freeze a été fermé.
merge_hold.overrideUne personne autre que le responsable l’a levé ou modifié.
merge_hold.exemptedUne pull request a été autorisée à passer.
merge_hold.expiredIl a atteint son échéance et a été levé.
merge_hold.renewedUn gel release-freeze a expiré alors que son ticket était toujours ouvert.
merge_hold.enforcement_enabled / merge_hold.enforcement_disabledL’application a été activée ou désactivée.
merge_hold.status_foreignQuelqu’un d’autre a publié fremforge/hold, et fremforge l’a rétabli.