GitHub Actions を使用して CI のワークフローを作成するには

完了

ここでは、CI の GitHub Actions とワークフローについて学びます。

学習内容は次のとおりです。

  • テンプレートからワークフローを作成する
  • GitHub Actions ログを理解する
  • 複数のターゲットに対してテストする
  • ビルドとテストのジョブを分離する
  • ビルド成果物を保存してアクセスする
  • レビューでの PR のラベル付けを自動化する

テンプレートからワークフローを作成する

ワークフローを作成するには、まずテンプレートを使用します。 テンプレートには、実装している特定の種類の自動化に対して事前構成された共通のジョブとステップがあります。 ワークフロー、ジョブ、およびステップに詳しくない場合は、「GitHub Actions を使用して開発タスクを自動化する」モジュールを参照してください。

リポジトリのメイン ページで、[アクション] タブを選択して、[新しいワークフロー] を選択してください。

[ワークフロー の選択] ページでは、さまざまなテンプレートから選択できます。 一例として Node.js テンプレートがあります。これを使って、ノードの依存関係のクリーン インストールを実行し、ソース コードをビルドし、さまざまなバージョンの Node のテストを実行できます。 もう 1 つの例は "Python パッケージ" テンプレートです。これを使って、Python の依存関係をインストールし、Python のさまざまなバージョンに対して lint を含むテストを実行できます。

検索ボックスに「Node.js」と入力します。

Screenshot showing GitHub Actions tab with the search box highlighted and containing the text 'Node.js'.

検索結果の Node.js ペインで、[構成] を選択します。

Screenshot showing GitHub Actions tab with the Node.js pane highlighted and the Node.js template selected.

この既定の Node.js テンプレート ワークフローは、新しく作成されたファイル node.js.yml に表示されます。

name: Node.js CI

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  build:

    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [14.x, 16.x, 18.x]

    steps:
    - uses: actions/checkout@v3
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'
    - run: npm ci
    - run: npm run build --if-present
    - run: npm test

on: 属性に注目してください。 このワークフローは、リポジトリへのプッシュ時と、メイン ブランチに対して pull request が行われたときにトリガーされます。

このワークフローには job が 1 つあります。 何が行われるかを確認してみましょう。

runs-on: 属性は、オペレーティング システムについて、ワークフローが ubuntu-latest で実行されることを指定します。 node-version: 属性は、Node バージョン 14.x、16.x、18.x 用にそれぞれ 1 つずつ、3 つのビルドが存在することを指定します。 matrix の部分については、後でワークフローをカスタマイズする際に詳しく説明します。

このジョブ内の steps は、GitHub Actions actions/checkout@v3 アクションを使用してリポジトリから VM にコードを取得し、actions/setup-node@v3 アクションを使用して正しいバージョンの Node.js を設定します。 ${{ matrix.node-version }} 属性で、3 つのバージョンの Node.js をテストすることを指定します。 この属性は、前に定義したマトリックスを参照します。 cache 属性は、既定のディレクトリにキャッシュするためのパッケージ マネージャーを指定します。

このステップの最後の部分では、Node.js プロジェクトによって使用されるコマンドを実行します。 npm ci コマンドは package-lock.json ファイルから依存関係をインストールし、npm run build --if-present はビルド スクリプトがあればそれを実行し、npm test はテスト フレームワークを実行します。 このテンプレートには、同じジョブにビルドとテストの両方のステップが含まれていることに注意してください。

npm の詳細については、次の npm のドキュメントをご覧ください。

ビルドのアクション ログ

ワークフローを実行すると、発生した内容とエラーまたはテストの失敗の詳細を含むログが生成されます。

エラーが発生した場合、またはテストが失敗した場合は、緑のチェックマーク ✔ ではなく赤い ✖ がログに表示されます。 エラーまたは失敗の詳細を調べて、何が発生したかを調査することができます。

 GitHub Actions log with details on a failed test.

この演習では、ログの詳細を調べて、失敗したテストを特定します。 ログには、[アクション] タブからアクセスできます。

ワークフロー テンプレートをカスタマイズする

このモジュールの冒頭で、チームに CI を設定する必要があるシナリオについて説明しました。 Node.js テンプレートは優れた開始点として使用できますが、ご自身のチームの要件に合わせてカスタマイズすることもできます。 異なるバージョンの Node や異なるオペレーティング システムをターゲットにしたい場合があります。 また、ビルドとテストのステップを別々のジョブに分割したい場合もあります。

ワークフローをカスタマイズする方法を見てみましょう。

strategy:
  matrix:
    os: [ubuntu-latest, windows-latest]
    node-version: [16.x, 18.x]

