Skip to main content
Devin の API は強力なツールです。このガイドを読み進める前に、まず次の記事をお読みください。

1. プロセス概要

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

2. この手順を完了するためのステップ

  1. 必要なシークレットを保持するために GitLab 環境を構成する:
    • Devin の API やその他の連携ツールとやり取りするために必要な認証トークンや設定キーなどのシークレットを安全に保存できるよう、GitLab 環境を設定します。
これらの手順が完了すると、パイプラインは Devin の API を使用して問題を自動的に解決できるようになり、処理の高速化と手動対応の削減につながります。
  1. 連携をテストする
セットアップが完了したら、GitLab Action を手動でトリガーして連携をテストできます。これにより、Action が正しく Devin API を呼び出し、検出された問題を解決できているかを検証できます。
  1. Devin Sessions ページを参照する
GitLab Build がトリガーされ、Devin が問題を処理した後は、Devin の Sessions ページでステータスと結果を確認できます。このページでは、解決された問題の詳細や、提案された変更内容を確認できます。 前述のとおり、SonarQube から取得する必要がある値は次のとおりです。 連携を構成するには、SonarQube インスタンスから次の 3 つの値を取得する必要があります: SONAR_TOKEN, SONAR_ORG, SONAR_PROJECT_KEY すべての必要な値がそろったら、GitLab Action を構成する準備が整います。
これは、sonar-project.properties というローカルの SonarCloud プロパティファイルがあり、そこで次の内容が指定されていることを前提としています:
sonar.projectKey={PROJECT_KEY}
sonar.sources=FILE_PATH (usually ".")
GitLab Action のソースコードは次のとおりです。
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
おさらいとして、devin_remediation.py は次のとおりです。
python
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())
GitLab Action が正しい環境変数を設定できるようにするには、それらを GitLab CI/CD Secrets に追加します。 目的の設定画面へ移動するのは少し分かりにくい場合があります。Settings に移動し、Secrets を編集します。Repository Secrets のセクションに SONAR_TOKENDEVINS_API を追加します。
SonarQube
セルフホスト型の GitLab を使用している場合、異なる点は次のとおりです。 設定が完了すると、実行中の GitLab Action を監視できます。正常に実行されると、次のように表示されます。
SonarQube
Session Manager で Devin のセッションを確認できます。
SonarQube
処理が完了すると、Devin は自動的にプルリクエストを作成します。GitLab のユーザーは、リンク先のガイドを参照してください。