8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHub ActionsAdvent Calendar 2023

Day 4

GitHub Actionsのon:に書かれるイベントでよく見るもの

Posted at

イベントとは

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:

とだけ書かれている場合も多いです。

またそれだと走りすぎなんだよな~という場合にbranchespathsという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と同様branchespathsのフィルターで実行を制限することが可能です。

テスト実行のトリガーとしてon: pushが使われる場面

ブランチの保護ルールでRequire branches to be up to date before mergingがオンになっていない場合、featureブランチでテストを通したのに他のPRとの兼ね合いでdevelopが壊れてしまった!という事態が起こり得ます。

image.png

そういった場合にpushイベントを併用して

  1. feature/** → developのPRでテスト
  2. マージ後の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: 他のワークフローに呼ばれたら

いわゆる再利用可能ワークフローと呼ばれるものです。

my-org/repo1/.github/workflows/echo.yml
name: Echo
on:
  workflow_call:
    inputs:
      msg: 
        required: true
        type: string
jobs:
  echo:
    runs-on: ubuntu-latest
    steps:
      - run: echo "${{ inputs.msg }}"
my-org/repo2/.github/workflows/caller.yml
name: 
on:
  workflow_dispatch:
jobs:
  echo:
    uses: my-org/repo1/.github/workflows/echo.yml@main
    with:
      msg: hoge!

これはシンプルな例ですが、実際にはシークレットが絡んで結構面倒くさめだったりもするのでこちらの項目だけでも読んでおくことをおすすめします。

workflow_dispatch: 手動で呼ばれたら

onworkflow_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_requestworkflow_callの項はそれだけで記事1本文になってしまいそうで頑張って削ったのですが、どこかのタイミングで削った部分についても改めて記事を出せればと思います。

それでは。

8
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?