Comment générer des commits significatifs. Appliquer la norme des engagements conventionnels



Chaos familier au nom des commits. Une image familière?

Vous connaissez sûrement Git-Flow . Il s'agit d'un grand ensemble de conventions de branchement dans Git. Il est bien documenté et largement distribué. Habituellement, nous connaissons la bonne ramification et en parlons beaucoup, mais, malheureusement, nous prêtons trop peu d'attention à la question des noms de commits, c'est pourquoi les messages dans Git sont souvent écrits au hasard.

Je m'appelle Yerzhan Tashbenbetov, je travaille dans l'une des équipes de Yandex.Market. Et aujourd'hui, je vais dire aux lecteurs de Habr quels outils nous utilisons pour créer des commits significatifs dans une équipe. Je vous invite à participer à la discussion sur ce sujet.


L'absence d'accord sur les noms de commits rend difficile le travail avec l'histoire dans Git. C'était sur notre équipe. Avant d'utiliser des règles communes pour tous et d'implémenter l'automatisation, les validations typiques se présentaient comme suit:

SECRETMRKT-700:     , . SECRETMRKT-701, SECRETMRKT-702:     ... 

Premièrement, chaque développeur a écrit des messages comme il le voulait: quelqu'un a décrit la tâche, quelqu'un a énuméré les modifications apportées, quelqu'un a utilisé un générateur de phrases aléatoires. Tout était en désaccord. Deuxièmement, les numéros de tâche présents dans les validations raccourcissaient souvent le texte utile. Tout cela a rendu difficile de travailler efficacement avec l'histoire dans Git.

Pour cette raison, nous avons implémenté la norme Conventional Commits dans l'équipe, commencé à générer des commits dans l'utilitaire de console commitizen et vérifié le résultat à l'aide de commitlint . En conséquence, les validations ont changé et elles ressemblent à ceci:

 refactor(tutorial):      feat(products):      fix(products):      

Lire l'histoire et reconnaître les changements a été facilité. Nous n'avons pas refusé de préciser les numéros de tâche, tout a été soigneusement déplacé en commits conformément à la convention Commits conventionnels .

Ensuite, je vais vous montrer comment réaliser un ordre similaire dans Git.



Meilleures pratiques, recommandations et solutions courantes pour nommer les commits


Si vous essayez de comprendre quelles pratiques sont utilisées dans l'industrie, vous pouvez trouver les options suivantes:

  • Des articles avec des conseils généraux pour rédiger des commits. Pour la plupart, ils sont assez logiques et ouvrent un bon sujet, mais il y a un sentiment de désordre et un manque de solution globale au problème.
  • Normes d'écriture des commits. Il y en a peu. Ce sont des documents avec une liste claire de règles, souvent écrites spécifiquement pour une grande bibliothèque ou un framework. Ces normes impressionnent par leur approche systématique, leur popularité et leur soutien dans la communauté open source.

Nous avons besoin de plus d'ordre dans les commits!

La méthodologie des engagements conventionnels se distingue des autres normes et mérite un examen attentif pour un certain nombre de raisons:

  1. Il est bien documenté et conçu. Sa spécification fournit des réponses aux questions les plus courantes.
  2. Les créateurs de la convention ont été inspirés par les exigences d'écriture des commits, qui sont utilisées dans le cadre populaire et éprouvé d' AngularJS .
  3. Les règles de la convention sont suivies par plusieurs grandes bibliothèques open source populaires (telles que yargs et lerna ).
  4. Pour les avantages, je vais préparer la formation automatique des notes de publication et du journal des modifications.

Un exemple de validation de cette norme:

 fix(products):             -     .  : SECRETMRKT-578, SECRETMRKT-602 



