CIでCobertura XMLを生成できているのに、プルリクエストのGitHub Code Qualityにカバレッジが表示されない場合は、XMLを作成しただけではGitHubへ登録されていない可能性があります。
表示に必要なのは、Cobertura XMLの生成に加えて、actions/upload-code-coverage@v1によるアップロード、code-quality: write権限、デフォルトブランチとPRブランチの両方での実行、リポジトリでのCode Quality有効化です。
GitHub Code Qualityは2026年7月20日に一般提供となり、GitHub TeamとGitHub Enterprise Cloudで、既存のCobertura XMLレポートをプルリクエスト上に表示できるようになりました。GitHub Enterprise Serverは一般提供開始時点では対象外です。(The GitHub Blog)
結論:Cobertura XMLは生成するだけでは表示されない
PRにカバレッジを表示するには、次の条件をすべて満たす必要があります。(GitHub Docs)
| 確認項目 | 必要な状態 |
|---|---|
| 利用プラン | GitHub TeamまたはGitHub Enterprise Cloud |
| Code Quality | 対象リポジトリで有効 |
| テスト実行環境 | GitHub Actions |
| レポート形式 | Cobertura XML |
| GitHubへの送信 | actions/upload-code-coverage@v1を実行 |
| Actions権限 | code-quality: writeを付与 |
| デフォルトブランチ | push時にもカバレッジをアップロード |
| PRブランチ | pull_request時にもカバレッジをアップロード |
特に間違えやすいのが、actions/upload-artifactとの違いです。
actions/upload-artifactは、XMLファイルをGitHub Actionsの成果物として保存するためのActionです。Code Qualityへカバレッジデータを登録する機能はありません。成果物として保存した後、別ジョブでactions/download-artifactを実行し、最終的にactions/upload-code-coverage@v1へ渡す必要があります。(GitHub)
GitHub Code Qualityがカバレッジを表示する仕組み
GitHub Code Qualityは、各ブランチについて最後にアップロードされたCobertura XMLを保持し、PRブランチのカバレッジをデフォルトブランチと比較します。
たとえば、デフォルトブランチが44%、PRブランチが65%なら、PRでは「21ポイント増加」として扱われます。変更されたファイルごとの増減も表示されます。(GitHub Docs)
そのため、PR側のワークフローだけを実行しても不十分です。比較元となるデフォルトブランチ側でも、一度はカバレッジレポートをアップロードする必要があります。
PRにCobertura XMLのカバレッジを表示する手順
Code Qualityをリポジトリで有効にする
リポジトリの管理権限を持つユーザーが、次の順番で設定します。
- 対象リポジトリを開く
Settingsを開く- 左側の
SecurityからCode qualityを選択する Enable code qualityをクリックする- 言語やRunnerの設定を確認する
Save changesをクリックする
Enterprise環境では、先にEnterprise ownerがCode Qualityの利用を許可している必要があります。また、Code Qualityの処理にはGitHub Actionsが使われるため、Actionsも有効でなければなりません。(GitHub Docs)
Cobertura XMLを生成する
GitHub Code Qualityへ送信できるのはCobertura XML形式です。テストツールが別形式を出力する場合は、Cobertura XMLへ変換します。
GitHub公式ドキュメントで示されている代表的な生成方法は次のとおりです。(GitHub Docs)
| 言語 | ツール | 生成例 |
|---|---|---|
| Python | pytest、pytest-cov | pytest --cov=. --cov-report=xml |
| JavaScript/TypeScript | Istanbul、nyc | nyc report --reporter=cobertura |
| Go | go test、gocover-cobertura | go test -coverprofile=cover.out && gocover-cobertura < cover.out > coverage.xml |
| Java | JaCoCo | cover2cover.pyや変換用Gradle/Mavenプラグインを使用 |
| Ruby | SimpleCov | Cobertura用Formatterを設定 |
生成後は、ファイル名だけで判断せず、中身と保存場所を確認してください。たとえば、次のステップを一時的に追加すると、ファイルが存在し、空ではなく、Cobertura XMLらしい内容を持っているかを確認できます。
- name: Verify Cobertura XML
run: |
test -s coverage.xml
grep -q "<coverage" coverage.xml
ls -lh coverage.xml
テストコマンドがreports/coverage.xmlへ出力しているのに、アップロード側でcoverage.xmlを指定していると失敗します。モノレポでは、実行ディレクトリの違いにも注意が必要です。
GitHub Actionsへアップロード処理を追加する
Pythonプロジェクトを例にすると、基本構成は次のようになります。
name: Code Coverage
on:
push:
branches:
- main
pull_request:
branches:
- main
permissions:
contents: read
code-quality: write
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout source
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest pytest-cov
- name: Run tests with coverage
run: pytest --cov=. --cov-report=xml
- name: Verify Cobertura XML
run: |
test -s coverage.xml
grep -q "<coverage" coverage.xml
- name: Upload coverage report
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
uses: actions/upload-code-coverage@v1
with:
file: coverage.xml
language: Python
label: code-coverage/pytest
この構成には、表示に必要な重要ポイントが含まれています。(GitHub Docs)
pushとpull_requestの両方で実行する
pushはデフォルトブランチの基準値を登録するために必要です。pull_requestはPRブランチの値を登録するために必要です。
リポジトリのデフォルトブランチがmasterやdevelopの場合は、例のmainを実際のブランチ名へ変更してください。
code-quality: writeを付与する
カバレッジデータのアップロードには、次の権限が必要です。
permissions:
contents: read
code-quality: write
ワークフロー全体ではなく、アップロードを行うジョブだけに設定しても構いません。code-quality: writeはAction自身では追加できないため、呼び出し側のワークフローまたはジョブで明示する必要があります。(GitHub)
PRのhead commitをチェックアウトする
通常のPRワークフローでは、GitHubが作成したマージコミットがチェックアウトされる場合があります。公式例では、カバレッジの行番号とPR差分を正しく対応させるため、PRのhead SHAを明示的に指定しています。(GitHub Docs)
- uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
カバレッジ率は表示されるものの、ファイル単位の差分や対象行が不自然な場合は、この設定を確認してください。
file、language、labelを正しく指定する
actions/upload-code-coverage@v1では、次の入力を指定します。
with:
file: coverage.xml
language: Python
label: code-coverage/pytest
fileにはCobertura XMLの実際のパスを指定します。languageにはPython、Java、Goなど、GitHub Linguistで使われる言語名を設定します。
公式Actionのメタデータでは、file、language、labelはいずれも必須入力として定義されています。ドキュメント上の説明にかかわらず、labelも省略せず設定するのが確実です。(GitHub)
CI成果物を別ジョブからアップロードする場合
テストとカバレッジアップロードを別ジョブに分離している場合は、XMLをジョブ間で引き継ぐ必要があります。
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v6
- name: Run tests
run: |
# テストを実行し、cobertura.xmlを生成する
./run-tests.sh
- name: Store Cobertura report
uses: actions/upload-artifact@v4
with:
name: cobertura-report
path: cobertura.xml
upload-coverage:
needs: build
runs-on: ubuntu-latest
permissions:
contents: read
code-quality: write
steps:
- name: Download Cobertura report
uses: actions/download-artifact@v4
with:
name: cobertura-report
- name: Upload coverage to Code Quality
uses: actions/upload-code-coverage@v1
with:
file: cobertura.xml
language: Java
label: code-coverage/tests
この場合、upload-artifactはジョブ間の受け渡しに使い、upload-code-coverageがCode Qualityへの登録を担当します。前者だけではPRにカバレッジは表示されません。(GitHub)
表示されないときは、この順番で確認する
Cobertura XMLの出力形式を確認する
最初に、生成されたファイルが本当にCobertura XMLかを確認します。
確認するポイントは次のとおりです。
- XMLファイルが空ではない
- ルート要素に
coverageがある - テスト終了後もファイルが残っている
- JaCoCo XML、LCOV、OpenCoverなど別形式のままではない
- ソースファイルのパスが現在のリポジトリ構成と対応している
拡張子を.xmlにしただけではCobertura形式にはなりません。JavaのJaCoCoなど、標準出力が別形式のツールでは変換処理が必要です。(GitHub Docs)
CI成果物とアップロードステップを確認する
次に、Actionsの実行ログでUpload coverage reportステップを開きます。
確認するポイントは次のとおりです。
actions/upload-code-coverage@v1が実行されているfileで指定したパスにXMLが存在する- テスト失敗によりアップロードステップがスキップされていない
- 別ジョブの場合は
download-artifactが成功している code-quality: writeが設定されている- アップロード後の処理が成功している
Actionは初期設定では、アップロードまたはGitHub側の処理に失敗するとステップを失敗させます。また、処理完了を最大160秒待機します。(GitHub)
次のようにfail-on-error: falseを設定している場合は、アップロードに失敗してもステップ自体が成功扱いになります。
- uses: actions/upload-code-coverage@v1
with:
file: coverage.xml
language: Python
label: code-coverage/pytest
fail-on-error: false
この設定を使っているときは、緑色のチェックだけで成功と判断せず、ログ内のerrorアノテーションも確認してください。
対象ブランチと実行イベントを確認する
その次に、デフォルトブランチとPRブランチの両方でアップロードされているかを確認します。
よくある設定ミスは次のとおりです。
pull_requestしか設定していないpush対象が実際のデフォルトブランチと異なるbranches: [main]のままだが、実際はmasterを使用している- PRのマージ先がワークフローの対象外になっている
- ワークフロー変更後、デフォルトブランチ側の処理を一度も実行していない
まずデフォルトブランチへワークフローを反映し、pushイベントでカバレッジを登録します。その後、PRへ新しいコミットをpushして再実行すると、比較元と比較先の両方をそろえられます。GitHub Code Qualityは各ブランチの最新アップロードを使って比較します。(GitHub Docs)
pushイベントだけでPRへの関連付けも行う構成では、Actionがgh pr listを使ってPR番号を検索します。その場合は、追加でpull-requests: readが必要です。(GitHub)
permissions:
contents: read
pull-requests: read
code-quality: write
Code Qualityの有効化状態を確認する
最後に、対象リポジトリがCode Qualityの適用対象になっているかを確認します。
リポジトリでは次の画面を開きます。
Settings
└ Security
└ Code quality
組織単位でCode Qualityを管理している場合は、組織のSettingsにあるCode qualityから、対象リポジトリがRepository accessの範囲に含まれているかも確認してください。
組織側で特定リポジトリのみを選択している場合や、フィルター条件で対象を限定している場合、リポジトリ管理者が設定を変更できないことがあります。大規模な組織では、設定変更の反映に数分かかる場合もあります。(GitHub Docs)
ForkからのPRでは表示されないことがある
公式のactions/upload-code-coverageは、Forkリポジトリから作成されたPRをサポートしていません。
Fork側のPRにはベースリポジトリへの書き込み権限がないため、Actionはカバレッジのアップロードをスキップします。この場合、ワークフロー全体を失敗させず、ログにスキップした旨を出力して正常終了します。(GitHub)
公式例にある次の条件は、Fork PRでアップロード処理を実行しないためのものです。
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
社内の同一リポジトリ内で作成したブランチでは表示されるのに、外部ForkからのPRだけ表示されない場合は、設定不良ではなくこの制限に該当している可能性があります。
また、merge queueのmerge_groupイベントでもカバレッジアップロードはスキップされます。カバレッジはPRとデフォルトブランチで登録する構成にしてください。(GitHub)
設定後にPRで確認する内容
設定が正しければ、ワークフロー完了後にgithub-code-quality[bot]がPRへコメントを投稿します。
コメントでは主に次の内容を確認できます。
- PRブランチ全体のカバレッジ率
- デフォルトブランチのカバレッジ率
- カバレッジの増減
- 変更ファイルごとのカバレッジ差分
カバレッジ率は、テストで実行された行数を対象行数で割って計算されます。PRでは単純な現在値だけでなく、デフォルトブランチに対して改善したか、低下したかを判断できます。(GitHub Docs)
まず確認すべきチェックリスト
CIでCobertura XMLが作成されているのにPRへ表示されない場合は、次の順番で切り分けると原因を見つけやすくなります。
- Cobertura XMLが実際に生成され、空ではない
actions/upload-artifactだけで終わっていないactions/upload-code-coverage@v1が実行されているfileが実際のXMLパスと一致しているcode-quality: writeが設定されている- デフォルトブランチのpushでもアップロードしている
- PRではhead commitをチェックアウトしている
- 対象リポジトリでCode Qualityが有効になっている
- Fork PRやmerge queueによるスキップではない
- Actionsログにアップロードや処理エラーがない
最初にXMLの形式、次にCI成果物の受け渡し、続いて対象ブランチ、最後にCode Qualityの有効化状態を確認してください。特に、XMLをActionsの成果物として保存することと、Code Qualityへアップロードすることは別処理である点が重要です。

コメント