Skip to main content
L’API di Devin è uno strumento potente; leggi il seguente articolo prima di continuare con questa guida.

1. Panoramica del processo

  1. La pull request viene aperta: Una pull request (PR) viene inviata al repository con modifiche che possono contenere problemi identificati da uno strumento di code scanning.
  2. Viene attivata la GitLab Action: L’apertura della PR attiva automaticamente un workflow di GitHub Actions.
  3. La GitLab Action chiama la Devin API: La GitHub Action invia una richiesta alla Devin API, passando i problemi identificati per la loro risoluzione automatica.
  4. La sessione Devin viene inizializzata: Una sessione Devin viene avviata, riceve il contesto del problema e tenta di risolverlo sulla base dei dati forniti.
  5. Devin propone una PR per la revisione umana: Una volta risolto il problema, Devin genera una PR con le modifiche proposte e la invia per la revisione da parte di un revisore umano.

2. Passaggi per completare la procedura

  1. Configurare l’ambiente GitLab per contenere i segreti richiesti:
    • Configura l’ambiente GitLab per archiviare in modo sicuro i segreti necessari, come token di autenticazione e chiavi di configurazione, per interagire con l’API di Devin e altri strumenti integrati.
Una volta completati questi passaggi, la tua pipeline sarà pronta per risolvere automaticamente i problemi utilizzando l’API di Devin, velocizzando il processo e riducendo la necessità di intervento manuale.
  1. Testare l’integrazione
Una volta completata la configurazione, puoi testare l’integrazione avviando manualmente una GitLab Action. Questo ti consentirà di verificare che l’action richiami correttamente l’API di Devin e risolva i problemi identificati.
  1. Visualizzare la pagina delle sessioni di Devin
Dopo che la GitLab Build è stata avviata e Devin ha elaborato i problemi, puoi visualizzare lo stato e i risultati nella pagina delle sessioni di Devin. Questa pagina fornisce informazioni dettagliate sui problemi risolti e sulle modifiche proposte. Come menzionato in precedenza, i valori richiesti da SonarQube sono: Per configurare l’integrazione, dovrai ottenere i seguenti tre valori dalla tua istanza SonarQube: Avrai bisogno di tre_valori da SonarQube: {SONAR_TOKEN, SONAR_ORG, SONAR_PROJECT_KEY} Una volta ottenuti tutti i valori richiesti, sei pronto per configurare la GitLab Action.
Questo presuppone che tu disponga di un file locale di proprietà di SonarCloud sonar-project.properties che specifichi:
sonar.projectKey={PROJECT_KEY}
sonar.sources=FILE_PATH (solitamente ".")
La GitLab Action ha il seguente codice sorgente
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
Per riferimento, devin_remediation.py è il seguente:
python
import asyncio
import aiohttp
import os
from datetime import datetime

# Variabili di ambiente
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():
    """Recupera le vulnerabilità aperte da 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"Errore durante il recupero dei problemi da SonarCloud: {await response.text()}")
                return []
            result = await response.json()
            print(f"Trovati {len(result.get('issues', []))} problemi")
            return result.get('issues', [])

async def delegate_task_to_devin(issue):
    """Delega l'intera attività di correzione, commit e push a Devin AI."""
    async with aiohttp.ClientSession() as session:
        headers = {"Authorization": f"Bearer {DEVIN_API_KEY}"}
        prompt = f"""
        Correggi la seguente vulnerabilità in {GITHUB_REPOSITORY}: {issue['message']} nel file {issue['component']}.
        1. Crea un nuovo branch denominato 'devin/{issue['key']}-fix-vulnerability'.
        2. Implementa la correzione.
        3. Scrivi un messaggio di commit dettagliato che spieghi le modifiche:
            - Chiave problema: {issue['key']}
            - Componente: {issue['component']}
            - Corretto da Devin AI il {datetime.now().isoformat()}
            - Includi 'Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>'.
        4. Esegui il push del branch nel repository remoto.
        5. Apri una pull request con una descrizione della correzione.
        """

        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"Errore durante la delega dell'attività a Devin: {await response.text()}")
                return None
            result = await response.json()
            print(f"Sessione Devin creata: {result}")
            return result

async def monitor_devin_session(session_id):
    """Monitora il progresso di Devin fino al completamento dell'attività."""
    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"Errore durante il monitoraggio della sessione Devin: {await response.text()}")
                    return None

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

                if status in ["completed", "stopped"]:
                    print(f"Devin ha completato l'attività: {result}")
                    return result
                elif status == "blocked":
                    print("Devin ha riscontrato un problema. Verificare manualmente.")
                    return None

                await asyncio.sleep(5)

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

        for issue in issues:
            print(f"Elaborazione problema: {issue['key']}")

            # Delega l'attività a Devin AI
            session_data = await delegate_task_to_devin(issue)

            if session_data:
                session_id = session_data["session_id"]

                # Monitora il progresso di Devin
                await monitor_devin_session(session_id)

    except Exception as e:
        print(f"Si è verificato un errore: {str(e)}")
        raise

if __name__ == "__main__":
    asyncio.run(main())
Per assicurarti che la GitLab Action imposti le variabili d’ambiente corrette, aggiungile ai GitLab CI/CD Secrets. Individuare le impostazioni corrette può essere complicato. Vai su Settings e modifica Secrets. Aggiungi SONAR_TOKEN e DEVINS_API in Repository Secrets.
SonarQube
Se usi una versione self-hosted di GitLab, l’unica differenza sarà: Una volta configurato, puoi monitorare l’avanzamento della GitLab Action. Se viene eseguita correttamente, verrà visualizzata come segue:
SonarQube
Puoi visualizzare le sessioni di Devin nel Session Manager.
SonarQube
Al termine, Devin aprirà automaticamente delle pull request. Per gli utenti GitLab, consulta la guida collegata.