Skip to main content
La API de Devin es una potente herramienta diseñada para resolver automáticamente problemas de código detectados por herramientas de análisis como SonarQube. Aunque esta documentación se centra en SonarQube, la estrategia subyacente se aplica a otras herramientas de análisis de código, como Veracode, Orca y otras. Si deseas ver este proceso en acción, consulta nuestro repositorio de demostración y explora la explicación detallada en la publicación del blog de Cognition. En producción, el proceso tendrá el siguiente aspecto:

Resolución automática de incidencias con la API de Devin

En producción, el proceso de resolución automática de incidencias de código con la API de Devin es ágil y eficiente. A continuación se presenta una descripción general de alto nivel de los pasos que intervienen:

1. Descripción general del proceso

  1. Se abre el pull request: Se envía un pull request (PR) al repositorio con cambios que pueden contener problemas identificados por una herramienta de análisis de código.
  2. Se activa el flujo de trabajo de GitHub Actions: La apertura del PR activa automáticamente un flujo de trabajo de GitHub Actions.
  3. El flujo de trabajo de GitHub Actions llama a la API de Devin: El flujo de trabajo de GitHub Actions envía una solicitud a la API de Devin, pasando los problemas identificados para su resolución automática.
  4. Se inicializa una sesión de Devin: Se inicializa una sesión de Devin, que recibe el contexto del problema e intenta resolverlo en función de los datos proporcionados.
  5. Devin propone un PR para revisión humana: Una vez resuelto el problema, Devin genera un PR con los cambios propuestos y lo envía para revisión humana.

2. Pasos para lograr esto

Para integrar la API de Devin con tu canalización de CI/CD, deberás completar las siguientes configuraciones:
  1. Configurar SonarQube para compatibilidad con CI y API:
    • Asegúrate de que SonarQube esté configurado para admitir la integración continua (CI) y la integración mediante API. Si prefieres no configurar SonarQube para acceso por API, puedes usar una cookie para la autenticación. Obtén más información sobre esta configuración aquí.
  2. Configurar el entorno de GitHub para almacenar los secretos requeridos:
    • Configura el entorno de GitHub para almacenar de forma segura los secretos necesarios, como tokens de autenticación y claves de configuración, para interactuar con la API de Devin y otras herramientas integradas.
Una vez que estos pasos estén completos, tu canalización estará lista para resolver problemas automáticamente usando la API de Devin, lo que acelerará el proceso y reducirá la necesidad de intervención manual.
  1. Probar la integración
Una vez que tu configuración esté completa, puedes probar la integración activando manualmente una GitHub Action. Esto te permitirá verificar que la acción invoque correctamente la API de Devin y resuelva los problemas identificados.
  1. Ver la página de sesiones de Devin
Después de que se active la GitHub Action y Devin procese los problemas, podrás ver el estado y los resultados en la página de sesiones de Devin. Esta página proporciona información detallada sobre los problemas resueltos y los cambios propuestos. Guía en profundidad Omite esta sección si tu proyecto de SonarQube ya está configurado correctamente. De lo contrario, lo siguiente explica cómo asegurarte de que GitHub tenga acceso a la API de SonarQube. Valores requeridos de SonarQube Para configurar la integración, deberás obtener los siguientes tres valores de tu instancia de SonarQube:

1. Crear SONAR_TOKEN:

  1. Haz clic en el ícono de tu cuenta en la esquina superior derecha de SonarQube.
  2. Selecciona Security en el menú desplegable.
  3. En Tokens, haz clic en Generate Tokens.
  4. Asigna un nombre al token y haz clic en Generate.
  • Copia el token generado para usarlo en GitHub Actions.
SonarQube

2. Crear SONAR_PROJECT

  1. Selecciona el proyecto en SonarQube.
  2. Haz clic en Information en la esquina inferior izquierda.
  3. Desplázate hacia abajo para encontrar la clave del proyecto.
SonarQube

3. Crear SONAR_ORG

