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

完了

開発者がコード ベースに変更を追加するたびに機能が更新されるように、コードのビルドと発行プロセスを自動化することが目的であることを思い出してください。

このプロセスを実装するには、次の方法を学習します。

  • テンプレートからワークフローを作成します。
  • 再利用可能なワークフローを使用して重複を回避します。
  • ワークフローをトリガーしたイベントを特定します。
  • GitHub Actions ワークフロー ログを使用します。
  • 複数のターゲットに対してテストする。
  • ビルド ジョブとテスト ジョブを分離します。
  • ビルド成果物を保存してアクセスします。
  • レビュー後にプル要求へのラベルの追加を自動化します。

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

ワークフローを作成するには、テンプレートを使用することから始めるのが一般的です。 テンプレートには、実装している特定の種類の自動化に対して事前に構成された一般的なジョブとステップがあります。 ワークフロー、ジョブ、手順に慣れていない場合は、 GitHub Actions モジュールを使用して開発タスクを自動化 する方法を確認してください。

GitHub リポジトリのメイン ページで、[ アクション] を選択し、[ 新しいワークフロー] を選択します。

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

Node.js ワークフロー テンプレートから開始するには、検索ボックスに「 Node.js」と入力します。

検索ボックスが強調表示され、テキストが Node.jsされた [GitHub Actions] タブを示すスクリーンショット。

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

[Node.js] ウィンドウが強調表示され、[構成] ボタンが選択されている [GitHub Actions] タブを示すスクリーンショット。

プロジェクトの 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属性に示すように、この例のワークフローは、リポジトリへのプッシュに応答するか、メイン ブランチに対してプル要求が作成されたときに実行されます。

このワークフローは、 job 属性で示される 1 つのジョブを実行します。

runs-on属性は、オペレーティング システムに対してワークフローがubuntu-latestで実行されることを指定します。 node-version属性は、バージョン 14.x、16.x、18.x Node.js それぞれ 3 つのビルドがあることを指定します。 matrix属性については、モジュールの後半で詳しい説明を行います。

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

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

npm の詳細については、npm のドキュメントを参照してください。

開発者のチームは、再利用可能なワークフローを使用して、自動化の繰り返し手順を合理化および標準化することでメリットを得ることができます。 再利用可能なワークフローを使用することで、冗長性を減らし、保守性を向上させ、継続的インテグレーション/継続的デプロイ (CI/CD) パイプライン全体の一貫性を確保できます。

再利用可能なワークフローを使用して重複を回避する

チームの規模とプロジェクトが拡大するにつれて、複数のワークフロー ファイルで同じ手順が繰り返されるのが一般的です。 これらの手順には、コードのチェックアウト、依存関係のインストール、テスト、デプロイが含まれる場合があります。 この種の重複により、コード ベースが煩雑になるだけでなく、コードの変更が必要な場合のメンテナンス時間も長くなります。 再利用可能なワークフローでは、自動化ロジックを 1 回定義し、他のワークフローからロジックを呼び出すことで、この問題を解決できます。

再利用可能なワークフローは、プログラミングの関数と同様に、他のワークフローが呼び出すことができる特別な GitHub Actions ワークフローです。 それらを作成して、ビルド ステップ、テスト 手順、デプロイ戦略などの繰り返しのロジックを共有します。 再利用可能なワークフローを作成した後は、同じリポジトリ内または異なるリポジトリ内の他のワークフローから参照できます。

GitHub Actions の再利用可能なワークフローの概念を示す図。複数のリポジトリまたはワークフローは、中央のワークフローを参照できます。

再利用可能なワークフローを使用する理由

再利用可能なワークフローを使用する利点は次のとおりです。

  • 一貫性。 Teams は、すべてのプロジェクトで同じ自動化標準に従うことができます。
  • 効率性。 ステップをコピーして貼り付ける代わりに、再利用可能なワークフローを指すだけです。
  • より簡単な更新。 テスト ステップを追加するなどしてプロセスが変更された場合は、1 つの場所で更新します。 すると、そのワークフローを使用するすべてのワークフローが自動的にその恩恵を受けます。
  • スケーラビリティ。 再利用可能なワークフローは、複数のサービスを管理するプラットフォームまたは DevOps チームに最適です。

次に、再利用可能なワークフローを使用してプロジェクトを改善する方法について説明します。

再利用可能なワークフローを実装する