ここでは、複数のオペレーティング システムおよび言語バージョンにわたってテストするためのビルド マトリックスを構成しました。 このマトリックスでは、4 つのビルド (Node の各バージョンとペアになっているオペレーティング システムごとに 1 つ) が生成されます。

4 つのビルドとそのすべてのテストによって、かなりのログ情報が生成されます。 それらすべてを整理することは簡単ではありません。 次のサンプルでは、テスト ステップを専用のテスト ジョブに移動する方法を示します。 このジョブは、複数のターゲットに対してテストを行います。 ビルドとテストのステップを分離すると、ログを理解しやすくなります。

test:
  runs-on: ${{ matrix.os }}
  strategy:
    matrix:
      os: [ubuntu-latest, windows-latest]
      node-version: [16.x, 18.x]
  steps:
  - uses: actions/checkout@v3
  - name: Use Node.js ${{ matrix.node-version }}
    uses: actions/setup-node@v3
    with:
      node-version: ${{ matrix.node-version }}
  - name: npm install, and test
    run: |
      npm install
      npm test
    env:
      CI: true

成果物とは

ワークフローからログ エントリ以外のものが生成された場合、その生成物は "成果物" と呼ばれます。 たとえば、Node.js ビルドでは、デプロイ可能な Docker コンテナーが生成されます。 この成果物 (コンテナー) は、アクションactions/upload-artifact を使用してストレージにアップロードし、後でアクションactions/download-artifact を使用してストレージからダウンロードできます。

成果物を保存すると、それはジョブ間で保持されます。 各ジョブは仮想マシン (VM) の新しいインスタンスを使用するため、成果物を VM に保存して再利用することはできません。 別のジョブで成果物が必要な場合は、成果物を 1 つのジョブのストレージにアップロードし、他のジョブ用にダウンロードできます。

成果物ストレージ

成果物は、GitHub の記憶領域に保存されます。 領域は、パブリック リポジトリの場合は無料で、プライベート リポジトリの場合はアカウントに応じてある程度の量が無料になります。 GitHub では、成果物は 90 日間保存されます。

次のワークフロー スニペットでは、actions/upload-artifact@main アクションに path: 属性が存在することに注目してください。 この属性の値は、成果物を格納するパスです。 ここでは、すべてをディレクトリにアップロードするために public/ を指定します。 1 つのファイルをアップロードする場合は、public/mytext.txt などを使います。

  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: npm install and build webpack
        run: |
          npm install
          npm run build
      - uses: actions/upload-artifact@main
        with:
          name: webpack artifacts
          path: public/

テスト用の成果物をダウンロードするには、ビルドが正常に完了し、成果物がアップロードされている必要があります。 次のコードでは、テスト ジョブがビルド ジョブに依存することを指定します。

test:
    needs: build
    runs-on: ubuntu-latest

次のワークフロー スニペットでは、成果物をダウンロードします。 これで、テスト ジョブで成果物をテストに使用できるようになりました。

steps:
    - uses: actions/checkout@v3
    - uses: actions/download-artifact@main
      with:
        name: webpack artifacts
        path: public

ワークフローでの成果物の使用の詳細については、GitHub ドキュメントの「ワークフロー データを成果物として格納する」を参照してください。

ワークフローを使用して GitHub のレビューを自動化する

ここまで、pushpull-request などの GitHub イベントを使用したワークフローの開始について説明しました。 また、スケジュールに従って、または GitHub 以外のイベントに基づいてワークフローを実行することもできます。

場合によっては、ユーザーがアクションを実行した後にのみワークフローを実行する必要があります。 たとえば、レビュー担当者が pull request を承認した後にのみ、ワークフローを実行したい場合があります。 このシナリオでは、pull-request-review でトリガーできます。

別のアクションとして、pull request にラベルを追加することもできます。 この場合、pullreminders/label-when-approved-action アクションを使用します。

    steps:
     - name: Label when approved
       uses: pullreminders/label-when-approved-action@main
       env:
         APPROVALS: "1"
         GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
         ADD_LABEL: "approved"

env: というブロックに注目してください このブロックで、このアクションの環境変数を設定します。 たとえば、必要な承認者の数を設定できます。 ここでは、1 人です。 アクションでは、ラベルを追加することによってリポジトリに変更を加える必要があるため、secrets.GITHUB_TOKEN 認証変数が必要です。 最後に、追加するラベルの名前を指定します。

ラベルの追加は、マージなどの別のワークフローを開始するイベントになる場合があります。 このイベントについては、GitHub Actions を使用した継続的デリバリーに関する次のモジュールで説明します。