GitHub ActionsでOpenCodeに記事PRを自動レビューさせる
PR #24 で OpenCode を動かしたとき、レビューは始まりませんでした。Actions のコメントに残ったのは、次の 1 行です。
fatal: could not read Username for 'https://github.com': No such device or address
checkout 自体は成功していました。失敗したのは、その後に OpenCode が実行したgit fetch originです。actions/checkoutに認証情報を残し、runner の token をGITHUB_TOKENとTOKENへ渡す必要がありました。
この修正を記事へ同期したのが PR #26 です。その後、PR #27 で hibanas-net #15 の品質バーを自動レビューの prompt へ加えました。ここでは、2026 年 8 月 18 日時点の main にある 2 本の workflow を、そのまま使います。
前回から今回への差分
前回のGit管理ブログへ安全に書き込むcronでは、記事を content branch へ push するところまでを扱いました。
| 前回完了時 | 今回完了後 |
|---|---|
| 記事とOGをcontent branchへpushします | 記事PRを開くとOpenCodeが差分を読みます |
| 品質ゲートはローカルコマンドで実行します | hibanas-net #15の項目もPR上で検査します |
| GitHub側の失敗は人がActionsを開いて調べます | 認証失敗と権限不足の切り分け方が決まっています |
OpenRouter の secret を登録済みなら、「main の workflow を確認する」まで飛ばせます。
なぜTOKENとpersist-credentialsが要るのか
GitHub Actions は job ごとにGITHUB_TOKENを発行します。ただし、token が存在するだけではgit fetchに使われません。
actions/checkoutのpersist-credentials: trueは、checkout 後の Git コマンドでも認証情報を使えるようにします。OpenCode Action にはGITHUB_TOKENとTOKENの両方を渡します。今回使った Action が GitHub API と Git 操作で参照する変数名を揃えるためです。
自動レビュー側のcontentsはreadのままです。コメント起動側にはcontents: writeがあります。この 2 つを混ぜると、レビューだけの job にもファイル変更権限を渡してしまいます。
用語表
| 用語 | hibanas-netでの役割 |
|---|---|
| OpenCode | GitHub-hosted runnerでPR差分を読むエージェントです |
| OpenRouter | deepseek-v4-flash-0731へ接続するproviderです |
GITHUB_TOKEN | GitHubがjobごとに発行するrepository用tokenです |
TOKEN | OpenCode Actionへ同じrunner tokenを渡す環境変数です |
persist-credentials | checkout後のGitコマンドへ認証情報を残す設定です |
synchronize | PRのhead branchへ追加commitをpushしたときのeventです |
2本のworkflowを分ける
コメントに /oc または /opencode
└─ opencode.yml
└─ 明示された作業を実行できます
記事またはOGを変更したPR
└─ opencode-pr-review.yml
├─ PR差分だけを読みます
├─ #15とdocs/guidelines.mdを確認します
└─ コメントだけを投稿します
画面の説明用に生成画像は使っていません。実スクリーンショットを取れない箇所は、このテキスト図だけにしています。
mainのworkflowを確認する
記憶や過去 PR から YAML を写さず、origin/mainのファイルを読みます。hibanas-net で実行したコマンドは次の 2 つです。
git show origin/main:.github/workflows/opencode.yml
git show origin/main:.github/workflows/opencode-pr-review.yml
コメント起動用のopencode.yml
次のコードブロックは、main の.github/workflows/opencode.ymlと同じ内容です。
name: opencode
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
jobs:
opencode:
if: |
contains(github.event.comment.body, '/oc') ||
contains(github.event.comment.body, '/opencode')
runs-on: ubuntu-latest
permissions:
id-token: write
contents: write
pull-requests: write
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 1
persist-credentials: true
- name: Run OpenCode
uses: anomalyco/opencode/github@latest
env:
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
model: openrouter/deepseek/deepseek-v4-flash-0731
use_github_token: true
/ocか/opencodeを含むコメントで起動します。contents: writeがあるため、記事 PR を自動で読むだけの job には流用しません。
記事PR用のopencode-pr-review.yml
次のコードブロックも、main の.github/workflows/opencode-pr-review.ymlと同じ内容です。prompt には PR #27 で追加した hibanas-net #15 の品質バーが入っています。
name: opencode-pr-review
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
paths:
- "src/content/posts/**"
- "public/images/posts/**"
jobs:
review:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
pull-requests: write
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
persist-credentials: true
- name: Run OpenCode
uses: anomalyco/opencode/github@latest
env:
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
model: openrouter/deepseek/deepseek-v4-flash-0731
use_github_token: true
prompt: |
Review only this pull request's diff. Do not review unrelated files.
If the PR title, description, or changed content is Japanese, write the review in Japanese. Otherwise match the language of the PR.
Post one concise review comment only.
Do not merge the pull request.
Do not apply patches, edit files, or commit.
Do not dump secrets, tokens, or environment values.
Review posts against hibanas-net issue #15 and docs/guidelines.md. For each applicable post, treat every item below as required:
- Use consistent です・ます調 (desu/masu).
- Have full serial hands-on depth, not a short tips article.
- Include a table showing the delta from the previous installment to this one.
- Explain Why before How.
- Include a glossary, a text architecture diagram, runnable commands with honest expected output, clearly skippable sections, a common-errors table, and a primary-source references table.
- Keep draft: true. Flag changing it to draft: false or removing it unless the PR title or body explicitly says 公開 or publish.
- Require the OG image to be 16:9 with no article title or other typography baked in.
- Require procedure images to be real screenshots from reachable systems; generated procedure screenshots are prohibited. A text diagram is allowed when a real screen is unavailable.
Label any missing required quality-bar item as "required". Label subjective prose or style preferences as "nit".
Never return LGTM while any required item is missing.
A successful OpenCode review is not permission to publish the article.
pathsは記事と OG だけに反応します。synchronizeがあるため、指摘を直して同じ PR へ push すると再レビューが走ります。OpenCode が成功しても、merge や公開の許可にはなりません。
3本のPRで実動を確認する
main へ入った結果を、GitHub CLI で読み直します。この確認も hibanas-net で実行しました。
~/.local/bin/gh pr view 24 --repo dicekanbe/hibanas-net --json number,state,headRefName --jq '"#\(.number) \(.state) \(.headRefName)"'
~/.local/bin/gh pr view 26 --repo dicekanbe/hibanas-net --json number,state,headRefName --jq '"#\(.number) \(.state) \(.headRefName)"'
~/.local/bin/gh pr view 27 --repo dicekanbe/hibanas-net --json number,state,headRefName --jq '"#\(.number) \(.state) \(.headRefName)"'
実行結果は次のとおりです。
#24 MERGED content/2026-08-18-ai-agent-draft-approval-publish-gates
#26 MERGED content/2026-08-18-sync-opencode-workflow-article
#27 MERGED ci/opencode-review-issue-15-quality-bar
PR #24 では最初のgit fetch originが認証で失敗しました。PR #26 では、persist-credentials: true、GITHUB_TOKEN、TOKENを含む本番 YAML と記事を一致させました。PR #27 では、短い記事へ安易に LGTM を返さないよう、#15 の必須項目を prompt へ入れました。
よくあるエラー
| 症状 | 実際に確認する場所 | 対応 |
|---|---|---|
could not read Usernameで止まります | checkout後のgit fetch originです | persist-credentials: trueとTOKENを本番YAMLどおりに揃えます |
| OpenRouterの認証で止まります | Run OpenCode stepです | OPENROUTER_API_KEYのsecret名を確認します。値はログへ出しません |
| PRを開いても起動しません | PRのFiles changedです | 変更がsrc/content/posts/**かpublic/images/posts/**にあるか確認します |
| コメントを投稿できません | jobのpermissionsです | pull-requests: writeとissues: writeを確認します |
| 修正push後に動きません | pull_request.typesです | synchronizeを残します |
| 品質項目が抜けても通ります | promptです | PR #27後の#15項目とNever return LGTMを残します |
運用で残した境界
第三者 Action のanomalyco/opencode/github@latestは、参照先が将来変わります。固定運用へ進めるなら、動作確認した commit SHA へ切り替える余地があります。ただし、この記事では main に存在しない設定を完成形として書き足していません。
自動レビューjob のcontents: readも広げません。修正を頼む場合はコメント起動用 workflow へ明示します。レビューjob は、差分を読み、1 件のコメントを返すところで止めます。
出典
| 一次情報 | 確認した内容 |
|---|---|
| OpenCode公式ドキュメント: GitHub | GitHub Actions、use_github_token、custom prompt |
| GitHub Docs: GITHUB_TOKENで認証する | jobごとのtokenとpermissions |
| hibanas-net PR #24 | git fetch originで起きた認証失敗 |
| hibanas-net PR #26 | 記事と本番workflowの同期 |
| hibanas-net PR #27 | #15品質バーを含むprompt |
| hibanas-netのopencode.yml | コメント起動workflowの本番内容 |
| hibanas-netのopencode-pr-review.yml | 記事PRレビューworkflowの本番内容 |
