GitHub Actionsワークフロー上で取得できるイベント情報の調べ方

2024.01.30

はじめに

GitHub Actionsのワークフローを作成しようと思ってサンプルなどを検索した際、以下のような表記が使われているのを見かけると思います。

${{ github.event.pull_request.title }}

これはプルリクエストのタイトルを取得する場合ですが、他にもワークフロー上で取得できる情報は数多くあります。GitHub上で作業を自動化しようと思ったときに、他にどんな情報が取得できるのか、欲しい情報を取得するにはどのプロパティを使うのか、などを調べる必要があります。この記事ではそれらをどのように調べれば良いのかを解説します。

ワークフローのトリガーイベント

GitHub Actionsワークフローが実行される契機となるイベントは多岐にわたります。ユーザーやリポジトリに対する変更、プッシュやプルリクエストの作成など、様々なトリガーがあります。

どのようなトリガーがあるかは下記の公式ドキュメントに記載があります。

ワークフローをトリガーするイベント - GitHub Docs

まずはこのドキュメントを参照して、自動化したい作業内容に合ったトリガーはどれかを決定します。トリガーが決まったら、ワークフローのYAMLファイルのonセクションに記載します。

例えば、ブランチ保護ルールの作成や変更をトリガーにしたい場合は、このイベント名をYAMLファイルに記載します。

on: branch_protection_rule

このとき、イベントによっては「アクティビティの種類」に記載がある場合があります。これは、ワークフローの実行タイミングをより細かく制御できるようにするものです。

上記のブランチ保護ルールの場合は、ルールを作成したとき、ルールを編集したとき、ルールを削除したときにそれぞれワークフローを実行するかどうかを細かく制御できます。

ブランチ保護ルールを作成または編集したときはワークフローを実行したいが、削除したときは実行したくない場合は、以下のようにtypesで指定します。

on:
  branch_protection_rule:
    types: 
      - created
      - edited

イベントのペイロード取得

イベントが決まったら、次にどのようなイベントペイロードが取得できるかを調べます。ポイントは、イベントによって取得できるペイロードが異なるということです。

どのイベントからどのペイロードが取得できるかは、下記の公式ドキュメントに記載があります。

Webhook のイベントとペイロード - GitHub Docs

または、下記画像の「webhookイベントのペイロード」のリンクをクリックします。

branch_protection_ruleイベントが発生したときのペイロードに含まれる情報が記載されています。「アクティビティの種類」に記載がある場合は、「アクションの種類」を切り替えることで、各アクティビティが発生したときのペイロードを参照することができます。

このペイロードオブジェクトがgithub.eventで参照できる情報です。

例えば、下記画像のadmin_enforcedを取得したい場合は、${{ github.event.rule.admin_enforced }}でアクセスできます。

プログラムコード上で取得する

イベントペイロードはワークフロー上で取得するほか、ワークフローから呼び出されたプログラムコード上でも取得することができます。

そのためにはGitHubが設定する規定の環境変数を利用します。

変数 - GitHub Docs

上記ドキュメントのうち、GITHUB_EVENT_PATHを使います。説明にあるとおり、この環境変数にはイベントペイロードを含んだファイルへのパスが格納されています。そのため、プログラムコードからファイルの内容を読み取ることで、ペイロードを取得できます。

以下はJavaScriptでの例です。

import fs from 'fs';

const eventPath = process.env.GITHUB_EVENT_PATH;
const eventData = JSON.parse(fs.readFileSync(eventPath, 'utf8'));

console.log(eventData)

イベント情報を利用してプログラム上で複雑な処理をしたい場合は、この方法が便利です。

下記のドキュメントにある通り、${{ github }}全体を出力するとgithub.tokenなど機密情報が含まれる場合があります。意図しない情報が出力されないように注意してください。

コンテキスト - GitHub Docs

試してみる

ここからは実際にGitHub Actionsワークフローを作って、ペイロードを取得できることを確かめてみます。

YAMLファイルは以下の通りです。Log GitHub Eventステップではgithub.eventの内容をワークフロー上で取得して出力しています。Log GitHub Event On JavaScriptステップではJavaScriptコードを呼び出し、コード上でペイロードの内容を取得して出力しています。

name: On Branch Protection Rule

on:
  branch_protection_rule:
    types:
      - created
      - edited

jobs:
  onBranchProtectionRuleLog:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4

      - name: Set Up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: latest

      - name: Install Dependencies
        run: npm install

      - name: Log GitHub Event
        env:
          GITHUB_EVENT: ${{ toJson(github.event) }}
        run: echo "$GITHUB_EVENT"

      - name: Log GitHub Event On JavaScript
        run: node index.js

index.jsは以下の通りです。

import fs from 'fs';

const eventPath = process.env.GITHUB_EVENT_PATH;
const eventData = JSON.parse(fs.readFileSync(eventPath, 'utf8'));

console.log(eventData)

コードをリポジトリにpushした後、適当なブランチ保護ルールを作ります。

ルールを作成するとGitHub Actionsが実行されます。

以下がLog GitHub Eventステップで出力された内容です。ドキュメントにある通りにペイロードが出力されています。

{
  "action": "created",
  "repository": {
    "allow_forking": true,
    "archive_url": "hoge",
    "archived": false,
    // 略
  },
  "rule": {
    "admin_enforced": false,
    "allow_deletions_enforcement_level": "off",
    "allow_force_pushes_enforcement_level": "off",
    "authorized_actor_names": [],
    "authorized_actors_only": false,
    "authorized_dismissal_actors_only": false,
    // 略
  },
  "sender": {
    "avatar_url": "hoge",
    "events_url": "hoge",
    "followers_url": "hoge",
    // 略
  }
}

続いてLog GitHub Event On JavaScriptステップでの出力内容です。どちらも同じ内容が出力されています。

{
  action: 'created',
  repository: {
    allow_forking: true,
    archive_url: 'hoge',
    archived: false,
    // 略
  },
  rule: {
    admin_enforced: false,
    allow_deletions_enforcement_level: 'off',
    allow_force_pushes_enforcement_evel: 'off',
    authorized_actor_names: [],
    authorized_actors_only: false,
    authorized_dismissal_actors_only: false,
    // 略
  },
  sender: {
    avatar_url: 'hoge',
    events_url: 'hoge',
    followers_url: 'hoge',
    // 略
  }
}
上の方でも書きましたが、出力する場合は意図しない情報が含まれないように十分注意してください。

おわりに

私もそうでしたが、慣れていないうちはサンプルを参考にして応用しようとしてもうまくいかないことがあるかと思います。ドキュメントでどこを調べれば目的の情報が手に入るのかを知ることで理解が進み、自由自在に使いこなすための近道になるのではないでしょうか。

この記事がどなたかの参考になれば幸いです。