再利用可能なワークフローを使用するには:

  1. リポジトリ フォルダーに、再利用可能なワークフローを作成します。 このファイルには、テスト、ビルド、デプロイに関連する一般的な手順など、共有する自動化手順が含まれています。
  2. workflow_call イベントを使用してワークフローを構成することで、ワークフローを再利用可能に明示的に有効にします。
  3. メイン ワークフロー (呼び出し元ワークフロー) で、この再利用可能なファイルを参照し、必要な入力またはシークレットを指定します。

再利用可能なワークフローの利点を示すために、次の実際のシナリオを検討してください。

組織に 10 個のマイクロサービスがあるとします。 10 個のマイクロサービスはすべて、次の操作を行うために同じ手順を必要とします。

  • テストを実行する
  • コードをリントする
  • 特定の環境にデプロイする

再利用可能なワークフローがない場合、すべてのリポジトリには、各ワークフローの繰り返しの手順を一覧表示する重複したロジックが含まれます。

再利用可能なワークフローを使用する場合:

  • プロセスは、中央ファイル (たとえば、 ci-standard.yml) で 1 回定義します。
  • このファイルは、すべてのマイクロサービス独自のワークフローから呼び出し、環境やアプリケーション名などの変数を渡します。

脆弱性のスキャンなど、新しいセキュリティ手順またはツールが追加された場合は、再利用可能なワークフローに 1 回だけ追加します。 10 個のマイクロサービスはすべて、更新されたプロセスの使用をすぐに開始します。 10 個のマイクロサービスを変更する必要はありません。

再利用可能なワークフローの機能とその利点を理解することで、ベスト プラクティスを採用して有効性を最大化し、CI/CD パイプラインとのシームレスな統合を確保できます。

ベスト プラクティス

  • チーム間で共有する予定の場合は、再利用可能なワークフローを 1 つのリポジトリに一元化します。
  • ブランチまたはタグを使用してワークフローのバージョンを設定し (たとえば、 @v1を使用)、必要に応じて変更を簡単にロールバックできるようにします。
  • 入力とシークレットを明確に文書化します。 再利用可能なワークフローは、多くの場合、入力とシークレットに依存します。 チームは、使用する情報を把握する必要があります。
  • いくつかの手順のみを再利用する必要がある場合は、完全なワークフローを作成するのではなく、再利用可能なワークフローと複合アクションを組み合わせます。

再利用可能なワークフローは、任意のエンジニアリング チームで一貫性を強制し、重複を減らし、DevOps プラクティスをスケーリングするための強力な方法です。 単一のリポジトリ、マイクロサービス、オープンソース ライブラリのいずれを管理する場合でも、再利用可能なワークフローによって自動化を簡素化できるため、CI/CD はより高速で、よりクリーンで、管理しやすくなります。

ワークフローをトリガーしたイベントを特定する

GITHub Actions ワークフローをトリガーした理由を理解することは、CI/CD パイプラインのデバッグ、監査、および改善に不可欠です。 トリガーの種類には、ブランチへのプッシュ、作成または更新されたプル要求、スケジュールされたジョブ、手動ディスパッチが含まれます。 トリガー イベントは、ワークフローの実行、リポジトリの変更、および関連する GitHub の問題またはプル要求を調べることで識別できます。

プッシュ、プル要求、スケジュール、手動ディスパッチなど、GitHub Actions のさまざまなワークフロー トリガーを示す図。

ワークフロー トリガーとは

ワークフロー トリガーは、ワークフローを実行させるイベントです。 GitHub では、次のようなさまざまな種類のトリガーがサポートされています。

  • push または pull_request (コードの変更に基づく)
  • workflow_dispatch (手動トリガー)
  • schedule (cron ジョブ)
  • repository_dispatch (外部システム)
  • 問題、ディスカッション、pull request イベント ( issues.openedpull_request.closedなど)

トリガー イベントを識別する

