Skip to main content
L’API de Devin est un outil puissant conçu pour résoudre automatiquement les problèmes de code détectés par des outils d’analyse tels que SonarQube. Bien que cette documentation se concentre sur SonarQube, la stratégie sous-jacente s’applique à d’autres outils d’analyse de code, notamment Veracode, Orca et d’autres encore. Si vous souhaitez voir ce processus en action, consultez notre dépôt de démonstration et l’explication détaillée dans l’article de blog de Cognition. En production, le processus se déroulera comme suit :

Résolution automatique des problèmes avec l’API de Devin

En production, le processus de résolution automatique des problèmes de code à l’aide de l’API de Devin est simple et efficace. Voici un aperçu général des principales étapes :

1. Vue d’ensemble du processus

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

2. Étapes à suivre pour y parvenir

Pour intégrer l’API de Devin à votre pipeline CI/CD, vous devrez effectuer les configurations suivantes :
  1. Configurer SonarQube pour la prise en charge CI et API :
    • Assurez-vous que SonarQube est configuré pour prendre en charge l’intégration continue (CI) et l’intégration via API. Si vous préférez ne pas configurer SonarQube pour l’accès par API, vous pouvez utiliser un cookie pour l’authentification. En savoir plus sur cette configuration ici.
  2. Configurer l’environnement GitHub pour stocker les secrets requis :
    • Configurez l’environnement GitHub afin de stocker en toute sécurité les secrets nécessaires, tels que les jetons d’authentification et les clés de configuration, pour 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 votre configuration terminée, vous pouvez tester l’intégration en déclenchant manuellement une GitHub Action. 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 de la GitHub Action 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 changements proposés. Guide détaillé Vous pouvez passer à la suite si votre projet SonarQube est déjà correctement configuré. Sinon, la section suivante explique comment garantir que GitHub a accès à l’API de SonarQube. Valeurs requises depuis SonarQube Pour configurer l’intégration, vous devrez obtenir les trois valeurs suivantes depuis votre instance SonarQube : Vous aurez besoin de trois valeurs depuis SonarQube :

1. Créez le jeton SONAR_TOKEN :

  1. Cliquez sur l’icône de votre compte dans le coin supérieur droit de SonarQube.
  2. Sélectionnez Security dans le menu déroulant.
  3. Sous Tokens, cliquez sur Generate Tokens.
  4. Attribuez un nom au jeton, puis cliquez sur Generate.
  • Copiez le jeton généré pour l’utiliser dans GitHub Actions.
SonarQube

2. Créer SONAR_PROJECT

  1. Sélectionnez le projet dans SonarQube.
  2. Cliquez sur Information en bas à gauche.
  3. Faites défiler la page vers le bas pour trouver la clé du projet.
SonarQube

3. Créer SONAR_ORG

Reportez-vous aux étapes ci-dessus pour retrouver les informations de votre organisation dans SonarQube. Une fois que vous disposez de toutes les valeurs requises, vous êtes prêt à configurer l’action GitHub.
Cela suppose que vous disposez d’un fichier de propriétés SonarCloud local sonar-project.properties qui spécifie :
sonar.projectKey={PROJECT_KEY}
sonar.sources=FILE_PATH (généralement ".")
L’action GitHub a le code source suivant :
name: Analyse SonarCloud et correction Devin
on:
  workflow_dispatch:
  push:
    branches:
      - '**'
  pull_request:
    branches:
      - '**'

jobs:
  analyze:
    name: Analyser et corriger
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0

    - name: Analyse SonarCloud
      uses: SonarSource/sonarqube-scan-action@v4
      env:
        SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
        SONAR_ORG: ${{ secrets.SONAR_ORG }}
      with:
        args: >
          -Dsonar.organization=${{ env.SONAR_ORG }}
          -Dsonar.sources=.
    - name: Configurer Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.x'

    - name: Installer les dépendances
      run: pip install aiohttp

    - name: Configurer Git
      run: |
        git config --global user.name "GitHub Action"
        git config --global user.email "[email protected]"
    - name: Exécuter la correction Devin
      env:
        DEVIN_API_KEY: ${{ secrets.DEVIN_API_KEY }}
        SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        SONAR_ORG: ${{ secrets.SONAR_ORG }}
        SONAR_PROJECT_KEY: {SONAR_PROJECT_KEY}
      run: python .github/scripts/devin_remediation.py
Pour rappel, devin_remediation.py
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 vous assurer que l’action GitHub définit les bonnes variables d’environnement, ajoutez-les aux GitHub Repository Secrets. Accéder aux bons paramètres peut prêter à confusion. Allez dans Security, puis modifiez Secrets. Ajoutez SONAR_TOKEN et DEVINS_API dans Repository Secrets.
SonarQube
Une fois la configuration effectuée, vous pouvez suivre l’exécution de votre action GitHub. Si elle s’exécute avec succès, elle s’affichera comme suit :
SonarQube
Vous pouvez consulter les sessions Devin dans le Session Manager.
SonarQube
Une fois l’analyse terminée, Devin ouvrira automatiquement des pull requests. Pour les utilisateurs de GitLab, consultez le guide associé.