> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devinenterprise.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Resolvendo Problemas do SonarQube Automaticamente

> Fazer o Devin resolver problemas do SonarQube por meio de GitHub Actions

A API do Devin é uma ferramenta poderosa criada para resolver automaticamente problemas de código detectados por ferramentas de análise de código, como o SonarQube. Embora esta documentação foque no SonarQube, a estratégia subjacente se aplica a outras ferramentas de análise de código, incluindo Veracode, Orca e outras.

Se você tiver interesse em ver esse processo em ação, confira nosso repositório de demonstração e leia a explicação detalhada no post do blog da Cognition.

Em produção, o processo será semelhante ao seguinte:

<div id="automated-issue-resolution-with-devins-api">
  # Resolução automática de problemas com a API do Devin
</div>

Em produção, o processo de resolver problemas de código automaticamente usando a API do Devin é simplificado e eficiente. Abaixo está uma visão geral, em alto nível, das etapas envolvidas:

<div id="1-process-overview">
  ### 1. Visão geral do processo
</div>

1. **Pull request é aberto**: Um pull request (PR) é enviado ao repositório com alterações que podem conter problemas identificados por uma ferramenta de análise de código.

2. **GitHub Action é disparado**: A abertura do PR dispara automaticamente um fluxo de trabalho (workflow) do GitHub Action.

3. **GitHub Action chama a API do Devin**: O GitHub Action envia uma requisição para a API do Devin, repassando os problemas identificados para resolução automatizada.

4. **Sessão do Devin é inicializada**: Uma sessão do Devin é iniciada, recebendo o contexto do problema e tentando resolvê-lo com base nos dados fornecidos.

5. **Devin propõe PR para revisão humana**: Assim que o problema é resolvido, o Devin gera um PR com as alterações propostas e o envia para revisão humana.

<div id="2-steps-to-accomplish-this">
  ### 2. Passos para realizar isso
</div>

Para integrar a API do Devin ao seu pipeline de CI/CD, você precisará concluir as seguintes configurações:

