Github Actions: Reusable Workflow とジョブ名

Github Actions のあるワークフローから別ファイル(別リポジトリでも可)のワークフローを呼び出せる Reusable Workflow を触ったところ、不便というかどう対処するべきかわからない点があったのでメモとして残しておく。

ワークフローで定義したジョブ名と実行履歴としてのジョブ名

以下の callee.ymlcaller.yml を例に考える。

name: callee
on:
  workflow_call:
jobs:
  greet:
    runs-on: ubuntu-latest
    steps:
      - name: say-hello
        run: echo hello job name is $JOB
        env:
          JOB: ${{ github.job }}
name: caller
on:
  push
jobs:
  call-reusable:
    uses: org/repo/.github/workflows/callee.yml@main

callee の中ではジョブ名は greet と定義しており、環境変数 JOB の値も greet となる。しかし、GithubREST API GET /repos/:org/:repo/actions/runs/:runId/jobs で取得できる実際に実行されたジョブ一覧では違う名前となる。

{
  "jobs": [
    {
      "id": xxx,
      "run_id": 1663652585,
      ...
      "name": "call-reusable / greet", <- 名前が変わっている
      "steps": [
        {
          "name": "say-hello",
          ...
        }
      ],
      ...

この例では .jobs[0].namegreet ではなく call-reusable / greet となる。つまり、<caller> / <callee> のようなフォーマットに変換される。

実際に遭遇したこと

Slack 通知を行う 8398a7/action-slack を Reusable Workflow の中で使った際にジョブ名やジョブ実行時間が表示されない問題に遭遇した。

action-slack は自身のジョブ情報を得るために GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs にリクエストし、github.job と一致するジョブを探していた。しかし、前述の通りこの2つは異なる値になるため、検索に失敗していた。一応検索に用いるジョブ名は input で渡せば回避可能ではある。しかし、呼び出す側がいちいち自分のジョブ名を渡すのはあまりにも冗長でダルい。

ひとまず / ${this.jobName} という後方一致でも検索するように PR を出したところ無事マージされた。

ただし、この修正は完全とは言えない。同名のジョブを含む複数の Reusable Workflow を呼び出すと検索が上手くいかないだろう(レアケースだとは思うが……)。

どうあるべきか

Github Actions 側で以下のどちらかの対応が入ればマシになると思われる

  • 変換後のジョブ名を取得するための context が追加される(例えば ${{ github.realJob }}
  • 実行毎のジョブIDを取得するための context が追加される(例えば ${{ github.job_id }}
    • ジョブIDがわかれば GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs/{job_id} から一発でジョブ情報を引ける

現状は残念ながらどちらも対応されてない……と思われる。後者だと検索自体が不要になるため望ましい。今提供されているブツでもっとスマートな方法があればぜひ知りたいところ。

8398a7/action-slack の入力定義を修正する PR を出した

Github Actions で Slack 通知を行う 8398a7/action-slack の入力定義を修正する PR を出した & マージされた。

修正内容は入力パラメータの誤った必須指定を直すだけの簡単なもの。最近使い始めた ワークフローの YAML の補完・lint を行ってくれる VSCode 拡張に無駄に怒られるのが気になってしょうがなかった。マージ後すぐに最新版をリリースしてもらえたので、平穏な気持ちでワークフロー盆栽を行える日々を取り戻せた。

ちなみに required: true な入力パラメータを省略してアクションを使用したとしても、Github Actions 上で動かす分には問題は起きない。@actions/core*1getInputaction.yml 内の宣言は特に解釈せず、呼び出し時に required を改めて指定するようになっている(実態は特定の命名規則環境変数の値を取り出すだけ)。

import { getInput } from '@actions/core'

const myParam = getInput('myParam', { require: true })

action.yml 内の宣言はあくまでドキュメント用ということなんだろうか。せっかく宣言させるのだから、実行時に validate してくれてもいいのではと思った。

*1:JavaScript アクション用に公式が提供している npm パッケージ