gerrit-hygiene-operations

Par gerritcodereview · gerrit

Fournit des règles, des modèles et des bonnes pratiques pour la qualité du code, la mise en forme, les dépendances de plugins en aval et les opérations de release dans Gerrit.

npx skills add https://github.com/gerritcodereview/gerrit --skill gerrit-hygiene-operations

Guide d'hygiène Gerrit et d'ingénierie opérationnelle

Résumé exécutif

Bienvenue dans le guide d'ingénierie faisant autorité pour maintenir l'hygiène du code, gérer les déploiements en aval et optimiser les opérations au sein de la base de code. Ce référentiel vivant constitue la source définitive des connaissances métier visant à prévenir la dette technique et à maintenir notre écosystème de développement évolutif, prévisible et résilient face aux frictions d'intégration.

Les domaines couverts dans ce contenu ciblent les sources les plus courantes de dette technique, d'instabilité des pipelines et de désynchronisation des déploiements. Vous trouverez des mandats couvrant l'encapsulation stricte de l'infrastructure propriétaire pour protéger les contributeurs externes de l'outillage opaque, des stratégies pour éliminer l'instabilité des tests de régression visuelle et des protocoles pour l'élimination du code mort lors de la décommission d'expériences. De plus, il décrit les normes d'optimisation de performance—comme la parallélisation des requêtes côté client—et mandate une hygiène stricte CI/CD via les règles de formatage TypeScript et la génération automatisée des notes de release.

Les ingénieurs sont censés internaliser ces directives lors de l'architecture des composants UI, de la rédaction de la documentation API ou de la coordination des releases en aval. L'adhésion à ces principes réduit directement le bruit de déploiement, assure une expérience développeur transparente pour les contributeurs internes et open-source, et renforce l'intégrité de nos pipelines d'intégration continue.

Résumé

Thème de chapitre / Titre Portée et objectif
**Synchronisation des déploiements de Gouverne la coordination des

: l'écosystème en aval : calendriers de release et la gestion : : : des dépendances inter-projets pour les : : : plugins externes à travers les : : : déploiements Gerrit isolés en aval. : : : Requiert un audit strict pour prévenir : : : les défaillances d'intégration lors des : : : déploiements de plateforme centrale. : | Formatage du code TypeScript et | Définit le style structurel du code et | : normalisation de la syntaxe : les mandats de linting pour les : : : composants TypeScript frontend. : : : L'application stricte des règles de : : : formatage, comme les contraintes de : : : longueur de ligne, assure une : : : lisibilité optimale des diffs et : : : prévient les défaillances du pipeline : : : CI automatisé. : | Encapsulation de l'infrastructure | Établit des limites strictes pour la | : propriétaire : documentation des APIs publiques en : : : interdisant la fuite de chemins de : : : backend propriétaires ou d'URLs : : : d'entreprise interne. Assure : : : l'encapsulation de l'environnement et : : : prévient l'exposition de liens morts : : : ou de références opaques aux : : : contributeurs open-source. : | Parallélisation des requêtes côté | Gouverne l'optimisation des métriques | : client : de chargement frontend en transitant : : : de requêtes monolithiques ou en lots : : : côté serveur vers des requêtes : : : distribuées parallélisées et : : : asynchrones côté client. Mandate : : : l'exécution concurrente pour améliorer : : : les performances et simplifier la : : : logique de mise en cache. : | Décommission d'expériences et | Dicte le nettoyage obligatoire | : élimination du code mort : requis lors de la promotion des : : : fonctionnalités expérimentales réussies : : : au comportement par défaut. Force : : : l'élimination stricte des méthodes : : : fallback héritées, des évaluations de : : : feature flags et des dépendances de : : : services obsolètes pour prévenir : : : l'accumulation du code mort. : | Métadonnées de commit et | Mandate l'injection de footers git | : automatisation des notes de release : structurés dans les messages de commit.: : : L'adhésion stricte assure que les : : : pipelines CI/CD automatisés analysent : : : avec succès et génèrent des changelogs : : : et des notes de release précises sans : : : intervention manuelle. : | Déterminisme des tests de régression | Gouverne les stratégies pour éliminer | : visuelle** : l'instabilité des tests de régression : : : visuelle en orchestrant délibérément : : : des états UI transitionnels : : : déterministes. Établit la norme : : : d'omission intentionnelle des mocks API : : : pour capturer fiablement les états de : : : chargement lors de la génération des : : : baselines de capture d'écran. :



