Lambdaカクテル

京都在住Webエンジニアの日記です

Invite link for Scalaわいわいランド

GitHub Actionのジョブ実行画面からPull Requestを辿れるようにした

こういうのを作りました。

ジョブに紐付いたPull Requestへのリンクが表示される

行ったこと:

  • リンクを生成するジョブを1つ生やした
  • 綺麗な表示はStep Summary機能 (後述) の力を借りている

ジョブ実行画面からPull-Reqに戻りたい

GitHub Actionsのジョブ実行画面には、その実行元となったPull Requestへのリンクが存在しないため、困っていた。

よくあるシチュエーション:

  • Pull Requestを見るとジョブがコケていた
  • 様子を見に行くうちに履歴がどんどん深くなる -- ジョブ画面内での遷移はどんどんヒストリが積まれる
  • Pull Requestに戻れなくなってしまう

この話を同僚にしたところ共感の嵐だった。したがって隠れた需要がありそうだということが判明し、うまくやる方法を考えることにした。

結果、GitHub Action上でPull-Reqへのリンクを生成して良い感じにURLを表示しようと試みて、たまたまうまくいったのでメモ。

以下の3つがポイント。

  • GitHub Actionsが提供する変数を活用すれば元Pull-Reqへのリンクを構成できる
  • pushイベントだと直接Pull-Req番号を得られないが、ghコマンドで代替できる
  • $GITHUB_STEP_SUMMARYにリダイレクトすることで、Step Summaryを出力できる

まずは完成品を提示する。ここから順に何をしたのか見ていく。

name: CI

on:
  - push
  - workflow_dispatch

jobs:
  # Step SummaryにPull-Reqへのリンクを出力する。このジョブ1つが全てをやってくれる。
  designate-pull-req:
    name: Designate Pull-req URL
    runs-on: ubuntu-latest
    steps:
      # ghコマンドのために必要
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Get Pull Request Number
        id: pr
        run: echo "::set-output name=pull_request_number::$(gh pr view --json number -q .number || echo "")"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Show URL
        run: echo Pull Request is ${{ github.server_url }}/${{ github.repository }}/pull/${{ steps.pr.outputs.pull_request_number }}
      # $GITHUB_STEP_SUMMARYに書き込むと、step summaryを生成できる
      - name: Adding markdown
        run: echo '### [PR \#${{ steps.pr.outputs.pull_request_number }}](${{ github.server_url }}/${{ github.repository }}/pull/${{ steps.pr.outputs.pull_request_number }})' >> $GITHUB_STEP_SUMMARY
# 略

元Pull-Reqへのリンクを構成する

まずジョブのきっかけとなったPull-ReqへのURLを得なければならない。GitHub Actionsは実行環境にいくつもの変数を注入してくれるので、Pull-Req情報を得るのは容易だ。

特にジョブがpull_requestイベントにフックされて実行されている場合には造作もない。

echo ${{ github.server_url }}/${{ github.repository }}/pull/${{ github.event.number }}

Pull-Req番号は${{ github.event.number }}に入っているので、あっさりリンクを構成できた。

on: push の場合を考える

ところが前項の手段は、ジョブがon: pushで実行されている場合には使えない。${{ github.event.number }}が空になってしまうためだ。

このため代替策を用いる。ghコマンドを用いればPull-Req番号を得られる。うれしい副作用として、この方法を用いるとworkflow_dispatchによって実行した場合にも正しいPull-Req番号を得られるメリットがある。

# 略
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Get Pull Request Number
        id: pr
        run: echo "::set-output name=pull_request_number::$(gh pr view --json number -q .number || echo "")"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Show URL
        run: echo Pull Request is ${{ github.server_url }}/${{ github.repository }}/pull/${{ steps.pr.outputs.pull_request_number }}
# 略

やっていることは3つ。

  • gitを使って情報を得なければならないので、Checkoutする
  • ghコマンドによりPull-Req番号を得て、それをstepのoutputにする
  • stepのoutputを呼び出し、リンクを構成する

これを行うことで、実行時にPull-Requestへのリンクがechoされるようになった。

Step Summaries に書き込む

さて、これだけでは標準出力にリンクが出るだけなのであまり便利ではない。id:cohalz がリンクを表示するための便利な方法を教えてくれた。

GitHub Actionのジョブは、Step (Job) Summaryという概念を持っていて、各ステップの実行結果などの情報をMarkdownとして表示させられる。

Summaryを出力するには、 $GITHUB_STEP_SUMMARY にmarkdown文字列をリダイレクトして書き込めば良い。ちなみに、Step Summaryはジョブ実行画面のSummaryにまとめて表示される。

# 略
      - name: Adding markdown
        run: echo 'ここに何らかの文字列を書き込むとSummaryに表示される' >> $GITHUB_STEP_SUMMARY
# 略

これを実行すると次のような結果をもたらす:

書き込んだ文字列がSummaryとして出力される

この機能を使ってリンクをMarkdown形式で書き込んだのが、冒頭に示したyamlである。

最終的に実行結果がどうなるかを再掲しよう。

Summary画面に該当Pull-Reqへのリンクが挿入される

これでもう迷わない。

まとめ

ghコマンドを活用してPull Request番号を取得し、これを用いてPull Requestへのリンクを構成し、Step Summary機能を使ってリンクを分かりやすく示すことができるようになった。

特にStep Summary機能はリンクを表示する以外にも様々な活用が考えられるので、覚えておきたい。

参考文献

stackoverflow.com

github.blog

★記事をRTしてもらえると喜びます
Webアプリケーション開発関連の記事を投稿しています.読者になってみませんか?