👒

ClaudeCode+Amazon BedrockをGitHub Actionsで動かす(Claude Code Action&手動)

に公開

はじめに

Claude CodeをGitHubで動かせるClaude Code Actionsが出ましたね。

https://github.com/anthropics/claude-code-action

私はAnthropicのAPIをBedrock経由でアクセスしたいので、自分用の手順を用意します。

1. Claude Code Action

いきなりですが、記事を書くために調査していたら、既に他の方の記事が出ていたので書くことが無くなりました… せっかくなので利便性方向で差別化していきますか……

https://zenn.dev/339/articles/d297f2f7dd8619

使用感

使用感を先にざっくり書くと、GitHubのiPhoneアプリからVibe Codingができる。

このように音声入力で雑に指示を出す。

するとCIが発火し、Claudeが実装した結果を返信してくれる!

さらに「Create PR→」をクリックすると下書き済みのPullRequestの画面へ行くので、クリックするだけでPRを発行できる。(この辺自動でしてくれてもいいんだけど、便利は便利)

AWS CDK

以下の資材を使うことで、このあたりの煩雑な処理がシンプルになる。

  • OIDCプロバイダとしてGitHubを登録
  • Bedrockアクセス用のIAM Roleの作成
import * as cdk from 'aws-cdk-lib';
import * as iam from 'aws-cdk-lib/aws-iam';
import { Construct } from 'constructs';

export class CdkStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // 各自で変える
    const gitHubUser = 'hogehoge'
    const gitHubRepo = 'fugahuga'
    
    const githubOidcProvider = new iam.OpenIdConnectProvider(this, 'GitHubOidcProvider', {
      url: 'https://token.actions.githubusercontent.com',
      clientIds: ['sts.amazonaws.com'],
      thumbprints: ['6938fd4d98bab03faadb97b34396831e3780aea1', '1c58a3a8518e8759bf075b76b750d4f2df264fcd']
    });

    const trustPolicy = {
      StringEquals: {
        'token.actions.githubusercontent.com:aud': 'sts.amazonaws.com'
      },
      StringLike: {
        'token.actions.githubusercontent.com:sub': `repo:${gitHubUser}/${gitHubRepo}:*`
      }
    };

    const bedrockPolicy = new iam.Policy(this, 'BedrockPolicy', {
      statements: [
        new iam.PolicyStatement({
          effect: iam.Effect.ALLOW,
          actions: [
            'bedrock:InvokeModel',
            'bedrock:InvokeModelWithResponseStream'
          ],
          resources: ['*']
        })
      ]
    });

    const githubActionsRole = new iam.Role(this, 'GitHubActionsRole', {
      assumedBy: new iam.WebIdentityPrincipal(githubOidcProvider.openIdConnectProviderArn, trustPolicy),
      description: 'Role for GitHub Actions to access AWS services including Bedrock'
    });

    bedrockPolicy.attachToRole(githubActionsRole);

    new cdk.CfnOutput(this, 'GitHubActionsRoleArn', {
      value: githubActionsRole.roleArn,
      description: 'ARN of the role for GitHub Actions'
    });

    new cdk.CfnOutput(this, 'GitHubOidcProviderArn', {
      value: githubOidcProvider.openIdConnectProviderArn,
      description: 'ARN of the GitHub OIDC provider'
    });
  }
}

CIの例

こちらも紹介したブログとほぼ同じなのだが、大事な点として利用ユーザの制限がある。

例えばJobの発火条件がissue_commentであれば、このWorkFlowのようにgithub.event.issue.user.login条件を使って、不要なユーザからのいたずらを受けないように制限することが重要だ。

name: Claude Assistant
on:
  issue_comment:
    types: [created]

