GitHub Actions でテスト実行を tee で標準出力しつつファイルに出力するようにしました。
jobs: build: name: Build runs-on: ubuntu-latest steps: - name: Test & report run: | go test . -v 2>&1 | tee result.txt :
出力されたファイルをレポーティング用のツールで加工してテスト結果レポートなどの成果物を作成したいためです。
しかし、テストが失敗してもワークフローが success()
になってしまいます。
run: | go test . -v 2>&1; test $? -ne 0 && exit 1 | tee result.txt
とかやるとテスト失敗したらfailure()
にはなりますが、意図した内容がファイルに出力されません。
次のようにリダイレクトではちゃんとエラーになってくれます。
run: | go test . -v 2>&1 > result.txt :
GitHub Actions の run ではコマンドパイプの途中の処理でエラーになっても終端の処理が成功しているとジョブステータスも success()
になってしまうようです。ワンライナーで色々やりたい場合、ちょっと不便ですね。
テストの失敗はジョブのステータスとして検出したいのでテスト実行のみの step とテスト&レポート作成の step に分割しました。
jobs: build: name: Build runs-on: ubuntu-latest steps: - name: Test run: | go test . -v - name: Test & report run: | go test . -v 2>&1 | tee result.txt :
この場合 test が失敗するとワークフロー自体は終了するので後続のテスト&レポート作成 step は実行されません。失敗成功にかかわらず後続の step を実行したい場合は、実行条件に always()
を指定することで実行を強制可能です。
jobs: build: name: Build runs-on: ubuntu-latest steps: - name: Test run: | go test . -v - name: Test & report if: always() run: | go test | tee result.txt :
後続の step が成功しても、それ以前の step がエラーになっていればジョブ自体は failure()
になります。
テストを2回実行するコストが許容できない場合、テスト結果をファイルにリダイレクトして後続の step でログ出力するというやり方も考えられます。
jobs: build: name: Build runs-on: ubuntu-latest steps: - name: Test & report run: | go test . -v 2>&1 > result.txt : - name: Print test result if: always() run: cat result.txt
この方法だとエラーが発生してもログ出力の step は成功するためログがどこに出ているのかわかりづらいという問題はあります。