Chapitre : Synchronisation des déploiements de l'écosystème en aval

Contexte : Ce chapitre gouverne la coordination des calendriers de release et la gestion des dépendances inter-projets pour les plugins externes à travers les déploiements Gerrit isolés en aval. Un audit strict de ces écosystèmes externes est requis pour prévenir les défaillances d'intégration lors du déploiement des mises à jour de plateforme centrale.

Résumé

ID de règle Principe / Contrainte Priorité Symptôme principal / Piège
T1-01 Vérification des Haute Procéder avec un

: : dépendances des plugins : : calendrier de release core : : : en aval lors du : : sans vérifier la : : : déploiement central : : compatibilité des plugins : : : : : personnalisés en aval. :


Règles

T1-01 : Vérification des dépendances des plugins en aval lors du déploiement central

Règle : Auditez et vérifiez toujours la compatibilité des dépendances inter-projets, comme les plugins personnalisés, avant d'exécuter les mises à jour de release centrale sur les instances en aval isolées.

Quoi : Avant de déployer les mises à jour de release centrale sur les instances d'écosystème en aval isolées, les dépendances inter-projets (par ex., les plugins personnalisés) doivent être explicitement auditées et vérifiées pour la compatibilité.

S'applique à : La gestion des releases et la synchronisation des déploiements vers les environnements en aval (par ex., Chromium, pdfium, v8).

Pourquoi : Déployer les mises à jour centrales sans auditer et upgrader simultanément les plugins très utilisés (comme avatars-external) dans les installations en aval a historiquement risqué les délais de déploiement et les défaillances d'intégration. Échouer à adhérer à cela entraîne généralement une désynchronisation du déploiement.

Piège 1 : Procéder avec un calendrier de release centrale sans vérifier les états de compatibilité des plugins personnalisés en aval.

À ne pas faire :

  • Déployer la release centrale indépendamment des états de compatibilité des plugins externes.

À faire :

  • Auditer et signaler les exigences des plugins en aval (par ex., avatars-external) pour les mises à jour avant ou en même temps que la release centrale.

Chapitre : Formatage du code TypeScript et normalisation de la syntaxe

Contexte : Cette section définit le style structurel du code et les mandats de linting pour les composants TypeScript frontend. L'application stricte des règles de formatage, comme les contraintes de longueur de ligne, assure une lisibilité optimale des diffs et prévient les défaillances du pipeline CI automatisé.

Résumé

ID de règle Principe / Contrainte Priorité Symptôme principal / Piège
T2-01 Formatage strict de la Moyen Chaîner de longs rappels

: : longueur de ligne : : de promesses ou des : : : : : assignations de variables : : : : : sur une seule ligne. :


Règles

T2-01 : Formatage strict de la longueur de ligne

Règle : Formatez toujours les fichiers TypeScript pour adhérer strictement aux limites de linting en enrobant les expressions longues en chaîne. Ne commitez jamais du code qui déclenche des violations de style structurel.

Quoi : Les fichiers TypeScript frontend doivent adhérer strictement aux normes de linting en enrobant correctement les expressions longues en chaîne.

S'applique à : Les composants UI TypeScript (par ex., les éléments Lit comme gr-reply-dialog.ts).

Pourquoi : Le formatage incohérent et les lignes trop longues ont causé du bruit de diff inutile et ont échoué les vérifications de linting automatisées dans le pipeline CI frontend. Échouer à adhérer à cela entraîne généralement une défaillance du pipeline de linting.

Piège 1 : Chaîner de longs rappels de promesses ou des assignations de variables sur une seule ligne.

À ne pas faire :

