😀

GitHub Actions のベストプラクティス

2021/11/24に公開

はじめに

GitHub Actionsのベストプラクティス集です。

高速化

キャッシュのkey選択の最適化

プラクティス

キャッシュのkeyとして以下のような値を使用し、キャッシュを最大限活用します。

  1. lockファイルのハッシュ値
  2. OSの名称
  3. ランタイム(Node.js, java, python)のバージョン
  4. ブランチ名
OKの例
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/cache@v2
        id: poetry_cache_id
        with:
          path: .venv
          key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}
      - name: install dependencies
        if: steps.poetry_cache_id.outputs.cache-hit != 'true'
        run: |
          poetry install
NGの例
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: install dependencies
        run: |
          poetry install

効果

.mvn , .venv等のパッケージマネージャのキャッシュフォルダが保存され、使い回されるようになります。

デバッグのしやすさ

ローカル実行

プラクティス

CI/CDで実行するコマンドやオプションはGitHub Actionsには書かずに、shellやnpm-script等に記述します。

OKの例
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: build and package
        run: |
          . .venv/bin/activate
          ./bin/build.sh -t Release
          ./bin/package.sh
NGの例
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: build and package
        run: |
          . .venv/bin/activate
          conan install .. --build=missing --generator cmake_multi --settings
          conan build ..
          conan install .. --build=missing --generator cmake_multi --settings build_type=Release

効果

GitHub Actions内の処理をローカルで動作確認したいとき、workflowではなく、shellやnpm-scriptsに記述していると容易に実行でき、便利です。

手動実行

プラクティス

手動実行用のイベント( workflow_dispatch )を設定します。

OKの例
name: Manually triggered workflow
on:
  push:
  workflow_dispatch:
    inputs:
      name:
        description: 'Person to greet'
        required: true
        default: 'Mona the Octocat'
NGの例
name: Manually triggered workflow
on:
  push:

効果

Run workflowボタンが表示されて、手動で再ランできるようになり、CI/CDコードのデバッグがやりやすくなります。

image.png

安定性

OSのバージョン指定

プラクティス

runs-onのOSのバージョンを指定します。

OKの例
jobs:
  deploy:
    runs-on: ubuntu-20.04
NGの例
jobs:
  deploy:
    runs-on: ubuntu-latest

効果

バージョンを指定しない場合、OSの破壊的変更によってCI/CDが動かくなることがあります。

バージョンを固定することでCI/CDが安定するようになります。

アクションのバージョン指定

プラクティス

タグまたはSHAでアクションのバージョンを指定します。

OKの例
steps:
    - uses: actions/javascript-action@v1.2.0
    - uses: actions/javascript-action@172239021f7ba04fe7327647b213799853a9eb89
NGの例
steps:
    - uses: actions/javascript-action
    - uses: actions/javascript-action@latest

効果

バージョンを指定しない場合やブランチ名でバージョンを指定した場合、アクションの破壊的変更によってCI/CDが動かくなることがあります。

タグやSHAでバージョンを固定することでCI/CDが安定するようになります。

可読性

静的な環境変数

プラクティス

静的な環境変数はenv:で定義して、参照しましょう。

OKの例
env:
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: build
        run: docker build . --file Dockerfile --tag ${{ env.IMAGE_NAME }}:latest
NGの例
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: build
        run: docker build . --file Dockerfile --tag ${{ github.repository }}:latest

効果

steps内で使う変数は、環境変数で設定しましょう。
変数の意味がわかりやすくなり、可読性が向上します。

動的な環境変数

プラクティス

実行時の日付を含むなどの、動的な環境変数はrun: echo ENV_NAME=value >> $GITHUB_ENVで設定して、${ENV_NAME}で参照しましょう。

OKの例
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - run: echo TAG_NAME=`date +%s` >> $GITHUB_ENV
      - name: build
        run: docker build . --file Dockerfile --tag ${{ env.IMAGE_NAME }}:${TAG_NAME}
NGの例
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: build
        run: docker build . --file Dockerfile --tag ${{ env.IMAGE_NAME }}:`date +%s`

効果

動的な環境変数に名前をつけて管理できるようになり、可読性が向上します。

テスト

複数プラットフォームの並列テスト

プラクティス

strategyを使って複数のプラットフォームで同時にテストを実行しましょう。

以下の例は、バージョン14, 16のNode.jsで同時にテストを実行する例です。

OKの例
jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [14.x, 16.x]
    steps:
      - uses: actions/setup-node@v2
        with:
          node-version: ${{ matrix.python-version }}
      - run: npm run test
NGの例
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/setup-node@v2
        with:
          node-version: 16.x
      - run: npm run test

stepsは、strategyの数だけ分岐して同時に実行されます。
GitHub Actions では次のように表示されます。

Screenshot from 2021-12-03 23-44-01.png

効果

CI/CDの処理時間を変えずに、複数環境でのテストを簡単に実装できます。

マルチプラットフォームなアプリケーションの品質向上と生産性向上に寄与します。

Discussion