火曜日, 6月 3, 2025
- Advertisment -
ホームニューステックニュース【GitHub Actions + CI/CD】AIがワークフローエラーの解決方法を教えてくれる仕組みを作ってみた #初心者

【GitHub Actions + CI/CD】AIがワークフローエラーの解決方法を教えてくれる仕組みを作ってみた #初心者



【GitHub Actions + CI/CD】AIがワークフローエラーの解決方法を教えてくれる仕組みを作ってみた #初心者

GitHub ActionsでCI/CDを実現できるようになった今、pushする度にワークフローがエラーとなることが多々あります。
エラーが起きる度に原因を調べたり、AIに聞いたりしていたのですが、段々と面倒になってると感じていました。
そこで、GitHub Actionsのai-inferenceを使用して、エラーの原因と解消方法を自動で教えてもらうことはできないかと考え、AIと相談しながら実際に作成してみました。

CI/CDワークフロー(test-deploy.yml)が失敗した際に、エラーログを取得し、AIが自動で解析、ジョブの概要欄にて原因と解決方法を表示してくれます。

ai-failure-check.yml

ai-failure-check.yml

name: AI Failure check

on:
  workflow_run:
    workflows: "Test and Deploy"
    types:
      - completed

jobs:
  on-success:
    runs-on: ubuntu-latest
    if: ${{ github.event.workflow_run.conclusion == 'success' }}
    steps:
      - name: success
        run: |
          echo "trigger build workflow success"
  on-failure:
    runs-on: ubuntu-latest
    if: ${{ github.event.workflow_run.conclusion == 'failure' }}
    permissions:
      actions: read
      contents: read
      models: read
    steps:
      - name: failure
        run: |
          echo "trigger build workflow failed"

      - name: Checkout code
        uses: actions/checkout@v4

      - name: Get error info
        id: get-error
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          echo "::error::ワークフロー失敗"
          echo "branch: ${{ github.event.workflow_run.head_branch }}"

          # ワークフローの実行IDを取得
          RUN_ID=${{ github.event.workflow_run.id }}
          echo "RUN_ID: $RUN_ID"

          # ワークフロー情報を環境変数に保存
          echo "WORKFLOW_NAME=${{ github.event.workflow_run.name }}" >> $GITHUB_ENV
          echo "BRANCH_NAME=${{ github.event.workflow_run.head_branch }}" >> $GITHUB_ENV
          echo "COMMIT_SHA=${{ github.event.workflow_run.head_sha }}" >> $GITHUB_ENV

          # ジョブの一覧を取得
          JOBS=$(gh api repos/${{ github.repository }}/actions/runs/${RUN_ID}/jobs --jq '.jobs')

          # 失敗したジョブのログを取得
          echo "FAILED_LOGS> $GITHUB_ENV

          for job in $(echo "$JOBS" | jq -r '.[] | select(.conclusion == "failure") | .id'); do
            echo "=== Job ID: $job ===" >> $GITHUB_ENV
            gh api repos/${{ github.repository }}/actions/jobs/${job}/logs >> $GITHUB_ENV 2>&1 || echo "ログの取得に失敗しました" >> $GITHUB_ENV
            echo "" >> $GITHUB_ENV
          done

          echo "EOF" >> $GITHUB_ENV

      - name: Run AI check
        id: ai-check
        uses: actions/ai-inference@v1
        with:
          model: "openai/gpt-4o"
          prompt: |
            あなたは、エラー解決のプロです。初心者に向けてわかりやすくなぜエラーになったのか、どうすればエラーを解決できるかを教えてください。
            以下の形式で簡潔に(全体で10行以内)説明してください。
            エラーの内容は以下です。

            **失敗したワークフロー:**
            - ワークフロー名: ${{ env.WORKFLOW_NAME }}
            - ブランチ: ${{ env.BRANCH_NAME }}
            - コミットSHA: ${{ env.COMMIT_SHA }}
            - 使用技術: Vite, Supabase, Firebase

            **エラーログ:**
            ```
            ${{ env.FAILED_LOGS }}
            ```

            **回答形式フォーマット:**
            【原因】1-2行で説明
            【解決方法】具体的な手順を1-2個
            【予防策】1つだけ

      - name: Save AI response to summary
        if: always()
        run: |
          # GitHub Actionsのサマリーに出力(Web UIで確認可能)
          echo "## 分析結果" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo '${{ steps.ai-check.outputs.response }}' | base64 | base64 -d >> $GITHUB_STEP_SUMMARY

github.com_asa129_addiless-alcohol-app_actions_runs_15256956232.png

実際の流れ

①ワークフローエラー発生

