GitHub Actionsで湯婆婆を実装してみる

2020/11/16追記: [続編](https://qiita.com/nogic1008/items/6934b1b6d6e0cf7912d1)を書きました。

- 元ネタ様: [Javaで湯婆婆を実装してみる](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2)
- シェルスクリプト版の先駆者様: [Shell scriptで湯婆婆を実装してみた](https://qiita.com/watatomo1216/items/1c54bdda01891fafa8c8)

## Workflow

```yml:.github/workflows/yubaba.yml
name: 湯婆婆
on:
  workflow_dispatch:
    inputs:
      name:
        description: '契約書だよ。そこに名前を書きな。'
        required: false
jobs:
  keiyaku:
    runs-on: ubuntu-latest
    steps:
      - name: フン。${{ github.event.inputs.name }}というのかい。贅沢な名だねぇ。
        id: rnd
        run: |
          set -eu
          name='${{ github.event.inputs.name }}'
          random=$[RANDOM % ${#name}]
          echo ::set-output name=new_name::${name:random:1}
      - name: 今からお前の名前は${{ steps.rnd.outputs.new_name }}だ。いいかい、${{ steps.rnd.outputs.new_name }}だよ。分かったら返事をするんだ、${{ steps.rnd.outputs.new_name }}!!
        run: echo '::debug::Convert ${{ github.event.inputs.name }} to ${{ steps.rnd.outputs.new_name }}.'
```

## 登録方法

1. GitHub Actionsをリポジトリで有効化する
  - すでにアカウント単位で有効化していたので、説明は割愛
1. `/.github/workflows` フォルダに、上記内容のファイル(*.yml)を作成し、デフォルトブランチにコミット
1. 「Actions」タブを開き、「湯婆婆」がWorkflowsに登録されていることを確認する。


## 利用方法

1. 「Actions」タブを開き、「湯婆婆」workflowをクリックする。<br/>
    ![湯婆婆 workflow](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278493/c75d0c68-2b22-c6a6-fcfe-37b4e37e53ab.png "湯婆婆 workflow")
1. 右上の「Run workflow」ボタンをクリックし、「契約書だよ。そこに名前を書きな。」に名前を入力する。<br/>
    ![契約書だよ。そこに名前を書きな。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278493/26b9fdf7-1378-127b-3e2c-7add77566379.png "契約書だよ。そこに名前を書きな。")
1. 緑色の「Run workflow」ボタンを押す。

## 実行例

### 正常系

####「山田太郎」
https://github.com/nogic1008/gh-actions-advent-2020/runs/1383598101
![今からお前の名前は太だ。いいかい、太だよ。分かったら返事をするんだ、太!!](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278493/f6157165-3c97-6245-7557-9ee30d72eccc.png "今からお前の名前は太だ。いいかい、太だよ。分かったら返事をするんだ、太!!")
実行ごとにランダムで変わります。リランしたときも変わります
https://github.com/nogic1008/gh-actions-advent-2020/runs/1383715888
![今からお前の名前は郎だ。いいかい、郎だよ。分かったら返事をするんだ、郎!!](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278493/07845b55-b5a1-5d1a-70e7-9342d1b96ccd.png "今からお前の名前は郎だ。いいかい、郎だよ。分かったら返事をするんだ、郎!!")

#### 「𠮷田」
𠮷田さんもちゃんと働けます。
https://github.com/nogic1008/gh-actions-advent-2020/runs/1383740768
![今からお前の名前は𠮷だ。いいかい、𠮷だよ。分かったら返事をするんだ、𠮷!!](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278493/a0cceb8d-ef5d-9e79-39c7-e49ef833dd65.png "今からお前の名前は𠮷だ。いいかい、𠮷だよ。分かったら返事をするんだ、𠮷!!")

#### 「👪👪」
**贅沢**な絵文字もOK。
https://github.com/nogic1008/gh-actions-advent-2020/runs/1384113975
![今からお前の名前は👪だ。いいかい、👪だよ。分かったら返事をするんだ、👪!!](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278493/ddbfdeaa-371d-1228-3bc3-ba6180709502.png "今からお前の名前は👪だ。いいかい、👪だよ。分かったら返事をするんだ、👪!!")

### 異常系

#### 空白文字列
仕様通りです。
https://github.com/nogic1008/gh-actions-advent-2020/runs/1383609519
![クラッシュ湯婆婆](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278493/937de9b0-2caf-1fdd-365b-aa3f277b7fdb.png "クラッシュ湯婆婆")
#### 「'」
仕様外ですが、~~エスケープが面倒だし~~「'」は**そんなに贅沢な名じゃない**ので大丈夫でしょう。
https://github.com/nogic1008/gh-actions-advent-2020/runs/1383811952
![クラッシュ湯婆婆2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278493/e9584dd1-6a5e-a394-8f81-2c1a15b1d76c.png "クラッシュ湯婆婆2")

## 解説

### [手動実行トリガー](https://docs.github.com/ja/free-pro-team@latest/actions/reference/events-that-trigger-workflows#workflow_dispatch)(`workflow_dispatch`)

「Actions」タブから手動実行できるワークフローを定義できます。

```yml
# 単純に「実行」ボタンが出るだけ
on: workflow_dispatch

# 入力ボックスのある「実行」ボタン(今回使ったもの)
on:
  workflow_dispatch:
    inputs:
      # 後から値を参照するためのプロパティ名(任意)
      # この場合は ${{ github.event.inputs.name }}に入力値が入ってくる
      name:
        # 入力ボックスの名前
        description: '契約書だよ。そこに名前を書きな。'
        # 必須入力かどうか(未指定時はfalse)
        required: false
        # デフォルトで入っている値(未指定時は空)
        default: '山田太郎'
```

### ジョブステップ間の値のやり取り
- [出力パラメータの設定](https://docs.github.com/ja/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#%E5%87%BA%E5%8A%9B%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%81%AE%E8%A8%AD%E5%AE%9A)
- [steps コンテキスト](https://docs.github.com/ja/free-pro-team@latest/actions/reference/context-and-expression-syntax-for-github-actions#steps-%E3%82%B3%E3%83%B3%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88)

`::`で始まる特殊なコマンドを標準出力に投げることで、ワークフローの動作を制御できます。

```yml
    steps:
      - name: Set Randomly
        id: rnd # 後からこのステップを参照するために必要
        # rndの出力パラメータにnew_name=山を指定
        run: echo '::set-output name=new_name::山'
        # 出力パラメータはsteps.(ステップのid).outputs.(出力パラメータ名)で参照可能
      - run: echo '${{ steps.rnd.outputs.new_name }}'
```

## おわり
ワークフローの手動実行、「自動テストはしたいけど、リリースは自分のタイミングでやりたい」みたいなシチュエーションにいかがでしょうか。
余力があれば`::add-mask`を使って本当の名前を隠すとかやります。→[書きました。](https://qiita.com/nogic1008/items/6934b1b6d6e0cf7912d1)