Consulta los pasos anteriores para localizar los detalles de tu organización en SonarQube. Una vez que tengas todos los valores necesarios, estarás listo para configurar la GitHub Action.
Esto supone que tienes un archivo de propiedades local de SonarCloud sonar-project.properties que especifica:
sonar.projectKey={PROJECT_KEY}
sonar.sources=FILE_PATH (normalmente ".")
La GitHub Action tiene el siguiente código fuente:
name: Análisis de SonarCloud y Remediación con Devin
on:
  workflow_dispatch:
  push:
    branches:
      - '**'
  pull_request:
    branches:
      - '**'

jobs:
  analyze:
    name: Analizar y Remediar
    runs-on: ubuntu-latest

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

    - name: Análisis de 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: Configurar Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.x'

    - name: Instalar Dependencias
      run: pip install aiohttp

    - name: Configurar Git
      run: |
        git config --global user.name "GitHub Action"
        git config --global user.email "[email protected]"
    - name: Ejecutar Remediación con 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
A modo de recordatorio, devin_remediation.py
import asyncio
import aiohttp
import os
from datetime import datetime

# Variables de entorno
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():
    """Obtiene las vulnerabilidades abiertas de 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"Error al obtener los problemas de SonarCloud: {await response.text()}")
                return []
            result = await response.json()
            print(f"Se encontraron {len(result.get('issues', []))} problemas")
            return result.get('issues', [])

async def delegate_task_to_devin(issue):
    """Delega la tarea completa de corrección, commit y push a Devin AI."""
    async with aiohttp.ClientSession() as session:
        headers = {"Authorization": f"Bearer {DEVIN_API_KEY}"}
        prompt = f"""
        Corrige la siguiente vulnerabilidad en {GITHUB_REPOSITORY}: {issue['message']} en el archivo {issue['component']}.
        1. Crea una nueva rama llamada 'devin/{issue['key']}-fix-vulnerability'.
        2. Implementa la corrección.
        3. Escribe un mensaje de commit detallado que explique los cambios:
            - Clave del problema: {issue['key']}
            - Componente: {issue['component']}
            - Corregido por Devin AI el {datetime.now().isoformat()}
            - Incluye 'Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>'.
        4. Sube la rama al repositorio remoto.
        5. Abre un pull request con una descripción de la corrección.
        """

        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"Error al delegar la tarea a Devin: {await response.text()}")
                return None
            result = await response.json()
            print(f"Sesión de Devin creada: {result}")
            return result

async def monitor_devin_session(session_id):
    """Monitorea el progreso de Devin hasta que complete la tarea."""
    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"Error al monitorear la sesión de Devin: {await response.text()}")
                    return None

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

                if status in ["completed", "stopped"]:
                    print(f"Devin completó la tarea: {result}")
                    return result
                elif status == "blocked":
                    print("Devin encontró un problema. Verifica manualmente.")
                    return None

                await asyncio.sleep(5)

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

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

            # Delegar tarea a Devin AI
            session_data = await delegate_task_to_devin(issue)

            if session_data:
                session_id = session_data["session_id"]

                # Monitorear el progreso de Devin
                await monitor_devin_session(session_id)

    except Exception as e:
        print(f"Ocurrió un error: {str(e)}")
        raise

if __name__ == "__main__":
    asyncio.run(main())
Para asegurarte de que la GitHub Action configure las variables de entorno correctas, añádelas a los GitHub Repository Secrets. Llegar a la configuración correcta puede ser complicado. Ve a Security y edita Secrets. Agrega SONAR_TOKEN y DEVINS_API en Repository Secrets.
SonarQube
Una vez que hayas terminado la configuración, podrás monitorear tu GitHub Action en ejecución. Si se ejecuta correctamente, se verá de la siguiente manera:
SonarQube
Puedes ver las sesiones de Devin en el Session Manager.
SonarQube
Una vez que haya terminado, Devin abrirá automáticamente pull requests. Para usuarios de GitLab, consulta la guía enlazada.