GitHub Actions リリースプルリクエストを自動生成する

![61bf2eec-ea53-11e3-835b-50d63ed11b39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/fd684fd3-d843-dbea-a1b0-85e8a9fb97a7.png)

## 目的

今回は `develop` → `main` のリリースプルリクエストを自動で作成します。

Gitブランチのマージの流れの図です。

```
      H--------I feat-2
     /          \
    F---G feat-1 \
   /     \        \
  C-------D--------E develop
 /                  \ ★ リリースプルリクエスト
A--------------------B main
```

各開発者が `feature` ブランチで開発し、`develop` ブランチへマージされていきます。

リリースしたいタイミングで `develop` → `main` へ向けてリリースプルリエストを作成します。

図でいうと `E → B` のところです。

リリースプルリクエストは、今回のリリースでそのPRが本当にマージされて良いのかを確認するためにリリースプルリクエストを使用します。

## Gitシリーズ記事まとめ

https://qiita.com/ucan-lab/items/33c63a402f533aa92f3e

## 利用ツール

git-pr-release
https://github.com/x-motemen/git-pr-release

リリースプルリクエストを作成してくれるRuby製のツールです。
リリースプルリクエストのテンプレートにerbが使われています。

## 実装

- `.github/git-pr-release.erb`
  - リリースプルリクエストのテンプレート
- `.github/workflows/create-release-pull-request.yaml`
  - git-pr-releaseを実行するワークフロー

### .github/git-pr-release.erb

```erb:.github/git-pr-release.erb
Release <%= Time.now.strftime('%Y-%m-%d %H:%M') %>
<% pull_requests.each do |pr| -%>
<%= pr.to_checklist_item %>
<% end -%>
```

Rubyで書けます。
色々カスタマイズできるので公式のREADMEなど参照してみてください。

### .github/workflows/create-release-pull-request.yaml

```yaml:.github/workflows/create-release-pull-request.yaml
name: Create Release Pull Request
on:
  push:
    branches: [develop]
jobs:
  release-pull-request:
    permissions:
      pull-requests: write
      contents: read
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: 3.1
      - run: gem install --no-document git-pr-release
      - run: git-pr-release
        env:
          GIT_PR_RELEASE_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GIT_PR_RELEASE_BRANCH_PRODUCTION: main
          GIT_PR_RELEASE_BRANCH_STAGING: develop
          GIT_PR_RELEASE_LABELS: release
          GIT_PR_RELEASE_TEMPLATE: .github/git-pr-release.erb
          TZ: Asia/Tokyo
```

- `TZ`
  - タイムゾーン
  - 指定しないと `Time.now` が9時間ずれる
- `GIT_PR_RELEASE_BRANCH_PRODUCTION`
  - マージ先のブランチを指定(今回はmain)
- `GIT_PR_RELEASE_BRANCH_STAGING`
  - マージ元のブランチを指定(今回はdevelop)
- `GIT_PR_RELEASE_LABELS`
  - リリースプルリクエストに付与するラベル
- `GIT_PR_RELEASE_TEMPLATE`
  - リリースプルリクエストのテンプレートファイルのパス

## 使い方

![61bf2eec-ea53-11e3-835b-50d63ed11b39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/fd684fd3-d843-dbea-a1b0-85e8a9fb97a7.png)

いい感じのスクショが用意できなかったので、公式のもので解説します。
`staging` → `master` 向けに作成されてますが、
ワークフローの設定だと `develop` → `main` 向けに作成されます。

`develop` と `main` の差分のPRをリスト化してくれます。
PR作成した人にメンションが飛ぶので、メンションを受け取った人はマージして問題なければ✅します。

もし問題があれば[revertのPR](https://docs.github.com/ja/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/reverting-a-pull-request)を `develop` にマージして✅する。といった運用になります。

## 補足

### リリースプルリクエストが作られた後に追加でマージされたPRはどうなる？

プルリクエストがマージされるたびにリリースプルリクエストの中身が更新されます。

### リリースプルリクエストはどのタイミングで生成される？

`develop` のブランチが進んだタイミングで作成されます。
リリースプルリクエストがマージされて、`develop` ブランチに更新がない間はリリースプルリクエストが作られないです。

### テンプレートのチェックリストが消すには？

チェックボックスが不要な場合は次のように書くと良いです。

```erb:.github/git-pr-release.erb
Release <%= Time.now.strftime('%Y-%m-%d %H:%M') %>
<% pull_requests.each do |pr| -%>
- #<%= pr.number %> <%= pr.mention %>
<% end -%>
```

### PRのラベルを見てカテゴライズしたい

PRに付いているラベルからカテゴライズして一覧表示したい場合は次のように書き換えてました。
スペースを入れるとそのままスペースが入ったりするので読みづらくなっちゃうのがちょっと難点です。

```erb:.github/git-pr-release.erb
Release <%= Time.now.strftime('%Y-%m-%d %H:%M') %>
<% features_prs = pull_requests.select { |pr| pr.labels.include?('features') } %>
<% if features_prs.any? %>
## 🚀 Features
<% features_prs.each do |pr| -%>
<%= pr.to_checklist_item %>
<% end -%>
<% end %>
<% bug_prs = pull_requests.select { |pr| pr.labels.include?('bug') } %>
<% if bug_prs.any? %>
## 🐛 Bug Fixes
<% bug_prs.each do |pr| -%>
<%= pr.to_checklist_item %>
<% end -%>
<% end %>
<% maintenance_prs = pull_requests.reject { |pr| pr.labels.include?('features') || pr.labels.include?('bug') } %>
<% if maintenance_prs.any? %>
## 🧰 Maintenance
<% maintenance_prs.each do |pr| -%>
<%= pr.to_checklist_item %>
```

## 業務改善度: ★★★★★

文句なしの星5つです。
developにマージしたタイミングで自動的にリリースプルリクエストを作成してくれるのはとても便利です。
チェックリストがあることで、リリースに含めて良いPRか目視でチェックできます。

GitHubのプルリクエスト内のマージコミットを追って行くより一覧性、視認性に優れますし、チェックリスト化を手でやろうと思ったら運用途中で飽きる自信があります笑

erbなので比較的テンプレートをカスタマイズしやすく、ラベルを見てカテゴライズして一覧化できたのでより便利に使えます。

### 参考記事

https://songmu.jp/riji/entry/2022-08-05-git-pr-release.html