Skip to main content
Die Devin-API ist ein leistungsstarkes Werkzeug, das dafür entwickelt wurde, Codeprobleme automatisch zu beheben, die von Code-Scanning-Tools wie SonarQube erkannt werden. Obwohl sich diese Dokumentation auf SonarQube konzentriert, lässt sich die zugrunde liegende Strategie auch auf andere Code-Scanning-Tools wie Veracode, Orca und weitere anwenden. Wenn Sie diesen Prozess in Aktion sehen möchten, sehen Sie sich unser Demo-Repository an und lesen Sie die detaillierte Erklärung im Cognition-Blogbeitrag. Im produktiven Einsatz sieht der Prozess wie folgt aus:

Automatisierte Problembehebung mit der Devin-API

In Produktionsumgebungen ist der Prozess zur automatischen Behebung von Codeproblemen mithilfe der Devin-API schlank und effizient. Im Folgenden finden Sie einen groben Überblick über die einzelnen Schritte:

1. Prozessüberblick

  1. Pull Request wird geöffnet: Ein Pull Request (PR) mit Änderungen wird im Repository eingereicht, die Probleme enthalten können, die von einem Code-Scanning-Tool erkannt wurden.
  2. GitHub Action wird ausgelöst: Das Öffnen des PR löst automatisch einen GitHub-Action-Workflow aus.
  3. GitHub Action ruft Devin-API auf: Die GitHub Action sendet eine Anfrage an die Devin-API und übermittelt die identifizierten Probleme zur automatisierten Behebung.
  4. Devin-Sitzung wird initialisiert: Eine Devin-Sitzung wird gestartet, erhält den Kontext des Problems und versucht, es auf Basis der bereitgestellten Daten zu lösen.
  5. Devin schlägt PR zur menschlichen Überprüfung vor: Sobald das Problem gelöst ist, erstellt Devin einen PR mit den vorgeschlagenen Änderungen und legt ihn zur menschlichen Überprüfung vor.

2. Schritte zur Umsetzung

Um die Devin-API in Ihre CI/CD-Pipeline zu integrieren, müssen Sie die folgenden Konfigurationen vornehmen:
  1. SonarQube für CI- und API-Unterstützung konfigurieren:
    • Stellen Sie sicher, dass SonarQube so konfiguriert ist, dass Continuous Integration (CI) und API-Integration unterstützt werden. Wenn Sie SonarQube nicht für den API-Zugriff einrichten möchten, können Sie für die Authentifizierung ein Cookie verwenden. Erfahren Sie hier mehr über diese Einrichtung.
  2. GitHub-Umgebung zum Speichern der erforderlichen Secrets konfigurieren:
    • Richten Sie die GitHub-Umgebung so ein, dass die benötigten Secrets – wie Authentifizierungs-Token und Konfigurationsschlüssel – sicher gespeichert werden, um mit der Devin-API und anderen integrierten Tools zu interagieren.
Sobald diese Schritte abgeschlossen sind, ist Ihre Pipeline bereit, Probleme automatisch mit der Devin-API zu beheben, wodurch der Prozess beschleunigt und der Bedarf an manuellen Eingriffen reduziert wird.
  1. Integration testen
Sobald Ihre Einrichtung abgeschlossen ist, können Sie die Integration testen, indem Sie einen GitHub-Action-Workflow manuell auslösen. Dadurch können Sie überprüfen, ob die Action die Devin-API korrekt aufruft und die identifizierten Probleme behebt.
  1. Devin-Sessions-Seite anzeigen
Nachdem die GitHub Action ausgelöst wurde und Devin die Probleme verarbeitet hat, können Sie den Status und die Ergebnisse auf der Devin-Sessions-Seite einsehen. Diese Seite bietet detaillierte Einblicke in die behobenen Probleme und die vorgeschlagenen Änderungen. Ausführliche Anleitung Überspringen Sie diesen Abschnitt, wenn Ihr SonarQube-Projekt bereits entsprechend konfiguriert ist. Andernfalls führt Sie der folgende Abschnitt Schritt für Schritt durch die Sicherstellung, dass GitHub Zugriff auf die SonarQube-API hat. Erforderliche Werte von SonarQube
Um die Integration zu konfigurieren, müssen Sie die folgenden drei Werte aus Ihrer SonarQube-Instanz abrufen: Sie benötigen drei Werte von SonarQube:

1. SONAR_TOKEN erstellen:

  1. Klicke oben rechts in SonarQube auf dein Profilbild.
  2. Wähle im Dropdown-Menü Security aus.
  3. Klicke unter Tokens auf Generate Tokens.
  4. Gib dem Token einen Namen und klicke auf Generate.
  • Kopiere das generierte Token zur Verwendung in GitHub Actions.
SonarQube

2. Erstelle SONAR_PROJECT

  1. Wähle in SonarQube das Projekt aus.
  2. Klicke unten links auf Information.
  3. Scrolle nach unten, bis du den Projektschlüssel findest.
