GitHub Actionsのworkflowは、ジョブが増えるほど読みづらくなります。
特に needs が増えると、どのジョブが何を待っているのか、YAMLを上から読むだけでは把握しにくくなります。

GitHub Actions Visualizerを使うと、ジョブの依存関係をMermaidで確認できます。

こんなworkflowで迷いやすい

jobs:
  lint:
    runs-on: ubuntu-latest
  test:
    runs-on: ubuntu-latest
    needs: lint
  build:
    runs-on: ubuntu-latest
    needs: test
  deploy:
    runs-on: ubuntu-latest
    needs: build

このくらいなら読めますが、実際のworkflowでは linttestbuilde2edeploynotify が混ざります。
条件付き実行も入ると、失敗時にどこまで動くのかが分かりにくくなります。

実例:並列にできるジョブを見つける

次のように lintunit-testtypecheck がすべて直列になっているworkflowを見かけることがあります。

jobs:
  lint:
    runs-on: ubuntu-latest
  unit-test:
    runs-on: ubuntu-latest
    needs: lint
  typecheck:
    runs-on: ubuntu-latest
    needs: unit-test
  build:
    runs-on: ubuntu-latest
    needs: typecheck

実際には、unit-testtypecheck はどちらも lint の後に並列で動かせるかもしれません。

jobs:
  lint:
    runs-on: ubuntu-latest
  unit-test:
    runs-on: ubuntu-latest
    needs: lint
  typecheck:
    runs-on: ubuntu-latest
    needs: lint
  build:
    runs-on: ubuntu-latest
    needs: [unit-test, typecheck]

Visualizerで図にすると、直列化されすぎている箇所が目で分かります。CI時間を短くしたいときは、ステップの中身を最適化する前に、ジョブ依存が無駄に一直線になっていないかを見るのが効果的です。

まず依存だけを見る

最初に見るべきなのは、各ステップの中身ではなくジョブ同士の関係です。

flowchart LR
  lint --> test
  test --> build
  build --> deploy

この図があるだけで、失敗時の切り分けがしやすくなります。
たとえば build が動いていないなら、build 自体ではなく test の失敗を見るべきだと分かります。

レビューで見るポイント

  • 重いジョブが不要に直列化されていない
  • needs の指定漏れがない
  • deploy系のジョブが意図したチェックを待っている
  • 失敗時の通知ジョブが always() で動く設計になっている
  • 名前だけでは役割が分からないジョブがない

CIは動いている間は見落とされがちですが、壊れたときに構造の分かりやすさが効きます。
workflowを大きく変更するときは、先に図で依存関係を確認しておくのがおすすめです。

Cron系の自動化と分けて考える

GitHub Actionsには schedule トリガーもありますが、これは通常のCron式と同じく「いつ動くか」の確認が重要です。ジョブの順序はVisualizerで見て、実行時刻はCron式として別に確認すると、イベント駆動と時間駆動の問題を切り分けやすくなります。

たとえば、毎週月曜の深夜にレポート生成を動かす場合は、workflowの依存関係だけでなく、UTC基準の時刻になっているかも確認します。

on:
  schedule:
    - cron: "0 18 * * 0"

日本時間の月曜3時を狙っているなら、UTCでは日曜18時です。CIの依存図とスケジュールの読み替えを別々に確認すると、自動化の設定ミスを減らせます。

関連ツール