En bref

  • Automatiser la mise à jour de ses dépendances avec Renovate
  • Installer Renovate en mode self-hosted

Si comme moi vous avez des projets perso plus ou moins vivants dans lesquels vous vous replongez de temps en temps, il vous est sûrement arrivé de passer un peu de temps à mettre à jour toutes les dépendances.

Personnellement, je trouve ça même plutôt chouette de bumper toutes mes petites libs tranquillement et de faire en sorte que le projet soit à jour avant de coder: on se prépare pour le match!

Sauf que parfois, ça prend plus de temps que prévu — migration de framework 👋 — et on se dit que si on l’avait fait petit à petit, la marche aurait été un peu moins haute.


Sommaire

  1. Dependabot et ses limites
  2. Pourquoi choisir Renovate ?
  3. Installation technique
  4. Supervision des logs
  5. Conclusion

Dependabot

C’est là que des outils comme Dependabot peuvent nous aider. En gros, ça analyse vos dépendances et ouvre automatiquement des Pull Requests avec les dernières versions à jour de vos libs. Vous n’avez plus qu’à valider la PR et merger.

Vous pouvez même configurer Dependabot pour qu’il ouvre des PR par groupes (patch, minor ou major, packages spécifiques, etc.).

C’est pratique pour ne pas crouler sous les PRs qui changent juste la version d’une dépendance et accessoirement éviter de lancer des dizaines de GitHub Actions qui font fondre votre quota d’ actions minutes !

Il peut aussi se limiter aux mises à jour patch, minor ou major et merger automatiquement, c’est vous qui décidez.

Recherche d’alternatives

Seulement voilà, Dependabot est très lié à GitHub et j’avais envie de voir s’il y avait d’autres options, de préférence 100 % open-source.

J’ai donc commencé à chercher des alternatives qui peuvent m’aider à maintenir mes projets à jour.

Je suis tombé sur le plugin Maven versions-maven-plugin qui semblait cool, mais il n’apporte pas ce côté automatisation out-of-the-box avec ouverture de PRs. De plus, je n’ai pas que des dépendances maven à gérer, j’ai aussi du npm, gradle, Docker, etc.

C’est là qu’arrive Renovate ! Il peut gérer plusieurs types de dépendances, n’est pas lié à GitHub et peut être configuré pour ouvrir des PRs automatiquement.

On peut l’installer de plein de façons différentes, notamment en self-hosted sur un serveur.

Et ça tombe bien, car j’ai un serveur perso qui dort un peu trop en ce moment 😄

Installation

Je me suis donc lancé dans l’installation de Renovate en self-hosted et dans la configuration du lien entre ce Renovate et mon repo GitHub afin qu’il maintienne mes dépendances à jour automatiquement.

Ainsi, le calcul de mise à jour des dépendances est fait par Renovate sur mon serveur et seul le build du projet est fait sur GitHub.

Voici les différentes étapes que j’ai effectuées pour installer et configurer Renovate et garder mes projets à jour sans trop d’efforts!

1. Préparation des accès GitHub

Il faut générer un Personal Access Token (PAT) pour permettre à Renovate d’interagir avec vos repos.

  1. Rendez-vous dans Settings > Developer settings > Personal access tokens (classic).
  2. Générez un nouveau token avec les scopes : repo et workflow.
  3. Conservez ce token (type ghp_xxxx).

2. Configuration du bot (config.js)

On crée une structure simple sur le serveur :

mkdir -p renovate
cd renovate
touch config.js

Le fichier config.js définit le comportement du bot. On active l’auto-découverte pour scanner nos repos.

Pour que le token GitHub soit accessible à la fois par le script config.js (via process.env.RENOVATE_TOKEN) et par le service Docker, il devra être exporté en tant que variable d’environnement sur votre serveur (ou via un fichier .env).

module.exports = {
    platform: 'github',
    endpoint: 'https://api.github.com/',
    token: process.env.RENOVATE_TOKEN,
    autodiscover: true,
    autodiscoverFilter: ['votre-utilisateur-github/*'],
    baseBranches: ['main', 'master'],
    packageRules: [
        {
            description: 'Désactiver les mises à jour majeures par défaut',
            matchUpdateTypes: ['major'],
            enabled: false
        },
        {
            description: 'Grouper les mises à jour mineures et patches',
            matchUpdateTypes: ['minor', 'patch'],
            groupName: 'all non-major dependencies',
            groupSlug: 'all-minor-patch'
        }
    ],
    prCreation: 'immediate',
    dependencyDashboard: true
};

J’ai désactivé les mises à jour majeures pour le moment.

3. Déploiement

Pour info, j’utilise Traefik comme reverse proxy qui s’intègre bien avec Docker Swarm, d’où les labels.

Pour déployer Renovate, j’utilise le fichier docker-compose.yml suivant.

Notez l’utilisation de ${RENOVATE_TOKEN} qui permet de transmettre le token GitHub au conteneur :

version: '3.8'
services:
  renovate:
    image: renovate/renovate:latest
    environment:
      - RENOVATE_PLATFORM=github
      - RENOVATE_TOKEN=${RENOVATE_TOKEN}
      - RENOVATE_CONFIG_FILE=/usr/src/app/config.js
      - RENOVATE_LOG_FILE=/usr/src/app/logs/renovate.log
      - RENOVATE_LOG_FILE_LEVEL=debug
      - LOG_LEVEL=info
    volumes:
      - ./config.js:/usr/src/app/config.js:ro
      - ./logs:/usr/src/app/logs
    # Scan toutes les 12 heures
    command: [ "sh", "-c", "while true; do renovate; sleep 43200; done" ]
    networks:
      - traefik-public

  logs:
    image: nginx:alpine
    volumes:
      - ./logs:/usr/share/nginx/html:ro
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.renovate-logs.rule=Host(`renovate.mon-server.fr`)"
        - "traefik.http.routers.renovate-logs.entrypoints=websecure"
        - "traefik.http.routers.renovate-logs.tls=true"
        - "traefik.http.routers.renovate-logs.tls.certresolver=le"
        - "traefik.http.middlewares.renovate-auth.basicauth.users=admin:$$apr1$$HASH_SECURISE"
        - "traefik.http.routers.renovate-logs.middlewares=renovate-auth"
    networks:
      - traefik-public

networks:
  traefik-public:
    external: true

Reste à lancer la commande docker stack deploy -c renovate-stack.yml renovate et c’est marre!

  1. GitHub : Une PR d’onboarding est créée. Tant qu’elle ne sera pas fusionnée, Renovate ne traitera pas votre repo
  2. Logs Web : https://renovate.mon-server.fr pour voir le fichier renovate.log
  3. Lancer un scan manuellement : docker service update --force renovate_renovate

Conclusion

Et c’est tout, rien de très compliqué! J’ai désormais plein de PRs qui s’ouvrent régulièrement sur mes repos GitHub que je valide les yeux fermés en comptant religieusement sur mes super tests pour assurer la non-régression de tout ça 🍀

Au final c’est un vrai confort de ne plus avoir à se soucier de la mise à jour des libs. Je garde le contrôle d’un côté car c’est moi qui valide les PRs et de l’autre je n’ai pas à parcourir mvn repo et consorts pour check chaque version.

Voilà je sais que ça existe depuis longtemps, que c’est pas de l’IA donc ça n’intéresse personne, mais je suis content de l’avoir fait quand même :)

Allez ciao!