Skip to main content
L’API de Devin est un outil puissant, veuillez lire l’article suivant avant de poursuivre ce guide.

1. Vue d’ensemble du processus

  1. La Pull Request est ouverte : Une Pull Request (PR) est soumise au dépôt avec des modifications qui peuvent contenir des problèmes identifiés par un outil d’analyse de code.
  2. L’action GitLab est déclenchée : L’ouverture de la PR déclenche automatiquement un workflow GitHub Actions.
  3. L’action GitLab appelle l’API Devin : La GitHub Action envoie une requête à l’API Devin, en lui transmettant les problèmes identifiés pour qu’ils soient résolus automatiquement.
  4. La session Devin est initialisée : Une session Devin est lancée, reçoit le contexte du problème et tente de le résoudre à partir des données fournies.
  5. Devin propose une PR pour revue humaine : Une fois le problème résolu, Devin génère une PR avec les modifications proposées et la soumet pour revue humaine.

2. Étapes pour y parvenir

  1. Configurer l’environnement GitLab pour héberger les secrets requis :
    • Configurez l’environnement GitLab pour stocker en toute sécurité les secrets nécessaires, comme les jetons d’authentification et les clés de configuration, afin d’interagir avec l’API de Devin et les autres outils intégrés.
Une fois ces étapes terminées, votre pipeline sera prêt à résoudre automatiquement les problèmes à l’aide de l’API de Devin, ce qui accélérera le processus et réduira le besoin d’intervention manuelle.
  1. Tester l’intégration
Une fois la configuration terminée, vous pouvez tester l’intégration en déclenchant manuellement une action GitLab. Cela vous permettra de vérifier que l’action appelle correctement l’API Devin et résout les problèmes identifiés.
  1. Afficher la page des sessions Devin
Après le déclenchement du GitLab Build et le traitement des problèmes par Devin, vous pouvez consulter l’état et les résultats sur la page des sessions Devin. Cette page fournit des informations détaillées sur les problèmes résolus et les modifications proposées. Comme mentionné précédemment, les valeurs requises provenant de SonarQube sont : Pour configurer l’intégration, vous devrez obtenir les trois valeurs suivantes depuis votre instance SonarQube : Vous aurez besoin de three_values from SonarQube : {SONAR_TOKEN, SONAR_ORG, SONAR_PROJECT_KEY} Une fois que vous disposez de toutes les valeurs requises, vous êtes prêt à configurer l’action GitLab.
Ceci suppose que vous disposez d’un fichier de propriétés SonarCloud local sonar-project.properties qui indique :
sonar.projectKey={PROJECT_KEY}
sonar.sources=FILE_PATH (généralement ".")
L’action GitLab a le code source suivant
stages:
  - analyze
  - remediate

variables:
  SONAR_TOKEN: "$SONAR_TOKEN"
  SONAR_ORG: "$SONAR_ORG"
  SONAR_PROJECT_KEY: "Colhodm_juice-shop"
  DEVIN_API_KEY: "$DEVIN_API_KEY"
  GIT_STRATEGY: clone

analyze:
  stage: analyze
  image: sonarsource/sonar-scanner-cli:latest
  script:
    - sonar-scanner -Dsonar.organization=$SONAR_ORG
  only:
    - branches
    - merge_requests

setup_python:
  stage: remediate
  image: python:3.9
  before_script:
    - python --version
    - pip install aiohttp
  script:
    - git config --global user.name "GitLab Runner"
    - git config --global user.email "[email protected]"
    - python3 $CI_PROJECT_DIR/.gitlab/scripts/devin_remediation.py
  only:
    - branches
    - merge_requests
Pour rappel, voici devin_remediation.py :
python
import asyncio
import aiohttp
import os
from datetime import datetime

# Variables d'environnement
GITHUB_REPOSITORY = os.getenv("GITHUB_REPOSITORY")
SONAR_TOKEN = os.getenv("SONAR_TOKEN")
DEVIN_API_KEY = os.getenv("DEVIN_API_KEY")
SONAR_ORG = os.getenv("SONAR_ORG")
SONAR_PROJECT_KEY = os.getenv("SONAR_PROJECT_KEY")
DEVIN_API_BASE = "https://api.devin.ai/v1"