test-deploy.yml実行時、project_testジョブでテストが失敗しています。

image.png

②AIにてワークフローエラー解析

test-deploy.yml実行後、ai-failure-check.ymlのワークフローが自動で起動、エラーログを取得します。

③分析した結果の表示

AI分析した結果(原因と対処方法)が概要欄に表示されます。

github.com_asa129_addiless-alcohol-app_actions_runs_15256956232.png

1. ワークフロー実行後をトリガーとする新規ワークフローの作成

ワークフローの完了をトリガーに別のワークフローを実行するために、workflow_runを使用しました。

ai-failure-check

name: AI Failure check

on:
  workflow_run:
    workflows: "Test and Deploy"
    types:
      - completed

jobs:
  on-success:
    runs-on: ubuntu-latest
    if: ${{ github.event.workflow_run.conclusion == 'success' }}
    steps:
      - name: success
        run: |
          echo "trigger build workflow success"
  on-failure:
    runs-on: ubuntu-latest
    if: ${{ github.event.workflow_run.conclusion == 'failure' }}
    steps:
      - name: failure
        run: |
          echo "trigger build workflow failed"

workflows:トリガーにするワークフロー名
types:- completed:ワークフロー実行後を指定

${{ github.event.workflow_run.conclusion == 'success' }}:ワークフローの実行結果を取得

動作確認

下記の画像はtest-deploy.yml(ワークフロー名:Test and Deploy)実行後です。
job名変えたよのコメントでpush後、エラーなくワークフローが完了しています。

image.png

その後、ai-failure-check.yml(ワークフロー名:AI Failure check)の結果を確認、Test and Deployがエラーなく完了しているため、on-successジョブが実行されました。

image.png

コンソールにもメッセージが表示されています。

image.png

2. エラーログ取得とAI解析の実装

1.で作成したワークフロー失敗時に実行されるジョブ(on-failure)にて、以下を追加しました。

  • permissions:ワークフローが他のリソースなどにアクセスする際の権限設定
  • steps

stepsは以下を追加

  1. failure:コンソールに失敗した旨を表示
  2. Checkout code:チェックアウトとリポジトリのアクセス許可
  3. Get error info:エラーログの取得
  4. Run AI check:AIの分析
  5. Save AI response to summay:分析結果を表示

ai-failure-check.yml

name: AI Failure check

on:
  workflow_run:
    workflows: "Test and Deploy"
    types:
      - completed

jobs:
  on-success:
    runs-on: ubuntu-latest
    if: ${{ github.event.workflow_run.conclusion == 'success' }}
    steps:
      - name: success
        run: |
          echo "trigger build workflow success"
  on-failure:
    runs-on: ubuntu-latest
    if: ${{ github.event.workflow_run.conclusion == 'failure' }}
    permissions:
      actions: read
      contents: read
      models: read
    steps:
      - name: failure
        run: |
          echo "trigger build workflow failed"

      - name: Checkout code
        uses: actions/checkout@v4

      - name: Get error info
        id: get-error
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          echo "::error::ワークフロー失敗"
          echo "branch: ${{ github.event.workflow_run.head_branch }}"

          # ワークフローの実行IDを取得
          RUN_ID=${{ github.event.workflow_run.id }}
          echo "RUN_ID: $RUN_ID"

          # ワークフロー情報を環境変数に保存
          echo "WORKFLOW_NAME=${{ github.event.workflow_run.name }}" >> $GITHUB_ENV
          echo "BRANCH_NAME=${{ github.event.workflow_run.head_branch }}" >> $GITHUB_ENV
          echo "COMMIT_SHA=${{ github.event.workflow_run.head_sha }}" >> $GITHUB_ENV

          # ジョブの一覧を取得
          JOBS=$(gh api repos/${{ github.repository }}/actions/runs/${RUN_ID}/jobs --jq '.jobs')

          # 失敗したジョブのログを取得
          echo "FAILED_LOGS> $GITHUB_ENV

          for job in $(echo "$JOBS" | jq -r '.[] | select(.conclusion == "failure") | .id'); do
            echo "=== Job ID: $job ===" >> $GITHUB_ENV
            gh api repos/${{ github.repository }}/actions/jobs/${job}/logs >> $GITHUB_ENV 2>&1 || echo "ログの取得に失敗しました" >> $GITHUB_ENV
            echo "" >> $GITHUB_ENV
          done

          echo "EOF" >> $GITHUB_ENV

      - name: Run AI check
        id: ai-check
        uses: actions/ai-inference@v1
        with:
          model: "openai/gpt-4o"
          prompt: |
            あなたは、エラー解決のプロです。初心者に向けてわかりやすくなぜエラーになったのか、どうすればエラーを解決できるかを教えてください。
            以下の形式で簡潔に(全体で10行以内)説明してください。
            エラーの内容は以下です。

            **失敗したワークフロー:**
            - ワークフロー名: ${{ env.WORKFLOW_NAME }}
            - ブランチ: ${{ env.BRANCH_NAME }}
            - コミットSHA: ${{ env.COMMIT_SHA }}
            - 使用技術: Vite, Supabase, Firebase

            **エラーログ:**
            ```
            ${{ env.FAILED_LOGS }}
            ```

            **回答形式フォーマット:**
            【原因】1-2行で説明
            【解決方法】具体的な手順を1-2個
            【予防策】1つだけ

      - name: Save AI response to summary
        if: always()
        run: |
          # GitHub Actionsのサマリーに出力(Web UIで確認可能)
          echo "## 分析結果" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo '${{ steps.ai-check.outputs.response }}' | base64 | base64 -d >> $GITHUB_STEP_SUMMARY