jobs:
  claude-code-action:
    if:
   # ここを反応しても良いGitHubのユーザに変える
      github.event.issue.user.login == 'user-name'
      && contains(github.event.comment.body, '@claude') 
    runs-on: ubuntu-latest
    env:
      ANTHROPIC_BEDROCK_BASE_URL: "https://bedrock-runtime.us-west-2.amazonaws.com"
    permissions:
      contents: read
      pull-requests: read
      issues: read
      id-token: write
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 1
      # For AWS Bedrock with OIDC
      - name: Configure AWS Credentials (OIDC)
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
          aws-region: us-west-2
          role-duration-seconds: 7200
          role-session-name: GitHubActions${{ github.run_id }}
          mask-aws-account-id: true
      
      - uses: anthropics/claude-code-action@beta
        with:
          model: "us.anthropic.claude-sonnet-4-20250514-v1:0"
          use_bedrock: "true"
          

memo

現在(v0.0.7)ではenvにANTHROPIC_BEDROCK_BASE_URLを設定しないとAmazon Bedrock経由では動かないバグがある。
ただ、対応するパッチが当たった次のリリースでは大丈夫になりそう。

https://github.com/anthropics/claude-code-base-action/pull/9

2. Claude CodeをCIに組み込む

元々この記事を書こうとしていたのだが、awslabs/mcpを参考にするとClaude CodeがCIで動く。当然Bedrockでも動く。

https://github.com/awslabs/mcp/blob/main/.github/workflows/claude.yml

GitHub Actions

こんな感じで@cli-claude入りのCommentが作られると動く、CIも作れた。

name: Claude Code Assistant
on:
  issue_comment:
    types: [created]

jobs:
  claude-assistant:
    if: >
      # ここを反応しても良いGitHubのユーザに変える
      github.event.issue.user.login == 'user-name' &&
      contains(github.event.comment.body, '@cli-claude')
    runs-on: ubuntu-latest
    env:
      # for Amazon Bedrock
      CLAUDE_CODE_USE_BEDROCK: 1
      ANTHROPIC_MODEL: us.anthropic.claude-sonnet-4-20250514-v1:0
      GH_TOKEN: ${{ github.token }}
      GITHUB_TOKEN: ${{ github.token }}
    permissions:
      id-token: write
      contents: read
      pull-requests: write
      checks: read
      issues: write 

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 1

      - name: Configure AWS Credentials (OIDC)
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
          aws-region: us-west-2
          role-duration-seconds: 3600
          role-session-name: GitHubActions${{ github.run_id }}
          mask-aws-account-id: true

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "22.x"

      - name: Install Claude CLI
        run: |
          npm install -g @anthropic-ai/claude-code --force --no-os-check
          claude --version
          claude config set hasTrustDialogAccepted true
      - name: Process Comment with Claude
        run: |
          CLAUDE_PROMPT="${{ github.event.comment.body }}"

          if [ -z "$CLAUDE_PROMPT" ]; then
            CLAUDE_PROMPT="Please help me with this issue or pull request."
          fi

          echo "$CLAUDE_PROMPT" | claude \
            --allowedTools \
            "\
            Bash,\
            Read,\
            Write,\
            Edit,\
            Create,\
            gh\
            " \
            --print --output-format json | tee output.json
          cat output.json |  jq -r '.result' > response.txt
          echo "" >> response.txt
          cat output.json | jq -r '"cost: \(.total_cost)"' >> response.txt
     
      - name: Post the response as a comment
        run: |
          if [ ! -s response.txt ]; then
            echo "skipped."
            exit 0
          fi

          # post
          RESPONSE=$(cat response.txt)
          gh issue comment "${{ github.event.issue.number }}" --body "$RESPONSE"

こんな感じ。修正しました!って言ってるけど特に修正をPushしてる様子はなくてウケる。(できた人教えて欲しい)

感想

実装したけどPullrequestやGitHubにコメントをストリーミングで書くとかは面倒なので、Vibe Coding的な動きは普通にClaude Code Actionを使った方がいい。

レビューくらいなら回りそうなので、カスタムしたい人はこっちかな。

Discussion