Générer le changelog est une tâche plutôt chiante.

Souvent réalisée à la main, c’est une tâche répétitive et sans valeur ajoutée.

Prennons le temps ici de voir comment nous pouvons générer un changelog de manière automatiquée.

🤖 Générer le changelog

Pour générer le changelog, nous allons partir du pricipe suivant

Et surtout

Notre git flow ressemble donc à cela:

Git flow

Pour en savoir plus sur pourquoi on fait cela, vous pouvez aller lire mon article sur les workflow git

🚚 Sous le capot

En partant de ce flow, avec quelques commandes on peut rapidement voir ce qu’il s’est passé entre 2 commits.

Pour cela, on va utiliser la commande git log avec certaines options.

Les options seront

et surtout on peut préciser entre quels commits on veut regarder ce log !! Donc on peut exécuter

git log --oneline --merges 1.0.3 1.0.2

Et clea nous donnera le changelog entre nos 2 versions !

🤯 Le plugin changelog_from_git_commits

Ce qui est sympa avec fastlane, c’est que tout ça est déjà fait via un plugin qui permet exactement de faire ce qu’on veut: changelog_from_git_commits.

En gros, pour faire ce qu’on veut, il nous suffit de faire ça:

changelog_from_git_commits(
    # Donne moi le changelog entre ces 2 tags
    between: [old_tag, new_tag],
    # Pour chaque ligne dans git, écrit le commit sous la forme  "- commit message" (donne une liste)
    pretty: "- %s",
    # Pas besoin d'une grande date
    date_format: "short",
    # Vrais tags
    match_lightweight_tag: false,
    # Seulement les commits de merge (souvenez vous le --merges)
    merge_commit_filtering: "only_include_merges"
)

Il ne nous reste qu’a stocker le changelog pour pouvoir l’écrire plus tard.

Donc si on veut se créer une lane qui

voici le résultat:

desc "Generate changelog between 2 versions and return it"
lane :generate_changelog do |options|
  UI.message("🕵️‍♂️ Checking changelog")

  old_tag = options[:old_tag]
  new_tag = options[:new_tag]
  
  UI.message("🕵️‍♂️ Last tag was #{old_tag}, new tag is #{new_tag}")
  # Fetch the changelog
  changelog = changelog_from_git_commits(
    between: [old_tag, new_tag],
    pretty: "- %s",
    date_format: "short",
    match_lightweight_tag: false,
    merge_commit_filtering: "only_include_merges"
  )
  
  # Return it
  changelog
end

🏷 Trouver les tags

La dernière étape à notre plan, trouver le tag précédent (le old_tag)

Heureusement, git est encore là pour nous !

La commande

git describe --abbrev=0 --tags {tag_actuel}\^

Vous donnera le tag précédent celui donné en paramètre.

Donc, dans notre Fastfile, sous couvert de récupérer le tag actuel. On peut obtenir le précédent comme cela:

current_tag=???
old_tag = sh("git", "describe", "--abbrev\=0", "--tags", "#{current_tag}\^").delete("\n")

On peut modifier légèrement notre lane

desc "Generate changelog between 2 versions and return it"
lane :generate_changelog do |options|
  UI.message("🕵️‍♂️ Checking changelog")

  tag = options[:tag]
  old_tag = sh("git", "describe", "--abbrev\=0", "--tags", "#{tag}\^").delete("\n")
  
  UI.message("🕵️‍♂️ Last tag was #{old_tag}, new tag is #{tag}")
  # Fetch the changelog
  changelog = changelog_from_git_commits(
    between: [old_tag, tag],
    pretty: "- %s",
    date_format: "short",
    match_lightweight_tag: false,
    merge_commit_filtering: "only_include_merges"
  )
  
  # Return it
  changelog
end

Et il ne nous reste qu’a fournir le tag actuel, par exemple, au lancement de la lane.

bundle exec fastlane android generate_changelog tag:1.2.4

🧠 En résumé

Maintenant, quand vous allez faire des releases de tests pour votre équipe, les testeurs, votre PO, plus besoin de passer des heures à retrouver ce qui a été fait.

Plus besoin de retourner sur cette saloperie d’outil de suivi de tickets pour retrouver les “DONE”.

Maintenant, ce qui fait foi c’est git.

Avec une simple lane de 20 lignes (commentaires et logs inclus) on peut générer le changelog de la version actuelle vis-à-vis de la dernière version.

D'ailleurs, dans l'article, on prend le parti de dire qu'on trouve l'ancien tag depuis le courant, mais on peut très bien passer 2 tags en paramètres si on veut gérer de la beta, de l'alpha, etc...