Skip to main content
La API de Devin es una herramienta muy potente. Lee el siguiente artículo antes de continuar con esta guía.

1. Descripción general del proceso

  1. Se abre un 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 la GitLab Action: La apertura del PR activa automáticamente un flujo de trabajo de GitLab Action.
  3. La GitLab Action llama a la Devin API: La GitLab Action envía una solicitud a la Devin API, transfiriendo los problemas identificados para su resolución automatizada.
  4. Se inicializa una sesión de Devin: Se inicia una sesión de Devin, que recibe el contexto del problema e intenta resolverlo basándose en 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 lograrlo

  1. Configurar el entorno de GitLab para almacenar los secretos requeridos:
    • Configura el entorno de GitLab 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 completes estos pasos, tu pipeline estará listo para resolver incidencias automáticamente usando la API de Devin, acelerando el proceso y reduciendo la necesidad de intervención manual.
  1. Probar la integración
Una vez que hayas finalizado la configuración, puedes probar la integración activando manualmente una GitLab Action. Esto te permitirá verificar que la acción llama correctamente a la API de Devin y resuelve las incidencias identificadas.
  1. Ver la página de sesiones de Devin
Después de que se active el GitLab Build y Devin procese las incidencias, podrás ver el estado y los resultados en la página de sesiones de Devin. Esta página proporciona información detallada sobre las incidencias resueltas y los cambios propuestos. Como se mencionó antes, los valores requeridos de SonarQube son: Para configurar la integración, deberás obtener los siguientes tres valores de tu instancia de SonarQube: Necesitarás tres_valores de SonarQube: {SONAR_TOKEN, SONAR_ORG, SONAR_PROJECT_KEY} Una vez que tengas todos los valores requeridos, estarás listo para configurar la GitLab Action.
Esto asume que tienes un archivo local de propiedades de SonarCloud sonar-project.properties que especifica:
sonar.projectKey={PROJECT_KEY}
sonar.sources=FILE_PATH (generalmente ".")
La GitLab Action tiene el siguiente código fuente
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
A modo de recordatorio, devin_remediation.py es lo siguiente:
python
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 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 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 corregir, hacer 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 explicando 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. Haz push de 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 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 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 GitLab Action establezca las variables de entorno correctas, agrégalas a los GitLab CI/CD Secrets. Llegar a la configuración correcta puede ser complicado. Ve a Settings y edita Secrets. Agrega SONAR_TOKEN y DEVINS_API en Repository Secrets.
SonarQube
Si usas GitLab autohospedado, entonces la única diferencia sería: Una vez configurado, puedes supervisar la ejecución de tu GitLab Action. Si se ejecuta correctamente, se verá de la siguiente manera:
SonarQube
Puedes ver las sesiones de Devin en el Session Manager.
SonarQube
Una vez completado, Devin abrirá automáticamente pull requests. Para usuarios de GitLab, consulta la guía.