permissions

permissions:ワークフローがGitHubのリソースやAPIにアクセスする際の権限を設定する

permissions:
      actions: read
      contents: read
      models: read

公式ドキュメントより引用

permissions を使用して GITHUB_TOKEN に付与された既定のアクセス許可を変更し、必要に応じてアクセスを追加または削除することで、必要最小限のアクセスのみを許可することができます。
read (該当する場合)、write、または none のいずれかのアクセス レベルを割り当てることができます。

actions:GitHub Actions を操作します。
contents:リポジトリの内容を操作します。
models:GitHub Models を使用して AI 推論応答を生成します。たとえば、models: read は、GitHub Models 推論 API を使用するアクションを許可します。

steps

name: failure

コンソール上にtrigger build workflow failedを表示する

    steps:
      - name: failure
        run: |
          echo "trigger build workflow failed"

name: Checkout code

チェックアウトとリポジトリのアクセスをできるようにする

      - name: Checkout code
        uses: actions/checkout@v4

READMEより引用

このアクションは$GITHUB_WORKSPACE配下のリポジトリをチェックアウトし、ワークフローがリポジトリにアクセスできるようにします。

name: Get error info

id:ステップの一意な識別子

- name: Get error info
        id: get-error

env:ワークフロー内で使用できる変数を定義

        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

公式ドキュメントより引用

env:ワークフロー中のすべてのジョブのステップで使うことができる変数の map です

GITHUB_TOKENはワークフロー開始時に自動で作成してくれます。
${{ secrets.GITHUB_TOKEN }} で定義し、使用します。

各ワークフロー ジョブの開始時に、GitHub によって、ワークフローで使用する一意の GITHUB_TOKEN シークレットが自動的に作成されます。

${{ secrets.GITHUB_TOKEN }} を使って、GITHUB_TOKEN を使用できます。

ワークフローの実行IDを取得

github.event.workflow_run.~workflow_run:で指定したワークフロー情報(今回の場合はTest and Deployの実行結果を格納してくれる)
head_branch:実行されたブランチ名
id :ワークフロー実行ID

        run: |
          echo "::error::ワークフロー失敗"
          echo "branch: ${{ github.event.workflow_run.head_branch }}"

          # ワークフローの実行IDを取得
          RUN_ID=${{ github.event.workflow_run.id }}
          echo "RUN_ID: $RUN_ID"

ワークフロー情報を環境変数に保存

github.event.workflow_run.~workflow_run:で指定したワークフロー情報(今回の場合はTest and Deployの実行結果を格納してくれる)
name:ワークフロー名
head_branch:実行されたブランチ名
head_sha:コミットしたときのハッシュ値

echo "WORKFLOW_NAME=${{ github.event.workflow_run.name }}" >> $GITHUB_ENV

>>:ファイルに追記するシェルコマンド(>の場合は上書き)

  1. $GITHUB_ENVファイルを作成、WORKFLOW_NAME=${{ github.event.workflow_run.name }}を記載、保存
  2. WORKFLOW_NAME=${{ github.event.workflow_run.head_branch }}を追記
  3. WORKFLOW_NAME=${{ github.event.workflow_run.head_sha }}を追記
          # ワークフロー情報を環境変数に保存
          echo "WORKFLOW_NAME=${{ github.event.workflow_run.name }}" >> $GITHUB_ENV
          echo "BRANCH_NAME=${{ github.event.workflow_run.head_branch }}" >> $GITHUB_ENV
          echo "COMMIT_SHA=${{ github.event.workflow_run.head_sha }}" >> $GITHUB_ENV
ジョブの一覧を取得

GitHub CLI(gh)を使ってapiを呼び出す

