GitHub Actionsで「ブランチ作成 → jsonファイル更新 → コミット → プルリクエスト」までを実行する

GitHub Actionsから、自動でブランチ作成してプルリクエストするまでの流れを実装したため、まとめておきます。

ワークフローを実行するだけで、「ブランチ作成 → jsonファイル更新 → コミット → プルリクエスト」までを行います。
今回は例としてjsonファイル更新部分についてはハードコードしています。

# ワークフロー

ワークフローは下記のようになります。

```yaml:.github/workflows/create_pr.yml
name: "Create PR"

on: [ workflow_dispatch ]

env:
  JSON_FILE_PATH: sample.json
  PR_TITLE: プルリクエストタイトル
  PR_LABEL: hoge,foo
  PR_TEMPLATE: .github/PULL_REQUEST_TEMPLATE.md
  DEST_BRANCH: main

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 5

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Set current datetime as env variable
        env:
          TZ: 'Asia/Tokyo'
        run: echo "CURRENT_DATETIME=$(date +'%Y%m%d%H%M%S')" >> $GITHUB_ENV

      - name: Create new branch
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          git switch -c fix/hoge_${{ env.CURRENT_DATETIME }}
          git push -u origin fix/hoge_${{ env.CURRENT_DATETIME }}

      # 任意の更新処理
      - name: Update json file
        run: |
          cat ${{ env.JSON_FILE_PATH }} | jq '.+ {"user":{"name": "hoge","age": 30}}' > tmp && mv tmp ${{ env.JSON_FILE_PATH }}

      - name: Add and Commit
        uses: EndBug/add-and-commit@v7
        with:
          branch: fix/hoge_${{ env.CURRENT_DATETIME }}
          message: ${{ env.PR_TITLE }}
          add: ${{ env.JSON_FILE_PATH }}

      - name: Create pull request
        uses: repo-sync/pull-request@v2
        with:
          source_branch: fix/hoge_${{ env.CURRENT_DATETIME }}
          destination_branch: ${{ env.DEST_BRANCH }}
          pr_title: ${{ env.PR_TITLE }}
          pr_template: ${{ env.PR_TEMPLATE }}
          pr_label: ${{ env.PR_LABEL }}
          github_token: ${{ secrets.GITHUB_TOKEN }}
```

# 各処理の説明

```yaml:現在時刻の取得
- name: Set current datetime as env variable
  env:
    TZ: 'Asia/Tokyo'
  run: echo "CURRENT_DATETIME=$(date +'%Y%m%d%H%M%S')" >> $GITHUB_ENV
```

現在時刻を取得して `CURRENT_DATETIME` 環境変数に設定しています。
こちらの処理は必須ではないですが、作成するブランチ名に使用して、他のブランチ名が被らないようにする意図があります。

```yaml:ブランチ作成
- name: Create new branch
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  run: |
    git switch -c fix/hoge_${{ env.CURRENT_DATETIME }}
    git push -u origin fix/hoge_${{ env.CURRENT_DATETIME }}
```

新規ブランチを作成します。
ブランチ名は `fix/hoge_${{ env.CURRENT_DATETIME }}` として、現在時刻を含めて他のブランチ名と被らないようにしています。
このブランチ名は任意となります。

```yaml:ファイル更新
  # 任意の更新処理
- name: Update json file
  run: |
    cat ${{ env.JSON_FILE_PATH }} | jq '.+ {"user":{"name": "hoge","age": 30}}' > tmp && mv tmp ${{env.JSON_FILE_PATH }}
```

こちらは例として挙げている処理です。
jsonファイルを更新していますが、実際は [inputs](https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#onworkflow_dispatchinputs) を使ってフォームから入力したり、[GitHubActionsのAPI](https://docs.github.com/en/rest/reference/repos#create-a-repository-dispatch-event) から更新したい値を渡すなども可能です。

```yaml:コミット
- name: Add and Commit
  uses: EndBug/add-and-commit@v7
  with:
    branch: fix/hoge_${{ env.CURRENT_DATETIME }} # ブランチ名
    message: ${{ env.PR_TITLE }} # コミットメッセージ
    add: ${{ env.JSON_FILE_PATH }} # addするファイル
```

更新したファイルをコミットします。
[EndBug/add-and-commit@v7](https://github.com/EndBug/add-and-commit)というライブラリを使用しています。
コミット先に先ほど作成したブランチを指定し、メッセージを登録します。

```yaml:プルリクエスト
- name: Create pull request
  uses: repo-sync/pull-request@v2
  with:
    source_branch: fix/hoge_${{ env.CURRENT_DATETIME }} # プルリクエストを作成するブランチ
    destination_branch: ${{ env.DEST_BRANCH }} # マージ先のブランチ
    pr_title: ${{ env.PR_TITLE }} # プルリクエストのタイトル
    pr_template: ${{ env.PR_TEMPLATE }} # プルリクエストのテンプレート
    pr_label: ${{ env.PR_LABEL }} # プルリクエストのラベル（カンマ区切りで複数指定可能）
    github_token: ${{ secrets.GITHUB_TOKEN }}
```

プルリクエストには [repo-sync/pull-request](https://github.com/repo-sync/pull-request) というライブラリを使用しています。
必要な項目を指定し、プルリクエストを作成可能です。
[PULL_REQUEST_TEMPLATE](https://docs.github.com/ja/enterprise-server@3.1/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository)の使用も可能です。