😭

octocov 導入で5時間ハマった話

に公開

TL;DR

  • octocov をモノレポ構成で動かそうとしたら設定ファイルが見つからない地獄に落ちた
  • work-dir 指定で monorepo に対応できるはず
  • 原因は YAML ファイル内のタブ文字 だった
  • 最終的には想定通りシンプルな構成で動いた

背景

Go のプロジェクトに CI でカバレッジレポートを追加したくて、octocov を導入することにした。

プロジェクト構成はこんな感じ:

myapp/
├── backend/
│   ├── .octocov.yml      # ← ここに置きたい
│   └── (Go project files)
├── frontend/
│   └── (.octocov.yml)    # ← 将来的にここにも追加するかも?
└── .github/
    └── workflows/
        └── backend-ci.yml # ← ここから実行

理想的には backend/.octocov.yml に設定を置いて、将来 frontend/ 用の設定も分けたい。

地獄の始まり

試行 1: work-dir 指定だけ

- name: Run octocov
  uses: k1LoW/octocov-action@v1
  with:
    work-dir: backend

結果:
Github Actions は完遂するのだけれど、octocov からのコメントが投稿されない。
Actions の k1LoW/octocov-action@v1 のログを見ると気になる文言が。(まずこれに気がつくのに数時間かかった気がする)
.octocov.yml and .octocov.yaml and octocov.yml and octocov.yaml are not found

え、backend/.octocov.yml あるんだけど...?

試行 2: config で絶対パス指定

- name: Run octocov
  uses: k1LoW/octocov-action@v1
  with:
    config: backend/.octocov.yml
    work-dir: backend

結果: Error: open /home/runner/work/myapp/myapp/backend/backend/.octocov.yml: no such file or directory

なんで backend/backend/ になるんだよ!

試行 3: args で直接指定

- name: Run octocov
  uses: k1LoW/octocov-action@v1
  with:
    work-dir: backend
    args: --config=${{ github.workspace }}/backend/.octocov.yml

結果:

/usr/local/bin/octocov --config= --config=/home/runner/work/myapp/myapp/backend/.octocov.yml
.octocov.yml and .octocov.yaml and octocov.yml and octocov.yaml are not found

--config= が 2 回渡されてる!しかも空の方が先!

迷走

この辺から完全に混乱し始める。

  • .octocov.yml をルートにコピーして置いてみる → 見つからない
  • .octocov.yml をルートに置いてみる → 見つからない
  • 「これは完全に octocov のバグでは?」と疑い始める

デバッグステップ追加

- name: Debug - Check files
  run: |
    pwd
    ls -la | grep octocov || echo "No octocov files found"

結果:

/home/runner/work/myapp/myapp
-rw-r--r--  1 runner runner   648 Dec 18 11:06 .octocov.yml

ファイルは存在している!!!

もう意味がわからない。他のリポジトリでは同じ --config= (空) でも動いてるし...

真犯人

ふと、YAML の構文を疑ってみた。

タブ文字があった。

$ grep -n "^	" .octocov.yml
16:	if: true

octocov は設定ファイルをパースできず、なぜか
.octocov.yml and .octocov.yaml and octocov.yml and octocov.yaml are not found
と判断していたようだ。

スペースに修正:

testExecutionTime:
  if: true # タブ → スペース2つ

動いた。

最終的な構成

# .github/workflows/backend-ci.yml
- name: Run octocov
  uses: k1LoW/octocov-action@v1
  with:
    work-dir: backend
# backend/.octocov.yml
repository: ${GITHUB_REPOSITORY}/backend
coverage:
  paths:
    - coverage.out
codeToTestRatio:
  code:
    - "**/*.go"
    - "!**/*_test.go"
    - "!**/mock_*.go"
    - "!bob/**/*.go"
    - "!api/gen.go"
    - "!testutil/*.go"
  test:
    - "**/*_test.go"
testExecutionTime:
  if: true # ← ここ!スペース!
comment:
  if: is_pull_request

学び

  1. エラーメッセージを疑え - .octocov.yml and .octocov.yaml and octocov.yml and octocov.yaml are not found は必ずしも「ファイルが存在しない」を意味しない
  2. work-dir 後回しにすればもっと早く解決したはず - 最初から上手くやろうと思って work-dir を書いてたから、これが原因かと勘違いして時間を無駄にした
  3. 自分を疑え - octocov がバグってるはずがない。いつだって間違っているのは私

おまけ: わかったこと

YAML にタブは使えない

  • 長年触ってて初めて知ったのか、忘れてしまっていたのか分からないが、あ、そうなんだって思った。
  • たぶんどっかからコピペしたときにタブが混じってたっぽい。

octocov-action の挙動

  • config パラメータが未指定でも --config= (空) が付く
  • work-dir は octocov の実行ディレクトリを変更する

総括

5 時間かけてタブ 1 文字と戦った。

モノレポ全然関係なかったです。すみません。

私のような凡ミスをする人が他にいないとも限らないので、お役に立てたら幸いです。

Discussion