Points clés des engagements conventionnels


  • Le développeur doit respecter la structure de validation suivante:
    <type> (<scope>): <subject>

    <body>

    <footer>
  • Le commit doit avoir un en-tête, peut-être un corps et un pied de page.
  • L'en-tête de la validation doit commencer par un type indiquant les détails des modifications apportées à la base de code et se terminer par une description.
  • Parallèlement à l' exploit obligatoire, fix (dont l'utilisation est strictement réglementée), d'autres types sont autorisés.
  • Un commit peut avoir une portée . Il caractérise un morceau de code qui a été affecté par les modifications. La zone suit le type de validation. La norme ne réglemente pas une liste claire de domaines. Exemples de domaines: eslint, git, analytics, etc.
  • La description de la validation doit être immédiatement après le type / la zone.
  • Le corps du commit peut être utilisé pour explorer les modifications. Le corps doit être séparé de la description par une ligne vide.
  • Le pied de page doit être utilisé pour spécifier les liens externes, le contexte de la validation ou d'autres méta-informations. Le pied de page doit être séparé du corps par une ligne vide.


En plus des règles énumérées dans la convention, nous utilisons les recommandations populaires suivantes:


  • Dans le corps du commit, nous écrivons ce qui a été changé et pourquoi .
  • Nous utilisons les types de commits suivants:
    construireConstruisez un projet ou modifiez les dépendances externes
    ciConfiguration et script CI
    docsMise à jour de la documentation
    exploitAjout de nouvelles fonctionnalités
    réparerCorrection d'un bug
    perfChangements d'amélioration des performances
    refactorModifier le code sans corriger les bugs ni ajouter de nouvelles fonctionnalités
    revenirRevenir aux validations précédentes
    le styleModifications de style de code (tabulations, retraits, points, virgules, etc.)
    testAjout de tests
  • Nous écrivons la description de manière impérative , tout comme Git lui-même.
    Fusionner la branche 'fix / SECRETMRKT-749-fix-typos-in-title'
  • Ne téléchargez pas la description de validation avec des signes de ponctuation.




Convention conventionnelle utilisée par les contributeurs de lerna



Comment passer simplement au nom correct des commits?


Besoin d'ajouter l'automatisation et la commodité. Pour résoudre ce problème, nous avons besoin de deux outils: le générateur de validation et la litière de validation, configurés pour vérifier avant de passer au référentiel.



Configurer l'utilitaire commitizen


