GitHub Actions を使い子リポジトリが Push された時、親リポジトリにプルリクを作成する

メモです。
# モチベ
訳あって自分のリポジトリから他のリポジトリを submodule として利用していました。git submodule の仕様では特定のコミットを参照している形となるため、常に HEAD を参照のようなことができません。

[Git Tools - Submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules)

よって自動でプルリクエストを作成できないかなと考えました。
# 方針
- github actions を使用
- 子リポジトリから親リポジトリに向けては [repository_dispatch](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#repository_dispatch) で解決
- プルリクエスト作成は[peter-evans/create-pull-request@v3](https://github.com/peter-evans/create-pull-request)を使用
# 作成したもの
- push 時に子リポジトリから親リポジトリへPOST を送信し、repository_dispatch トリガを起動するもの
- repository_dispatch で待ち受け、変更を取り込んだプルリクエストを作成するもの

に分けます
## submodule側
push をトリガとして POST で対象リポジトリをのエンドポイントを叩くだけなので単純です。

```yml:update-submodule.yml
name: Dispatch
on:
  push:
    branches: [ master ]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - run: |
          curl -X POST -H "Authorization: token ${{ secrets.AUTO_PR_TOKEN }}" -H "Accept: application/vnd.github.everest-preview+json" -d '{"event_type": "update-submodule"}' -i  https://api.github.com/repos/{送信対象ユーザ or 組織}/{送信対象リポジトリ}/dispatches
```
master ブランチへの push で起動し、crul で対象ブランチのエンドポイントへ event_type を送信しています。

```url
 https://api.github.com/repos/{送信対象ユーザ or 組織}/{送信対象リポジトリ}/dispatches
```
この部分は実際に送信したいリポジトリに変更してください。

```
token ${{ secrets.AUTO_PR_TOKEN }}
```
となっている部分はリポジトリに設定したアクセストークンとなっています。

ユーザメニューの Settings → Developer settings → Personal access tokens で発行したものを
リポジトリのタブの Settings → Secrets → New repository secret で登録できます。
Personal access tokensの発行時に権限を指定できますが、この記事での操作ではrepo スコープがあれば問題ありません。
![トークン](https://raw.githubusercontent.com/uesugi6111/zenn-article/master/img/17a9f1cc47118df0903a/token.png)

```
-d '{"event_type": "update-submodule"}' 
```
このイベントタイプで指定した文字列合致した場合のみ、親リポジトリのWorkflowが実行されます。

## 親リポジトリ側
親リポジトリは [repository_dispatch](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#repository_dispatch) で待ち受け、プルリクを作成するところまでです。

```yml:autoPR.yml
name: Update submodule Pull Request
on:
  repository_dispatch:
    types: [update-submodule]
jobs:
  patch:
    runs-on: ubuntu-latest

    steps:

      - uses: actions/checkout@master 
        with:
          submodules: true

      - run: git submodule update --remote

      - name: Create Pull Request 
        id: cpr
        uses: peter-evans/create-pull-request@v3
        with:
          title: Update submodule.
          labels: Auto PR
          branch: auto-pr/update-submodule 
          branch-suffix : timestamp 
          commit-message: auto update submodule
          base : master
          delete-branch: true
          token: ${{ secrets.AUTO_PR_TOKEN }}
```


repository_dispatch にイベントタイプ "update-submodule" (子リポジトリで指定) を指定し待ち受けています。
step1でサブモジュールを含めたcheckout、step2 で submodule の更新を行います。
step3の

```yml
      - name: Create Pull Request 
        id: cpr
        uses: peter-evans/create-pull-request@v3
        with:
          title: Update submodule.
          labels: Auto PR
          branch: auto-pr/update-submodule 
          branch-suffix : timestamp 
          commit-message: auto update submodule
          base : master
          delete-branch: true
          token: ${{ secrets.AUTO_PR_TOKEN }}
```

については [peter-evans/create-pull-request@v3](https://github.com/peter-evans/create-pull-request)に詳細な説明があります。
現在のディレクトリの状態をコミットし、指定したブランチにプルリクエストを作成するものです。
ここで使用しているオプションの解説です。
- title: 作成されるプルリクエストのタイトル
- labels: 作成されたプルリクエストに付けられるラベル
- branch: マージ元となるブランチ
- branch-suffix : (random, timestamp, short-commit-hash) この値を設定すると branch オプションで設定した文字列をプレフィクスとしてブランチが作成されます。ブランチのサフィックスが指定された形式で設定されます。(逆にこの値を設定しない場合は branch で指定したブランチが存在している前提で動いている？気がします。)
- commit-message: コミットのメッセージ
- base : 派生元のブランチとなります。指定しない場合はWorkflowが動いているブランチが指定されます。
- delete-branch: プルリクエストがマージされた場合にブランチを削除(boolean)
- token: リポジトリへのアクセストークンを指定します。ここでは子リポジトリと同様の方法で親リポジトリにも作成した置いたものを利用しています。

## 実行結果

![実行結果](https://raw.githubusercontent.com/uesugi6111/zenn-article/master/img/17a9f1cc47118df0903a/pr.png)

# おわり
一通り調べて作成してみましたが github actions 便利だなーという感想です。
自分でもなにか作ってマーケットプレイスで公開できたらと思います。