はじめに
GitHub Actionsの特徴の一つは、条件付き実行をサポートしていることです。これにより、ワークフロー内の特定のステップやジョブがいつ実行されるかを制御できます。複数のジョブ、ステップ、および構成を管理する場合に特に便利な機能です。
条件式
GitHub Actionsの条件付き実行の基盤となるのが、条件式です。この章では、条件式の基礎、使用できる演算子、コンテキストや関数の使い方について説明します。
条件式の基礎
GitHub Actionsの条件式は、JavaScriptをベースにしたGitHub Actions式の構文を使って書かれます。これらの式は、if
キーワードと一緒に使用して、ステップやジョブが実行されるかどうかを決定するために使用されます。式の結果は、true
またはfalse
のブール値である必要があります。
条件式の単純な例を以下に示します。
if: success()
この場合、success()
関数を使用して前のステップが成功したかどうかを確認します。成功した場合、ステップまたはジョブが実行されます。そうでない場合は、スキップされます。
条件式での演算子
GitHub Actionsの式では、複雑な式を作成するために使用できるさまざまな演算子がサポートされています。これらの演算子には以下が含まれます。
- 論理演算子
&&
(かつ)、||
(または)、!
(否定) - 等価演算子
==
(等しい)、!=
(等しくない) - 比較演算子
<
(未満)、>
(より大きい)、<=
(以下)、>=
(以上)
以下は、いくつかの演算子を組み合わせた例です。
if: github.event_name == 'pull_request' && github.event.action == 'opened'
この式では、現在のイベントがオープンされたプルリクエストであるかどうかをチェックします。
コンテキストや関数を式で使用
GitHub Actionsの式では、様々なコンテキストオブジェクトや組み込み関数にアクセスできます。これらは、有用な情報と機能を提供します。いくつか例を挙げると、
github
: 現在のリポジトリ、イベント、ワークフロー実行などの情報を提供します。env
: 環境変数を含みます。secrets
: リポジトリのシークレットを保持します。steps
: 前のステップの出力にアクセスします。needs
: 依存するジョブの出力にアクセスします。
success()
、failure()
、cancelled()
、always()
などの関数もあります。
以下は、githubコンテキストオブジェクトを使用する例です。
if: github.ref == 'refs/heads/main' && success()
この式では、現在のブランチがmainブランチで、前のステップが成功した場合にステップまたはジョブが実行されます。
アクションをスキップ
特定のステップやジョブをワークフロー内でスキップしたい場合があります。この場合、if
キーワードと条件式を組み合わせて、アクションをスキップできます。この章では、アクションをスキップするためのさまざまなユースケースと、それらを実装する方法について説明します。
ifキーワードの使用
if
キーワードを使用すると、条件式の結果に基づいてステップやジョブを条件付きで実行できます。if
で指定された式がtrue
に評価される場合、ステップまたはジョブが実行されます。式がfalse
に評価される場合は、ステップまたはジョブがスキップされます。
以下は、if
キーワードの使用例です。
steps:
- name: Run tests
run: npm test
if: success()
この例では、「Run tests」ステップは、前のステップが成功した場合のみ実行されます。
ブランチやタグに基づくステップのスキップ
条件式を使用して、特定のブランチやタグに対してステップを実行するように指定できます。これは、特定のリリースやブランチでのみステップを実行する必要がある場合に役立ちます。以下は例です。
steps:
- name: Deploy to production
run: npm run deploy
if: github.ref == 'refs/heads/main'
この例では、「Deploy to production」ステップは、現在のブランチがmain
の場合にのみ実行されます。
変更されたファイルに基づくステップのスキップ
特定のファイルが変更された場合にのみ、ステップを実行するというユースケースがあります。これは、コミットやプルリクエストで特定のファイルが変更された場合にのみステップやジョブをトリガーする場合に役立ちます。
これは、contains()
およびfromJson()
関数を使用し、変更されたファイルをリストするカスタムアクションを使用して実現できます。以下は例です。
steps:
- name: Get changed files
id: changes
uses: trilom/file-changes-action@v1
with:
output: 'json'
- name: Run tests for important files
run: npm run test:important
if: contains(fromJson(steps.changes.outputs.files), 'path/to/important/file')
この例では、「Run tests for important files」ステップは、指定されたファイル(path/to/important/file
)が変更された場合にのみ実行されます。
マトリックスビルド
マトリックスビルドは、GitHub Actionsの強力な機能の一つであり、同じジョブを複数の構成で実行できるようになります。これは、コードを異なるプラットフォームで、またはプログラミング言語や依存関係のさまざまなバージョンでテストする場合に特に便利です。この章では、マトリックスビルドの概念、条件付きマトリックスビルドの使用方法、およびマトリックスビルドを高度なシナリオに組み合わせて、if
キーワードを使用して複雑なワークフローを作成する方法について説明します。
マトリックスビルドの理解
GitHub Actionsのマトリックスビルドでは、ジョブで実行する構成のセットを定義できます。これは、ジョブ定義内にmatrix
キーを指定し、変数とその可能な値のリストを続けることによって行います。GitHub Actionsは、これらの値の組み合わせごとにジョブを実行します。
以下は、マトリックスビルドの基本的な例です。
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node-version: [12, 14, 16]
steps:
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
この例では、test
ジョブが3つのオペレーティングシステム(Ubuntu、macOS、Windows)と3つのNode.jsバージョン(12、14、16)で実行され、合計9回のジョブ実行が行われます。
条件付きマトリックスビルドの使用
条件式をマトリックスビルド内で使用して、特定の条件に基づいて特定の構成を含めたり、除外したりできます。これは、matrix
定義内のinclude
およびexclude
キーを使用することで実現できます。
以下は、条件付きマトリックスビルドの使用例です。
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node-version: [12, 14, 16]
include:
- os: ubuntu-latest
node-version: 18
if: github.ref == 'refs/heads/main'
この例では、現在のブランチがmain
である場合にのみ、追加の構成(UbuntuでNode.jsバージョン18)がマトリックスに含まれます。
マトリックスビルドをifキーワードで組み合わせる
より高度なシナリオでは、ジョブやステップ内でifキーワードを使用して、マトリックスビルドの実行をさらに制御できます。条件式とmatrix
コンテキストオブジェクトを組み合わせることで、複雑で柔軟なワークフローを作成できます。
以下は、マトリックスビルドとif
キーワードを組み合わせた使用例です。
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node-version: [12, 14, 16]
steps:
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Publish coverage report
run: npm run coverage
if: matrix.os == 'ubuntu-latest' && matrix.node-version == 14
この例では、「Publish coverage report」ステップは、現在の構成がUbuntuでNode.jsバージョン14で実行されている場合にのみ実行されます。これは、特定のタスク(カバレッジレポートの公開やアプリケーションのデプロイなど)をマトリックスビルドまたは特定の構成でのみ一度だけ実行したい場合に役立ちます。