return this.saveReview(reviewInput, errFn).then(result => {

À faire :

return this.saveReview(reviewInput, errFn)
  .then(result => {

Chapitre : Encapsulation de l'infrastructure propriétaire

Contexte : Ce domaine établit des limites strictes pour la documentation des APIs publiques, des Enums et des définitions d'interfaces en interdisant explicitement la fuite de chemins de backend propriétaires (par ex., google3/) ou d'URLs d'entreprise interne. L'adhésion assure l'encapsulation de l'environnement et prévient l'exposition de liens morts ou de références opaques aux contributeurs open-source.

Résumé

ID de règle Principe / Contrainte Priorité Symptôme principal / Piège
T3-01 Omission des chemins Moyen Copier les chemins de

: : d'infrastructure propriétaire : : fichiers du référentiel : : : de la documentation Enum : : interne dans le bloc de : : : : : docstring d'une interface : : : : : ou d'un Enum. : | T3-02 | Exclusion des URIs de | Moyen | Utiliser des URLs | : : recherche de code interne : : propriétaires de recherche : : : des types d'interface : : de code interne pour : : : : : fournir des exemples de : : : : : chaînes de payload : : : : : acceptables. :


Règles

T3-01 : Omission des chemins d'infrastructure propriétaire de la documentation Enum

Règle : Supprimez toujours les chemins de répertoires internes des commentaires JSDoc ou TSDoc lors de la définition des modèles de données publics.

Quoi : Les commentaires JSDoc ou TSDoc définissant des modèles de données (par ex., les Enums) ne doivent pas divulguer les chemins de répertoires ou de référentiel de backend propriétaires et internes.

S'applique à : Les définitions API frontend, spécifiquement les Enums mappés Protobuf.

Pourquoi : Les chemins de répertoires internes (par ex., google3/.../proto) ont été accidentellement inclus dans la documentation du code frontend open-source, cassant l'encapsulation de l'environnement. Échouer à adhérer à cela entraîne généralement une fuite d'information.

Piège 1 : Copier les chemins de fichiers du référentiel interne dans le bloc de docstring d'une interface ou d'un Enum.

À ne pas faire :

/**
 * Enum to match the Action proto from CRUAS.
 * google3/path/to/internal/service/proto/file.proto.
 */
export enum ActionEnum { ... }

À faire :

/**
 * Enum to match the Action proto from CRUAS.
 */
export enum ActionEnum { ... }

T3-02 : Exclusion des URIs de recherche de code interne des types d'interface

Règle : N'incluez jamais les URLs de recherche de code propriétaires lors de la documentation des définitions de type ou des schémas de payload.

Quoi : Les commentaires de code ne doivent pas contenir de liens URL vers des outils de recherche de code internes ou des dépôts de source propriétaires lors de la documentation des types de champs d'interface.

S'applique à : Les déclarations d'interface API et les schémas de payload (par ex., ContextItem).

Pourquoi : Un développeur a créé un lien directement vers une URI de code-source propriétaire (source.corp.google.com) pour expliquer un champ d'ID de type, rendant la documentation inaccessible et inutile pour les contributeurs open-source externes. Échouer à adhérer à cela entraîne généralement un lien mort / opacité.

Piège 1 : Utiliser des URLs propriétaires de recherche de code interne pour fournir des exemples de chaînes de payload acceptables.

À ne pas faire :

// type_id should match the types here: https://source.corp.google.com/piper///depot/google3/...
type_id: string;

À faire :

// type_id should map to standard application contexts (e.g., 'gerrit_change', 'bug_tracker').
type_id: string;

Chapitre : Parallélisation des requêtes côté client

Contexte : Ce chapitre gouverne l'optimisation des métriques de chargement frontend en transitant de requêtes monolithiques ou en lots côté serveur vers des requêtes distribuées parallélisées et asynchrones côté client. Cette approche mandate l'exécution concurrente côté client pour améliorer la performance du tableau de bord et simplifier la logique de mise en cache en aval.

Résumé

ID de règle Principe / Contrainte Priorité Symptôme principal / Piège
T4-01 Distribution côté client Haute Transférer un tableau de

: : pour le traitement des : : requêtes vers une méthode : : : requêtes du tableau de : : d'endpoint dédié : : : bord : : multi-requête. :


Règles

T4-01 : Distribution côté client pour le traitement des requêtes du tableau de bord

Règle : Mappez et exécutez toujours plusieurs requêtes de backend simultanément en utilisant des construits de parallélisation côté client. Ne vous fiez jamais à des endpoints multi-requête en lots uniques côté serveur pour agréger les données.

Quoi : Les multiples requêtes de backend doivent être mappées et exécutées simultanément en utilisant Promise.all côté client, plutôt que de s'appuyer sur un seul endpoint de backend multi-requête en lots.

S'applique à : La couche API Service (GrRestApiServiceImpl), en particulier les routines de récupération des données du tableau de bord.

Pourquoi : Une approche héritée préchargeait les requêtes en lots dans le backend, ce qui compliquait la mise en cache et la logique backend. Le passage à des requêtes parallèles côté client a explicitement amélioré la métrique de performance DashboardDisplayed. Échouer à adhérer à cela entraîne généralement une dégradation des performances.

Piège 1 : Transférer un tableau de requêtes vers une méthode d'endpoint dédié multi-requête.

À ne pas faire :

return this.getChangesForMultipleQueries(changesPerPage, queries, offset, options);

À faire :

const requestPromises = queries.map(query =>
  this.getChanges(changesPerPage, query, offset, options)
);
return Promise.all(requestPromises).then(results => {
  if (results.includes(undefined)) return undefined;
  return results as ChangeInfo[][];
});

Dépendances inter-domaines

  • En aval : T5 | Décommission d'expériences et élimination du code mort - La transition vers des distributions côté client expose régulièrement les mécanismes de batching backend obsolètes et les feature flags expérimentaux qui doivent être ensuite supprimés.

Chapitre : Décommission d'expériences et élimination du code mort

Contexte : Ce domaine gouverne le nettoyage obligatoire requis lors de la promotion des fonctionnalités expérimentales réussies au comportement par défaut. Il force l'élimination stricte des méthodes fallback héritées, des évaluations de feature flags et des dépendances de services obsolètes pour prévenir l'accumulation du code mort.

Résumé

ID de règle Principe / Contrainte Priorité Symptôme principal / Piège
T5-01 Élagage agressif des fallbacks Moyen Laisser la méthode

: : d'expériences décommissionnées : : fallback héritée dans la : : : : : classe après suppression du : : : : : basculement de flag : : : : : d'expérience et du bloc : : : : : d'invocation. :


Règles

T5-01 : Élagage agressif des fallbacks d'expériences décommissionnées

Règle : Supprimez complètement toutes les méthodes fallback, les feature flags et les dépendances de services obsolètes immédiatement après la graduation d'une fonctionnalité expérimentale au comportement par défaut.

Quoi : Quand une fonctionnalité expérimentale est promue au comportement par défaut, toutes les évaluations de flag correspondantes (KnownExperimentId), les dépendances de services (FlagsService) et les méthodes de routage fallback obsolètes doivent être entièrement supprimées.

S'applique à : Les composants de couche Service et les implémentations API lors de la graduation des feature flags.

Pourquoi : Échouer à supprimer agressivement les méthodes fallback obsolètes (comme getChangesForMultipleQueries) après l'adoption native des requêtes parallèles côté client a entraîné du code mort et de la confusion sur l'utilisation correcte de l'API. Échouer à adhérer à cela entraîne généralement une accumulation de dette technique.

Piège 1 : Laisser la méthode fallback héritée dans la classe après suppression du basculement de flag d'expérience et du bloc d'invocation.

À ne pas faire :

  • Supprimer l'évaluation if (experimentEnabled), mais laisser getChangesForMultipleQueries(queries) déclaré dans la définition de classe.

À faire :

  • Supprimer entièrement la méthode fallback dépréciée getChangesForMultipleQueries pour assurer qu'aucun autre composant ne tente de l'invoquer.

Dépendances inter-domaines

  • En amont : T4 | Parallélisation des requêtes côté client - La transition vers des requêtes parallélisées côté client déclenche la dépréciation et le nettoyage ultérieur des requêtes monolithiques côté serveur héritées.

Chapitre : Métadonnées de commit et automatisation des notes de release

Contexte : Cette section mandate l'injection de footers git structurés dans les messages de commit. L'adhésion stricte assure que les pipelines CI/CD automatisés analysent avec succès et génèrent des changelogs et des notes de release précises sans intervention manuelle.

Résumé

ID de règle Principe / Contrainte Priorité Symptôme principal / Piège
T6-01 Injection obligatoire du Haute Omettre le footer

: : footer Release-Notes : : entièrement ou formater la : : : : : description de la note de : : : : : release comme un : : : : : paragraphe multi-lignes. :


Règles

T6-01 : Injection obligatoire du footer Release-Notes

Règle : Annexez toujours un footer Release-Notes: correctement formaté et sur une seule ligne à tous les commits. Bien qu'une note descriptive soit précieuse pour les mises à jour significatives, utiliser Release-Notes: skip est complètement acceptable et courant pour les petits changements UI, les ajustements de style, les petits correctifs ou tout changement pour lequel une entrée de changelog public détaillée n'est pas nécessaire.

Quoi : Les messages de commit doivent inclure un footer Release-Notes: correctement formaté et sur une seule ligne pour satisfaire les exigences de soumission CI/CD et déclencher la génération automatisée du changelog. Si un changement est mineur ou qu'une note de release publique n'est pas nécessaire (même pour les ajustements visibles par l'utilisateur comme ajouter de l'espacement pour prévenir les clics accidentels), utiliser la valeur skip est complètement valide et acceptable.

S'applique à : Les messages de commit Git pour tous les changements, incluant les mises à jour UI frontend, backend et configuration.

Pourquoi : Sans un footer dédié, les analyseurs de notes de release automatisés ou les vérifications de soumission peuvent échouer. Cependant, tous les commits n'ont pas besoin d'une note de release publique ; par conséquent, Release-Notes: skip est supporté pour garder l'historique git propre et satisfaire l'automatisation sans générer d'entrées de changelog public inutiles.

Piège 1 : Omettre le footer entièrement ou formater la description de la note de release comme un paragraphe multi-lignes.

À ne pas faire :

  • Soumettre un commit sans un footer explicite Release-Notes:, ou étaler la description de la note de release sur plusieurs lignes dans le corps du commit.

À faire :

  • Pour les fonctionnalités majeures ou les changements de configuration : Annexez un footer sur une seule ligne avec un résumé descriptif, par ex. : Release-Notes: Add config to control if review footers should be included into the commit message on submit
  • Pour les ajustements mineurs (comme la correction de clics accidentels en ajoutant de l'espacement), les corrections triviales ou les refactorisations : Une description de note de release détaillée peut toujours être fournie si désiré, mais annexer Release-Notes: skip est complètement acceptable.

Exceptions : Aucune. Le footer Release-Notes: doit être présent sur tous les commits, mais la valeur skip est toujours acceptable.

Chapitre : Déterminisme des tests de régression visuelle

Contexte : Ce chapitre gouverne les stratégies pour éliminer l'instabilité des tests de régression visuelle en orchestrant délibérément des états UI transitionnels déterministes. Spécifiquement, il établit la norme d'omission intentionnelle des mocks API pour capturer fiablement les états de chargement lors de la génération des baselines de capture d'écran.

Résumé

ID de règle Principe / Contrainte Priorité Symptôme principal / Piège
T7-01 Omission intentionnelle des Haute Mocker toutes les APIs par

: : mocks pour les baselines UI : : défaut dans un test de : : : déterministes : : capture d'écran, causant : : : : : une condition de course où : : : : : le mock se résout plus : : : : : vite que la capture : : : : : d'écran est prise. :


Règles

T7-01 : Omission intentionnelle des mocks pour les baselines UI déterministes

Règle : Omettez toujours les mocks API lorsque vous tentez de capturer fiablement les états UI transitionnels (comme les spinners de chargement) dans les tests de régression visuelle. Ne fournissez jamais les réponses mock si l'objectif est d'établir une baseline d'une vue asynchrone pré-résolue.

Quoi : Pour capturer les états UI transitionnels stables et déterministes (comme les spinners de chargement) dans les tests de régression visuelle, les endpoints API sous-jacents doivent être intentionnellement laissés sans mock.

S'applique à : Le test de baseline de capture d'écran (par ex., _screenshot_test.ts) pour les composants UI asynchrones.

Pourquoi : Capturer les états UI complètement résolus était difficile à synchroniser, causant des tests de capture d'écran instables. S'appuyer sur une API sans mock assure que le composant reste fiablement dans l'état 'chargement', produisant une baseline visuelle stable pour le loader. Échouer à adhérer à cela entraîne généralement une instabilité du test.

Piège 1 : Mocker toutes les APIs par défaut dans un test de capture d'écran, causant une condition de course où le mock se résout plus vite que la capture d'écran est prise.

À ne pas faire :

  • Fournir les réponses mock pour l'API afin de capturer l'état transitjonnel de chargement, introduisant l'instabilité basée sur le timing.

À faire :

  • Laisser l'API de récupération des données sans mock pour que le composant reste indéfiniment dans son état transitjonnel chargement, générant une capture d'écran 100% déterministe du loader.

Skills similaires