Durant le développement, il n’est pas toujours simple de suivre les évolutions des nombreuses librairies dont nos projets dépendent. Cela participe à l’entropie des projets et la conséquence est au mieux une dette technique latente qui s’accumule petit à petit, au pire, l’inclusion de failles de sécurité ouvrant la porte à des exploits.
Sur certains projets, on observait des efforts pour lutter contre cette dette. En exécutant des plugins dans le Delivery pour afficher les nouvelles versions disponibles, comme le plugin maven Versions. Il fallait toutefois s’assurer du changelog et des impacts de la nouvelle version, faire d’éventuelles modifications à la main et finalement lancer une passe de non-régression sur le projet. Des efforts qui nécessitaient beaucoup d’énergie. Surtout dans certains langages dont le rythme des releases et le nombres de librairies explose rapidement.
On retrouve la même démarche avec les commandes npm audit qui remontent les vulnérabilités des projets JS.
Aujourd’hui, il existe plusieurs solutions (gratuites ou payantes) plus ou moins avancées pour s’occuper de ce soucis. La plus connue est DependaBot, notamment parce qu’elle a été racheté récemment pour être intégré automatiquement dans Github.
DepandaBot est un outil en Ruby qui scanne vos dépendances et vérifie s’il n’existe pas une version plus récente dans les dépôts officiels ou des projets (Github). Jusque là, ok ce n’est pas une révolution à la Steve Job. Par contre, plutôt que de vous soumettre un rapport sur l’état de votre projet, il construit une Pull Request contenant la montée de version de la librairie à mettre à jour. Cela vous permet de valider chacune des modifications. De plus, il a le bon goût de mettre les releases notes, le changelog de la librairie ainsi que les commits en commentaire de la Pull Request pour vous prémâcher le travail de revue d’impacts (si ces informations sont disponibles évidemment).
Même si DependaBot est principalement dédié à Github, il est possible de l’intégrer à Gitlab très simplement. Ils ont d’ailleurs un projet disponible avec des instructions claires à suivre, dont voici le déroulé :
1. Importer le projet dans Gitlab
Ne pas oublier de cocher la case Mirror pour continuer de bénéficier des évolutions du projet de base. Le projet peut même être privé.
2. Générer un Personal Access Token dans Gitlab
Dependabot va avoir besoin d’accéder à l’api de Gitlab pour créer une Merge Request. Il lui faut donc un token pour s’authentifier avec les droits nécessaires.
Dans son compte, il faut générer un Personal Access Token avec les droits d’accès apis.
3. Générer un Access Token dans Github
Cette étape n’est pas obligatoire mais elle est fortement recommandée. En effet, Dependabot va utiliser les API Github notamment pour les vérifier les vulnérabilités déclarées sur les versions des librairies de notre projet. Ces API sont publiques mais soumises à un quota d’accès.
Il vaut donc mieux générer un access token côté Github pour avoir l’autorisation de dépasser ces quotas d’accès qui sont très bas pour les accès non authentifiés. Le droit public_repo est suffisant.
4. Mettre en place la CI
Pour que Gitlab puisse lancer la CI, il lui faut son descripteur. Soit en modifiant le projet et en renommant le fichier d’exemple fourni .gitlab-ci.example.yml en .gitlab-ci.yml, soit en modifiant le nom du fichier par défaut dans la configuration du projet.
On va aussi déclarer en variables d’environnements les Access Tokens créés ci-dessus, respectivement GITHUB_ACCESS_TOKEN et GITLAB_ACCESS_TOKEN. On peut trouver ces noms de variables d’environnement dans le script generic-update-script.rb.
Il en existe d’autres suivant les systèmes utilisés ou pour activer certaines fonctionnalités.
5. Créer une configuration de lancement programmé
Depuis votre projet dependabot-script sous Gitlab, il faut créer un cron qui exécutera la pipeline (menu CI / CD > Schedules ):
- Périodicité : 1 fois par semaine
- Target branch : master
- Ajouter les variables :
- PROJECT_PATH : le chemin pointant sur le projet à analyser
- PACKAGE_MANAGER_SET : la liste des gestionnaires de dépendances à appliquer (maven, npm, docker, …).
Une fois les builds lancés, vous obtiendrez de magnifiques merge requests comme celle-ci :
Avec un example de détail, ça donne ça :
What else ?
Il ne vous restent plus à y jeter un coup d’oeil, l’approuver et la merger.
Pour les plus confiants dans leur Delivery, il est possible d’automatiser encore plus le processus en ajoutant la variable GITLAB_AUTO_MERGE pour merger automatiquement la MR quand elle passe la CI.
Et voilà, plus d’excuses pour ne pas avoir les dépendances de vos projets toujours à jour !
Chez Liksi, c’est devenu un must have qui suit l’ensemble de nos projets de développement Java, JS, Python, les images Docker et même les dépendances de nos projets d’Infrastructure as Code sous Terraform.