Skip to main content
Devin の API は、SonarQube のようなコードスキャンツールによって検出されたコード上の問題を自動的に解決するために設計された強力な手段です。このドキュメントでは SonarQube に焦点を当てますが、基盤となる戦略は Veracode や Orca など、他のコードスキャンツールにも適用できます。 このプロセスが実際にどのように動作するかを確認したい場合は、デモリポジトリを参照し、Cognition のブログ記事で詳しい解説をご覧ください。 本番環境では、このプロセスは次のようになります。

Devin の API を用いたコード Issue の自動解決

本番環境では、Devin の API を使ってコード上の Issue を自動的に解決するプロセスは、シンプルかつ効率的です。以下では、その手順の大まかな流れを説明します。

1. プロセス概要

  1. Pull Request が作成される: コードスキャンツールによって問題が検出される可能性のある変更を含む Pull Request(PR)がリポジトリに送信されます。
  2. GitHub Action がトリガーされる: PR の作成をきっかけに、GitHub Action のワークフローが自動的に起動します。
  3. GitHub Action が Devin API を呼び出す: GitHub Action は Devin API にリクエストを送り、検出された問題を自動解決のために渡します。
  4. Devin セッションが初期化される: Devin セッションが立ち上がり、問題のコンテキストを受け取り、提供されたデータに基づいて解決を試みます。
  5. Devin が人間によるレビュー用の PR を提案する: 問題が解決されると、Devin は提案された変更を含む PR を生成し、人間によるレビューのために送信します。

2. これを実現するための手順

Devin の API を CI/CD パイプラインに統合するには、次の設定を行う必要があります。
  1. CI および API 連携用に SonarQube を構成する:
    • SonarQube が継続的インテグレーション (CI) と API 連携をサポートするように構成されていることを確認してください。API アクセス用に SonarQube をセットアップしたくない場合は、認証にクッキーを使用できます。このセットアップの詳細はこちら
  2. 必要なシークレットを保持する GitHub 環境を構成する:
    • Devin の API や他の連携ツールとやり取りするために必要な、認証トークンや設定キーなどのシークレットを安全に保存できるよう、GitHub 環境をセットアップします。
これらの手順が完了すると、パイプラインは Devin の API を使用して問題を自動的に解決できるようになり、プロセスが高速化されるとともに手動での対応が大幅に削減されます。
  1. 統合をテストする
セットアップが完了したら、GitHub Actions を手動トリガーして統合をテストできます。これにより、そのアクションが正しく Devin API を呼び出し、検出された問題を解決していることを確認できます。
  1. Devin Sessions ページを表示する
GitHub Actions がトリガーされ、Devin が問題を処理した後、Devin Sessions ページでステータスと結果を確認できます。このページでは、解決された問題と提案された変更についての詳細なインサイトが提供されます。 詳細ガイド すでに SonarQube プロジェクトが適切に構成されている場合は、このセクションはスキップしてください。そうでない場合は、GitHub から SonarQube の API にアクセスできるようにする方法を、以下で順を追って説明します。 SonarQube から必要な値
統合を構成するには、SonarQube インスタンスから次の 3 つの値を取得する必要があります。
SonarQube からは 3 つの値が必要です:

1. SONAR_TOKEN を作成する:

  1. SonarQube 画面右上のアカウントアイコンをクリックします。
  2. ドロップダウンから Security を選択します。
  3. Tokens セクションで Generate Tokens をクリックします。
  4. トークン名を入力し、Generate をクリックします。
  • GitHub Actions で使用するために、生成されたトークンをコピーします。
SonarQube

2. SONAR_PROJECT を作成する

  1. SonarQube でプロジェクトを選択します。
  2. 画面左下の Information をクリックします。
  3. 下にスクロールして、プロジェクトキー(project key)を確認します。
SonarQube

3. SONAR_ORG を作成する

