イベントとは
GitHub Actionsのワークフローを定義するyamlにはそのワークフローをどのタイミングで実行するのかを設定する項目があります。
name: Test
on: # ここ
pull_request:
types:
- opened
- synchronize
jobs:
...
この「どのタイミング」に該当するものをイベントと呼びます。
ドキュメントではワークフローをトリガーするイベントページにその一覧がまとまっていますが、今回はその中から実際によく見かけるものをいくつかピックアップしてご紹介したいと思います。
対象読者
- 非公開のリポジトリでチーム開発を行っている
- ↑の中で動いているワークフローを読んでみたい/書いてみたい
既にがっつり触っている方にとっては目新しい情報はないと思われます。
pull_request: PRが○○されたら
まずは一番使われているであろうところから。テストを実行したり環境を立ち上げたり色々します。
name: Test
on:
pull_request:
types:
- opened
- synchronize
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: |
do my test
この例ではPRが作成されたタイミングとPRが立っているブランチの内容が更新されたタイミングでそれぞれテストが実行されます。types
のデフォルトがopened
/synchronize
/reopene
なのでシンプルに
on:
pull_request:
とだけ書かれている場合も多いです。
またそれだと走りすぎなんだよな~という場合にbranches
とpaths
という2つのフィルターを使って実行を制限することがあります。
name: Test
on:
pull_request:
types:
- opened
- synchronize
branches:
- develop
- release
- main
paths:
- "*"
- src/**
- "!**.md"
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: |
do my test
ここでは同様のタイミングのうち
- PRの対象(マージ先)がdevelop/release/mainのいずれか
かつ
- 変更されたファイルが以下のいずれか
- トップレベルにあり、拡張子が.mdではない
- srcディレクトリ配下にあり、拡張子が.mdではない
である場合にテストが実行されます。論理演算がちょっと複雑ですが意外とすぐ慣れるので頑張りましょう。
push: リモートにpushされたら
リモート側でコミットメッセージを検証したり解析したりといった用途で使われることが多いです。
name: Commit Message
on:
push:
branches:
- feature/**
jobs:
msg:
runs-on: ubuntu-latest
steps:
- run: echo "${{ github.event.head_commit.message }}"
こちらもpull_request
と同様branches
とpaths
のフィルターで実行を制限することが可能です。
テスト実行のトリガーとしてon: push
が使われる場面
ブランチの保護ルールでRequire branches to be up to date before merging
がオンになっていない場合、featureブランチでテストを通したのに他のPRとの兼ね合いでdevelopが壊れてしまった!という事態が起こり得ます。
そういった場合にpush
イベントを併用して
- feature/** → developのPRでテスト
- マージ後のdevelopブランチでもう一度テスト
というフローが採用されることがあります。
name: Test
on:
pull_request:
types:
- opened
- synchronize
branches:
- develop
- release
- main
paths:
- "*"
- src/**
- "!**.md"
push:
branches:
- develop
- release
- main
paths:
- "*"
- src/**
- "!**.md"
jobs:
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: |
do my test
Require branches to be up to date before merging
を常にオンにしておけばいいだけでは?と思われるかもしれませんが、それはそれで複数のPRが存在する場合に1つPRを取り込むたび他の全てのPRでテストを再実行せねばならず実行時間が大変なことになったりするのでまあそこは運用次第という感じです。場合によってはreleaseブランチはオンにして安全に倒し、developブランチはオフにしてpush
と併用ということもあります(git-flowの場合、かつdevelop/release/main全てのブランチに保護がかかっている前提)。
workflow_call: 他のワークフローに呼ばれたら
いわゆる再利用可能ワークフローと呼ばれるものです。
name: Echo
on:
workflow_call:
inputs:
msg:
required: true
type: string
jobs:
echo:
runs-on: ubuntu-latest
steps:
- run: echo "${{ inputs.msg }}"
name:
on:
workflow_dispatch:
jobs:
echo:
uses: my-org/repo1/.github/workflows/echo.yml@main
with:
msg: hoge!
これはシンプルな例ですが、実際にはシークレットが絡んで結構面倒くさめだったりもするのでこちらの項目だけでも読んでおくことをおすすめします。
workflow_dispatch: 手動で呼ばれたら
on
にworkflow_dispatch
が指定されている場合、そのワークフローは手動で実行されることを期待しています。
name: Environment
on:
workflow_call: # 他のワークフローからも呼ばれる
inputs:
pr_num:
required: true
type: string
action:
required: true
type: string
workflow_dispatch: # 手動で実行することもできる
inputs:
pr_num:
required: true
type: string
action:
required: true
type: string
jobs:
run:
runs-on: self-hosted
if: inputs.action=='run' # どちらのイベントでトリガーされた場合でもコンテキストにinputsが存在するため正常に動く
steps:
- run: |
run environment
実行の手順はこのページの通り。
注意点として、手動実行が可能なのはworkflow_dispatch
を指定したワークフローがデフォルトブランチに存在する場合のみです。
schedule: 指定した時刻になったら
name: Announce
on:
schedule:
- cron: "0 0 * * *" # 毎日9時(JST)
jobs:
announce:
runs-on: ubuntu-latest
steps:
- id: count
run: |
pr_count=$(gh pr list -s open --json number --jq length)
echo "pr_count=$pr_count" >> $GITHUB_OUTPUT
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: slackapi/slack-github-action@v1.24.0
with:
channel-id: ${{ secrets.SLACK_CHANNEL_ID }}
payload: |
{
"text": "今朝のPRは${{ steps.count.outputs.pr_count }}件です"
}
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
デフォルトブランチに存在するschedule
が指定されたワークフローはcron
の時刻に実行されます。ただし…
ということは覚えておいた方がいいかもしれません。
おわりに
というわけで本当に極一部ですがon:
の読み方についてご紹介しました。
pull_request
やworkflow_call
の項はそれだけで記事1本文になってしまいそうで頑張って削ったのですが、どこかのタイミングで削った部分についても改めて記事を出せればと思います。
それでは。