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} から一発でジョブ情報を引ける

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