GitHub Code Quality REST API入門——FindingsをFirestoreへ同期する
GitHub Code Quality Findings REST APIのPublic Previewを踏まえ、Next.js + Firestoreで品質指摘を集計し、PR品質ゲートへつなげる実践手順を解説します。

はじめに
Next.jsのPRレビューで、こんな状態になっていませんか?
- PR上ではCode Qualityの指摘を見るが、長期傾向を追えていない
src/lib、app/api、componentsのどこに品質負債が多いか説明しにくい- PR品質ゲートを強めたいが、既存負債まで一気に止めるのは怖い
- AIエージェントに修正を任せる前に、対象を優先順位付けしたい
2026年6月23日、GitHubは Code Quality Findings REST API をPublic Previewとして公開しました。リポジトリ単位のFinding一覧と、単一Findingの詳細をREST APIで取得できるようになったため、GitHub UIの外で品質指摘を集計できます。
本記事では、架空の業務管理SaaS「KensaBoard」を題材に、Next.js App Router + Firestore + GitHub Actions + TypeScriptでCode Quality findingsを同期し、PR品質ゲートへつなげる手順を解説します。
参考にした一次情報は次の通りです。
- Fetch Code Quality findings via REST API
- REST API endpoints for code quality
- About GitHub Code Quality
- Setting up code coverage for your repository
- Setting code quality thresholds for pull requests
何が変わったのか
Code Qualityは、GitHub TeamまたはGitHub Enterprise Cloudのorganization-owned repository向けの品質分析機能です。公式ドキュメントでは、2026年7月20日にGAとなり、Public Preview中はGitHub Actions minutesを消費し、GA後は追加料金が発生すると説明されています。
今回のREST API追加で、次のような運用が組みやすくなりました。
| 観点 | 内容 | KensaBoardでの使い方 |
|---|---|---|
| 一覧取得 | GET /repos/{owner}/{repo}/code-quality/findings | 未解決Findingを日次同期 |
| 詳細取得 | GET /repos/{owner}/{repo}/code-quality/findings/{finding_number} | 修正IssueやAI依頼の材料にする |
| フィルタ | state=open / state=dismissed | 新規負債と対応済みを分ける |
| ページング | per_page と after / before | 100件ずつ安全に取得する |
| 権限 | Code qualityのread権限 | GitHub Appかfine-grained tokenで管理 |
事前準備
まず対象リポジトリでCode Qualityを有効化します。GitHub Docsでは、リポジトリの Settings > Code quality から有効化でき、organization単位の有効化手順も案内されています。
API認証では、classic PATならprivate/public repositoryに repo scope、public repositoryだけなら public_repo scopeが必要です。fine-grained tokenやGitHub App installation tokenでは、repository permissionとして Code quality: read を付与します。
実務では、ブラウザからGitHub APIを直接叩かない構成にします。KensaBoardでは、管理者限定のNext.js Route HandlerだけがGitHub APIトークンを持ち、GitHub Actionsのスケジュール実行からそのRoute Handlerを呼びます。
ハンズオン1: Firestoreの保存形式を決める
GitHub APIのレスポンスを丸ごと保存すると、画面や集計がAPI仕様に引きずられます。まずは使う項目だけを正規化します。
// src/types/codeQuality.ts
export type CodeQualityFinding = {
repository: string;
number: number;
state: "open" | "dismissed";
ruleId: string;
ruleTitle: string;
severity: string;
category: string;
path: string;
startLine: number;
message: string;
createdAt: string;
syncedAt: string;
};
Firestoreには codeQualityFindings コレクションを作り、ドキュメントIDは owner_repo_number のように決定的にします。同じFindingを毎日同期しても重複せず、最新状態だけを上書きできます。
| フィールド | 用途 |
|---|---|
repository | 複数リポジトリを横断集計する |
ruleId | 多発しているルールを見つける |
severity | PRブロック対象を決める |
path | app/api や src/lib など責務別に見る |
ハンズオン2: Next.jsでFindingsを同期する
次に、Code Quality findingsを取得するRoute Handlerを作ります。GitHub DocsのREST API例に合わせ、Accept: application/vnd.github+json と X-GitHub-Api-Version: 2026-03-10 を付けます。
// src/app/api/admin/code-quality/sync/route.ts
import { FieldValue } from "firebase-admin/firestore";
import { adminDb } from "@/lib/firebase/admin";
type GitHubFinding = {
number: number;
state: "open" | "dismissed";
rule: { id: string; title: string; severity: string; category: string };
location: { path: string; start_line: number };
message: { text: string };
created_at: string;
};
type SyncRequest = {
owner: string;
repo: string;
};
export async function POST(request: Request) {
const body = (await request.json()) as SyncRequest;
const token = process.env.GITHUB_CODE_QUALITY_TOKEN;
if (!token) {
return Response.json({ error: "token is not configured" }, { status: 500 });
}
const url = new URL(
`https://api.github.com/repos/${body.owner}/${body.repo}/code-quality/findings`,
);
url.searchParams.set("state", "open");
url.searchParams.set("per_page", "100");
const response = await fetch(url, {
headers: {
Accept: "application/vnd.github+json",
Authorization: `Bearer ${token}`,
"X-GitHub-Api-Version": "2026-03-10",
},
});
if (!response.ok) {
return Response.json({ error: `GitHub API ${response.status}` }, { status: 502 });
}
const findings = (await response.json()) as GitHubFinding[];
const batch = adminDb.batch();
for (const finding of findings) {
const docId = `${body.owner}_${body.repo}_${finding.number}`;
batch.set(
adminDb.collection("codeQualityFindings").doc(docId),
{
repository: `${body.owner}/${body.repo}`,
number: finding.number,
state: finding.state,
ruleId: finding.rule.id,
ruleTitle: finding.rule.title,
severity: finding.rule.severity,
category: finding.rule.category,
path: finding.location.path,
startLine: finding.location.start_line,
message: finding.message.text,
createdAt: finding.created_at,
syncedAt: FieldValue.serverTimestamp(),
},
{ merge: true },
);
}
await batch.commit();
return Response.json({ synced: findings.length });
}
100件を超えるリポジトリでは、afterカーソルを使ってページングします。また、実運用では管理者認可、対象リポジトリのallowlist、同期失敗ログを必ず入れます。
ハンズオン3: GitHub Actionsで毎朝同期する
同期APIは、GitHub Actionsのスケジュール実行から呼びます。GitHub API用トークンはNext.js側に置き、Actionsには同期API用の短い権限だけを渡します。
name: sync-code-quality
on:
schedule:
- cron: "15 22 * * *"
workflow_dispatch:
jobs:
sync:
runs-on: ubuntu-latest
steps:
- name: Sync findings
env:
SYNC_ENDPOINT: ${{ secrets.CODE_QUALITY_SYNC_ENDPOINT }}
SYNC_TOKEN: ${{ secrets.CODE_QUALITY_SYNC_TOKEN }}
run: |
curl -fsS -X POST "$SYNC_ENDPOINT" \
-H "Authorization: Bearer $SYNC_TOKEN" \
-H "Content-Type: application/json" \
-d '{"owner":"morison-example","repo":"kensaboard"}'
20〜30リポジトリを扱う場合は、3〜4件ずつバッチに分けます。Code Quality未有効化、権限不足、API一時失敗を個別に記録できるため、全体ジョブの再実行が楽になります。
ハンズオン4: coverageとPRしきい値へつなげる
Code QualityはcoverageアップロードやrulesetのPRしきい値とも組み合わせられます。公式ドキュメントでは、Cobertura XML形式のcoverageを actions/upload-code-coverage@v1 でアップロードする手順が案内されています。
permissions:
contents: read
code-quality: write
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v4
with:
node-version: 22
cache: yarn
- run: yarn install --frozen-lockfile
- run: yarn test:coverage
- uses: actions/upload-code-coverage@v1
with:
file: coverage/cobertura-coverage.xml
language: JavaScript
label: code-coverage/nextjs
いきなり全PRを止めるのではなく、30日分のFindingsをFirestoreに貯めてから段階的に強めます。
| フェーズ | 運用 |
|---|---|
| 1 | Firestore集計だけで多いルールとディレクトリを見る |
| 2 | Errors だけPRブロックする |
| 3 | 新規FindingをGitHub Issues化する |
| 4 | 一部リポジトリで Warnings and higher を試す |
まとめ
Code Quality Findings REST APIにより、GitHub上の品質指摘をNext.jsアプリやFirestoreの運用データとして扱いやすくなりました。
実務では、少数リポジトリでCode Qualityを有効化し、open findingsをFirestoreに同期します。そのうえでcoverageアップロードを追加し、30日ほど傾向を見てからPRしきい値を強めるのが安全です。
2026年7月20日のGA以降は追加料金が発生するため、どのリポジトリで何を品質ゲートにするかを決める必要があります。APIで傾向を可視化しておけば、品質ルールを感覚ではなくデータで調整できます。