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の依存図とスケジュールの読み替えを別々に確認すると、自動化の設定ミスを減らせます。

matrix を使うとジョブはさらに増える

strategy.matrix を使うと、ひとつのジョブ定義から複数の実行(例:Node 18/20/22 × OS 3種)が展開されます。YAML上は数行でも、実際に動くのは何倍もの数になり、依存を頭の中で追うのはさらに難しくなります。

このとき、needs で matrix ジョブ全体を待つのか、特定の組み合わせだけを待つのかで挙動が変わります。図で依存を俯瞰しておくと、「build は本当に全matrixの完了を待つべきか」「一部だけ先に deploy できないか」といった見直しの糸口がつかめます。

ジョブが増えるほど、YAMLを読む力よりも「構造を絵にして見る」価値が上がります。CIの実行時間が気になり始めたら、まず依存図でボトルネックを探すのが近道です。

よくある質問

needs はどう読むと依存が分かりますか?

needs: lint は「そのジョブが lint の完了を待つ」という意味です。図にすると矢印で依存が表現され、どこが直列で、どこが並列なのかが一目で分かります。YAMLを上から追うより誤読が減ります。

並列にできるジョブはどう見つけますか?

同じ前提(たとえば lint の完了)だけに依存しているジョブは、並列で動かせる可能性があります。図で「lint だけを待つジョブ」が直列に並んでいたら、needs をそろえて並列化できないか検討すると、CI時間を縮められます。

失敗したとき、どのジョブが動くか分かりますか?

needs の依存先が失敗すると、後続のジョブはスキップされます。通知ジョブだけは if: always() を付けると失敗時にも動きます。依存図を見ると、ある失敗でどこまでがスキップされるかを読み取れます。

貼り付けたワークフローYAMLは外部に送信されますか?

いいえ。可視化はすべてブラウザ内で完結します。社内のworkflow定義やジョブ名を貼り付けても、サーバーへ送られることはありません。

関連ツール