ワークフロー トリガー イベントは、次の複数の方法で識別できます。

  • GitHub Actions UI を使用します。

    1. リポジトリで、[ アクション] タブを選択します。
    2. ワークフロー実行を選択します。

    ワークフロー実行の概要の上部に、 pushpull_requestworkflow_dispatchなどのイベントの種類が表示されます。

  • ログまたはワークフローで github.event_name を使用します。

    • GitHub は、ワークフローの実行中にコンテキスト データを公開します。 github.event_name変数は、ワークフローをトリガーしたイベントを示します。

    • デバッグの手順で情報を出力できます。

      -name: Show event trigger
        run: echo "Triggered by ${{ github.event_name }}"
      
  • ワークフローの実行詳細を使う。

    • API を使用するなど、プログラムによってワークフローの実行を検査する場合、実行オブジェクトにはトリガーを指定する event プロパティが含まれます。
    • コミット セキュア ハッシュ アルゴリズム (SHA)、アクター、タイムスタンプを見つけて、トリガーの原因をトレースできます。

リポジトリの効果からトリガーを推論する

ワークフロー実行に直接アクセスできない場合もありますが、リポジトリ アクティビティに基づいてワークフロー実行をトリガーした原因を推測する必要があります。

観察された動作 トリガー イベント
新しいコミットが main にプッシュされ、ワークフローが実行されました。 push 出来事
pull request が開かれました、または更新されました。 pull_request 出来事
共同作成者がワークフローを手動で実行しました。 workflow_dispatch
ワークフローは、特定の時刻に毎日実行されます。 schedule (cron)
ワークフローは、外部サービス呼び出しの後に実行されました。 repository_dispatch
ワークフローは、問題にラベルまたはコメントが追加されたときに実行されました。 issues.* 出来事

タイムスタンプ、プル要求アクティビティ、コミット履歴を確認することで、ワークフローの実行原因となったアクションを特定できることがよくあります。

ワークフローをトリガーした原因を特定する方法を要約するには:

  • [アクション] タブでワークフロー実行の概要を確認します。
  • ワークフロー内の github.event_name を印刷またはログに記録して表示します。
  • タイムスタンプとリポジトリ アクティビティ (コミット、プル要求、問題) を比較して、トリガーを推論します。
  • 詳細な調査には、完全な event コンテキストを使用します。

これらのプラクティスは、開発パイプラインとデプロイ パイプライン全体でワークフローの信頼性をデバッグ、監査、および向上するのに役立ちます。

構成ファイルを読み取ってワークフロー効果を記述する

構成ファイルの読み取りによるワークフローの影響を説明するには、.ymlに格納されている.github/workflows/ ファイルの構造と内容を分析します。

ワークフロー構成ファイルは、ワークフローに関する次の情報を識別します。

  • 実行時 (on セクション)。
  • それが何をするか( jobsstepsで)。
  • 実行場所 ( runs-on セクション)。
  • なぜ実行するのか(テスト、デプロイ、リンティングなどの目的)
  • 特定の条件 (環境、フィルター、ロジック) での動作。

ワークフロー効果を解釈する

  1. トリガーを特定します。

    ワークフローを開始したアクションを特定するには、ワークフローの on セクションを参照してください。

    例えば次が挙げられます。

    on:
      push:
        branches: [main]
      pull_request:
        types: [opened, synchronize]
      workflow_dispatch:
    

    このワークフローの例:

    • コードがメイン ブランチ (push) にプッシュされると、自動的に実行されます。
    • pull request が作成または更新されたときに実行されます (pull_request)。
    • ユーザー (workflow_dispatch) によって手動でトリガーできます。
  2. ワークフロー ジョブとステップを特定します。

    ワークフローの動作を確認するには、ワークフローの jobssteps のセクションを参照してください。

    例えば次が挙げられます。

    jobs:
      test:
        runs-on: ubuntu-latest
        steps:
          - name: Checkout code
            uses: actions/checkout@v3
          - name: Install dependencies
            run: npm install
          - name: Run tests
            run: npm test
    

    このワークフローの例:

    • Linux 仮想環境 (runs-on) を使用します。
    • リポジトリのコード (steps>name) をチェックアウトします。
    • プロジェクトの依存関係 (steps>name) をインストールします。
    • 自動テスト (steps>name) を実行します。
  3. ワークフローの目的と結果を評価します。

    構成ファイルを読み取ることで、ワークフローの意図した結果を記述できます。

    "このワークフローは継続的インテグレーション (CI) パイプラインです。 これにより、リポジトリにプッシュされた、または pull request を介して送信された新しいコードが自動的にテストされます。 テストが失敗した場合、GitHub ワークフロー UI にこの結果が表示され、コードの品質を維持するのに役立ちます。"

  4. ワークフローの実行方法に影響を与えるオプションの機能を特定または設定します。

    • env は環境変数を設定します。
    • if では、条件が満たされた場合にのみ特定のステップを実行する条件付きロジックが追加されます。
    • timeout-minutes または continue-on-error ワークフローの実行とエラー処理を設定します。

