Tips - ワークフローを書く
GitHub Actionsを使いこなせば、開発ワークフローの自動化が驚くほど柔軟かつ強力になります。本記事では、公式ドキュメントの内容を体系的に整理し、実践的な知識として活用できる形でお届けします。
目次
1. ワークフローのトリガー制御
1.1 基本的なトリガー設定
ワークフローはonキーで指定したイベントによって自動実行されます。単一イベントでも複数イベントでも指定可能です。
# 単一イベント
on: push
# 複数イベント
on: [push, pull_request, fork]
複数イベントを指定した場合、いずれか1つのイベントが発生すればワークフローがトリガーされます。同時に複数のイベントが発生した場合は、それぞれに対してワークフローが実行されます。
1.2 アクティビティタイプによる細かい制御
イベントには複数のアクティビティタイプが存在し、より詳細な条件でワークフローを起動できます。
on:
issues:
types:
- opened
- labeled
pull_request:
types:
- opened
- synchronize
複数のアクティビティタイプを指定すると、いずれか1つが発生すればトリガーされます。例えば、ラベルが2つ付いたIssueがオープンされた場合、1回のopenedイベントと2回のlabeledイベントで合計3回のワークフローが実行されます。
1.3 ブランチとタグのフィルタリング
特定のブランチやタグに対してのみワークフローを実行できます。
on:
push:
branches:
- main
- 'releases/**'
branches-ignore:
- 'releases/**-alpha'
tags:
- v2
- v1.*
重要なポイント:
-
branchesとbranches-ignoreは同一イベント内で同時に使用できません -
tagsとtags-ignoreも同様です - グロブパターン(
*,**,+,?,!など)が使用可能 - 否定パターン(
!プレフィックス)を使う場合、少なくとも1つは肯定パターンが必要です - パターンの順序が重要:肯定マッチ後の否定パターンは除外し、否定マッチ後の肯定パターンは再度含めます
ブランチとタグの組み合わせ例:
on:
push:
branches:
- 'releases/**'
- '!releases/**-alpha'
この設定では、releases/10やreleases/beta/monaにはマッチしますが、releases/10-alphaやreleases/beta/3-alphaには マッチしません。
1.4 パスフィルタリング
変更されたファイルパスに基づいてワークフローを制御できます。
on:
push:
paths:
- '**.js'
- 'sub-project/**'
- '!sub-project/docs/**'
パスフィルタの動作:
-
paths: 指定パターンに一致するファイルが変更された場合に実行 -
paths-ignore: すべてのファイルがパターンに一致する場合のみスキップ - 同一イベント内で
pathsとpaths-ignoreは同時使用不可 -
branches/branches-ignoreとpaths/paths-ignoreを両方定義した場合、両方の条件を満たす必要があります
注意事項:
- 1,000コミット以上のプッシュではフィルタが常に実行されます
- タイムアウトで差分生成に失敗した場合も常に実行されます
- 差分は最初の300ファイルまでしか評価されません
- ワークフローがスキップされた場合、関連するチェックは「Pending」状態のままになります
Git差分の比較方法:
- プルリクエスト:3点差分(トピックブランチとベースブランチの最新同期コミット間)
- 既存ブランチへのプッシュ:2点差分(HEADとベースSHAの直接比較)
- 新規ブランチへのプッシュ:最も深いコミットの祖先との2点差分
1.5 プルリクエストイベントのブランチフィルタ
プルリクエストイベントでは、ターゲットブランチに基づいてフィルタリングできます。
on:
pull_request:
branches:
- main
- 'releases/**'
評価対象はrefs/headsに対するGit refの名前です。例えばrefs/heads/mainやrefs/heads/releases/10にマッチします。
1.6 workflow_runイベントのブランチフィルタ
トリガー元のワークフローが特定ブランチで実行された場合のみ、自ワークフローを実行できます。
on:
workflow_run:
workflows: ["Build"]
types: [requested]
branches:
- 'releases/**'
- '!releases/**-alpha'
この例では、Buildワークフローがreleases/で始まるブランチで実行された場合のみトリガーされますが、-alphaで終わるブランチは除外されます。
1.7 手動トリガーと入力パラメータ
workflow_dispatchイベントで手動実行時の入力を定義できます。このトリガーはワークフローファイルがデフォルトブランチにある場合のみ有効です。
on:
workflow_dispatch:
inputs:
logLevel:
description: 'ログレベル'
required: true
default: 'warning'
type: choice
options:
- info
- warning
- debug
print_tags:
description: '標準出力に表示'
required: true
type: boolean
tags:
description: 'テストシナリオタグ'
required: true
type: string
environment:
description: 'テスト実行環境'
type: environment
required: true
jobs:
print-tag:
runs-on: ubuntu-latest
if: ${{ inputs.print_tags }}
steps:
- name: タグを出力
run: echo タグは ${{ inputs.tags }} です
入力の制限:
- トップレベルプロパティは最大25個
- ペイロード全体で最大65,535文字
-
choiceタイプは文字列として解決され、単一選択のみ
コンテキストでの参照:
-
inputsコンテキスト:Boolean値はBooleanのまま -
github.event.inputsコンテキスト:すべて文字列に変換
1.8 再利用可能なワークフローの入力・出力・シークレット
再利用可能なワークフローでは、呼び出し元から受け取る入力とシークレット、呼び出し元へ返す出力を定義できます。
# 再利用可能なワークフロー
on:
workflow_call:
inputs:
config-path:
required: true
type: string
secrets:
token:
required: true
outputs:
result:
description: "処理結果"
value: ${{ jobs.my-job.outputs.result }}
1.9 GITHUB_TOKENの挙動と再帰的実行の防止
GITHUB_TOKENを使用したイベントは、再帰的なワークフロー実行を防ぐため、新しいワークフローをトリガーしません(workflow_dispatchとrepository_dispatchは例外)。
これにより、ワークフローがコードをプッシュしても、pushイベントで設定されたワークフローが再度実行されることはありません。
別のワークフローをトリガーする方法:
- Personal Access Token (PAT) を使用
- GitHub Appのインストールアクセストークンを使用
steps:
- env:
GH_TOKEN: ${{ secrets.MY_TOKEN }} # カスタムトークン
ISSUE_URL: ${{ github.event.issue.html_url }}
run: |
gh issue edit $ISSUE_URL --add-label "triage"
GitHub Appを使う場合:
- GitHub Appを作成
- App IDと秘密鍵をシークレットとして保存
- ワークフロー内で認証APIリクエストを実行
再帰的または意図しないワークフロー実行を作成しないよう注意してください。GitHub Actionsの使用コストを最小化できます。
1.10 イベント情報の活用
ワークフロー実行をトリガーしたイベントの情報は、github.eventコンテキストで利用できます。プロパティはイベントタイプによって異なります。
イベントのすべてのプロパティを確認:
jobs:
print_context:
runs-on: ubuntu-latest
steps:
- env:
EVENT_CONTEXT: ${{ toJSON(github.event) }}
run: |
echo $EVENT_CONTEXT
イベントプロパティの使用例:
on:
pull_request:
types:
- opened
paths:
- '.github/workflows/**'
- '.github/CODEOWNERS'
- 'package*.json'
jobs:
triage:
if: >-
github.event.pull_request.user.login != 'octobot' &&
github.event.pull_request.user.login != 'dependabot[bot]'
runs-on: ubuntu-latest
steps:
- name: "受け入れられない変更についてコメント"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR: ${{ github.event.pull_request.html_url }}
run: |
gh pr edit $PR --add-label 'invalid'
gh pr comment $PR --body '`package*.json`、`.github/CODEOWNERS`、または`.github/workflows/**`を編集したようです。これらのファイルへの貢献は受け付けていません。'
この例では、特定のユーザー以外が特定のファイルを変更したPRに自動でラベルとコメントを追加します。
2. 同時実行の制御
2.1 concurrencyキーワードの基本
concurrencyを使用すると、同じグループ内で実行されるワークフローやジョブを制御できます。同時実行グループには、任意の文字列または式を指定できます。
使用可能な式コンテキスト:github、inputs、vars、needs、strategy、matrix
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
動作の仕組み:
- 同じグループ内では、最大1つの実行中ジョブと1つの保留中ジョブが存在できます
- 同じグループの実行中ジョブがある状態で新しいジョブがキューイングされると、既存の保留中ジョブはキャンセルされ、新しいジョブが保留状態になります
-
cancel-in-progress: trueの場合、実行中のジョブもキャンセルされます
注意事項:
- グループ名は大文字小文字を区別しません(
prodとProdは同じグループ) - 同じグループ内のジョブやワークフロー実行の順序は保証されません
2.2 ワークフローレベルの制御
ワークフロー全体の同時実行を制御します。
on:
push:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
この設定により、同じブランチへの複数のプッシュが連続して発生した場合、古い実行がキャンセルされ、最新の実行のみが継続されます。
2.3 ジョブレベルの制御
個別のジョブの同時実行を制御できます。
on:
push:
branches:
- main
jobs:
job-1:
runs-on: ubuntu-latest
concurrency:
group: example-group
cancel-in-progress: true
2.4 同時実行グループの例
同時実行グループは、同じキーを持つワークフローやジョブをまとめて管理する方法を提供します。
jobs:
job-1:
runs-on: ubuntu-latest
concurrency:
group: staging_environment
cancel-in-progress: true
ステージング環境へのデプロイなど、並列実行を防ぎたい場合に有効です。競合やリソースの過剰消費を防げます。
動的な式を使った例:
on:
push:
branches:
- main
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
この場合、mainブランチへ新しいコミットがプッシュされると、進行中の実行はキャンセルされ、新しい実行が開始されます。
2.5 条件付きキャンセル
特定のブランチではキャンセルしないよう設定できます。
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ !contains(github.ref, 'release/') }}
この例では、release/1.2.3ブランチへの複数のプッシュでは進行中の実行がキャンセルされませんが、mainなどの他のブランチではキャンセルされます。
2.6 フォールバック値の使用
特定のイベントでのみ定義されるプロパティを使う場合、フォールバック値を設定します。
concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true
github.head_refはpull_requestイベントでのみ定義されます。他のイベントでは未定義となるため、github.run_idがフォールバック値として使用されます。これにより、構文エラーを回避できます。
2.7 特定ワークフローのみキャンセル
複数のワークフローがある場合、グループ名はワークフロー間で一意である必要があります。そうでないと、他のワークフローの実行もキャンセルされてしまいます。
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
github.workflowプロパティを含めることで、同じワークフローの実行のみがキャンセルされます。
2.8 組織・エンタープライズのジョブ監視
同時実行やキューイングの制約を特定するため、組織またはエンタープライズのGitHub-hostedランナーで現在処理中のジョブ数を確認できます。
3. 実行環境の選択
3.1 概要
jobs.<job_id>.runs-onを使用して、ジョブを実行するマシンのタイプを定義します。
対象マシン:
- GitHub-hostedランナー
- Larger runner(上位プラン向け)
- セルフホストランナー
ランナーのターゲット指定方法:
- 割り当てられたラベル
- グループメンバーシップ
- 両方の組み合わせ
runs-onの指定形式:
- 単一の文字列
- 文字列を含む単一の変数
- 文字列、変数、または両方の組み合わせの配列
-
groupまたはlabelsキーを使ったキー・バリューペア
配列を指定した場合、すべてのruns-on値に一致するランナーで実行されます。
runs-on: [self-hosted, linux, x64, gpu]
この例では、self-hosted、linux、x64、gpuのすべてのラベルを持つセルフホストランナーでジョブが実行されます。
文字列と変数の混在:
on:
workflow_dispatch:
inputs:
chosen-os:
required: true
type: choice
options:
- Ubuntu
- macOS
jobs:
test:
runs-on: [self-hosted, "${{ inputs.chosen-os }}"]
steps:
- run: echo Hello world!
注意事項:
- 単純な文字列には引用符は不要ですが、式(
"${{ inputs.chosen-os }}"など)には引用符が必要です - 複数のマシンでワークフローを実行したい場合は
jobs.<job_id>.strategyを使用します
3.2 GitHub-hostedランナーの選択
GitHub-hostedランナーを使用する場合、各ジョブはruns-onで指定したランナーイメージの新しいインスタンスで実行されます。
runs-onの値は、ランナーラベルまたはランナーグループの名前です。
3.2.1 パブリックリポジトリ向け標準ランナー(無料・無制限)
| 仮想マシン | CPU | メモリ | ストレージ | アーキテクチャ | ラベル |
|---|---|---|---|---|---|
| Linux | 1 | 5 GB | 14 GB | x64 | ubuntu-slim |
| Linux | 4 | 16 GB | 14 GB | x64 |
ubuntu-latest, ubuntu-24.04, ubuntu-22.04
|
| Windows | 4 | 16 GB | 14 GB | x64 |
windows-latest, windows-2025, windows-2022
|
| Linux | 4 | 16 GB | 14 GB | arm64 |
ubuntu-24.04-arm, ubuntu-22.04-arm
|
| Windows | 4 | 16 GB | 14 GB | arm64 | windows-11-arm |
| macOS | 4 | 14 GB | 14 GB | Intel |
macos-13, macos-15-intel
|
| macOS | 3 (M1) | 7 GB | 14 GB | arm64 |
macos-latest, macos-14, macos-15, macos-26 (パブリックプレビュー) |
シングルCPUランナーを除き、各GitHub-hostedランナーはGitHubがホストする新しい仮想マシンです。シングルCPUランナーは共有VM上のコンテナでホストされます。
3.2.2 プライベートリポジトリ向け標準ランナー(従量課金)
| 仮想マシン | CPU | メモリ | ストレージ | アーキテクチャ | ラベル |
|---|---|---|---|---|---|
| Linux | 1 | 5 GB | 14 GB | x64 | ubuntu-slim |
| Linux | 2 | 7 GB | 14 GB | x64 |
ubuntu-latest, ubuntu-24.04, ubuntu-22.04
|
| Windows | 2 | 7 GB | 14 GB | x64 |
windows-latest, windows-2025, windows-2022
|
| macOS | 4 | 14 GB | 14 GB | Intel |
macos-13, macos-15-intel
|
| macOS | 3 (M1) | 7 GB | 14 GB | arm64 |
macos-latest, macos-14, macos-15, macos-26 (パブリックプレビュー) |
プライベートリポジトリでは、GitHubアカウントの無料分を使用後、分単位で課金されます。
Larger runners:
GitHub TeamおよびGitHub Enterprise Cloudプランの顧客向けに、より多くのコアやディスクスペース、GPU搭載マシン、ARM搭載マシンなど、高度な機能を持つ管理された仮想マシンも提供されています。
注意事項:
-
-latestランナーイメージはGitHubが提供する最新の安定版イメージであり、OSベンダーが提供する最新版とは限りません - ベータ版および非推奨のイメージは「現状のまま」「すべての欠陥を含む」「利用可能な状態で」提供され、SLAや保証の対象外です
- GitHub Free、GitHub Pro、またはGitHub Teamプランでは、他のデプロイメント保護ルール(待機タイマーや必須レビュアーなど)はパブリックリポジトリでのみ利用可能です
3.2.3 OSの指定例
runs-on: ubuntu-latest
3.3 セルフホストランナーの選択
セルフホストランナーにはself-hostedラベルが付与されます(セットアップ時に--no-default-labelsフラグで無効化可能)。
ラベルを使用してランナーのターゲットオプション(OSやアーキテクチャなど)を作成できます。ラベルの配列を指定する場合、self-hostedを最初にリストする必要があります。
runs-on: [self-hosted, linux]
注意事項:
- Actions Runner Controllerは複数ラベルをサポートせず、
self-hostedラベルもサポートしません
3.4 グループを使ったランナー選択
ランナーグループを使用して、グループのメンバーである任意のランナーでジョブを実行できます。より細かい制御が必要な場合は、ランナーグループとラベルを組み合わせることができます。
ランナーグループは、Larger runnerまたはセルフホストランナーのみをメンバーとして持つことができます。
3.4.1 グループを使ったジョブ実行制御
name: learn-github-actions
on: [push]
jobs:
check-bats-version:
runs-on:
group: ubuntu-runners
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v4
with:
node-version: '14'
- run: npm install -g bats
- run: bats -v
この例では、Ubuntuランナーがubuntu-runnersグループに追加されています。runs-onキーは、ubuntu-runnersグループ内の利用可能な任意のランナーにジョブを送信します。
3.4.2 グループとラベルの組み合わせ
グループとラベルを組み合わせると、ランナーは両方の要件を満たす必要があります。
name: learn-github-actions
on: [push]
jobs:
check-bats-version:
runs-on:
group: ubuntu-runners
labels: ubuntu-20.04-16core
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v4
with:
node-version: '14'
- run: npm install -g bats
- run: bats -v
この例では、ubuntu-runnersグループ内の、ubuntu-20.04-16coreラベルも持つランナーでジョブが実行されます。
4. コンテナでの実行
4.1 概要
jobs.<job_id>.containerを使用して、コンテナを指定していないジョブ内のすべてのステップを実行するコンテナを作成します。スクリプトとコンテナアクションの両方を使用するステップがある場合、コンテナアクションは同じネットワーク上で同じボリュームマウントを持つ兄弟コンテナとして実行されます。
コンテナを設定しない場合、すべてのステップはruns-onで指定されたホスト上で直接実行されます(ただし、ステップがコンテナで実行されるよう設定されたアクションを参照している場合を除く)。
注意事項:
- コンテナ内の
runステップのデフォルトシェルはbashではなくshです -
jobs.<job_id>.defaults.runまたはjobs.<job_id>.steps[*].shellで上書き可能です
4.2 基本的なコンテナ設定
name: CI
on:
push:
branches: [ main ]
jobs:
container-test-job:
runs-on: ubuntu-latest
container:
image: node:18
env:
NODE_ENV: development
ports:
- 80
volumes:
- my_docker_volume:/volume_mount
options: --cpus 1
steps:
- name: dockerenv ファイルを確認
run: (ls /.dockerenv && echo dockerenvが見つかりました) || (echo dockerenvがありません)
簡易記法:
コンテナイメージのみを指定する場合、imageキーワードを省略できます。
jobs:
container-test-job:
runs-on: ubuntu-latest
container: node:18
4.3 Dockerfileの命令とオーバーライド
Dockerfileには、Dockerコンテナの内容と起動動作を定義する命令と引数が含まれています。一部のDocker命令はGitHub Actionsと相互作用し、アクションのメタデータファイルが一部のDocker命令を上書きできます。
ワークフローがDockerfileとどのように相互作用するかを理解し、予期しない動作を防ぐようにしてください。
4.4 コンテナイメージの定義
jobs.<job_id>.container.imageを使用して、アクションを実行するコンテナとして使用するDockerイメージを定義します。値はDocker Hubのイメージ名またはレジストリ名です。
注意事項:
Docker Hubは通常、プッシュとプル操作の両方にレート制限を課しており、セルフホストランナーのジョブに影響します。ただし、GitHub-hostedランナーはGitHubとDockerの契約に基づき、これらの制限の対象外です。
4.5 コンテナレジストリの認証情報定義
イメージのコンテナレジストリがイメージのプルに認証を要求する場合、jobs.<job_id>.container.credentialsを使用してusernameとpasswordのマップを設定できます。認証情報はdocker loginコマンドに提供する値と同じです。
container:
image: ghcr.io/owner/image
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
4.6 コンテナでの環境変数の使用
jobs.<job_id>.container.envを使用して、コンテナ内で環境変数のマップを設定します。
4.7 コンテナのネットワークポート公開
jobs.<job_id>.container.portsを使用して、コンテナで公開するポートの配列を設定します。
4.8 コンテナでのボリュームマウント
jobs.<job_id>.container.volumesを使用して、コンテナが使用するボリュームの配列を設定します。ボリュームを使用して、ジョブ内のサービスまたは他のステップ間でデータを共有できます。名前付きDockerボリューム、匿名Dockerボリューム、またはホスト上のバインドマウントを指定できます。
ボリュームを指定するには、ソースパスと宛先パスを指定します:
<source>:<destinationPath>
<source>はホストマシン上のボリューム名または絶対パス、<destinationPath>はコンテナ内の絶対パスです。
volumes:
- my_docker_volume:/volume_mount
- /data/my_data
- /source/directory:/destination/directory
4.9 コンテナリソースオプションの設定
jobs.<job_id>.container.optionsを使用して、追加のDockerコンテナリソースオプションを設定します。
警告:
--networkおよび--entrypointオプションはサポートされていません。
5. アクションの活用
5.1 ワークフローエディターでのMarketplaceアクション閲覧
リポジトリのワークフローエディターで、アクションを直接検索および閲覧できます。サイドバーから特定のアクションを検索したり、注目のアクションを表示したり、注目のカテゴリーを閲覧したりできます。GitHubコミュニティからアクションが受け取ったスター数も表示されます。
- リポジトリ内の編集したいワークフローファイルを開きます
- ファイルビューの右上隅にある鉛筆アイコンをクリックしてワークフローエディターを開きます
- エディターの右側にあるGitHub Marketplaceサイドバーを使用してアクションを閲覧します
- バッジ付きのアクションは、GitHubがアクションの作成者をパートナー組織として検証したことを示します
5.2 ワークフローへのアクション追加
アクションをワークフローに追加するには、ワークフローファイル内でアクションを参照します。ワークフローで使用するアクションは、次の場所で定義できます:
- ワークフローファイルと同じリポジトリ
- 任意のパブリックリポジトリ
- Docker Hubで公開されているDockerコンテナイメージ
ワークフローで参照されるアクションは、ワークフローを含むリポジトリの依存関係グラフに依存関係として表示できます。
注意事項:
セキュリティ強化のため、GitHub Actionsはアクションや再利用可能なワークフローのリダイレクトをサポートしていません。アクションのリポジトリの所有者、名前、またはアクション名が変更されると、以前の名前を使用したワークフローは失敗します。
5.3 GitHub Marketplaceからのアクション追加
アクションのリストページには、アクションのバージョンと、アクションを使用するために必要なワークフロー構文が含まれています。アクションに更新が行われてもワークフローを安定させるため、ワークフローファイルでGitまたはDockerタグ番号を指定してアクションのバージョンを参照できます。
- ワークフローで使用したいアクションに移動します
- アクションの完全なマーケットプレイスリストを表示するためクリックします
- 「Installation」の下で、コピーアイコンをクリックしてワークフロー構文をコピーします
- 構文をワークフローの新しいステップとして貼り付けます
- アクションが入力を要求する場合は、ワークフローで設定します
ワークフローに追加したアクションのDependabotバージョン更新を有効にすることもできます。
5.4 同じリポジトリからのアクション追加
アクションがワークフローファイルを使用するのと同じリポジトリで定義されている場合、{owner}/{repo}@{ref}または./path/to/dir構文でワークフローファイル内のアクションを参照できます。
リポジトリファイル構造の例:
|-- hello-world (リポジトリ)
| |__ .github
| └── workflows
| └── my-first-workflow.yml
| └── actions
| |__ hello-world-action
| └── action.yml
パスはデフォルトの作業ディレクトリ(github.workspace、$GITHUB_WORKSPACE)からの相対パスです。アクションがワークフローとは異なる場所にリポジトリをチェックアウトする場合、ローカルアクションに使用される相対パスを更新する必要があります。
ワークフローファイルの例:
jobs:
my_first_job:
runs-on: ubuntu-latest
steps:
# リポジトリのコピーをチェックアウト
- name: 最初のステップ - リポジトリをチェックアウト
uses: actions/checkout@v5
# アクションを含むディレクトリを参照
- name: ローカルのhello-world-actionを使用
uses: ./.github/actions/hello-world-action
action.ymlファイルは、アクションのメタデータを提供するために使用されます。
5.5 別のリポジトリからのアクション追加
アクションがワークフローファイルとは異なるリポジトリで定義されている場合、ワークフローファイル内で{owner}/{repo}@{ref}構文を使用してアクションを参照できます。
アクションはパブリックリポジトリに保存されている必要があります。
jobs:
my_first_job:
steps:
- name: 最初のステップ
uses: actions/setup-node@v4
5.6 Docker Hubのコンテナを参照
アクションがDocker Hub上の公開されているDockerコンテナイメージで定義されている場合、ワークフローファイル内でdocker://{image}:{tag}構文を使用してアクションを参照する必要があります。コードとデータを保護するため、ワークフローで使用する前にDocker HubからのDockerコンテナイメージの整合性を検証することを強くお勧めします。
jobs:
my_first_job:
steps:
- name: 最初のステップ
uses: docker://alpine:3.8
5.7 ワークフローでアクションを使用するためのセキュリティ強化
GitHubは、ワークフローのセキュリティを高めるために使用できるセキュリティ機能を提供しています。GitHubの組み込み機能を使用して、使用するアクションの脆弱性について通知を受けたり、ワークフロー内のアクションを最新の状態に保つプロセスを自動化したりできます。
5.8 カスタムアクションのリリース管理の使用
コミュニティアクションの作成者は、タグ、ブランチ、またはSHA値を使用してアクションのリリースを管理するオプションがあります。依存関係と同様に、アクションの更新を自動的に受け入れることに対する快適さに基づいて、使用したいアクションのバージョンを示す必要があります。
ワークフローファイル内でアクションのバージョンを指定します。アクションのドキュメントでリリース管理へのアプローチ、使用するタグ、ブランチ、またはSHA値の情報を確認してください。
注意事項:
サードパーティのアクションを使用する場合、SHA値を使用することをお勧めします。ただし、Dependabotは、セマンティックバージョニングを使用するGitHub Actionsに対してのみDependabotアラートを作成します。
5.8.1 タグの使用
タグは、メジャーバージョンとマイナーバージョンの間で切り替えるタイミングを決定するのに役立ちますが、これらはより一時的であり、メンテナーによって移動または削除される可能性があります。
steps:
- uses: actions/javascript-action@v1.0.1
5.8.2 SHAの使用
より信頼性の高いバージョニングが必要な場合は、アクションのバージョンに関連付けられたSHA値を使用する必要があります。SHAは不変であるため、タグやブランチよりも信頼性があります。ただし、このアプローチでは、重要なバグ修正やセキュリティ更新を含むアクションの更新を自動的に受け取ることはできません。コミットの完全なSHA値を使用する必要があり、省略値は使用できません。
SHAを選択する際は、アクションのリポジトリからのものであることを確認し、リポジトリのフォークからではないことを確認する必要があります。
steps:
- uses: actions/javascript-action@a824008085750b8e136effc585c3cd6082bd575f
5.8.3 ブランチの使用
アクションのターゲットブランチを指定すると、そのブランチに現在あるバージョンが常に実行されます。このアプローチは、ブランチへの更新に破壊的変更が含まれている場合、問題を引き起こす可能性があります。
steps:
- uses: actions/javascript-action@main
5.9 アクションでの入力と出力の使用
アクションは多くの場合、入力を受け入れたり要求したりし、使用できる出力を生成します。例えば、アクションは、ファイルへのパス、ラベルの名前、またはアクション処理の一部として使用する他のデータを指定することを要求する場合があります。
アクションの入力と出力を確認するには、リポジトリのルートディレクトリにあるaction.ymlを確認します。
action.ymlの例:
name: "例"
description: "ファイルを受け取り、出力を生成"
inputs:
file-path: # 入力のID
description: "テストスクリプトへのパス"
required: true
default: "test-file.js"
outputs:
results-file: # 出力のID
description: "結果ファイルへのパス"
この例では、inputsキーワードはfile-pathという必須入力を定義し、指定されていない場合に使用されるデフォルト値を含んでいます。outputsキーワードはresults-fileという出力を定義し、結果を見つける場所を示します。
6. シークレットと変数の管理
6.1 シークレットの作成場所
6.2 リポジトリのシークレット作成
組織リポジトリのシークレットや変数をGitHubで作成するには、書き込みアクセス権が必要です。個人アカウントリポジトリの場合、WebUIでシークレットや変数を作成するにはリポジトリ所有者である必要があり、REST API経由で作成するにはリポジトリコラボレーターである必要があります。
- GitHub上でリポジトリのメインページに移動
- リポジトリ名の下にある「Settings」タブをクリック
- サイドバーの「Security」セクションで、「Secrets and variables」を選択し、「Actions」をクリック
- 「Secrets」タブをクリック
- 「New repository secret」をクリック
- 「Name」フィールドにシークレットの名前を入力
- 「Secret」フィールドにシークレットの値を入力
- 「Add secret」をクリック
リポジトリに環境シークレットがある場合、または親組織からシークレットにアクセスできる場合、それらのシークレットもこのページにリストされます。
6.3 環境のシークレット作成
個人アカウントリポジトリで環境のシークレットや変数を作成するには、リポジトリ所有者である必要があります。組織リポジトリで環境のシークレットや変数を作成するには、管理者アクセス権が必要です。
- GitHub上でリポジトリのメインページに移動
- リポジトリ名の下にある「Settings」タブをクリック
- 左サイドバーで「Environments」をクリック
- シークレットを追加したい環境をクリック
- 「Environment secrets」の下で「Add secret」をクリック
- 「Name」入力ボックスにシークレットの名前を入力
- シークレットの値を入力
- 「Add secret」をクリック
6.4 組織のシークレット作成
注意事項:
組織レベルのシークレットと変数は、GitHub Freeのプライベートリポジトリではアクセスできません。
組織でシークレットや変数を作成する場合、ポリシーを使用してリポジトリごとのアクセスを制限できます。例えば、すべてのリポジトリへのアクセスを許可したり、プライベートリポジトリまたは指定したリポジトリのリストのみにアクセスを制限したりできます。
組織所有者は、組織レベルでシークレットや変数を作成できます。
- GitHub上で組織のメインページに移動
- 組織名の下にある「Settings」タブをクリック
- サイドバーの「Security」セクションで、「Secrets and variables」を選択し、「Actions」をクリック
- 「Secrets」タブをクリック
- 「New organization secret」をクリック
- 「Name」入力ボックスにシークレットの名前を入力
- シークレットの「Value」を入力
- 「Repository access」ドロップダウンリストからアクセスポリシーを選択
- 「Add secret」をクリック
6.5 組織レベルシークレットへのアクセスの確認
組織内のシークレットにどのアクセスポリシーが適用されているかを確認できます。
- GitHub上で組織のメインページに移動
- 組織名の下にある「Settings」タブをクリック
- サイドバーの「Security」セクションで、「Secrets and variables」を選択し、「Actions」をクリック
- シークレットのリストには、設定された権限とポリシーが含まれています。各シークレットの設定された権限の詳細については、「Update」をクリックします
6.6 ワークフローでのシークレット使用
注意事項:
-
GITHUB_TOKENを除き、シークレットはフォークリポジトリからトリガーされたワークフローにはランナーに渡されません - シークレットは再利用可能なワークフローに自動的に渡されません
- Dependabotイベントによってトリガーされたワークフローではシークレットは利用できません
GitHub ActionsワークフローがOpenID Connect(OIDC)をサポートするクラウドプロバイダーのリソースにアクセスする必要がある場合、ワークフローをクラウドプロバイダーに直接認証するように設定できます。これにより、これらの認証情報を長期間有効なシークレットとして保存するのを停止でき、他のセキュリティ上の利点も得られます。
警告:
GitHubシークレットではない機密情報は、::add-mask::VALUEを使用してマスクしてください。これにより、値がシークレットとして扱われ、ログから編集されます。
シークレットを入力または環境変数としてアクションに提供するには、secretsコンテキストを使用して、リポジトリで作成したシークレットにアクセスできます。
steps:
- name: Hello worldアクション
with: # 入力として設定
super_secret: ${{ secrets.SuperSecret }}
env: # または環境変数として
super_secret: ${{ secrets.SuperSecret }}
シークレットはif条件内で直接参照できません。代わりに、シークレットをジョブレベルの環境変数として設定し、ジョブ内のステップを条件付きで実行するために環境変数を参照することを検討してください。
シークレットが設定されていない場合、シークレットを参照する式(例:例の${{ secrets.SuperSecret }})の戻り値は空の文字列になります。
可能な限り、コマンドラインからプロセス間でシークレットを渡すことは避けてください。コマンドラインプロセスは他のユーザー(psコマンドを使用)に見える可能性があるか、セキュリティ監査イベントによってキャプチャされる可能性があります。シークレットを保護するために、環境変数、STDIN、またはターゲットプロセスがサポートする他のメカニズムの使用を検討してください。
コマンドライン内でシークレットを渡す必要がある場合は、適切な引用規則内に含めてください。シークレットには多くの場合、シェルに意図せず影響を与える可能性のある特殊文字が含まれています。これらの特殊文字をエスケープするには、環境変数で引用を使用します。
Bashを使用した例:
steps:
- shell: bash
env:
SUPER_SECRET: ${{ secrets.SuperSecret }}
run: |
example-command "$SUPER_SECRET"
PowerShellを使用した例:
steps:
- shell: pwsh
env:
SUPER_SECRET: ${{ secrets.SuperSecret }}
run: |
example-command "$env:SUPER_SECRET"
Cmd.exeを使用した例:
steps:
- shell: cmd
env:
SUPER_SECRET: ${{ secrets.SuperSecret }}
run: |
example-command "%SUPER_SECRET%"
6.7 大きなシークレットの保存
48KBより大きいシークレットを使用するには、回避策を使用してシークレットをリポジトリに保存し、復号化パスフレーズをGitHub上のシークレットとして保存できます。例えば、gpgを使用して、シークレットを含むファイルをローカルで暗号化してから、暗号化されたファイルをGitHub上のリポジトリにチェックインできます。
警告:
ワークフローの実行時にシークレットが出力されないように注意してください。この回避策を使用する場合、GitHubはログに出力されたシークレットを編集しません。
- ターミナルから次のコマンドを実行して、
gpgとAES256暗号アルゴリズムを使用してシークレットを含むファイルを暗号化します。この例では、my_secret.jsonがシークレットを含むファイルです。
gpg --symmetric --cipher-algo AES256 my_secret.json
-
パスフレーズの入力を求められます。パスフレーズを覚えておいてください。パスフレーズを値として使用する新しいシークレットをGitHubで作成する必要があります。
-
パスフレーズを含む新しいシークレットを作成します。例えば、
LARGE_SECRET_PASSPHRASEという名前で新しいシークレットを作成し、シークレットの値を上記のステップで使用したパスフレーズに設定します。 -
暗号化されたファイルをリポジトリ内のパスにコピーしてコミットします。この例では、暗号化されたファイルは
my_secret.json.gpgです。
警告:
.gpgファイル拡張子で終わる暗号化されたmy_secret.json.gpgファイルをコピーしてください。暗号化されていないmy_secret.jsonファイルではありません。
git add my_secret.json.gpg
git commit -m "暗号化された新しいシークレットJSONファイルを追加"
- シークレットファイルを復号化するシェルスクリプトをリポジトリに作成します。この例では、スクリプトは
decrypt_secret.shという名前です。
#!/bin/sh
# ファイルを復号化
mkdir $HOME/secrets
# --batchで対話コマンドを防止
# --yesで質問に対して「yes」を仮定
gpg --quiet --batch --yes --decrypt --passphrase="$LARGE_SECRET_PASSPHRASE" \
--output $HOME/secrets/my_secret.json my_secret.json.gpg
- リポジトリにチェックインする前に、シェルスクリプトが実行可能であることを確認します。
chmod +x decrypt_secret.sh
git add decrypt_secret.sh
git commit -m "新しい復号化スクリプトを追加"
git push
- GitHub Actionsワークフローから、ステップを使用してシェルスクリプトを呼び出し、シークレットを復号化します。ワークフローが実行される環境にリポジトリのコピーを持つには、
actions/checkoutアクションを使用する必要があります。リポジトリのルートからの相対パスでrunコマンドを使用してシェルスクリプトを参照します。
name: 大きなシークレットを使用するワークフロー
on: push
jobs:
my-job:
name: マイジョブ
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: 大きなシークレットを復号化
run: ./decrypt_secret.sh
env:
LARGE_SECRET_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }}
# このコマンドは、シークレットが出力されていることを示す例に過ぎません
# シークレットの出力ステートメントを削除してください。GitHubは
# この回避策を使用するシークレットを隠しません。
- name: シークレットの出力テスト(本番環境ではこのステップを削除)
run: cat $HOME/secrets/my_secret.json
6.8 Base64バイナリブロブをシークレットとして保存
Base64エンコーディングを使用して、小さなバイナリブロブをシークレットとして保存できます。その後、ワークフロー内でシークレットを参照し、ランナーで使用するためにデコードできます。サイズ制限については、本セクションを参照してください。
注意事項:
Base64は単にバイナリをテキストに変換するだけで、実際の暗号化の代替ではありません。
他のシェルを使用すると、シークレットをファイルにデコードするために異なるコマンドが必要になる場合があります。Windowsランナーでは、上記のrunステップでコマンドを使用するために、shell: bashを使用したbashシェルを使用することをお勧めします。
-
base64を使用してファイルをBase64文字列にエンコードします。
macOSの場合:
base64 -i cert.der -o cert.base64
Linuxの場合:
base64 -w 0 cert.der > cert.base64
- Base64文字列を含むシークレットを作成します。
$ gh secret set CERTIFICATE_BASE64 < cert.base64
✓ シークレットCERTIFICATE_BASE64をoctocat/octorepoに設定しました
- ランナーからBase64文字列にアクセスするには、シークレットを
base64 --decodeにパイプします。
name: Base64シークレットを取得
on:
push:
branches: [ octo-branch ]
jobs:
decode-secret:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: シークレットを取得してファイルにデコード
env:
CERTIFICATE_BASE64: ${{ secrets.CERTIFICATE_BASE64 }}
run: |
echo $CERTIFICATE_BASE64 | base64 --decode > cert.der
- name: 証明書情報を表示
run: |
openssl x509 -in cert.der -inform DER -text -noout
6.9 設定変数の定義
複数のワークフローで使用する設定変数を作成でき、リポジトリ、環境、または組織レベルで定義できます。
例えば、設定変数を使用して、組織レベルでビルドツールに渡されるパラメータのデフォルト値を設定し、リポジトリ所有者がこれらのパラメータをケースバイケースで上書きできるようにすることができます。
設定変数を作成すると、varsコンテキストで自動的に利用可能になります。
6.9.1 リポジトリの設定変数作成
組織リポジトリのシークレットや変数をGitHubで作成するには、書き込みアクセス権が必要です。個人アカウントリポジトリの場合、WebUIでシークレットや変数を作成するにはリポジトリ所有者である必要があり、REST API経由で作成するにはリポジトリコラボレーターである必要があります。
- GitHub上でリポジトリのメインページに移動
- リポジトリ名の下にある「Settings」タブをクリック
- サイドバーの「Security」セクションで、「Secrets and variables」を選択し、「Actions」をクリック
- 「Variables」タブをクリック
- 「New repository variable」をクリック
- 「Name」フィールドに変数の名前を入力
- 「Value」フィールドに変数の値を入力
- 「Add variable」をクリック
6.9.2 環境の設定変数作成
個人アカウントリポジトリで環境のシークレットや変数を作成するには、リポジトリ所有者である必要があります。組織リポジトリで環境のシークレットや変数を作成するには、管理者アクセス権が必要です。
- GitHub上でリポジトリのメインページに移動
- リポジトリ名の下にある「Settings」タブをクリック
- 左サイドバーで「Environments」をクリック
- 変数を追加したい環境をクリック
- 「Environment variables」の下で「Add variable」をクリック
- 「Name」フィールドに変数の名前を入力
- 「Value」フィールドに変数の値を入力
- 「Add variable」をクリック
6.9.3 組織の設定変数作成
注意事項:
組織レベルのシークレットと変数は、GitHub Freeのプライベートリポジトリではアクセスできません。
組織でシークレットや変数を作成する場合、ポリシーを使用してリポジトリごとのアクセスを制限できます。例えば、すべてのリポジトリへのアクセスを許可したり、プライベートリポジトリまたは指定したリポジトリのリストのみにアクセスを制限したりできます。
組織所有者は、組織レベルでシークレットや変数を作成できます。
- GitHub上で組織のメインページに移動
- 組織名の下にある「Settings」タブをクリック
- サイドバーの「Security」セクションで、「Secrets and variables」を選択し、「Actions」をクリック
- 「Variables」タブをクリック
- 「New organization variable」をクリック
- 「Name」フィールドに変数の名前を入力
- 「Value」フィールドに変数の値を入力
- 「Repository access」ドロップダウンリストからアクセスポリシーを選択
- 「Add variable」をクリック
6.10 コンテキストを使用した変数値へのアクセス
コンテキストは、ワークフロー実行、変数、ランナー環境、ジョブ、ステップに関する情報にアクセスする方法です。
多くの他のコンテキストがあり、ワークフロー内でさまざまな目的で使用できます。ワークフロー内で特定のコンテキストを使用できる場所の詳細については、コンテキストリファレンスを参照してください。
6.10.1 envコンテキストを使用した環境変数値へのアクセス
ランナー環境変数に加えて、GitHub Actionsではenvキー値を使用してコンテキストを設定および読み取ることができます。環境変数とコンテキストは、ワークフロー内の異なるポイントで使用することを目的としています。
ワークフロー内のrunステップ、または参照されるアクションは、ランナーによって処理されます。その結果、ランナー環境変数をここで使用できます。ランナーで使用しているシェルに適した構文を使用します。例えば、Linuxランナーのbashシェルの場合は$NAME、WindowsのPowerShellの場合は$env:NAMEです。ほとんどの場合、コンテキストも使用でき、構文は${{ CONTEXT.PROPERTY }}で、同じ値にアクセスできます。違いは、コンテキストが補間され、ジョブがランナーに送信される前に文字列に置き換えられることです。
ただし、ワークフローの一部でGitHub Actionsによって処理され、ランナーに送信されないものについては、ランナー環境変数を使用できません。代わりに、コンテキストを使用する必要があります。例えば、ジョブやステップがランナーに送信されるかどうかを決定するif条件は、常にGitHub Actionsによって処理されます。したがって、変数の値にアクセスするには、if条件ステートメント内でコンテキストを使用する必要があります。
name: 条件付きenv変数
on: workflow_dispatch
env:
DAY_OF_WEEK: Monday
jobs:
greeting_job:
runs-on: ubuntu-latest
env:
Greeting: Hello
steps:
- name: "月曜日にHello Monaと言う"
if: ${{ env.DAY_OF_WEEK == 'Monday' }}
run: echo "$Greeting $First_Name. 今日は$DAY_OF_WEEKです!"
env:
First_Name: Mona
この前の例の修正版では、if条件を導入しました。ワークフローステップは、DAY_OF_WEEKが「Monday」に設定されている場合のみ実行されます。if条件ステートメントからenvコンテキストを使用してこの値にアクセスします。envコンテキストはrunコマンド内で参照される変数には必要ありません。これらはランナー環境変数として参照され、ジョブがランナーによって受信された後に補間されます。ただし、ジョブをランナーに送信する前にこれらの変数を補間するために、コンテキストを使用することもできます。結果の出力は同じです。
run: echo "${{ env.Greeting }} ${{ env.First_Name }}. 今日は${{ env.DAY_OF_WEEK }}です!"
注意事項:
コンテキストは通常、${{ context.property }}のようにドル記号と中括弧を使用して表されます。if条件では、${{ }}はオプションですが、使用する場合は、上記のように比較ステートメント全体を囲む必要があります。
警告:
ワークフローとアクションを作成する際は、コードが潜在的な攻撃者からの信頼できない入力を実行する可能性があるかどうかを常に考慮する必要があります。特定のコンテキストは信頼できない入力として扱われる必要があります。攻撃者が自分の悪意のあるコンテンツを挿入する可能性があるためです。
6.10.2 varsコンテキストを使用した設定変数値へのアクセス
設定変数は、varsコンテキストを使用してワークフロー全体でアクセスできます。
設定変数が設定されていない場合、変数を参照するコンテキストの戻り値は空の文字列になります。
次の例は、varsコンテキストを使用したワークフロー全体での設定変数の使用を示しています。次の各設定変数は、リポジトリ、組織、または環境レベルで定義されています。
on:
workflow_dispatch:
env:
# envコンテキスト変数に設定変数の値を設定
env_var: ${{ vars.ENV_CONTEXT_VAR }}
jobs:
display-variables:
name: ${{ vars.JOB_NAME }}
# varsコンテキストを使用して動的ジョブを作成できます
if: ${{ vars.USE_VARIABLES == 'true' }}
runs-on: ${{ vars.RUNNER }}
environment: ${{ vars.ENVIRONMENT_STAGE }}
steps:
- name: 変数を使用
run: |
echo "リポジトリ変数: $REPOSITORY_VAR"
echo "組織変数: $ORGANIZATION_VAR"
echo "上書きされた変数: $OVERRIDE_VAR"
echo "シェル環境からの変数: $env_var"
env:
REPOSITORY_VAR: ${{ vars.REPOSITORY_VAR }}
ORGANIZATION_VAR: ${{ vars.ORGANIZATION_VAR }}
OVERRIDE_VAR: ${{ vars.OVERRIDE_VAR }}
- name: ${{ vars.HELLO_WORLD_STEP }}
if: ${{ vars.HELLO_WORLD_ENABLED == 'true' }}
uses: actions/hello-world-javascript-action@main
with:
who-to-greet: ${{ vars.GREET_NAME }}
6.11 OSの検出
単一のワークフローファイルを作成し、RUNNER_OSデフォルト環境変数と対応するコンテキストプロパティ${{ runner.os }}を使用して、異なるOSで使用できます。例えば、次のワークフローは、OSをmacos-latestからwindows-latestに変更しても、ランナーが使用しているシェルに応じて異なる環境変数の構文を変更することなく、正常に実行できます。
on: workflow_dispatch
jobs:
if-Windows-else:
runs-on: macos-latest
steps:
- name: 条件1
if: runner.os == 'Windows'
run: echo "ランナー上のOSは$env:RUNNER_OSです。"
- name: 条件2
if: runner.os != 'Windows'
run: echo "ランナー上のOSはWindowsではなく、$RUNNER_OSです。"
この例では、2つのifステートメントがrunnerコンテキストのosプロパティをチェックして、ランナーのOSを判定します。if条件はGitHub Actionsによって処理され、チェックがtrueと解決されたステップのみがランナーに送信されます。ここでは、チェックの1つが常にtrueで、もう1つがfalseであるため、これらのステップの1つのみがランナーに送信されます。ジョブがランナーに送信されると、ステップが実行され、echoコマンド内の環境変数が適切な構文(WindowsのPowerShellの場合は$env:NAME、LinuxおよびmacOSのbashおよびshの場合は$NAME)を使用して補間されます。この例では、ステートメントruns-on: macos-latestは2番目のステップが実行されることを意味します。
6.12 ワークフロー内のステップとジョブ間での値の受け渡し
ジョブの1つのステップで値を生成した場合、既存または新しい環境変数に値を割り当て、これをGITHUB_ENV環境ファイルに書き込むことで、同じジョブの後続のステップで値を使用できます。環境ファイルはアクションによって直接使用することも、runキーワードを使用してワークフローファイル内のシェルコマンドから使用することもできます。
ワークフロー内の1つのジョブのステップから、ワークフロー内の別のジョブのステップに値を渡したい場合、値をジョブ出力として定義できます。その後、別のジョブのステップからこのジョブ出力を参照できます。
7. ジョブとステップの制御
7.1 ジョブのIDの設定
jobs.<job_id>を使用して、ジョブに一意の識別子を付けます。キーjob_idは文字列であり、その値はジョブの設定データのマップです。<job_id>は、jobsオブジェクトに固有の文字列に置き換える必要があります。<job_id>は、文字または_で始まり、英数字、-、または_のみを含む必要があります。
例:ジョブの作成
この例では、2つのジョブが作成され、それらのjob_id値はmy_first_jobとmy_second_jobです。
jobs:
my_first_job:
name: 最初のジョブ
my_second_job:
name: 2番目のジョブ
7.2 ジョブの名前設定
jobs.<job_id>.nameを使用して、GitHub UIに表示されるジョブの名前を設定します。
7.3 前提条件ジョブの定義
jobs.<job_id>.needsを使用して、このジョブが実行される前に正常に完了する必要があるジョブを特定します。文字列または文字列の配列にすることができます。ジョブが失敗またはスキップされた場合、それを必要とするすべてのジョブはスキップされます。ただし、ジョブが継続する条件式を使用している場合を除きます。
実行に互いに必要な一連のジョブが含まれている場合、失敗またはスキップは、失敗またはスキップのポイントから先の依存関係チェーン内のすべてのジョブに適用されます。
ジョブが依存しているジョブが成功しなかった場合でもジョブを実行したい場合は、jobs.<job_id>.ifでalways()条件式を使用します。
例:成功した依存ジョブの要求
jobs:
job1:
job2:
needs: job1
job3:
needs: [job1, job2]
この例では、job1はjob2が開始される前に正常に完了する必要があり、job3はjob1とjob2の両方が完了するまで待機します。
この例のジョブは順次実行されます:
job1job2job3
例:成功した依存ジョブを要求しない
jobs:
job1:
job2:
needs: job1
job3:
if: ${{ always() }}
needs: [job1, job2]
この例では、job3はalways()条件式を使用して、job1とjob2が完了した後、成功したかどうかに関係なく常に実行されます。
7.4 条件付き実行
jobs.<job_id>.if条件を使用して、条件が満たされない限りジョブが実行されないようにすることができます。サポートされている任意のコンテキストと式を使用して条件を作成できます。
if条件で式を使用する場合、式構文(${{}})を省略できます。GitHubは自動的にif条件を式として評価するためです。
例:特定のリポジトリでのみジョブを実行
この例では、ifを使用して、production-deployジョブをいつ実行できるかを制御します。リポジトリがocto-repo-prodという名前で、octo-org組織内にある場合のみ実行されます。それ以外の場合、ジョブはスキップされたとしてマークされます。
name: example-workflow
on: [push]
jobs:
production-deploy:
if: ${{ github.repository == 'octo-org/octo-repo-prod' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v4
with:
node-version: '14'
- run: npm install -g bats
スキップされたジョブには、「This check was skipped」というメッセージが表示されます。
注意事項:
スキップされたジョブは、そのステータスを「Success」として報告します。必須チェックであっても、プルリクエストのマージを妨げることはありません。
7.5 異なる変数でジョブを実行するためのマトリックスの使用
単一のジョブ定義で変数を使用して、変数の組み合わせに基づいて複数のジョブ実行を自動的に作成するには、マトリックス戦略を使用します。例えば、マトリックス戦略を使用して、複数のバージョンの言語または複数のOSでコードをテストできます。
7.5.1 ワークフロージョブへのマトリックス戦略の追加
jobs.<job_id>.strategy.matrixを使用して、異なるジョブ設定のマトリックスを定義します。マトリックス内で、値の配列が続く1つ以上の変数を定義します。例えば、次のマトリックスには、値[10, 12, 14]を持つversionという変数と、値[ubuntu-latest, windows-latest]を持つosという変数があります:
jobs:
example_matrix:
strategy:
matrix:
version: [10, 12, 14]
os: [ubuntu-latest, windows-latest]
変数の可能なすべての組み合わせに対してジョブが実行されます。この例では、ワークフローは6つのジョブを実行します。osとversion変数の各組み合わせに1つずつです。
上記のマトリックスは、次の順序でジョブを作成します:
{version: 10, os: ubuntu-latest}{version: 10, os: windows-latest}{version: 12, os: ubuntu-latest}{version: 12, os: windows-latest}{version: 14, os: ubuntu-latest}{version: 14, os: windows-latest}
7.5.2 コンテキストを使用したマトリックスの作成
ワークフロー実行、変数、ランナー環境、ジョブ、ステップに関する情報を使用してマトリックスを作成するには、${{ <context> }}式構文を使用してコンテキストにアクセスします。
例えば、次のワークフローはrepository_dispatchイベントでトリガーされ、イベントペイロードの情報を使用してマトリックスを構築します。以下のようなペイロードでリポジトリディスパッチイベントが作成されると、マトリックスversion変数の値は[12, 14, 16]になります。
{
"event_type": "test",
"client_payload": {
"versions": [12, 14, 16]
}
}
on:
repository_dispatch:
types:
- test
jobs:
example_matrix:
runs-on: ubuntu-latest
strategy:
matrix:
version: ${{ github.event.client_payload.versions }}
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.version }}
7.5.3 マトリックス設定の拡張または追加
既存のマトリックス設定を拡張したり、新しい設定を追加したりするには、jobs.<job_id>.strategy.matrix.includeを使用します。includeの値はオブジェクトのリストです。
例えば、次のマトリックスを考えてみましょう:
strategy:
matrix:
fruit: [apple, pear]
animal: [cat, dog]
include:
- color: green
- color: pink
animal: cat
- fruit: apple
shape: circle
- fruit: banana
- fruit: banana
animal: cat
これにより、次のマトリックス組み合わせで6つのジョブが作成されます:
{fruit: apple, animal: cat, color: pink, shape: circle}{fruit: apple, animal: dog, color: green, shape: circle}{fruit: pear, animal: cat, color: pink}{fruit: pear, animal: dog, color: green}{fruit: banana}{fruit: banana, animal: cat}
各includeエントリは次のように適用されます:
-
{color: green}は、元の組み合わせの一部を上書きせずに追加できるため、すべての元のマトリックス組み合わせに追加されます -
{color: pink, animal: cat}は、animal: catを含む元のマトリックス組み合わせにのみcolor:pinkを追加します。これにより、前のincludeエントリによって追加されたcolor: greenが上書きされます -
{fruit: apple, shape: circle}は、fruit: appleを含む元のマトリックス組み合わせにのみshape: circleを追加します -
{fruit: banana}は、値を上書きせずに元のマトリックス組み合わせに追加できないため、追加のマトリックス組み合わせとして追加されます -
{fruit: banana, animal: cat}は、値を上書きせずに元のマトリックス組み合わせに追加できないため、追加のマトリックス組み合わせとして追加されます。これは、元のマトリックス組み合わせの1つではなかったため、{fruit: banana}マトリックス組み合わせには追加されません
7.5.4 マトリックス設定の除外
マトリックスで定義された特定の設定を削除するには、jobs.<job_id>.strategy.matrix.excludeを使用します。
例えば、次のワークフローは9つのジョブを実行します。12の設定それぞれに1つのジョブ、{os: macos-latest, version: 12, environment: production}に一致する1つの除外ジョブ、および{os: windows-latest, version: 16}に一致する2つの除外ジョブを引いた数です。
strategy:
matrix:
os: [macos-latest, windows-latest]
version: [12, 14, 16]
environment: [staging, production]
exclude:
- os: macos-latest
version: 12
environment: production
- os: windows-latest
version: 16
runs-on: ${{ matrix.os }}
7.5.5 出力を使用して2つのマトリックスを定義
1つのジョブの出力を使用して、複数のジョブのマトリックスを定義できます。
例えば、次のワークフローは、1つのジョブでマトリックス値を定義し、2番目のジョブでそのマトリックスを使用してアーティファクトを生成し、3番目のジョブでそれらのアーティファクトを使用する方法を示しています。各アーティファクトはマトリックスの値に関連付けられています。
name: 共有マトリックス
on:
push:
workflow_dispatch:
jobs:
define-matrix:
runs-on: ubuntu-latest
outputs:
colors: ${{ steps.colors.outputs.colors }}
steps:
- name: 色を定義
id: colors
run: |
echo 'colors=["red", "green", "blue"]' >> "$GITHUB_OUTPUT"
produce-artifacts:
runs-on: ubuntu-latest
needs: define-matrix
strategy:
matrix:
color: ${{ fromJSON(needs.define-matrix.outputs.colors) }}
steps:
- name: 色を定義
env:
color: ${{ matrix.color }}
run: |
echo "$color" > color
- name: アーティファクトを生成
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.color }}
path: color
consume-artifacts:
runs-on: ubuntu-latest
needs:
- define-matrix
- produce-artifacts
strategy:
matrix:
color: ${{ fromJSON(needs.define-matrix.outputs.colors) }}
steps:
- name: アーティファクトを取得
uses: actions/download-artifact@v5
with:
name: ${{ matrix.color }}
- name: 色をレポート
run: |
cat color
7.5.6 失敗の処理
ジョブの失敗を処理する方法を制御するには、jobs.<job_id>.strategy.fail-fastとjobs.<job_id>.continue-on-errorを使用します。
jobs.<job_id>.strategy.fail-fastとjobs.<job_id>.continue-on-errorを一緒に使用できます。例えば、次のワークフローは4つのジョブを開始します。各ジョブについて、continue-on-errorはmatrix.experimentalの値によって決定されます。continue-on-error: falseのジョブのいずれかが失敗した場合、進行中またはキューに入れられているすべてのジョブがキャンセルされます。continue-on-error: trueのジョブが失敗した場合、他のジョブは影響を受けません。
jobs:
test:
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.experimental }}
strategy:
fail-fast: true
matrix:
version: [6, 7, 8]
experimental: [false]
include:
- version: 9
experimental: true
7.5.7 同時ジョブの最大数の定義
マトリックスジョブ戦略を使用する際に同時に実行できるジョブの最大数を設定するには、jobs.<job_id>.strategy.max-parallelを使用します。
例えば、次のワークフローは、6つのジョブすべてを一度に実行するランナーが利用可能であっても、一度に最大2つのジョブを実行します。
jobs:
example_matrix:
strategy:
max-parallel: 2
matrix:
version: [10, 12, 14]
os: [ubuntu-latest, windows-latest]
7.6 ジョブ間での情報受け渡し
7.6.1 ジョブ出力の定義と使用
- 出力を取得したいジョブを含むワークフローファイルを開きます
-
jobs.<job_id>.outputs構文を使用して、ジョブの出力を定義します。例えば、次のジョブはoutput1とoutput2の出力を定義し、それぞれstep1とstep2の結果にマップされています:
jobs:
job1:
runs-on: ubuntu-latest
outputs:
output1: ${{ steps.step1.outputs.test }}
output2: ${{ steps.step2.outputs.test }}
steps:
- id: step1
run: echo "test=hello" >> "$GITHUB_OUTPUT"
- id: step2
run: echo "test=world" >> "$GITHUB_OUTPUT"
- それらの出力にアクセスしたい別のジョブで、
jobs.<job_id>.needs構文を使用して元のジョブに依存させます。例えば、次のジョブはjob1が完了してから実行されることを確認します:
jobs:
# 上記のようにjob1が定義されていると仮定
job2:
runs-on: ubuntu-latest
needs: job1
- 依存ジョブで出力にアクセスするには、
needs.<job_id>.outputs.<output_name>構文を使用します。例えば、次のジョブはjob1で定義されたoutput1とoutput2の出力にアクセスします:
jobs:
# 上記のようにjob1が定義されていると仮定
job2:
runs-on: ubuntu-latest
needs: job1
steps:
- env:
OUTPUT1: ${{needs.job1.outputs.output1}}
OUTPUT2: ${{needs.job1.outputs.output2}}
run: echo "$OUTPUT1 $OUTPUT2"
8. 実践的な機能
8.1 デフォルトシェルと作業ディレクトリ
8.1.1 概要
defaultsを使用して、ワークフロー内のすべてのジョブに適用されるデフォルト設定のmapを作成します。ジョブにのみ使用可能なデフォルト設定を設定することもできます。
同じ名前で複数のデフォルト設定が定義されている場合、GitHubは最も具体的なデフォルト設定を使用します。例えば、ジョブで定義されたデフォルト設定は、ワークフローで定義された同じ名前のデフォルト設定を上書きします。
8.1.2 デフォルトシェルと作業ディレクトリの設定
defaults.runを使用して、ワークフロー内のすべてのrunステップにデフォルトのshellとworking-directoryオプションを提供できます。ジョブにのみ使用可能なrunのデフォルト設定を設定することもできます。このキーワードではコンテキストや式を使用できません。
同じ名前で複数のデフォルト設定が定義されている場合、GitHubは最も具体的なデフォルト設定を使用します。例えば、ジョブで定義されたデフォルト設定は、ワークフローで定義された同じ名前のデフォルト設定を上書きします。
例:デフォルトシェルと作業ディレクトリを設定
defaults:
run:
shell: bash
working-directory: ./scripts
8.1.3 特定のジョブのデフォルト値設定
jobs.<job_id>.defaultsを使用して、ジョブ内のすべてのステップに適用されるデフォルト設定のmapを作成できます。ワークフロー全体のデフォルト設定を設定することもできます。
同じ名前で複数のデフォルト設定が定義されている場合、GitHubは最も具体的なデフォルト設定を使用します。例えば、ジョブで定義されたデフォルト設定は、ワークフローで定義された同じ名前のデフォルト設定を上書きします。
8.1.4 ジョブのデフォルトシェルと作業ディレクトリの設定
jobs.<job_id>.defaults.runを使用して、ジョブ内のすべてのrunステップにデフォルトのshellとworking-directoryを提供できます。
ジョブ内のすべてのrunステップにデフォルトのshellとworking-directoryオプションを提供できます。ワークフロー全体のrunのデフォルト設定を設定することもできます。
これらはjobs.<job_id>.defaults.runおよびjobs.<job_id>.steps[*].runレベルで上書きできます。
同じ名前で複数のデフォルト設定が定義されている場合、GitHubは最も具体的なデフォルト設定を使用します。例えば、ジョブで定義されたデフォルト設定は、ワークフローで定義された同じ名前のデフォルト設定を上書きします。
例:ジョブのデフォルトrunステップオプションの設定
jobs:
job1:
runs-on: ubuntu-latest
defaults:
run:
shell: bash
working-directory: ./scripts
8.2 環境変数のスコープ
8.2.1 単一ワークフローの環境変数定義
単一のワークフローのカスタム環境変数を設定するには、ワークフローファイルでenvキーを使用して定義できます。この方法で設定されたカスタム変数のスコープは、定義された要素に制限されます。次のようにスコープが設定された変数を定義できます:
- ワークフローファイルのトップレベルで
envを使用して、ワークフロー全体 -
jobs.<job_id>.envを使用して、ワークフロー内のジョブの内容 -
jobs.<job_id>.steps[*].envを使用して、ジョブ内の特定のステップ
name: 変数の日の挨拶
on:
workflow_dispatch
env:
DAY_OF_WEEK: Monday
jobs:
greeting_job:
runs-on: ubuntu-latest
env:
Greeting: Hello
steps:
- name: "月曜日にHello Monaと言う"
run: echo "$Greeting $First_Name. 今日は$DAY_OF_WEEKです!"
env:
First_Name: Mona
ランナー環境変数を使用するか、コンテキストを使用してenv変数値にアクセスできます。上記の例は、echoコマンドで3つのカスタム変数をランナー環境変数として使用しています:$DAY_OF_WEEK、$Greeting、および$First_Name。これらの変数の値は、ワークフロー、ジョブ、ステップレベルでそれぞれ設定およびスコープが設定されます。これらの変数の補間は、ランナーで発生します。
ワークフローのrunステップのコマンド、または参照されるアクションは、ランナーで使用しているシェルによって処理されます。ワークフローの他の部分はGitHub Actionsによって処理され、ランナーには送信されません。runステップではランナー環境変数またはコンテキストを使用できますが、ランナーに送信されないワークフローの部分では、変数値にアクセスするためにコンテキストを使用する必要があります。
ランナー環境変数の補間はワークフロージョブがランナーマシンに送信された後に行われるため、ランナーで使用されているシェルに適した構文を使用する必要があります。この例では、ワークフローはubuntu-latestを指定しています。デフォルトでは、Linuxランナーはbashシェルを使用するため、$NAME構文を使用する必要があります。デフォルトでは、WindowsランナーはPowerShellを使用するため、$env:NAME構文を使用します。
8.3 デプロイメント環境の指定
8.3.1 前提条件
ワークフローで環境を使用する前に、環境を作成する必要があります。
8.3.2 ワークフローでの環境の使用
- 編集したいワークフローファイルを開きます
- 次の構文を使用して、ワークフローに
jobs.<job_id>.environmentキーを追加します:
jobs:
JOB-ID:
environment: ENVIRONMENT-NAME
選択されたジョブは、指定された環境用に設定されたすべてのルールの対象になります。
- オプションで、次の構文を使用して環境のデプロイメントURLを指定します:
jobs:
JOB-ID:
environment:
name: ENVIRONMENT-NAME
url: URL
指定されたURLは、次の場所に表示されます:
- リポジトリのデプロイメントページ
- ワークフロー実行の視覚化グラフ
- (プルリクエストがワークフローをトリガーする場合)プルリクエストのタイムラインの「View deployment」ボタンとして
8.4 GitHub CLIの使用
注意事項:
GitHub CLIはすべてのGitHub-hostedランナーにプリインストールされています。GitHub CLIを使用する各ステップでは、必要なスコープを持つトークンにGH_TOKENという環境変数を設定する必要があります。
任意のGitHub CLIコマンドを実行できます。例えば、このワークフローはgh issue commentサブコマンドを使用して、Issueがオープンされたときにコメントを追加します。
name: オープン時にコメント
on:
issues:
types:
- opened
jobs:
comment:
runs-on: ubuntu-latest
steps:
- run: gh issue comment $ISSUE --body "このIssueを開いていただきありがとうございます!"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE: ${{ github.event.issue.html_url }}
GitHub CLI経由でAPIコールを実行することもできます。例えば、このワークフローはまずgh apiサブコマンドを使用してGraphQL APIをクエリし、結果を解析します。次に、結果を後のステップでアクセスできる環境変数に保存します。2番目のステップでは、gh issue createサブコマンドを使用して、最初のステップからの情報を含むIssueを作成します。
name: 残りのオープンIssueをレポート
on:
schedule:
# 毎日8:20 UTC
- cron: '20 8 * * *'
jobs:
track_pr:
runs-on: ubuntu-latest
steps:
- run: |
numOpenIssues="$(gh api graphql -F owner=$OWNER -F name=$REPO -f query='
query($name: String!, $owner: String!) {
repository(owner: $owner, name: $name) {
issues(states:OPEN){
totalCount
}
}
}
' --jq '.data.repository.issues.totalCount')"
echo 'NUM_OPEN_ISSUES='$numOpenIssues >> $GITHUB_ENV
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OWNER: ${{ github.repository_owner }}
REPO: ${{ github.event.repository.name }}
- run: |
gh issue create --title "Issueレポート" --body "$NUM_OPEN_ISSUES件のIssueが残っています" --repo $GITHUB_REPOSITORY
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8.5 スクリプトの実行
GitHub Actionsワークフローを使用してスクリプトやシェルコマンドを実行でき、これらは割り当てられたランナーで実行されます。この例では、runキーワードを使用してランナーでnpm install -g batsコマンドを実行する方法を示しています。
jobs:
example-job:
runs-on: ubuntu-latest
steps:
- run: npm install -g bats
ワークフローを使用してリポジトリに保存されているスクリプトを実行するには、まずリポジトリをランナーにチェックアウトする必要があります。これを行った後、runキーワードを使用してランナーでスクリプトを実行できます。次の例は、それぞれ別のジョブステップで2つのスクリプトを実行します。ランナー上のスクリプトの場所は、runコマンドのデフォルト作業ディレクトリを設定することで指定されます。
jobs:
example-job:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./scripts
steps:
- name: リポジトリをランナーにチェックアウト
uses: actions/checkout@v5
- name: スクリプトを実行
run: ./my-script.sh
- name: 別のスクリプトを実行
run: ./my-other-script.sh
ワークフロージョブで実行したいスクリプトは実行可能でなければなりません。ワークフロー内でスクリプトを実行するインタープリタに引数としてスクリプトを渡すか(例:run: bash script.sh)、ファイル自体を実行可能にすることでこれを行えます。ファイルに実行権限を与えるには、ローカルでgit update-index --chmod=+x PATH/TO/YOUR/script.shコマンドを使用してから、ファイルをコミットしてリポジトリにプッシュできます。または、LinuxおよびMacランナーで実行されるワークフローの場合、スクリプトを実行する前に、ワークフロージョブでファイルに実行権限を与えるコマンドを追加できます:
jobs:
example-job:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./scripts
steps:
- name: リポジトリをランナーにチェックアウト
uses: actions/checkout@v5
- name: スクリプトファイルを実行可能にする
run: chmod +x my-script.sh my-other-script.sh
- name: スクリプトを実行
run: |
./my-script.sh
./my-other-script.sh
8.6 ワークフローテンプレートの使用
GitHubは、さまざまな言語やツール向けのワークフローテンプレートを提供しています。
8.6.1 ワークフローテンプレートの選択と使用
- GitHub上でリポジトリのメインページに移動します
- リポジトリ名の下にある「Actions」をクリックします
- リポジトリにすでにワークフローがある場合は、「New workflow」をクリックします
- 「Choose a workflow」ページには、推奨されるワークフローテンプレートの選択が表示されます。使用したいワークフローテンプレートを見つけ、「Configure」をクリックします。ワークフローテンプレートを見つけるために、キーワードを検索したり、カテゴリでフィルタリングしたりできます
- ワークフローテンプレートに追加のセットアップステップを詳述するコメントが含まれている場合は、これらのステップに従ってください
- 一部のワークフローテンプレートはシークレットを使用します。例:
${{ secrets.npm_token }}。ワークフローテンプレートがシークレットを使用する場合、シークレット名に記述された値をリポジトリ内のシークレットとして保存します - オプションで、追加の変更を加えます。例えば、ワークフローが実行されるときに
onの値を変更することができます - 「Start commit」をクリックします
- コミットメッセージを書き、デフォルトブランチに直接コミットするか、プルリクエストを開くかを決定します
まとめ
GitHub Actionsは、トリガー条件、実行環境、並行制御、シークレット管理など、多岐にわたる機能を提供しています。これらを適切に組み合わせることで、シンプルなCI/CDから複雑なワークフロー自動化まで、幅広いユースケースに対応できます。
効果的な活用のポイント:
-
トリガーの最適化: 不要なワークフロー実行を避けるため、ブランチ・パス・アクティビティタイプでフィルタリングします。
GITHUB_TOKENの挙動を理解し、再帰的実行を防ぎます。 -
同時実行の制御:
concurrencyを使用してリソースの競合を避け、コストを最適化します。グループ名とキャンセル戦略を適切に設計します。 -
環境の使い分け: GitHub-hostedランナー、Larger runner、セルフホストランナーを要件に応じて選択します。開発・ステージング・本番で異なる設定とシークレットを使用します。
-
コンテナの活用: 一貫した実行環境を保証し、依存関係を明示的に管理します。レジストリ認証やボリュームマウントを適切に設定します。
-
マトリックス戦略: 複数環境でのテストを効率的に実行し、
include/excludeで柔軟にカスタマイズします。並列実行数を制御してリソースを最適化します。 -
シークレット管理: 機密情報を安全に扱い、適切なスコープで共有します。大きなシークレットは暗号化し、Base64エンコードも活用します。設定変数とシークレットを適切に使い分けます。
-
ジョブの依存関係:
needsで効率的なパイプラインを構築し、並列実行を最大化します。if条件とalways()を組み合わせて柔軟な制御を実現します。 -
コンテキストの活用:
github、env、vars、secrets、needs、matrix、runnerなどのコンテキストを適切に使い分け、動的な条件判定と情報の受け渡しを実現します。 -
デフォルト設定: ワークフローレベルやジョブレベルでデフォルトシェルと作業ディレクトリを設定し、コードの重複を減らします。
-
実践的機能: GitHub CLI、スクリプト実行、環境指定、ワークフローテンプレートを活用して開発効率を向上させます。
これらの機能を理解し実践することで、開発プロセスの自動化が大きく前進します。公式ドキュメントと本記事を参照しながら、自分のプロジェクトに最適なワークフローを構築してください。