gh api repos/${{ github.repository }}/actions/runs/${RUN_ID}/jobs

          # ジョブの一覧を取得
          JOBS=$(gh api repos/${{ github.repository }}/actions/runs/${RUN_ID}/jobs --jq '.jobs')

gh: GitHub CLIを使用するコマンド
api: APIを呼び出す
repos/\\${{ github.repository }}/actions/runs/${RUN_ID}/jobs: エンドポイント、実行したワークフローのjobを取得

失敗したジョブのログを取得
          # 失敗したジョブのログを取得
          echo "FAILED_LOGS> $GITHUB_ENV

          for job in $(echo "$JOBS" | jq -r '.[] | select(.conclusion == "failure") | .id'); do
            echo "=== Job ID: $job ===" >> $GITHUB_ENV
            gh api repos/${{ github.repository }}/actions/jobs/${job}/logs >> $GITHUB_ENV 2>&1 || echo "ログの取得に失敗しました" >> $GITHUB_ENV
            echo "" >> $GITHUB_ENV
          done

          echo "EOF" >> $GITHUB_ENV

echo "FAILED_LOGS> $GITHUB_ENV:$GITHUB_ENVファイルにFAILED_LOGS
FAILED_LOGS:環境変数FAILED_LOGSを設定
:ヒアドキュメント、EOFという文字列が現れるまで、複数行の値として扱う

          for job in $(echo "$JOBS" | jq -r '.[] | select(.conclusion == "failure") | .id'); do
            echo "=== Job ID: $job ===" >> $GITHUB_ENV
            gh api repos/${{ github.repository }}/actions/jobs/${job}/logs >> $GITHUB_ENV 2>&1 || echo "ログの取得に失敗しました" >> $GITHUB_ENV
            echo "" >> $GITHUB_ENV
          done

          echo "EOF" >> $GITHUB_ENV

$JOBS:ジョブ一覧を格納
jq -r '.[]jq jsonを取り扱うコマンド、-r オプションを直接取り扱う、.[]JSON配列の各要素をループして取り出す
select(.conclusion == "failure"):conclusionが”failure”のもののみ取得
.id:idだけ取り出す
取り出したものはjobに格納

echo "=== Job ID: $job ===" >> $GITHUB_ENV:=== Job ID: $job ===取り出したjob(id)をGITHUB_ENVに追記

gh api repos/${{ github.repository }}/actions/jobs/${job}/logs >> $GITHUB_ENV 2>&1 || echo "ログの取得に失敗しました" >> $GITHUB_ENV
idのlogsをGITHUB_ENVに追記、2>&1は2は標準エラー出力、>&1は標準出力にリダイレクトする(エラーメッセージも通常の出力としてファイルに書き込む)
|| はOR演算子、左側のコマンドが失敗したら(false)の右側の処理を行う

|:YAMLの複数行記法

name: Run AI check

uses: actions/ai-inference@v1を指定
model: AIのモデルを指定
prompt:プロンプトを指定

      - name: Run AI check
        id: ai-check
        uses: actions/ai-inference@v1
        with:
          model: "openai/gpt-4o"
          prompt: |
            あなたは、エラー解決のプロです。初心者に向けてわかりやすくなぜエラーになったのか、どうすればエラーを解決できるかを教えてください。
            以下の形式で簡潔に(全体で10行以内)説明してください。
            エラーの内容は以下です。

            **失敗したワークフロー:**
            - ワークフロー名: ${{ env.WORKFLOW_NAME }}
            - ブランチ: ${{ env.BRANCH_NAME }}
            - コミットSHA: ${{ env.COMMIT_SHA }}
            - 使用技術: Vite, Supabase, Firebase

            **エラーログ:**
            ```
            ${{ env.FAILED_LOGS }}
            ```

            **回答形式フォーマット:**
            【原因】1-2行で説明
            【解決方法】具体的な手順を1-2個
            【予防策】1つだけ

name: Save AI response to summary

if: always()前のステップに関係なくステップを実行できる

GITHUB_STEP_SUMMARYに追加することでジョブの概要に出力することができる

      - name: Save AI response to summary
        if: always()
        run: |
          # GitHub Actionsのサマリーに出力(Web UIで確認可能)
          echo "## 分析結果" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo '${{ steps.ai-check.outputs.response }}' | base64 | base64 -d >> $GITHUB_STEP_SUMMARY

GitHub Actionsの新しいトリガーやGitHubCLI、シェルスクリプトなど新しい知識を得ることができました。
自分のリサーチだけでは今回の仕組みはできなかったです。AIの助けを借りながら知識を得ることができ、良い機会になりました。





Source link

Views: 3

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -