notebook

都内でWEB系エンジニアやってます。

GitHub Actionsの手動実行 workflow_dispatchを試す

先日GitHub Actionsで特定のworkflowの手動実行ができるようになりました

GitHub Actions: Manual triggers with workflow_dispatch The GitHub Blog

github.blog

もう見たまんまでスクショも貼る必要なさそうな気がしますが、触ってみないと何とも言えないので触ってみます

workflow_dispatch

Events that trigger workflows - GitHub Docs

docs.github.com

書いてあるとおりrepository_dispatchとの違いは

  • workflow_dispatch
    • 単一workflowに対してトリガーさせる
    • ブランチ指定が可能
  • repository_dispatch
    • リポジトリの複数workflowに対してトリガーさせる
    • イベントタイプやカスタムイベントをカスタマイズして発行する

ということで待っていたのはこれだよ!という個人的感想

repository_dispatchに関しては次の記事で言及している

GitHubActionsのrepository_dispatchを使い特定ブランチでWorkflowを実行する - notebook

swfz.hatenablog.com

実行するブランチ指定をするにもrepository_dispatchで行うには一工夫必要だったがworkflow_dispatchでは最初から選択できるので特に頑張る必要なく実行できそう

手動実行

  • ドキュメント

Configuring a workflow - GitHub Docs

docs.github.com

ドキュメントからコピーして試してみる

  • manual.yml
name: Manually triggered workflow
on:
  workflow_dispatch:
    inputs:
      name:
        description: 'Person to greet'
        required: true
        default: 'Mona the Octocat'
      home:
        description: 'location'
        required: false

jobs:
  say_hello:
    runs-on: ubuntu-latest
    steps:
    - run: |
        echo "Hello ${{ github.event.inputs.name }}!"
        echo "- in ${{ github.event.inputs.home }}!"

f:id:swfz:20200710200939p:plain

workflow_dispatchトリガーを指定したworkflowの実行結果一覧を表示している状態で手動実行ができる

サンプルだとlocation,Person to greetの入力欄が出てくる

適当に入力して実行してみる

f:id:swfz:20200710200952p:plain

入力した値が出力された

API経由での実行

APIからの実行も行えるのでやってみる

実行にはworkflowのIDが必要なので取得から行う

workflow一覧の取得

workflow一覧を取得する

ドキュメントは下記

Actions - GitHub Docs

docs.github.com

  • 結果(一部抜粋)
$ curl -H "Accept: application/vnd.github.v3+json" \
  https://api.github.com/repos/swfz/github-actions-playground/actions/workflows
{
  "total_count": 2,
  "workflows": [
    {
      "id": 1839554,
      "node_id": "MDg6V29ya2Zsb3cxODE0MDkw",
      "name": "Manually triggered workflow",
      "path": ".github/workflows/manual.yml",
      "state": "active",
      "created_at": "2020-07-07T18:49:09.000Z",
      "updated_at": "2020-07-08T21:19:50.000Z",
      "url": "https://api.github.com/repos/swfz/github-actions-playground/actions/workflows/1839554",
      "html_url": "https://github.com/swfz/github-actions-playground/blob/master/.github/workflows/manual.yml",
      "badge_url": "https://github.com/swfz/github-actions-playground/workflows/Manually%20triggered%20workflow/badge.svg"
    },
    {
      "id": 1038390,
      "node_id": "MDg6V29ya2Zsb3cxMDM4Mzkw",
      "name": "sample",
      "path": ".github/workflows/takeover-output.yml",
      "state": "active",
      "created_at": "2020-04-16T08:00:12.000Z",
      "updated_at": "2020-04-16T08:00:12.000Z",
      "url": "https://api.github.com/repos/swfz/github-actions-playground/actions/workflows/1038390",
      "html_url": "https://github.com/swfz/github-actions-playground/blob/master/.github/workflows/takeover-output.yml",
      "badge_url": "https://github.com/swfz/github-actions-playground/workflows/sample/badge.svg"
    }
  ]
}

id部分がworkflow_id、今回手動実行対象のworkflowのIDをメモしておく

特定workflowの実行

Actions - GitHub Docs

docs.github.com

ということで、次のような感じで実行できる

$GITHUB_TOKENにはあらかじめpersonal tokenを設定しておく

  • masterブランチでの実行
curl -XPOST -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/swfz/github-actions-playground/actions/workflows/1839554/dispatches -d '{"ref":"master"}'

動いた!

f:id:swfz:20200710201003p:plain

ref指定しないと怒られる

{
  "message": "Invalid request.\n\n\"ref\" wasn't supplied.",
  "documentation_url": "https://developer.github.com/v3"
}
  • パラメータの指定

inputs以下に各種key,valueを指定することでフォームから入力するのと同様に値を渡して実行できる

namehomeを指定して実行する

  • 抜粋
on:
  workflow_dispatch:
    inputs:
      name:
        description: 'Person to greet'
        required: true
        default: 'Mona the Octocat'
      home:
        description: 'location'
        required: false
curl -XPOST -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.everest-preview+json" https://api.github.com/repos/swfz/github-actions-playground/actions/workflows/1839554/dispatches -d '{"ref":"master","inputs": {"home":"Tokyo", "name": "swfz"}}'

無事渡した値が表示された

f:id:swfz:20200710200952p:plain

homerequired: trueにしてinputsに何も指定せず実行してみる

$ curl -XPOST -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/swfz/github-actions-playground/actions/workflows/1839554/dispatches -d '{"ref":"master"}'

{
  "message": "Required input 'home' not provided",
  "documentation_url": "https://developer.github.com/v3"
}

パラメータがないよと怒られる

nameはdefault値を定義しているので何も指定しなかった場合はdefault値が採用される

cronとworkflow_dispatchの併用

自分の中で需要があった使い方

cronを用いて毎日今月分のレポートを集計してslackなりなんなりに送信している

仕様変更や処理内容の変更によって過去の日付でやり直したいみたいなパターン

手動入力での実行の場合とスケジュールでの実行の場合で同じ変数を使って後続の処理を行いたい

集計処理などの部分は特に今回関係ないので対象日付の指定部分だけ抜粋する

  • .github/workflows/manual.yml
name: Manual Input And Scheduled
on:
  schedule:
    - cron: '0 1 * * *'
  workflow_dispatch:
    inputs:
      date:
        description: 'date'
        required: true

  print_date:
    runs-on: ubuntu-latest
    steps:
    - name: input date
      run: |
        input_date=${{ github.event.inputs.date }}
        if [[ -z "$input_date" ]]; then
          start_date=$(date -d "1 day ago" +"%Y-%m-01")
        else
          start_date=$(echo $input_date)
        fi

        echo $start_date

最終行のechoで、workflow_dispatchで実行した場合はinputs.dateの値が採用され、cronで実行した場合は昨日時点での月初の日付が採用される

最初ifを使ったほうがGitHub Actions使っている感あるかなと感じたが

stepを分割(workflow_dispatch用のstepとcron用のstep)してID振ってset-outputで変数を後続stepで参照させることになるがID指定は重複できないしっていう時点で考えるのをやめた

ということでshellに頼ってしまった感はあるがやりたいことは実現できた

まとめ

やったこと

  • 画面からの手動実行
  • API経由での実行
  • cronとworkflow_dispatchの併用

特にブランチ指定できるのが嬉しいですね

今まで使ってきた中で「これがほしかったんだよ!」という部分が結構あったので追加していこうと思います