Versioning, Releases : semantic-release est là ! – Première partie

 

Contexte

En tant que développeur ou chef de projet, vous avez certainement dû passer par la routine habituelle : je push, je versionne, j'écris et publie la release correspondante à cette nouvelle version. Le versionning ainsi que la publication d'une release permet de faire suivre aux clients (et à nous même) les modifications apportées entre deux versions.

Malheureusement, d'un développeur à l'autre, la version risque de ne pas être incrémentée de la même manière et la release risque de ne pas respecter la même convention de nommage. Cela complexifie la compréhension et le suivi de vos utilisateurs.

De plus, cela prend du temps que vous pourriez utiliser pour d'autres tâches.

C'est pour cela que nous avons envisagé l'usage de l'outil "semantic-release" (site officiel) afin d'automatiser et de standardiser le nom de nos releases. Nous évitons ainsi l'erreur humaine puisque ce sera le code qui garantira l'incrémentation de nos versions (majeure, mineure ou patch).

Présentation

L'outil "semantic-release" (GitHub) permet de :

  • Versionner votre application.
  • Générer et publier une release automatiquement.
  • Si vous le souhaitez, notifier vos utilisateurs.
  • Générer et maintenir votre changelog

Cet outil s'appuie sur un mix de deux conventions

 Étape 1/3 : Installation et configuration

Créer dans votre projet un fichier appelé : .releaserc.json et insérer le code suivant

 Première partie : Gestion des branches

{
#sert à spécifier les branches sur lesquelles le plugin semantic-release agit.
  "branches": [ 
    {
    # Définition du comportement de la branche master
      "name": "master"
    },
   # Gestion de branches exotiques comme alpha (beta, rc, ...)
    {
      "name": "alpha",
      "channel": "alpha",
      "prerelease": "alpha"
    },
  ],
  ```

Comme vous pouvez le voir ci-dessus, nous avons configuré plusieurs types de commit possibles ainsi que le type de release qu'il pouvait amener. Par exemple, un fix donne un patch, etc.

## Deuxième partie : Gestion des plugins
 ```
  "plugins": [
    [
      "@semantic-release/commit-analyzer",
      {
        "preset": "conventionalcommits",
        "releaseRules": [
          {
            "breaking": true,
            "release": "major"
          },
          {
            "type": "ci",
            "release": "patch"
          },
          {
            "type": "docs",
            "release": "patch"
          },
          {
            "type": "feat",
            "release": "minor"
          },
          {
            "type": "fix",
            "release": "patch"
          },
        ]
      }
    ],
    [
      "@semantic-release/release-notes-generator",
      {
        "preset": "conventionalcommits",
        "presetConfig": {
          "types": [
            {
              "type": "ci",
              "section": "CI/CD",
              "hidden": false
            },
            {
              "type": "docs",
              "section": "Docs",
              "hidden": false
            },
            {
              "type": "feat",
              "section": "Features",
              "hidden": false
            },
            {
              "type": "fix",
              "section": "Bug Fixes",
              "hidden": false
            },
          ]
        }
      }
    ],
    "@semantic-release/changelog",
    "@semantic-release/git",
    "@semantic-release/gitlab",
    {
      "gitlabUrl": "https://git.aukfood.net"
    }
  ]
}

Pour retrouver l'ensemble des plugins disponibles voici une liste des plugins

  • @semantic-release/commit-analyze : analyse vos commit et choisir d'incrémenter ou non la version de votre branche principale en patch/minor/major version
  • @semantic-release/release-notes-generator : créé la release correspondant au tag créé
  • @semantic-release/git : analyse la version actuelle et la branche où vous vous trouvez
  • @semantic-release/gitlab : va créer le tag et push la release

Étape 2/3 : Automatisation avec la GitLab CI

Il est temps maintenant configurer la CI de votre projet. Pour la suite, nous choisissons de travailler sur GitLab.

Vous aurez besoin d'avoir une image docker contenant semantic-release ainsi que ses différents plugins.

Dans le fichier .gitlab-ci.yml rajouter dans "stages" l'étape suivante :

stages:
  - release

Rajouter ensuite plus loin dans le code :

publish:
  image: **Votre image semantic**
  stage: release
  script:
    - semantic-release
    - echo "VERSION=v${SEMANTICVERSION}" > version.env
  rules:
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "pre/rc"'
    - if: '$CI_COMMIT_BRANCH == "branches"'
      when: never
  artifacts:
    reports:
      # propagates variables into the pipeline level, but never stores the actual file
      dotenv: version.env

N'oubliez pas de mettre des rules selon votre gestion de branches

Étape finale : initialisation des variables

Afin que les tags, les releases ainsi que le fichier changelog puissent être généré sur gitlab (ou github), vous devez créer un access token.

Pour ce faire, aller dans votre projet -> settings -> Access Tokens, mettre comme nom de token "GITLAB_TOKEN", lui mettre les droits API et write_repository avec le role Maintener puis créer le jeton et enfin, copier le jeton.

Une fois cela fait, Rendez-vous sur votre projet -> settings -> CI/CD -> Variables et enfin ajouter votre token en donnant comme nom de variable : GITLAB_TOKEN

Attention ! Si vous mettez l'attribut protected à votre variable, il faut que les branches avec lesquelles vont se faire vos release soient en protected elles aussi ! Sinon le plugin ne pourra pas récupérer la variable et donc ne pourra pas upload la release

Les releases ne se feront uniquement sur les branches définies dans les rules de votre CI (exemple : alpha, beta, main).

Vous savez maintenant comment automatiser les releases 😉