上記の手順を参照して、SonarQube 内で組織情報を確認します。 必要な値がすべて揃ったら、GitHub Action を設定する準備が整いました。
ここでは、以下を指定したローカルの SonarCloud プロパティファイル sonar-project.properties があることを前提としています。
sonar.projectKey={PROJECT_KEY}
sonar.sources=FILE_PATH (通常は ".")
この GitHub Action のソースコードは次のとおりです。
name: SonarCloudスキャンとDevin修復
on:
  workflow_dispatch:
  push:
    branches:
      - '**'
  pull_request:
    branches:
      - '**'

jobs:
  analyze:
    name: 分析と修復
    runs-on: ubuntu-latest

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

    - name: 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: Pythonセットアップ
      uses: actions/setup-python@v5
      with:
        python-version: '3.x'

    - name: 依存関係インストール
      run: pip install aiohttp

    - name: Git設定
      run: |
        git config --global user.name "GitHub Action"
        git config --global user.email "[email protected]"
    - name: 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
念のため devin_remediation.py
import asyncio
import aiohttp
import os
from datetime import datetime

# 環境変数
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():
    """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"SonarCloudの問題取得エラー: {await response.text()}")
                return []
            result = await response.json()
            print(f"{len(result.get('issues', []))}件の問題を検出しました")
            return result.get('issues', [])

async def delegate_task_to_devin(issue):
    """修正、コミット、プッシュの全タスクをDevin AIに委任します。"""
    async with aiohttp.ClientSession() as session:
        headers = {"Authorization": f"Bearer {DEVIN_API_KEY}"}
        prompt = f"""
        {GITHUB_REPOSITORY}の以下の脆弱性を修正してください: ファイル{issue['component']}内の{issue['message']}。
        1. 'devin/{issue['key']}-fix-vulnerability'という名前の新しいブランチを作成してください。
        2. 修正を実装してください。
        3. 変更内容を説明する詳細なコミットメッセージを記述してください:
            - Issue Key: {issue['key']}
            - Component: {issue['component']}
            - Fixed by Devin AI at {datetime.now().isoformat()}
            - 'Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>'を含めてください。
        4. ブランチをリモートリポジトリにプッシュしてください。
        5. 修正内容の説明を含むプルリクエストを開いてください。
        """

        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"Devinへのタスク委任エラー: {await response.text()}")
                return None
            result = await response.json()
            print(f"Devinセッションを作成しました: {result}")
            return result

async def monitor_devin_session(session_id):
    """タスク完了までDevinの進捗を監視します。"""
    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"Devinセッション監視エラー: {await response.text()}")
                    return None

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

                if status in ["completed", "stopped"]:
                    print(f"Devinがタスクを完了しました: {result}")
                    return result
                elif status == "blocked":
                    print("Devinが問題を検出しました。手動で確認してください。")
                    return None

                await asyncio.sleep(5)

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

        for issue in issues:
            print(f"問題を処理中: {issue['key']}")

            # Devin AIにタスクを委任
            session_data = await delegate_task_to_devin(issue)

            if session_data:
                session_id = session_data["session_id"]

                # Devinの進捗を監視
                await monitor_devin_session(session_id)

    except Exception as e:
        print(f"エラーが発生しました: {str(e)}")
        raise

if __name__ == "__main__":
    asyncio.run(main())
GitHub Action が正しい環境変数を設定できるようにするには、それらを GitHub Repository Secrets に追加します。 目的の設定画面にたどり着くのは少し分かりづらいかもしれません。Security に移動し、Secrets を編集してください。Repository Secrets セクションに SONAR_TOKENDEVINS_API を追加します。
SonarQube
設定が完了したら、実行中の GitHub Action を確認できます。正常に実行されていれば、次のように表示されます。
SonarQube
Session Manager で Devin セッションを確認できます。
SonarQube
完了すると、Devin が自動的にプルリクエストを作成します。GitLab ユーザーは、こちらのガイドを参照してください。