📦

octocovのcentral modeでmonorepoのカバレッジが収集できなかった話

に公開

はじめに

前回の記事では octocov 導入時に YAML のタブ文字で苦労しましたが、
今度こそ嘘じゃなく monorepo 構成での octocov(central mode) について書きます。

私の所属している会社では、複数のプロダクトのコードカバレッジを一元管理するために、octocov の central mode を導入しています。

octocov の central mode とは、複数リポジトリのカバレッジを集約する機能です。

各プロダクトでテスト実行時に生成されたカバレッジレポートを GitHub Actions の artifact としてアップロードし、central-coverage リポジトリで定期的に収集してバッジを生成しています。

今回、新しく monorepo 構成のプロダクト「myapp(仮)」を追加しようとしたところ、なぜかカバレッジが収集されず、バッジも生成されない問題に遭遇しました。この記事では、その原因と解決方法を共有します。

問題の状況

構成

  • myapp リポジトリ: monorepo 構成で、backend/ ディレクトリに Go のプロジェクトがある
  • デフォルトブランチ: develop
  • octocov 設定: backend/.octocov.yml に配置

症状

central-coverage の定期実行ログを見ると、他のプロダクトは正常に収集できているのに、myapp だけレポートが見つからない。

Collect report of owner/ababababa
2025/12/19 00:14:14 artifact name: octocov-report
Collect report of owner/urararara
2025/12/19 00:14:15 artifact name: octocov-report
2025/12/19 00:14:15 artifact name: octocov-report
Skip re storing report: central.reReport: is not set
Commit and push central report
No files to be commit

最後のところ、myapp のログかは断定できませんが、不自然なメッセージが出ていました。

原因の調査

myapp/backend での設定

前提として、myapp 側の設定を確認すると:

repository: ${GITHUB_REPOSITORY}/backend # owner/myapp/backend
diff:
  datastores:
    - artifact://${GITHUB_REPOSITORY} # owner/myapp
report:
  if: is_default_branch
  datastores:
    - artifact://${GITHUB_REPOSITORY} # owner/myapp

のようになっています。

なんとなく repository の書き方に合わせてみる

central 側の設定artifact://owner/myapp/backend にすべき?と思い変更してみたところ、

Collect report of owner/myapp
artifact name: backend
Skip re storing report: central.reReport: is not set
No files to be commit

myapp のところだけ artifact name: backend という謎のメッセージが出ていました。
行き当たりばったりじゃなくて、ちゃんと調べないとダメそうですね。

central の artifact 名の問題

octocov のドキュメント(GitHub Actions Artifacts)を見ると:

artifact://[owner]/[repo]

と指定した場合は、artifactName は octocov-report となることが分かります。

artifact://[owner]/[repo]/[artifactName]

と記述例があるため、

artifact://[owner]/[repo]/octocov-report-backend

と指定すれば、artifactName は octocov-report-backend を探しに行きます。

central 側の設定を見直してみました:

# central-coverage/.octocov.yml
central:
  reports:
    datastores:
-       - artifact://owner/myapp # ← これだとoctocov-reportを探しにいく
+       - artifact://owner/myapp/octocov-report-backend # ← これならoctocov-report-backendを探しにいく

これで octocov-report ではなく、octocov-report-backend を探しに行くため、monorepo 構成でも frontend と分けて取得できるはずです。

myapp リポジトリ
  ├── backend/.octocov.yml
  │   └── artifact にアップロード: octocov-report-backend
  └── (将来) frontend/.octocov.yml
      └── artifact にアップロード: octocov-report-frontend

central-coverage リポジトリが収集

monorepo での artifact 命名規則

そもそも、なぜ central から octocov-report が見つからなかったんでしょうか?

先ほどのmyapp 側の設定を見ると...:

repository: ${GITHUB_REPOSITORY}/backend # owner/myapp/backend
diff:
  datastores:
    - artifact://${GITHUB_REPOSITORY} # owner/myapp
report:
  if: is_default_branch
  datastores:
    - artifact://${GITHUB_REPOSITORY} # owner/myapp

のようになっていました。repository: の設定については、monorepo のドキュメントに記載されていたため、記述しました。
正直、設定した時点ではあまり意味がわかっていませんでしたが、artifact を確認してみたところ、artifact://owner/myapp/octocov-report-backend という名前でアップロードされることがわかりました。

※ 以下ついては README に記載が見つけられませんでした。間違いがありましたらすみません

octocov は以下のルールで artifact 名を決定しているようです:

octocov-report-{repository指定の末尾}

つまり:

  • repository: owner/myapp/backend の末尾は backend
  • デフォルトの artifact 名 octocov-report-backend が付く
  • 結果: octocov-report-backend

最終的な設定

myapp 側は問題ない:

# backend/.octocov.yml
repository: ${GITHUB_REPOSITORY}/backend # owner/myapp/backend
diff:
  datastores:
    - artifact://${GITHUB_REPOSITORY} # owner/myapp
report:
  if: is_default_branch
  datastores:
    - artifact://${GITHUB_REPOSITORY} # owner/myapp

central 側:

# central-coverage/.octocov.yml
central:
  reports:
    datastores:
      - artifact://owner/myapp/octocov-report-backend

まとめ

  • monorepo での artifact 名は自動的にサフィックスが付く
    • repository: owner/repo/subdir とすると、artifact 名は octocov-report-subdir になる
    • artifact://owner/repo/octocov-report-subdir のように明示する必要がある
  • いつこの問題に遭遇するか: monorepo + central mode の組み合わせ
  • トラブルシューティング: 「No files to be commit が出たら artifact 名を疑え」

おわりに

octocov の central mode は非常に便利ですが、monorepo 構成の場合は命名規則を理解しておく必要があります。

特に、repository: フィールドの末尾が artifact 名のサフィックスになるという仕様は、ドキュメントを読んでいてもわかりませんでした。

同じような問題で悩んでいる方の参考になれば幸いです!

参考リンク

Discussion