GitHub Actionsで特定のコミットをcheckoutしてワークフローを実行する

2 min read読了の目安(約1900字

実現したいこと

"任意のブランチにある(HEADではない)任意のコミットを任意のタイミングで開発環境にデプロイしたい!" という要件です。
今回はQA用途でこの要件が発生しました。

workflow_dispatchについて

GitHub Actionsではworkflow_dispatchイベントを使うと手動で特定のワークフローを実行することができます。

https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#workflow_dispatch
.github/workflows/manual_deploy.yml
name: Manual Deploy
on: [workflow_dispatch] # ←ここ

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
# 以下省略

上記のようなymlを設定しておくと、GitHubのActionsタブから下のスクリーンショットのように任意のブランチを指定してワークフローを実行することができます。

この場合はスクリーンショットで指定したブランチのHEADをチェックアウトしてそのコミットに対してworkflowを実行する(テストやデプロイを実行する)ことになります。

今回は特定のブランチのHEADではない特定のコミットを指定してデプロイしたいという要件であったために少しコツが必要でした。

特定のコミットをcheckoutしてワークフローを実行する方法

次のスクリーンショットのように任意のコミットハッシュをworkflow実行時に指定できるようにしたいとします。
また、refを空のまま実行したらそのブランチのHEADを取得する既存の処理にしたいとします。

ymlは次のようになります。

.github/workflows/manual_deploy.yml
name: Manual Deploy
on:
  workflow_dispatch:
    inputs: # <= 入力欄の定義
      ref:
        description: "ref"
        required: false
        default: ""
jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0 # <= https://github.com/actions/checkout/issues/265
      - run: git checkout ${{ github.event.inputs.ref }}
        if: ${{ github.event.inputs.ref != '' }} # <= ref が指定されていたら git checkout

基本的にはシンプルなのですがfetch-depth: 0のみ要注意です。

actions/checkout@v2ではチェックアウト時の時間短縮のために指定されたブランチの先頭コミットしか取得(fetch)してきません。
その状態でgit checkoutしてもerror: pathspec 'xxxxxxx' did not match any file(s) known to gitというエラーになってしまいます。
fetch-depth: 0を指定してあげることにより、全タグ・全ブランチ・全履歴を取得するようになるため、次のgit checkoutが意図通り動く、という仕掛けです。