Loading search data...

Comment mettre à jour les dépendances automatiquement avec Renovate

Lorsque vous démarrez un projet, vous le configurez normalement avec les dernières versions stables de toutes les bibliothèques et outils. Puis le temps passe, le projet grandit et de nouvelles fonctionnalités et bibliothèques sont ajoutées. Mais les versions des bibliothèques et des packages restent les mêmes, et personne de l’équipe ne s’en charge.

Après tout, pourquoi les mettre à jour si le projet fonctionne parfaitement avec les versions actuelles ?

Tout simplement cela permettrait de :

  • de corriger des bugs.
  • de corriger des vulnérabilités.
  • d’ajouter de nouvelles fonctionnalités
  • profiter d’éventuelles augmentations de performances via des optimisations apportées à leur code.

Toutes ces améliorations contribuent à la maintenabilité du code et à la bonne santé de votre application.

Et bien voici un outil gratuit répondant au nom de Renovate qui va vous aider dans cette tâche. Une fois configuré, il va scruter le code source de vos repositories pour vérifier si ils nécessitent des mises à jour de dépendances. Si c’est le cas il va créer automatiquement des Merge Requests pour leur mis à jour. En plus, si votre CI est complet et vos tests unitaires aussi, vous aurez une validation quasi automatique de ces modifications.

Renovate prend en charge les langages: Bazel, Docker, Golang, Java, JavaScript, , Nuget, PHP, Python et Ruby.

Renovate fonctionne avec Github, Gitlab.com, Bitbucket ou en self-hosted.

Mettre en place Renovate dans vos projets

Renovate est un outil écrit en Typescript, disponible dans différentes configurations.

Si vous utilisez GitHub ou Azure, vous pouvez l' activer en tant qu’application pour tous vos référentiels. Par contre, si vous utilisez Gitlab.com/Auto-Hébergé ou tout autre gestionnaire Git, vous devrez intégrer Renovate vous-même dans vos pipelines.

Ici je vais vous décrire comment le tester sur gitlab.com en lançant les commandes dans un shell. Pour les autres je vous renvoie à la documentation du produit.

Je vais prendre l’exemple d’une image Docker avec le Dockerfile suivant :

# syntax=docker/dockerfile:1.3-labs
FROM alpine:3.13 as builder
ENV PYROOT=/venv
ENV PYTHONUSERBASE=$PYROOT
WORKDIR /
COPY Pipfile* ./
RUN <<EOF
  apk update
  apk add --no-cache bc gcc libffi-dev musl-dev openssl-dev python3-dev py3-pip
  pip3 install --no-cache-dir --no-compile pipenv
  pipenv lock
  PIP_USER=1 pipenv sync --system
EOF

FROM alpine:3.13 as default

RUN <<EOF
  adduser -D user
  apk add --no-cache py3-pip
  echo export PYTHONPATH="/venv/lib/python$(python3 -c 'import sys; print(".".join(map(str, sys.version_info[:2])))')/site-packages/">>/etc/profile && \
  echo PATH="/venv/bin:$PATH">>/etc/profile
EOF

COPY --from=builder /venv /venv
USER user
WORKDIR /src
COPY entrypoint.sh /usr/bin

# Make sure we use the virtualenv:

ENTRYPOINT ["entrypoint.sh"]
CMD ["--version"]

Ce Dockerfile utilise la technique permettant de limiter la taille des images Docker.

Vous remarquez qu’il charge un produit python répondant au nom de bandit via un fichier Pipfile dont voici le contenu:

[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
bandit = "==1.5.0"
[dev-packages]

[requires]
python_version = "3"

Il fait appelle à un script entrypoint.sh pour charger des variables d’environment:

#!/bin/sh
# Read in the file of environment settings
. /etc/profile
# Then run the CMD
exec bandit "$@"

Maintenant que nous avons tous les éléments pour construire l’image. On commit dans un repository gitlab. Puis on mets en place ce qu’il faut pour faire tourner Renovate.

En premier commencez par créer un PAT, pour cela allez dans le menu profile > personal_access_tokens dans gitlab. Donnez lui les droits: read_user, api et write_repository. Collez le dans la config ci-dessous (token). Modifiez également endpoint pour qu’il corresponde à celui de votre serveur gitlab et repositories avec la liste des repos que voulez scanner. Sauvegardez le tout dans le fichier renovate-config.js.

module.exports = {
  endpoint: 'https://gitlab.robert.local/api/v4/',
  token: 'xxxxxxxxxxxxxxxxx',
  platform: 'gitlab',
  gitUrl: 'ssh',
  onboardingConfig: {
    extends: ['config:base'],
  },
  repositories: ['stephane.r/test-renovate'],
};

Je vais utiliser ma clé ssh pour récupérer les projets. Donc pour lancer le container je monte mon répertoire contenant ma clé ssh que j’utilise dans ma config gitlab.

docker run --rm -v $PWD/renovate-config.js:/usr/src/app/config.js -v /home/vagrant/.ssh:/home/ubuntu/.ssh -it renovate/renovate

Whaoouu la taille du container. Ca fait peur. Lors du premier lancement il va détecter que le repository ne contient pas de fichier de configuration. Il va donc créer un premier merge request pour l’ajouter.

Un fois mergé, vous pouvez relancer un seconde fois le container:

docker run --rm -v $PWD/renovate-config.js:/usr/src/app/config.js -v /home/vagrant/.ssh:/home/ubuntu/.ssh -it renovate/renovate

 INFO: Repository started (repository=stephane.r/test-renovate)
       "renovateVersion": "28.10.4"
 INFO: Dependency extraction complete (repository=stephane.r/test-renovate)
       "baseBranch": "master",
       "stats": {
         "managers": {
           "dockerfile": {"fileCount": 1, "depCount": 2},
           "pipenv": {"fileCount": 1, "depCount": 1}
         },
         "total": {"fileCount": 2, "depCount": 3}
       }

Ah il a fait des choses allons voir dans le repo. En fait il a créé une issue qui en fait le dashboard de suivi de mise à jour des dépendances. Dans mon cas il dit que mon Dockerfile utilise une ancienne version de l’image Alpine et me propose de passer à alpine 3.14. Mais aussi que le package pypi bandit peut aussi être mis à jour vers la version 1.7.0.

renovate dependances check

Il a également créé deux requests contenant chacun une mise à jour.

renovate dependances check

Par contre je me pose la question des dépendances croisées. Comment il gère ça ? A explorer donc.

Maintenant acceptons de merger et voyons le résultat :

# syntax=docker/dockerfile:1.3-labs
FROM alpine:3.14 as builder

[packages]
bandit = "==1.7.0"
[dev-packages]

[requires]
python_version = "3.8"

Ah il a mis à jour la version de Python. Cool! Donc ça réponds en partie à ma question sur les dépendances croisées.

Pour debuger ajouter ceci à la commande docker -e LOG_LEVEL=debug.

Et si si vos projets contiennent des pipelines avec des tests de validation ca va être du bonheur. Je vais continuer à l’évaluer avant une intégration plus poussé dans mon serveur Gitlab.

Source

Mots clés :

devops tutorials

Si vous avez apprécié cet article de blog, vous pouvez m'encourager à produire plus de contenu en m'offrant un café sur Ko-Fi. Vous pouvez aussi passer votre prochaine commande sur amazon, sans que cela ne nous coûte plus cher, via ce lien. Je vous remercie de votre soutien