Cet outil vous permet de générer des validations à l'aide de l'assistant intégré. De plus, commitizen est bien soutenu par la communauté et, grâce à des modules supplémentaires, est hautement personnalisable.

  1. Installez l'utilitaire commitizen globalement (vous pourriez avoir besoin des droits d'administrateur).

     npm i -g commitizen 
  2. Ensuite, installez l'adaptateur personnalisable cz . Il est nécessaire de configurer le modèle avec les questions utilisées par l'utilitaire commitizen .

     npm i -D cz-customizable 
  3. Créons le fichier commitizen.js, il est nécessaire pour configurer cz-personnalisable. Placez le fichier créé dans le répertoire ./config/git. Je recommande de ne pas joncher la racine du projet avec les fichiers de configuration et d'essayer de regrouper les fichiers dans un dossier préparé pour cela. Contenu:

    Afficher commitizen.js
     "use strict"; module.exports = { //         types: [ { value: "build", name: "build:      " }, { value: "ci", name: "ci:  CI    " }, { value: "docs", name: "docs:  " }, { value: "feat", name: "feat:   " }, { value: "fix", name: "fix:  " }, { value: "perf", name: "perf:     " }, { value: "refactor", name: "refactor:         " }, { value: "revert", name: "revert:    " }, { value: "style", name: "style:    (, , ,   ..)" }, { value: "test", name: "test:  " } ], // .    ,    scopes: [ { name: "components" }, { name: "tutorial" }, { name: "catalog" }, { name: "product" } ], //         (  'fix') /* scopeOverrides: { fix: [ {name: 'style'}, {name: 'e2eTest'}, {name: 'unitTest'} ] }, */ //    messages: { type: "   ?", scope: "\n ,    ():", //   allowCustomScopes  true customScope: "  :", subject: "     :\n", body: '   ().  "|"   :\n', breaking: " BREAKING CHANGES ():\n", footer: "    (,   ). : SECRETMRKT-700, SECRETMRKT-800:\n", confirmCommit: "   ?" }, //    allowCustomScopes: true, //   Breaking Changes allowBreakingChanges: false, //     footerPrefix: " :", // limit subject length subjectLimit: 72 }; 


  4. Ajoutez des liens vers cz-personnalisable et le fichier de configuration créé précédemment dans package.json:

    Afficher une partie de package.json
     { "config": { "commitizen": { "path": "node_modules/cz-customizable" }, "cz-customizable": { "config": "config/git/commitizen.js" } }, } 

  5. Vérifions le résultat. Tapez la commande suivante dans le terminal:

     git cz 

L'assistant de validation collectera d'abord des informations sur le type, la zone de la validation, puis demandera séquentiellement le texte qui sera dans la description, dans le corps, dans le pied de page et, après votre consentement, créera une validation.

Assurez-vous de regarder l'exemple de l'utilitaire commitizen configuré et de l'adaptateur cz-cusomizable connecté à celui-ci



Configurer les utilitaires husky et commitlint


  1. Installez husky et commitlint dans le projet:

     npm i -D husky @commitlint/cli 
  2. Avec husky, nous ajouterons un chèque de validation. Pour ce faire, dans package.json, immédiatement après les scripts, ajoutez le hook suivant et indiquez-y un lien vers le fichier commitlint.js:

    Afficher une partie de package.json
     { "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "husky": { "hooks": { "commit-msg": "commitlint -E HUSKY_GIT_PARAMS -g './config/git/commitlint.js'" } }, "devDependencies": { "@commitlint/cli": "^7.2.1", "husky": "^1.1.3", } 


  3. Créez le fichier commitlint.js nécessaire au bon fonctionnement du linter. Placez le fichier créé dans le répertoire ./config/git. Contenu du fichier:

    Afficher commitlint.js
     //     @commitlint/config-conventional module.exports = { rules: { //        "body-leading-blank": [2, "always"], //         "footer-leading-blank": [2, "always"], //    72  "header-max-length": [2, "always", 72], //       "scope-case": [2, "always", "lower-case"], //      "subject-empty": [2, "never"], //     '.' "subject-full-stop": [2, "never", "."], //       "type-case": [2, "always", "lower-case"], //      "type-empty": [2, "never"], //      "type-enum": [ 2, "always", [ "build", "ci", "docs", "feat", "fix", "perf", "refactor", "revert", "style", "test" ] ] } }; 



C’est tout. Maintenant, toutes les validations seront vérifiées avant d'être envoyées au référentiel :)

Assurez-vous de regarder l'exemple de l'utilitaire commitlint configuré



Alors, que choisir commitizen ou commitlint?


À la fois cela et un autre! Conjointement, ils apportent d'excellents résultats: le premier génère des commits, le second les vérifie.


Pourquoi les normes recommandent-elles l'utilisation de l'impératif?


C'est une question extrêmement intéressante. Un commit est un changement de code; un message dans un commit peut être considéré comme une instruction pour changer ce code. Créer, modifier, ajouter, mettre à jour, corriger - ce sont toutes des instructions spécifiques pour le développeur.

Soit dit en passant, impératif est recommandé dans le système de versioning de Git lui - même :

 [[imperative-mood]] Describe your changes in imperative mood, eg "make xyzzy do frotz" instead of "[This patch] makes xyzzy do frotz" or "[I] changed xyzzy to do frotz", as if you are giving orders to the codebase to change its behavior. 


Pourquoi s'en tenir à des conventions? Vaut-il le temps? Quel est le profit?


Ça vaut le coup. En général, j'ai remarqué que nous devenions plus disposés à détailler les modifications apportées à la base de code. Dans le corps du commit, nous décrivons en détail pourquoi nous avons dû utiliser telle ou telle solution. Comprendre l'histoire est devenu objectivement plus facile. De plus, notre produit se développe et nous nous attendons à un réapprovisionnement dans l'équipe. Je suis sûr que grâce à l'introduction de la norme et de l'automatisation, il sera plus facile pour les débutants de s'intégrer dans le processus de développement.

Essayez de partager le résultat.


Liens utiles:


Source: https://habr.com/ru/post/fr431432/


All Articles