Github Actions で Issue をスケジューリングして自動作成しよう

最近はほぼフルリモートで仕事をすることが多く、Github などで日々のタスクを Donelist として管理することが多くなってきました。そんな時に、Donelist の Issue を自動で管理できたら便利ですよね🙃
今回はそんなちょこっと面倒な Issue の管理を Github Actions を使用して自動で管理できるようにしていきたいと思います。



### Github Actions とは？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292456/bca30f68-f80d-c073-9c3c-759436184896.png)


CircleCi や Bitrise と同様に CI/CD としての役割はもちろんのこと、Github 関連のイベントをトリガーに様々な処理を実行することができます。Action の実体は Docker コンテナで、ユーザは Github のインフラ上で任意のコマンドやスクリプトを実行することができます。また、データ領域は Action 間で共有されるので、ある Action を実行した結果を次の Action で使用するなんてこともできます。

Github には Extend App と呼ばれる Action の拡張がオープンソースで作られており、好きな Action を [MarketPlace](https://github.com/marketplace) から自身のワークフローに取り込むことができます。また、Github でトリガーにできるイベントについては[こちら](https://docs.github.com/en/actions/reference/events-that-trigger-workflows)を参照してください。


https://codezine.jp/article/detail/11450



### それではワークフローを作っていくっ👨‍💻

今回は下記のような使用でワークフローを作っていきたいと思います。

- 日曜午前9時に Issue が作成される
  - title: 自分の名前 + 日付
  - assign: 自分に設定
  - label: 自分の名前
     - 自分の名前のラベルにしておくことで、他の人の Issue を作成する必要が出てきた時にちょっと楽になります
  - body: 用意したテンプレートを使用
- 次の日曜に新しい Issue を作成するのと同時に前回の Issue を Close する


まずは、`.github/ISSUE_TEMPLATE` 配下に Issue のテンプレートを作成しておきましょう。今回は `generate_donelist.md` という名前でファイルを作成しました。

``` 
$ touch .github/ISSUE_TEMPLATE/generate_donelist.md
```

ファイルの中身は下記のように `title`・`labels`・`assignees` はワークフローの定義で書くので空欄にしておきます。

```markdown
---
name: Default issue template
about: Describe this issue template's purpose here.
title: ''
labels: ''
assignees: ''

---

## やること

やることをここに書いてね🙃
```

次に、`.github/workflows`ないに Github Actions で実行するワークフローの定義を `yml` で作成していきます。このファイルを複数あっても良いそうですが、今回は必要ないので `generate_donelist.yml` というファイルのみで作成していきます。

```
$ touch .github/workflows/generate_donelist.yml
``` 

ファイルの中身を順番に説明していきます。まずは、`name` でワークフローの名前を定義します。これは Github 上の Actions タブのワークフロー一覧に表示される名前になり、省略するとリポジトリのルートに対するワークフローファイルの相対パスが値に設定されます。次に `on` は、ワークフローをトリガーする Github の名前を設定します。これは必須の定義なので何かしらのトリガーイベントを指定する必要があります。また、これには複数のイベントや、さらに細かい設定などもできるので詳しくは[こちら](https://docs.github.com/ja/actions/reference/workflow-syntax-for-github-actions#)の `on` セクションを参照してみてください。今回はワークフローをスケジュールしたいので `schedule` イベントを指定します。また、スケジュールする間隔については[POSIXクーロン構文](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/crontab.html#tag_20_25_07)というものを使用して特定の UTC 時間にワークフローを実行できるように設定します。クーロン構文について馴染みがなくても下記のサイトを見れば時間の指定の仕方が理解できるかと思います。

https://crontab.guru

また、時間指定は基本的に UTC なので、日本標準時(JST) で指定したいという場合は、`JST での希望日時 - 9時間` で UTC 時間を求めることができます。これで、毎週日曜の午前9時にイベントをトリガーできるようになりました。

```yaml
name: Donelist generate
on:
  schedule:
  - cron: '0 0 * * 7'  # At 09:00 on Sunday(JST).
```

次に、`job` を定義していきます。基本的に、１つのワークフローの実行は、１つ以上のジョブが必要です。デフォルトではジョブは並行して実行されるので、直列で実行したい場合は別途設定が必要です。また、それぞれのジョブは `runs-on` で定義された仮想環境の新しいインスタンスで実行されます。詳細は下記の通りです。

|仮想環境|YAMLのワークフロラベル|
|---|---|
|Windows Server 2019|**windows-latest** or **windows-2019**|
|Ubuntu 20.04|**ubuntu-20.04**|
|Ubuntu 18.04|**ubuntu-latest**または**ubuntu-18.04**|
|Ubuntu 16.04|**ubuntu-16.04**|
|macOS Catalina 10.15|**macos-latest**もしくは**macos-10.15**|

また、先で紹介したようにオープンソースのアクションや再利用可能なワークフロー、または公開されている Docker コンテナイメージと同じリポジトリで定義されているアクションを `uses` で定義することができます。
今回はコメントの通りカレントの日付の取得は[こちら](https://stackoverflow.com/a/60942437)の記事を `名前 + 日付` のタイトルを実現しました。また、それぞれの拡張 Action や定義する値についてさらに詳しく知りたい方は下記を参照してみてください。

- https://github.com/marketplace/actions/checkout
- https://github.com/marketplace/actions/scheduled-issue

```yaml
name: Donelist generate
on:
  schedule:
  - cron: '* 0 * * 5'  # At 09:00 on Friday. – https://crontab.guru

jobs:
  donelist_generate:
    name: Friday Standup
    runs-on: ubuntu-latest
    steps:

    # Repo code checkout required if `template` is used
    - name: Checkout
      uses: actions/checkout@v2
    
    # https://stackoverflow.com/a/60942437
    - name: Get current date
      id: date
      run: echo "::set-output name=date::$(date +'%Y/%m/%d')"
  
    - name: Scheduled Issue with YamatoOtaka
      uses: imjohnbo/issue-bot@v2.3
      with:
        title: YamatoOtaka - ${{ steps.date.outputs.date }} ~ 🎣
        assignees: "YamatoOtaka" # Github Account name without @.
        labels: "YamatoOtaka"
        pinned: false
        close-previous: true
        template: ".github/ISSUE_TEMPLATE/generate_donelist.md"
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

それでは、リポジトリにソースコードを反映して job が実行された結果が下記になります。ちゃんと `Title`・`Label`・`Assigne` されてますね🙃

<img src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yum_fishing/20200904/20200904233254.png">


### 参考

- https://codezine.jp/article/detail/11450
- https://docs.github.com/ja/actions/reference/workflow-syntax-for-github-actions
- https://crontab.guru/
- https://docs.github.com/ja/actions/reference/events-that-trigger-workflows
- https://docs.github.com/ja/actions/configuring-and-managing-workflows/authenticating-with-the-github_token
- https://qiita.com/hirothings/items/0cd2561dbf6c53cf470c