13
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Last updated at Posted at 2025-06-01

はじめに

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<<EOF" >> $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<<EOF" >> $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<<EOF" >> $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<<EOF" >> $GITHUB_ENV:$GITHUB_ENVファイルにFAILED_LOGS<<EOFを追記
FAILED_LOGS<<EOF:環境変数FAILED_LOGSを設定
<<EOF:ヒアドキュメント、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の助けを借りながら知識を得ることができ、良い機会になりました。

参考

13
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?