blog.bressure.net

Carnet professionnel d'un informaticien

Gestion de projet, Paramétrage

Génération de note de livraison automatique avec Gitlab

admin

Tout ce qui est fait de manière répétitive, prévisible, sans avoir recours à la créativité, est automatisable et faisable par la machine. J’avais mis en place un pipeline gitflow pour Gitlab dans l’article https://blog.bressure.net/2021/11/14/ci-cd-avec-workflow-git-et-pipeline-gitlab/ et je propose maintenant de générer automatiquement une note de livraison.

La note de livraison contient les changements fonctionnels ou techniques qu’une version apporte. Ces informations peuvent être renseignées dans un simple fichier mis à jour au moment de la création de la version. Cette façon de faire requiert une tâche de gestion pour faire le lien entre le contenu du code qui sera livré et les fonctionnalités ou correctifs attendues. C’est un rôle dévolu à disons le chef de projet ou plus précisément le release manager. Ce sont des fonctions qui coûtent plus cher que celle du développeur or c’est le développeur qui ajoute les fonctions dans l’application donc c’est le développeur qui est à l’origine de ce qui ira ou non dans la note de livraison ! Par conséquence la note de livraison doit être un document construit par une action de développement et non pas de gestion administrative.

D’aucuns me diront que la construction de la note de livraison doit être contrôlée car c’est la vitrine extérieure du contenu de l’application. Y renseigner une correction qui n’est pas réelle par exemple va nuire à l’image de marque de l’éditeur ou de l’équipe de développement. Heureusement qu’il y a la méthode ! Je suis un adepte de LA Méthode. Face à un problème j’aime une solution définitive. Utiliser la bonne méthode permet d’éviter bien des problèmes …

Dans le cas de cet article, la Gitflow est la méthode utilisée. Je l’implémente sous forme d’un pipeline Gitlab agrémenté d’étape de validation (review). Ainsi une branche issue de develop ne retourne sur develop que si elle passe la validation. Donc l’action de fusion vers develop est bien le moment de mettre à jour la note de livraison ! On pourrait alors se demander si il ne suffirait pas de mettre à jour la note de livraison sur la branche de bug avant fusion vers develop mais on voit que cela va produire des conflits de fusion car il ne faut jamais oublier qu’il y a plusieurs branches de bug en même temps issues de develop. Donc la mise à jour de la note de livraison doit se faire sur la branche develop après la fusion. Voilà les principes sont posés.

L’implémentation dans le POC est assez simple et directe. Il suffit d’ajouter dans le job de fusion retour vers develop l’action de mise à jour de la note de livraison.

.ensure_release_note_does_exist: &ensure_release_note_does_exist
   - | 
      if [ ! -f "RELEASE_NOTE.txt" ]
      then 
          echo "release 0.1.0" >> RELEASE_NOTE.txt;           
          echo "==============" >> RELEASE_NOTE.txt; 
          echo "" >> RELEASE_NOTE.txt;           
          git add RELEASE_NOTE.txt;
      fi
   
.add_release_note_entry: &add_release_note_entry
   - RELEASE_NOTE_ENTRY="$CI_COMMIT_BRANCH"
   - if [ ! -z $ISSUE ]; then RELEASE_NOTE_ENTRY="$RELEASE_NOTE_ENTRY for issue $ISSUE"; fi
   - echo $RELEASE_NOTE_ENTRY >> RELEASE_NOTE.txt

.update_release_note_on_develop: &update_release_note_on_develop    
   - git checkout develop
   - echo "ensure RELEASE_NOTE.txt does exist"
   - *ensure_release_note_does_exist
   - cat RELEASE_NOTE.txt
   - echo "add release note entry for pipeline branch $CI_COMMIT_BRANCH which were previously merged into develop"
   - *add_release_note_entry
   - cat RELEASE_NOTE.txt
   - git commit -a -m "add $RELEASE_NOTE_ENTRY in RELEASE_NOTE.txt"
   - git push

merge_to_develop:
    stage: deliver
    rules:
        - if: '$CI_COMMIT_BRANCH =~/^release-.*$/'        
          when: never
        - if: '$CI_COMMIT_BRANCH =~/^hotfix-.*$/'        
          when: never
        - if: $CI_COMMIT_BRANCH == "develop"
          when: never
        - if: $CI_COMMIT_BRANCH == $MAIN_BRANCH
          when: never
        - if: $CI_COMMIT_TAG
          when: never        
        - when: manual
          allow_failure: true
    image:
        name:  alpine/git 
        entrypoint: [""]    
    before_script:
        - git --version
    script:        
        - *clone_repos_with_authent
        - *merge_commit_sha_to_develop
        - *update_release_note_on_develop
        - *delete_current_branch

La note de livraison reçoit alors une entrée qui indique la nom de la branche de bug qui a été fusionnée. Comme par défaut dans Gitlab une branche de bug est nommée avec le numéro de bug suivi du titre, cela est suffisamment explicite. Voici un exemple:

release 0.1.0
==============
11-generation-automatique-de-release-note
12-ajout-des-hot-fix-dans-la-note-de-livraison

Cas des hotfix

