Génération de texte pour les Merges-Requests automatique avec un LLM
Wed 29 May 2024Notre métier consiste à installer des applications en respéctant l’état de l’art. Lorsque l’installation de l’application se fait via la mise à jour de code Gitlab, la documentation de ce code est primordiale. Toute mise à jour du code d’infrastructure est documenté dans une demande Gitlab de merge-request.
Aujourd’hui, je vous propose d’automatiser une des tâches de documentation: la rédaction de descriptions pour les merge-requests. J’ai pu remarquer qu’au début des projets, on se force à écrire de la documentation et des descriptions de changements clair et complet. Cependant, avec la pression ou les changements qui sont à effectuer rapidement, avec le temps, il arrive qu’on se retrouve à rédiger des notes trop brèves, non-exhaustives, ou ne reflétant pas l’intégralité des changements effectués dans le code.
Du coup, nos MR ressemblent à ça et c’est assez vide.

Alors que la documentation et ces descriptions sont très importantes pour :
- les échanges avec l’équipe (Review, double checks, …)
- l’audibilité des changements (savoir qui a changé quoi)
- La gestion de la documentation du projet
Heureusement, avec Vertex AI et GitLab CI, on peut automatiser cette tâche !
Dans cet article, nous allons explorer comment utiliser Vertex AI pour générer automatiquement du texte de merge-request à partir des changements effectués dans une branche GitLab.
1. Configuration de Vertex AI¶
Tout d’abord, il faut configurer l’API Vertex AI capable de générer du texte à partir de données textuelles. Dans cet article, j’ai utilisé le modèle “gemini-1.5-flash-001”.
Il faut bien sûr activer l’api Vertex AI en suivant la documentation. On peut ensuite utiliser VertexAI via la console Google Cloud pour construire le meilleur prompt Après quelques textes voici le prompt que j’ai mis en place :
As a senior DevOps engineer reviewing a merge request for a Terraform module. Please provide a comprehensive description of the changes in french, focusing on the following:
* **What is the overall purpose of the changes?**
* **What specific resources are affected?**
* **What are the main changes made to those resources?**
* **Are there any security or performance implications of the changes?**
* **Are there any potential risks or considerations?
On peut tester le prompt dans VertexAI, comme ci-dessous en glissant-déposser un fichier “git-diff”.