1. **Configurar o SonarQube para suporte a CI e API**:
   * Certifique-se de que o SonarQube esteja configurado para oferecer suporte à integração contínua (CI) e à integração via API. Se você preferir não configurar o SonarQube para acesso via API, poderá usar um cookie para autenticação. [Saiba mais sobre essa configuração aqui](#).

2. **Configurar o ambiente do GitHub para armazenar os segredos necessários**:
   * Configure o ambiente do GitHub para armazenar com segurança os segredos necessários, como tokens de autenticação e chaves de configuração, para interagir com a API do Devin e outras ferramentas integradas.

Quando essas etapas estiverem concluídas, seu pipeline estará pronto para resolver problemas automaticamente usando a API do Devin, acelerando o processo e reduzindo a necessidade de intervenção manual.

3. **Testar a integração**

Com a configuração concluída, você pode testar a integração acionando manualmente uma GitHub Action. Isso permitirá verificar se a Action chama corretamente a API do Devin e resolve os problemas identificados.

4. **Visualizar a página de sessões do Devin**

Depois que a GitHub Action for acionada e o Devin processar os problemas, você poderá visualizar o status e os resultados na página de sessões do Devin. Essa página fornece insights detalhados sobre os problemas resolvidos e as alterações propostas.

Guia detalhado

Pule esta seção se o seu projeto SonarQube já estiver configurado adequadamente. Caso contrário, o que segue descreve como garantir que o GitHub tenha acesso à API do SonarQube.

Valores necessários do SonarQube\
Para configurar a integração, você precisará obter os três valores a seguir da sua instância do SonarQube:

<div id="1-create-sonar_token">
  ### 1. Crie o **SONAR\_TOKEN**:
</div>

1. Clique no ícone da sua conta no canto superior direito do SonarQube.
2. Selecione **Security** na lista suspensa.
3. Em **Tokens**, clique em **Generate Tokens**.
4. Dê um nome ao token e clique em **Generate**.

* Copie o token gerado para usar no GitHub Actions.

<Frame>
  <img src="https://mintcdn.com/cognitionai-enterprise/oqBYXWmkhuOhl3HZ/images/SonarQubeImages/Onboarding-Token-SonarQube.png?fit=max&auto=format&n=oqBYXWmkhuOhl3HZ&q=85&s=261c24d698b1a017b47b10712d40eba6" alt="SonarQube" width="2988" height="1610" data-path="images/SonarQubeImages/Onboarding-Token-SonarQube.png" />
</Frame>

<div id="2-create-sonar_project">
  ### 2. Crie **SONAR\_PROJECT**
</div>

1. Selecione o projeto no SonarQube.
2. Clique em **Information** no canto inferior esquerdo.
3. Role para baixo para encontrar a chave do projeto.

<Frame>
  <img src="https://mintcdn.com/cognitionai-enterprise/oqBYXWmkhuOhl3HZ/images/SonarQubeImages/Onboarding-Project-SonarQube.png?fit=max&auto=format&n=oqBYXWmkhuOhl3HZ&q=85&s=6219dafe63fa21d57f9493c0939227ec" alt="SonarQube" width="2990" height="1702" data-path="images/SonarQubeImages/Onboarding-Project-SonarQube.png" />
</Frame>

<div id="3-create-sonar_org">
  ### 3. Crie **SONAR\_ORG**
</div>

Consulte as etapas acima para localizar os detalhes da sua organização no SonarQube.

Depois que você tiver todos os valores necessários, estará pronto para configurar a GitHub Action.

<Note>
  Pressupõe-se que você tenha um arquivo de propriedades local do SonarCloud `sonar-project.properties` que defina:

  ```
  sonar.projectKey={PROJECT_KEY}
  sonar.sources=FILE_PATH (normalmente ".")
  ```
</Note>

A GitHub Action tem o seguinte código-fonte

```
name: Análise do SonarCloud e Remediação do Devin
on:
  workflow_dispatch:
  push:
    branches:
      - '**'
  pull_request:
    branches:
      - '**'

jobs:
  analyze:
    name: Analyze and Remediate
    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: Setup Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.x'

    - name: Install Dependencies
      run: pip install aiohttp

    - name: Configure Git
      run: |
        git config --global user.name "GitHub Action"
        git config --global user.email "action@github.com"
    - name: Run Devin Remediation
      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
```

Lembrando, devin\_remediation.py

```
import asyncio
import aiohttp
import os
from datetime import datetime

# Variáveis de 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():
    """Busca vulnerabilidades abertas no 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"Erro ao obter issues do SonarCloud: {await response.text()}")
                return []
            result = await response.json()
            print(f"Encontradas {len(result.get('issues', []))} issues")
            return result.get('issues', [])

async def delegate_task_to_devin(issue):
    """Delega a tarefa completa de corrigir, fazer commit e push para o Devin AI."""
    async with aiohttp.ClientSession() as session:
        headers = {"Authorization": f"Bearer {DEVIN_API_KEY}"}
        prompt = f"""
        Corrija a seguinte vulnerabilidade em {GITHUB_REPOSITORY}: {issue['message']} no arquivo {issue['component']}.
        1. Crie uma nova branch chamada 'devin/{issue['key']}-fix-vulnerability'.
        2. Implemente a correção.
        3. Escreva uma mensagem de commit detalhada explicando as alterações:
            - Chave da Issue: {issue['key']}
            - Componente: {issue['component']}
            - Corrigido pelo Devin AI em {datetime.now().isoformat()}
            - Inclua 'Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>'.
        4. Faça push da branch para o repositório remoto.
        5. Abra um pull request com uma descrição da correção.
        """

        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"Erro ao delegar tarefa ao Devin: {await response.text()}")
                return None
            result = await response.json()
            print(f"Sessão do Devin criada: {result}")
            return result

async def monitor_devin_session(session_id):
    """Monitora o progresso do Devin até que ele conclua a tarefa."""
    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"Erro ao monitorar sessão do Devin: {await response.text()}")
                    return None

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

                if status in ["completed", "stopped"]:
                    print(f"Devin concluiu a tarefa: {result}")
                    return result
                elif status == "blocked":
                    print("Devin encontrou um problema. Verifique manualmente.")
                    return None

                await asyncio.sleep(5)

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

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

            # Delega tarefa ao Devin AI
            session_data = await delegate_task_to_devin(issue)

            if session_data:
                session_id = session_data["session_id"]

                # Monitora o progresso do Devin
                await monitor_devin_session(session_id)

    except Exception as e:
        print(f"Erro ocorrido: {str(e)}")
        raise

if __name__ == "__main__":
    asyncio.run(main())
```

Para garantir que a GitHub Action defina as variáveis de ambiente corretas, adicione-as em **GitHub Repository Secrets**.

Navegar até as configurações corretas pode ser complicado. Acesse **Security** e edite **Secrets**. Adicione **SONAR\_TOKEN** e **DEVINS\_API** em **Repository Secrets**.

<Frame>
  <img src="https://mintcdn.com/cognitionai-enterprise/oqBYXWmkhuOhl3HZ/images/SonarQubeImages/Onboarding-Repository-Secret.png?fit=max&auto=format&n=oqBYXWmkhuOhl3HZ&q=85&s=d0b5dfd32f76c7fbc25e600e2fd75b8a" alt="SonarQube" width="1562" height="664" data-path="images/SonarQubeImages/Onboarding-Repository-Secret.png" />
</Frame>

Depois de configurado, você pode monitorar a execução da sua GitHub Action. Se ela for executada com sucesso, ela aparecerá da seguinte forma:

<Frame>
  <img src="https://mintcdn.com/cognitionai-enterprise/oqBYXWmkhuOhl3HZ/images/SonarQubeImages/Sonarqube-Github-Action.png?fit=max&auto=format&n=oqBYXWmkhuOhl3HZ&q=85&s=80e1150ab575d2095b62446462eebdfd" alt="SonarQube" width="3412" height="1468" data-path="images/SonarQubeImages/Sonarqube-Github-Action.png" />
</Frame>

Você pode visualizar sessões do Devin no **Session Manager**.

<Frame>
  <img src="https://mintcdn.com/cognitionai-enterprise/oqBYXWmkhuOhl3HZ/images/SonarQubeImages/Devin-API-SonarQube.png?fit=max&auto=format&n=oqBYXWmkhuOhl3HZ&q=85&s=571a22298c7c58d45babbc29af8ba5bc" alt="SonarQube" width="1648" height="1688" data-path="images/SonarQubeImages/Devin-API-SonarQube.png" />
</Frame>

Quando terminar, o Devin abrirá PRs (pull requests) automaticamente. Para usuários do GitLab, consulte o [guia](/pt-BR/enterprise/use-cases/sonarqube/gitlab) correspondente.
