電通総研 テックブログ

電通総研が運営する技術ブログ

GitHub Actions ワークフロー設計のTips ~スムーズな依存関係管理と並列実行~

こんにちは。XI 本部 AIトランスフォーメーションセンター所属の山田です。

今回は比較的にライトな内容で、GitHub Actionsのワークフロー設計のTipsを紹介したいと思います。

紹介するワークフロー

ここで紹介するワークフローは、Node.js系アプリケーションで静的解析、テスト、ビルド実行を想定したものになります。

依存関係インストール用のジョブ

このワークフローの特徴は、依存関係の解決に重点を置き、取得した依存関係をキャッシュエントリに追加することを目的とするsetupジョブを配置している点です。

setupジョブの定義部分を抜粋すると以下になります。

jobs:
  setup:
    runs-on: ubuntu-latest
    defaults:
      run:
        shell: bash

    steps:
    - name: Check out repository
      uses: actions/checkout@v3

    - name: Set up Node.js
      uses: actions/setup-node@v2
      with:
        node-version:  ${{ env.NODE_VERSION }}
        cache: 'yarn'
        cache-dependency-path: '**/yarn.lock'

    - name: Get yarn cache directory path
      id: yarn-cache-dir-path
      run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT

    - uses: actions/cache@v3
      id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
      with:
        path: |
          **/node_modules
          ${{ steps.yarn-cache-dir-path.outputs.dir }}
        key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}

    - name: Install dependencies
      if: steps.yarn-cache.outputs.cache-hit != 'true'
      run: yarn

setupジョブでの依存関係の解決部分でもキャッシュがヒットする場合は、キャッシュを利用するようにしています。

静的解析、テスト、ビルドのジョブの並列実行

静的解析、テスト、ビルドの3つのジョブはそれぞれ独立して実行可能なため並列に実行します。
GitHub Actionsでは依存関係を指定しない限りジョブは並列に実行されます。

それぞれのジョブ定義でneeds: setupと記述します。

  lint:
    needs: setup
    # 省略

  test:
    needs: setup
    # 省略

  build:
    needs: setup
    # 省略

ジョブの依存関係にsetupジョブに指定しているため、各ジョブの依存関係の解決時には常にキャッシュが利用され、処理がスキップされるため静的解析、テスト、ビルドが速やかに開始されます。

ワークフローの実行時間

今回の例のワークフローの実行時間を確認すると、setupジョブの2分36秒、並行実行されるジョブの中で最も時間のかかったbuildジョブの実行時間1分30秒を加え、4分6秒ほどで開発者は静的解析、テスト、ビルドの結果を確認できます。

なお上記はsetupジョブでキャッシュがヒットしなかった場合になります。
setupジョブでキャッシュがヒットする場合も確認してみると、setupジョブで47秒、並行して実行されるジョブの中で最も長かったbuildジョブの1分12秒を足して1分59秒ほどで開発者は静的解析、テスト、ビルドの結果を見ることができます。

ただしジョブの実行時間の請求は秒数が切り上げで計算される点には注意が必要です(画像中のBillable time部分をご参照ください)。

まとめ

本記事ではGitHub Actionsのワークフローを設計する際に依存関係の解決だけを行うsetupジョブを用意することで後続のジョブを並行して速やかに実行するというTipsを紹介しました。
記事ではNode.jsを例に説明しましたが、JavaやGo、Pythonなどの多くのプログラミング言語で活用できる方法だと思います。ぜひ試してみてください。

参考

依存関係をキャッシュしてワークフローのスピードを上げる - GitHub Docs

執筆:@yamada.y、レビュー:@kinjo.ryuki
Shodoで執筆されました