2. Construction d’un script et intégration dans une image docker¶
Pour commencer, on va créer un script python capable :
Interroger Gitlab pour obtenir le “gitdiff” changement Le soumettre à VertexAI Mettre a jour la MR Gitlab avec le résultat de VertexAI Voici le script : generate-mr-text.py
import base64
import vertexai
from vertexai.generative_models import GenerativeModel, Part, FinishReason
import vertexai.preview.generative_models as generative_models
import gitlab
import os, json
import argparse;
GCP_PROJECT_ID = os.getenv("GCP_PROJECT_ID", "sandbox-mgoulin")
GCP_LOCATION = os.getenv("GCP_LOCATION", "us-central1")
GCP_MODEL = os.getenv("GCP_MODEL", "gemini-1.5-flash-preview-0514")
GITLAB_HOST=os.getenv("GITLAB_HOST","https://gitlab.com")
GITLAB_TOKEN=os.getenv("GITLAB_TOKEN", False)
GITLAB_SSL_SKIP_VERIFY=os.getenv("GITLAB_SSL_SKIP_VERIFY",False)
LLM_PROMPT = """As a senior DevOps engineer reviewing a merge request for a Terraform module. Please provide a comprehensive description of the changes in french, focusing on the following:
* **What is the overall purpose of the changes?**
* **What specific resources are affected?**
* **What are the main changes made to those resources?**
* **Are there any security or performance implications of the changes?**
* **Are there any potential risks or considerations?**"""
def generate(diff):
vertexai.init(project=GCP_PROJECT_ID, location=GCP_LOCATION)
model = GenerativeModel(
GCP_MODEL,
)
responses = model.generate_content(
[LLM_PROMPT, diff],
generation_config=generation_config,
safety_settings=safety_settings,
stream=True,
)
rep = ""
for response in responses:
rep += response.text
return rep
generation_config = {
"max_output_tokens": 8192,
"temperature": 1,
"top_p": 0.95,
}
safety_settings = {
generative_models.HarmCategory.HARM_CATEGORY_HATE_SPEECH: generative_models.HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
generative_models.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: generative_models.HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
generative_models.HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: generative_models.HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
generative_models.HarmCategory.HARM_CATEGORY_HARASSMENT: generative_models.HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
}
def find_mr(project, mr_id):
gl = gitlab.Gitlab(url=GITLAB_HOST, private_token=GITLAB_TOKEN, ssl_verify=not(GITLAB_SSL_SKIP_VERIFY))
prj = gl.projects.get(project)
return prj.mergerequests.get(mr_id)
parser = argparse.ArgumentParser(
prog='generate-mr-text.py',
description='Use Gemini to update a merge request with a description',
)
parser.add_argument('-p', '--gitlab_project', required=True)
parser.add_argument('-m', '--gitlab_mr_id', required=True, type=int)
project = parser.parse_args().gitlab_project
mr_id = parser.parse_args().gitlab_mr_id
mr = find_mr(project, mr_id)
changes = mr.changes()
#print(json.dumps(changes, indent=4))
#diff=find_diff()
text=generate(json.dumps(changes, indent=4))
mr.description=mr.description.split("=== Start block generated by generate-mr-text.py ===")[0]+"""
=== Start block generated by generate-mr-text.py ===
"""+text
mr.save()
On peut intégrer rapidement ce script via Dockerfile et pip, pour cela, on a besoin de créer deux fichiers permettant d’installer le script dans un container docker.
Fichier requirements.txt
python-gitlab
google-cloud-aiplatform
Fichier : Dockerfile
FROM registry.access.redhat.com/ubi8/python-38
# Add application sources with correct permissions for OpenShift
USER 0
ADD . .
RUN chown -R 1001:0 ./
USER 1001
# Install the dependencies
RUN pip install -U "pip>=19.3.1" && \
pip install -r requirements.txt
La commande docker build . permettra de construire le container et pour rester cohérent dans nos outils et rester dans le monde GCP, je propose de l’héberger dans Artifact registry
Pour résumé voici les commandes :
cloud artifacts repositories create --project sandbox-mgoulin --repository-format=DOCKER --location europe-west9 generate-mr-text
docker build . -t europe-west9-docker.pkg.dev/sandbox-mgoulin/generate-mr-text/generate-mr-text:latest
docker push europe-west9-docker.pkg.dev/sandbox-mgoulin/generate-mr-text/generate-mr-text:latest
Le container s’utilisera donc simplement de la façon suivante (d’autre variable d’environnement peuvent être ajouté dans le script).
docker run \
-e GCP_PROJECT_ID=... \
-e GITLAB_TOKEN=... \
-e GOOGLE_APPLICATION_CREDENTIALS=... \
europe-west9-docker.pkg.dev/sandbox-mgoulin/generate-mr-text/generate-mr-text:latest \
python generate-mr-text.py -p -m
3. Intégration dans GitLab CI¶
Une fois le modèle Vertex AI configuré, le script crée, il faut l’intégrer dans le pipeline GitLab CI. Cela se fait en ajoutant une nouvelle étape dans le fichier : gitlab-ci.yml.
Voici un exemple de code :
merge_request_text:
stage: generate
image: europe-west9-docker.pkg.dev/sandbox-mgoulin/generate-mr-text/generate-mr-text:latest
script:
- |
python generate-mr-text.py -p $CI_PROJECT_ID -m $vCI_MERGE_REQUEST_IID
Fonctionnement du pipeline :
- Lorsque vous ouvrez une merge-request, le pipeline GitLab CI s’exécute.
- L’étape merge_request_text lance le script écrit à l’étape 2.
- Le modèle génère un texte de merge-request, qui peut ensuite être utilisé pour créer la description de la merge-request.
Conclusion¶
Après la mise en place de ce job en pipeline nos Merge-Requests ont clairement changés. Voici un exemple pour illustrer la monté de version de nextcloud.

