claude-code-actionをcronで回し、毎朝のコミットとIssueを要約する
claude-code-actionにscheduleとpromptを渡し、日本時間の毎朝9時にコミットとIssueの要約をログへ出す手順です。cronはUTCに換算して書きます。
anthropics/claude-code-actionにpromptを渡し、トリガーをscheduleにすると、毎朝決まった時刻にClaudeがリポジトリの動きを要約します。結果はコメントではなくワークフローの実行ログに出ます。通知もPRも増えないので、まず「昨日の動きを朝に読む」用途から始めるのに向いた形です。
ただし、プレーンテキストのpromptだけではClaudeはシェルもGitHub APIも使えません。--allowedToolsで使うツールを許可して初めて、コミットとIssueを読みにいけます。この記事は、その最小構成のYAMLと、許可を外したときの挙動、checkoutを省ける理由、cronが動かないときの切り分けをまとめます。
毎朝9時(日本時間)にコミットとIssueを要約するワークフロー
.github/workflows/daily-report.ymlとして置く最小の構成は次のとおりです。公式の例は"0 9 * * *"(9:00 UTC、日本時間の18:00)ですが、ここでは日本時間の9時に走るよう"0 0 * * *"(0:00 UTC)に換算してあります。
name: Daily Report
on:
schedule:
- cron: "0 0 * * *"
jobs:
report:
runs-on: ubuntu-latest
permissions:
contents: read
issues: read
id-token: write
steps:
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: "Generate a summary of yesterday's commits and open issues"
claude_args: |
--model claude-opus-5-5
--allowedTools "mcp__github__list_commits,mcp__github__list_issues"これは、GitHub Actions連携のドキュメントにある「Run on a schedule」の例から、cronの行だけを変えた形です。注目する行は4つあります。
このワークフローの要になる4行
on.schedule.cron
"0 0 * * *"は毎日0:00 UTC、つまり日本時間の9:00です。JSTはUTCより9時間進んでいるので、日本時間の時刻から9を引いてUTCに直します。公式の例の"0 9 * * *"をそのまま写すと、日本時間では18:00に走ります。prompt
この入力があると、Claudeは
@claudeの言及を待たずに動きます。要約したい内容を1文で書きます。--allowedTools
コミットとIssueを読むGitHub MCPツール2つだけを許可します。これが無いと、promptを実行する手段がありません。
permissions
contents: readとissues: readで、読み取りに必要な権限だけを渡します。id-token: writeも例に含まれており、GitHub Appによる既定の認証に必要な権限です。
時刻の換算だけは、読み飛ばすと朝に結果が届かなくなる部分です。cronはタイムゾーンを指定できず、UTCで書きます。
prompt付きのscheduleはなぜ自動で動くのか
このアクションは、ワークフローの設定から動作を決めます。prompt入力が無ければ、@claudeなどのトリガーフレーズを待つ対話モードです。promptがあれば、言及を待たない自動化モードで走ります。
自動化モードの出力先は、既定ではワークフローの実行ログです。日次レポートをログに留めるなら、何も足さなくて済みます。
scheduleには、実行者に関する制約もあります。アクションは起動前に2つの確認をします。
- 書き込み権限の確認:
scheduleのように人が起こしていないイベントでは省かれます - 人間の実行者かどうかの確認: ボットは
allowed_botsに載せない限り拒否されます
2つ目はscheduleにも効きます。GitHubは定期実行を、cron行を最後に変更したユーザーの実行として記録するのが通常です。そのユーザーがボットなら、allowed_botsに加えます。
--allowedToolsを外すとどうなるか
プレーンテキストのpromptでは、許可しないかぎりClaudeにシェルもGitHub APIもありません。上のYAMLから--allowedToolsの行だけを消すと、promptは「昨日のコミットを要約して」と頼んでいるのに、コミットを取りにいく手段がない状態になります。
落とし穴
許可の無いscheduleは、要約が出てこない
要約が出ないときは、まずclaude_argsの--allowedToolsに、読ませたい操作に対応するツール名が入っているかを確かめます。
許可の書き方は2通りあります。
| 書き方 | 置き場所 | 向く場面 |
|---|---|---|
--allowedTools | 置き場所claude_args | 向く場面ワークフロー内で完結させたいとき |
permissions.allow | 置き場所settings入力 | 向く場面許可を設定ファイルとして分けたいとき |
--allowedToolsはカンマ区切りで複数のツールを渡せ、--allowed-toolsの別名も使えます。settings入力にはJSON文字列か設定JSONファイルへのパスを渡せるので、許可を別ファイルに切り出すこともできます。ルールの書式は、権限設定のドキュメントにあるToolかTool(specifier)の形です。
settings: |
{"permissions": {"allow": ["mcp__github__list_commits", "mcp__github__list_issues"]}}ドキュメントのYAML例は--allowedToolsの版だけです。上のsettingsの書き方は、「permissions.allowルールでも許可できる」という説明と、Tool形式のルール書式に沿った構成例です。
許可は、必要最小限に絞るのが基本です。このワークフローが読むのはコミットとIssueの一覧だけなので、ツールも2つで足ります。シェルを丸ごと許可する必要はありません。
checkoutを省けるのはなぜか
通常のCIは、最初にactions/checkoutでリポジトリを取得します。この日次レポートの例にはその手順がありません。
理由は、ClaudeがGitHub MCPツールで、コミットとIssueをAPI経由で直接読むからです。ローカルにファイルを置く必要がないので、手順を1つ減らせます。
省いてよいのは、要約の材料がすべてAPIで取れるときです。ソースコードの中身を読ませたい、ファイルを編集させたい場合は、その作業をAPIで済ませられないので、チェックアウトの要否を別に考えます。ドキュメントの例は、チェックアウトなしで成立する読み取り専用の構成です。
promptを具体的にして、ログの読み味を揃える
例のpromptは1文で、書式の指定がありません。毎日読むログなので、項目の並びを決めておくと比べやすくなります。コミットとIssueの取得は許可した2ツールの範囲で済むので、promptでは「何をどの順で書くか」だけを足します。
prompt: |
Summarize yesterday's commits and the issues that are still open.
Output three sections in this order:
1. Commits: author, one-line summary
2. Open issues: number, title, label
3. Anything that needs a human decision today
Do not guess. If a tool returns nothing, write "none".最後の2行は、材料が無い日に作り話をさせないための指示です。許可の外にあるツールを使わせる指示は書いても実行できないので、promptと--allowedToolsは組で見直します。
skillに任せるときの許可の持ち方
プレーンテキストのpromptの代わりにskillを呼ぶ形でも、scheduleから動かせます。このときClaudeが使えるのは、skillのallowed-toolsフロントマターが許可したツールです。日次レポートを何度も育てるなら、promptをYAMLに直書きせず、skill側に手順と許可をまとめる方法があります。
結果をIssueやPRに投稿させたいとき
ログは実行履歴を開かないと読めません。チームで朝に共有したいなら、promptに「結果をIssueのコメントに書く」と指示し、投稿用のツールを--allowedToolsに足します。投稿用のツール名はGitHub MCPのツール一覧で確かめます。
書き込みを足すと、ワークフロー側のissues: readのままでは足りなくなります。許可を足すほど誤動作の影響も大きくなるので、権限も一緒に見直します。
cronが動かないときの切り分け
アクション側の設定より先に、GitHub側の条件を確かめます。
- 定期実行は、デフォルトブランチ上のワークフローだけが走ります。featureブランチに置いただけでは動きません
- 公開リポジトリでは、60日間リポジトリの動きが無いと、スケジュールが無効になります
- 実行者がボットのとき、
allowed_botsに載せていないと拒否されます
動作確認の段階では、cronを待たずに済ませたくなります。on:にworkflow_dispatchを足す手がありますが、これはGitHub Actions一般の機能で、アクションの仕様ではありません。
月の請求を抑える設定
毎日走る処理なので、1回あたりの上限を決めておくと安心です。コスト管理のドキュメントが挙げる手段のうち、日次レポートに効くのは次の3つです。
claude_argsに--max-turnsを足して、往復の回数に上限を付ける- ワークフローにタイムアウトを設定して、暴走を止める
- GitHubのconcurrency制御で、並列実行を絞る
--modelを省くと、Claude Codeの既定モデルが使われます。例のYAMLはclaude-opus-5-5を指定していますが、要約だけなら、モデルを小さいものへ変えて単価を下げる選択肢もあります。どのモデルが要約の質とコストの釣り合いに合うかは、実際に数日回して比べるしかありません。
認証にOAuthトークンを使うと、API課金ではなくClaudeのサブスクリプション枠で動きます。APIキーの管理を避けたい場合に選べます。キーやトークンは必ずGitHub Secretsに置き、リポジトリへは書きません。
アクションのパラメータ全体やclaude_argsの渡し方はGitHub Actionsのパラメータとclaude_argsの渡し方に表でまとまっています。action v1の全体像とheadless実行はClaude CodeをGitHub Actionsに組み込むにあります。
他の定期実行手段との使い分け
Claude Codeの定期実行には、GitHub Actionsのほかに複数の手段があります。ドキュメントは、セッションに縛られない定期実行の手段として、クラウドのスケジュールタスク、デスクトップのスケジュールタスク、GitHub Actionsのscheduleトリガーを並べています。
GitHub Actionsを選ぶ理由は、リポジトリのイベントと同じ場所で管理でき、ワークフローがコードと一緒にレビューされることです。ログも実行履歴に残ります。
一方、Coworkでレポートを組むならCowork Scheduled Tasksで定型レポートを自動化する実践パターンが、Agent SDK側の定期実行ならManaged Agentsのスケジュールデプロイをcronで定期実行するが近い話題です。
まとめ
この構成の落とし穴は、動かないことより「動いたのに想定と違う時刻・内容だった」ことです。公式の例は18:00 JSTに走るので、朝に読みたいなら、cronをUTCへ換算し直すのが最初の一手です。
ログだけの構成なら失敗しても被害は小さく済みます。書き込みを足す段階では、permissions・--allowedTools・promptの3つを同じコミットで変えると、どれが原因かを切り分けやすくなります。
参照した一次ソース
この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。