失敗したワークフロー実行を診断する

  1. リポジトリで、[ アクション] タブに移動します。

  2. 失敗した実行を見つけます (通常は赤い X で示されます)。

  3. 失敗したワークフローを選択して、実行の概要を開きます。

  4. ワークフロー ログで、エラーを確認します。

    1. 実行の概要で、失敗を示すジョブが見つかるまで各ジョブとステップを展開します。

    2. ジョブまたはステップを選択してログを表示します。

    3. 検索対象:

      • エラー メッセージ
      • スタック トレース
      • 終了コード

    たとえば、失敗したテストには、 npm ERR! Test failed または exit code 1が表示される場合があります。

  5. ワークフロー構成ファイルを確認します。

    .yml ファイルを使用して、以下を確認します。

    • 各ステップで何をしようとしたのですか?
    • 実行に影響する環境変数 (env) または条件 (if) がある場合。
    • エラーが依存関係の不足、構文エラー、または手順の誤った設定によって発生した場合。

    ステップが失敗した場合は、次の原因を確認します。

    • 前の手順で依存関係が正常にインストールされましたか?
    • テスト ファイルは存在し、ローカルに渡されますか?

一般的な失敗シナリオ

次の表では、一般的なワークフローエラーのシナリオについて説明します。

症状 考えられる原因
ステップが失敗し、 command not foundが返されます。 依存関係がないか、セットアップが間違っている
npm install 失敗。 破損した package-lock.json ファイルまたはネットワークの問題
テスト ステップが失敗します。 単体テストの問題、構成ファイルが見つからない、または無効なテスト構文
Permission denied が表示されます。 ファイルのアクセス許可が正しくないか、シークレットが見つからない

GitHub でワークフロー ログにアクセスする方法を特定する

  1. リポジトリで、[ アクション] タブに移動します。

  2. ワークフローの一覧で、関連するワークフローを選択します。

    たとえば、 .yml ファイルに次のコードがある場合、 CI Workflow という名前のリンクが一覧に表示されます。

    name: CI Workflow
    
  3. 特定の実行を選択します。

    状態を示す実行の一覧で、検査する特定の実行のタイムスタンプまたはコミット メッセージを選択します。

  4. 各ジョブとステップを展開します。

    実行の概要ページには、ワークフロー ファイルで定義されているジョブ (ビルドやテストなど) が表示されます。

    1. ジョブを選択して展開します。
    2. ジョブ内で、"依存関係のインストール" や "テストの実行" など、個々の手順を展開します。
  5. ログ出力を表示します。

    コンソール ログ、エラー メッセージ、デバッグ情報など、ログ出力全体を表示するには、ワークフロー ステップを選択します。 ログをコピー、検索、ダウンロードできます。

次の表は、ワークフロー ログにアクセスするために実行する手順をまとめたものです。

アクション 目的
[アクション] タブ すべてのワークフロー実行を表示します。
ワークフロー名を選択する ワークフロー別に実行をフィルター処理します。
実行を選択する 特定のジョブとステップの結果を確認します。
ステップを展開する 詳細なログを表示します。
ログのダウンロード オフラインまたはチームのトラブルシューティング用のログをダウンロードします。

ビルドのアクション ログ

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

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

失敗したテストの詳細を含む GitHub Actions ログのスクリーンショット。

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

このモジュールの冒頭では、開発者のチームに CI を設定する必要があるシナリオを検討しました。 Node.js テンプレートは優れたスタートですが、チームの要件に合わせてカスタマイズする必要があります。 異なるバージョンの Node.js と異なるオペレーティング システムを対象にする必要があります。 また、ビルドとテストの手順を個別のジョブにする必要があります。

カスタマイズされたワークフローの例を次に示します。

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

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

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 コンテナーが生成されます。 コンテナーは、 アクション/upload-artifact アクション を使用してストレージにアップロードできる成果物です。 後で アクション/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 でレビューを自動化する

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

レビュー担当者がプル要求を承認した後など、ユーザーが特定のアクションを完了した後にのみワークフローを実行できます。 このシナリオでは、 pull-request-reviewでトリガーできます。

実行できるもう 1 つのアクションは、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 での継続的デリバリーの使用について説明します。