## Revue de la demande de fusion du module Terraform Nextcloud
**Objet des changements:**
Cette demande de fusion vise à mettre à niveau le module Terraform pour Nextcloud vers la version 28. Cela implique une série de modifications pour assurer la compatibilité et la stabilité du service Nextcloud.
**Ressources affectées:**
Les changements affectent principalement les ressources suivantes :
* **Dockerfile:** La base de l'image Docker est mise à jour vers PHP 8.2 et la version de Nextcloud est modifiée en 28.
* **Fichier htaccess:** Un nouveau fichier `.htaccess` est ajouté, contenant des directives de configuration spécifiques à Nextcloud, notamment la gestion des en-têtes de sécurité, des directives de cache pour les ressources statiques et des règles de réécriture d'URL pour le bon fonctionnement de Nextcloud.
* **Fichier nextcloud.tf:** L'image Docker utilisée pour le conteneur Nextcloud est mise à jour pour refléter la nouvelle version.
**Principales modifications:**
* **Mise à niveau de la version de Nextcloud:** L'image Docker est mise à jour vers la version 28, incluant les dernières fonctionnalités et corrections de sécurité.
* **Configuration du fichier `.htaccess`:** Un nouveau fichier `.htaccess` est ajouté pour garantir la configuration optimale de Nextcloud et l'application des meilleures pratiques de sécurité.
**Implications en matière de sécurité et de performance:**
* **Sécurité:** La mise à jour de Nextcloud vers la version 28 inclut des correctifs de sécurité importants. La configuration du fichier `.htaccess` contribue également à améliorer la sécurité en appliquant des en-têtes de sécurité essentiels.
* **Performance:** La nouvelle image Docker basée sur PHP 8.2 pourrait entraîner des améliorations de performance, en particulier pour les applications gourmandes en ressources.
**Risques et considérations:**
* **Compatibilité:** Il est important de tester minutieusement la mise à jour pour s'assurer que toutes les applications et les configurations existantes sont compatibles avec la version 28 de Nextcloud.
* **Configurations spécifiques:** Des configurations spécifiques ou des extensions personnalisées pourraient nécessiter des ajustements supplémentaires.
* **Intégration:** Assurez-vous que la mise à jour de Nextcloud n'impacte pas négativement d'autres services ou composants du système.
* **Sauvegardes:** Il est crucial de créer des sauvegardes complètes de la base de données Nextcloud et des fichiers de données avant d'effectuer la mise à jour.
**Conclusion:**
Cette demande de fusion vise à améliorer la sécurité et la stabilité du service Nextcloud en effectuant une mise à niveau vers la version 28. Il est essentiel de procéder à des tests complets avant de la valider en production pour garantir une transition en douceur et minimiser les risques.
Avantages de l’automatisation:
- Gain de temps: Plus besoin de rédiger manuellement les descriptions de merge-request.
- Cohérence: Le texte généré est toujours cohérent et suit un format standard.
- Précision: Le modèle Vertex AI peut identifier des informations importantes qui pourraient être oubliées.
- Meilleure communication: Des descriptions claires et précises facilitent la communication entre les membres de l’équipe.
En utilisant Vertex AI et GitLab CI, vous pouvez automatiser la génération de texte de merge-request et améliorer votre workflow de développement. Ce gain de temps et d’efficacité vous permettra de vous concentrer sur des tâches plus stratégiques.
N’hésitez pas à tester cette solution et à l’adapter à vos besoins !
Cloud Ops Chronicles