async def get_sonarcloud_issues():
    """Récupère les vulnérabilités ouvertes depuis SonarCloud."""
    url = "https://sonarcloud.io/api/issues/search"
    headers = {"Authorization": f"Bearer {SONAR_TOKEN}"}
    params = {
        "organization": SONAR_ORG,
        "projectKeys": SONAR_PROJECT_KEY,
        "types": "VULNERABILITY",
        "statuses": "OPEN"
    }

    async with aiohttp.ClientSession() as session:
        async with session.get(url, headers=headers, params=params) as response:
            if response.status != 200:
                print(f"Erreur lors de la récupération des problèmes SonarCloud : {await response.text()}")
                return []
            result = await response.json()
            print(f"{len(result.get('issues', []))} problèmes trouvés")
            return result.get('issues', [])

async def delegate_task_to_devin(issue):
    """Délègue l'ensemble de la tâche de correction, commit et push à Devin AI."""
    async with aiohttp.ClientSession() as session:
        headers = {"Authorization": f"Bearer {DEVIN_API_KEY}"}
        prompt = f"""
        Corrigez la vulnérabilité suivante dans {GITHUB_REPOSITORY} : {issue['message']} dans le fichier {issue['component']}.
        1. Créez une nouvelle branche nommée 'devin/{issue['key']}-fix-vulnerability'.
        2. Implémentez la correction.
        3. Rédigez un message de commit détaillé expliquant les modifications :
            - Clé du problème : {issue['key']}
            - Composant : {issue['component']}
            - Corrigé par Devin AI le {datetime.now().isoformat()}
            - Incluez 'Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>'.
        4. Poussez la branche vers le dépôt distant.
        5. Ouvrez une pull request avec une description de la correction.
        """

        data = {"prompt": prompt, "idempotent": True}

        async with session.post(f"{DEVIN_API_BASE}/sessions", json=data, headers=headers) as response:
            if response.status != 200:
                print(f"Erreur lors de la délégation de la tâche à Devin : {await response.text()}")
                return None
            result = await response.json()
            print(f"Session Devin créée : {result}")
            return result

async def monitor_devin_session(session_id):
    """Surveille la progression de Devin jusqu'à ce qu'il termine la tâche."""
    async with aiohttp.ClientSession() as session:
        headers = {"Authorization": f"Bearer {DEVIN_API_KEY}"}

        while True:
            async with session.get(f"{DEVIN_API_BASE}/sessions/{session_id}", headers=headers) as response:
                if response.status != 200:
                    print(f"Erreur lors de la surveillance de la session Devin : {await response.text()}")
                    return None

                result = await response.json()
                status = result.get("status_enum")

                if status in ["completed", "stopped"]:
                    print(f"Devin a terminé la tâche : {result}")
                    return result
                elif status == "blocked":
                    print("Devin a rencontré un problème. Veuillez vérifier manuellement.")
                    return None

                await asyncio.sleep(5)

async def main():
    try:
        issues = await get_sonarcloud_issues()

        for issue in issues:
            print(f"Traitement du problème : {issue['key']}")

            # Déléguer la tâche à Devin AI
            session_data = await delegate_task_to_devin(issue)

            if session_data:
                session_id = session_data["session_id"]

                # Surveiller la progression de Devin
                await monitor_devin_session(session_id)

    except Exception as e:
        print(f"Erreur survenue : {str(e)}")
        raise

if __name__ == "__main__":
    asyncio.run(main())
Pour garantir que l’Action GitLab définit les bonnes variables d’environnement, ajoutez-les aux GitLab CI/CD Secrets. Accéder aux bons paramètres peut être délicat. Allez dans Settings et modifiez Secrets. Ajoutez SONAR_TOKEN et DEVINS_API sous Repository Secrets.
SonarQube
Si vous utilisez une instance GitLab auto-hébergée, la seule différence est la suivante : Une fois configurée, vous pouvez surveiller l’exécution de votre GitLab Action. Si elle s’exécute correctement, elle apparaîtra comme suit :
SonarQube
Vous pouvez afficher les sessions Devin dans le Session Manager.
SonarQube
Une fois terminé, Devin ouvrira automatiquement des pull requests. Pour les utilisateurs de GitLab, consultez le guide.