SonarQube

3. Erstelle SONAR_ORG

Siehe die oben beschriebenen Schritte, um deine Organisationsdetails in SonarQube zu finden. Sobald du alle erforderlichen Werte hast, kannst du die GitHub Action konfigurieren.
Dabei wird vorausgesetzt, dass du eine lokale SonarCloud-Property-Datei sonar-project.properties hast, die Folgendes definiert:
sonar.projectKey={PROJECT_KEY}
sonar.sources=FILE_PATH (in der Regel ".")
Die GitHub Action hat den folgenden Quellcode:
name: SonarCloud-Scan und Devin-Fehlerbehebung
on:
  workflow_dispatch:
  push:
    branches:
      - '**'
  pull_request:
    branches:
      - '**'

jobs:
  analyze:
    name: Analysieren und Fehler beheben
    runs-on: ubuntu-latest

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

    - name: SonarCloud-Scan
      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: Python einrichten
      uses: actions/setup-python@v5
      with:
        python-version: '3.x'

    - name: Abhängigkeiten installieren
      run: pip install aiohttp

    - name: Git konfigurieren
      run: |
        git config --global user.name "GitHub Action"
        git config --global user.email "[email protected]"
    - name: Devin-Fehlerbehebung ausführen
      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
Zur Erinnerung: devin_remediation.py
import asyncio
import aiohttp
import os
from datetime import datetime

# Umgebungsvariablen
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():
    """Offene Schwachstellen von SonarCloud abrufen."""
    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"Fehler beim Abrufen der SonarCloud-Issues: {await response.text()}")
                return []
            result = await response.json()
            print(f"{len(result.get('issues', []))} Issues gefunden")
            return result.get('issues', [])

async def delegate_task_to_devin(issue):
    """Die gesamte Aufgabe des Behebens, Commitens und Pushens an Devin AI delegieren."""
    async with aiohttp.ClientSession() as session:
        headers = {"Authorization": f"Bearer {DEVIN_API_KEY}"}
        prompt = f"""
        Beheben Sie die folgende Schwachstelle in {GITHUB_REPOSITORY}: {issue['message']} in Datei {issue['component']}.
        1. Erstellen Sie einen neuen Branch mit dem Namen 'devin/{issue['key']}-fix-vulnerability'.
        2. Implementieren Sie die Behebung.
        3. Schreiben Sie eine detaillierte Commit-Nachricht, die die Änderungen erläutert:
            - Issue Key: {issue['key']}
            - Component: {issue['component']}
            - Fixed by Devin AI at {datetime.now().isoformat()}
            - Include 'Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>'.
        4. Pushen Sie den Branch in das Remote-Repository.
        5. Öffnen Sie einen Pull Request mit einer Beschreibung der Behebung.
        """

        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"Fehler beim Delegieren der Aufgabe an Devin: {await response.text()}")
                return None
            result = await response.json()
            print(f"Devin-Session erstellt: {result}")
            return result

async def monitor_devin_session(session_id):
    """Fortschritt von Devin überwachen, bis die Aufgabe abgeschlossen ist."""
    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"Fehler beim Überwachen der Devin-Session: {await response.text()}")
                    return None

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

                if status in ["completed", "stopped"]:
                    print(f"Devin hat die Aufgabe abgeschlossen: {result}")
                    return result
                elif status == "blocked":
                    print("Devin ist auf ein Problem gestoßen. Bitte manuell prüfen.")
                    return None

                await asyncio.sleep(5)

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

        for issue in issues:
            print(f"Issue wird verarbeitet: {issue['key']}")

            # Aufgabe an Devin AI delegieren
            session_data = await delegate_task_to_devin(issue)

            if session_data:
                session_id = session_data["session_id"]

                # Fortschritt von Devin überwachen
                await monitor_devin_session(session_id)

    except Exception as e:
        print(f"Fehler aufgetreten: {str(e)}")
        raise

if __name__ == "__main__":
    asyncio.run(main())
Um sicherzustellen, dass die GitHub Action die korrekten Umgebungsvariablen setzt, füge diese zu den GitHub Repository Secrets hinzu. Die richtigen Einstellungen zu finden, kann etwas knifflig sein. Gehe zu Security und bearbeite Secrets. Füge SONAR_TOKEN und DEVINS_API unter Repository Secrets hinzu.
SonarQube
Sobald alles konfiguriert ist, kannst du die laufende GitHub Action überwachen. Wenn sie erfolgreich ausgeführt wird, sieht sie wie folgt aus:
SonarQube
Sie können Devin-Sitzungen im Session Manager anzeigen.
SonarQube
Sobald der Prozess abgeschlossen ist, öffnet Devin automatisch Pull Requests. Für GitLab-Benutzer finden Sie weitere Informationen im verlinkten Leitfaden.