Les branches de bug ne sont pas les seules qui apportent du code à la branche develop. Ainsi lors du cas particulier d’un bug découvert en production ou du moins sur une version déjà délivrée, il se peut que la correction soit évidente et rapide. Dans ce cas on peut passer par une branche hotfix tirée du tag de version (porté par la branche principale main) comme indiqué dans le Gitflow. Cette correction doit alors être fusionnée avec develop au même titre qu’elle sera envoyée sur la branche principale main.

Il y a alors un problème car sur branche develop la note de livraison a déjà bougée pour avoir à la fin la prochaine version. Par exemple sur main au dernier tag on a 0.1.0 et sur develop 0.2.0 avec des entrées éventuelles de tickets. Ainsi les 2 notes de livraison vont diverger. Sur main on va avoir apres le hotfix, une 0.1.1 avec une entrée qui indiquera la branche hotfix-0.1.1 et sur develep dans la release 0.2.0 une entrée hotfix-0.1.1

Les entrées de la note de livraison contiennent la branche source de la fusion et comme le pipeline est guidé par la branche, cela entraîne que pour la branche hotfix (qui au même titre que release contient la version a produire) on perd l’information de numéro de bug. J’adapte donc le job de validation de hofix pour rendre obligatoire la fourniture du ou des numéro de tickets corrigés par le hotfix.

Le pipeline devient:

.add_release_note_next: &add_release_note_next
   - cat RELEASE_NOTE.txt
   - echo " " >> RELEASE_NOTE.txt; 
   - echo "release $NEXT_RELEASE" >> RELEASE_NOTE.txt;           
   - echo "==============" >> RELEASE_NOTE.txt; 
   - echo " " >> RELEASE_NOTE.txt; 
   - cat RELEASE_NOTE.txt



.add_release_note_next_on_master: &add_release_note_next_on_master
   - git checkout $MAIN_BRANCH
   - *add_release_note_next
   - git commit -a -m "add next release $NEXT_RELEASE in RELEASE_NOTE.txt"
   - git push


.merge_commit_sha_and_tag_master_with_version_as_hotfix: &merge_commit_sha_and_tag_master_with_version_as_hotfix
        - git checkout ${MAIN_BRANCH}
        - git merge -X theirs $CI_COMMIT_SHA
        
        - NEXT_RELEASE=`echo $CI_COMMIT_BRANCH | cut -d - -f 2`
        - *add_release_note_next_on_master
        - *add_release_note_entry
        
        - git commit -a -m "add $RELEASE_NOTE_ENTRY in RELEASE_NOTE.txt"
        - git push

        - BRANCH_SUFFIX=`echo $CI_COMMIT_BRANCH | cut -d - -f 1`
        - git tag `echo $CI_COMMIT_REF_NAME | sed -e "s/$BRANCH_SUFFIX/v/g"`
        - git push --tag
        - git tag "fix-$ISSUE"
        - git push --tag


validate_hotfix:
    stage: deliver
    rules:
        - if: '$CI_COMMIT_BRANCH =~ /^hotfix-.*$/'
          when: manual
          allow_failure: true                
    image:
        name:  alpine/git 
        entrypoint: [""]    
    before_script:
        - if [ -z "$ISSUE" ]; then echo "ISSUE is not defined"; exit 1; fi 
        - git --version              
    script:        
        - *clone_repos_with_authent
        - *merge_commit_sha_to_develop
        - *update_release_note_on_develop
        - *merge_commit_sha_and_tag_master_with_version_as_hotfix
        - *delete_current_branch

Par exemple si on a livré une 0.1.0 qi contient un seul ticket disons numéro 1 et que l’on fasse un hotfix-0.1.1 corrigeant le bug 3 alors que la branche develop contient déjà le ticket 2 alors on à les note de livraisons suivantes. Sur le tag v-0.1.0 sur la branche main

release 0.1.0
==============
 
1-fonction-principale-de-l-appli

Sur la branche develop après la production de 0.1.0 on a:

release 0.1.0
==============
 
1-fonction-principale-de-l-appli

release 0.2.0
==============

2-super-fonction-qui-revolutionne-le-web

On découvre le bug sur la 0.1.0 et on décide de produire un hotfix versionnée 0.1.1. On tire donc la branche hotfix-0.1.1 depuis le tag v-0.1.0. A la fin des tests du correctif on valide le hotfix via le job idoine du pipeline sur la branche hotfix-0.1.1. Cela produit une version v-0.1.1 avec comme note de livraison:

release 0.1.0
==============
 
1-fonction-principale-de-l-appli
 
release 0.1.1
==============
 
hotfix-0.1.1 for issue 3

Sur la branche develop la note de livraison est alors mise à jour par le job précédent pour produire:

release 0.1.0
==============
 
1-fonction-principale-de-l-appli

release 0.2.0
==============

2-super-fonction-qui-revolutionne-le-web
hotfix-0.1.1 for issue 3

Cas des branches release

Une branche release est à périmètre fonctionnel fini. La fusion retour vers develop sert a récupérer les correction de bug découvert lors de la recette. Cela ne change rien à la note de livraison.


On vient de montrer comment produire une note de livraison via un pipeline Gitlab en respectant le Gitflow. Le pipeline complet se trouve ici https://gitlab.bressure.net/cicd/blank/-/blob/27dcdad0c3cc6e2f44ebe762e31144a04ffe14a6/.gitlab-ci.yml.

Tags:

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

Back to top