🚀

git-pr-releaseとGitHub Actionsで作るリリースPR自動化

2024/12/22に公開

本記事では、git-pr-releaseを使ってリリース用のプルリクエストの作成を自動化したことについて話していきます。

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

導入前の課題

リリース用プルリクエストの作成は定期的に発生する作業ですが、以下のような課題がありました。

  1. プルリクエストの作成が手作業となっており、作業工数が発生する
  2. 手動でプルリクエストを作成する場合、レビュアーへのapprove依頼が必要
  3. リリースPRから変更内容をdescriptionにまとめるのが困難

これらの課題を解決するため、git-pr-releaseGitHub Actionsを組み合わせて自動化を実現しました。

git-pr-releaseとは

git-pr-releaseは、本番環境などへのデプロイ前に作成するリリース用プルリクエストを自動で生成するRuby製のgemです。

主な機能は以下の通りです。

  1. 指定したブランチ(例:mainブランチ)にマージされていない、developブランチのプルリクエストを検出
  2. 1で検出されたプルリクエストの一覧をdescriptionに含めたリリース用プルリクエストを自動生成
  3. リリース用プルリクエストのタイトルやdescriptionのテンプレートをカスタマイズ可能

Rubyのプロジェクトで使われることが多いツールですが、GitHub Actionsと組み合わせることで、他の言語のプロジェクトでも利用できます。

また、git-pr-releaseを実行するためのactionsとしてgit-pr-release-actionを使うことでRubyのセットアップなどが不要になるため、Ruby以外の言語を使用されているプロジェクトで利用する際は検討してみてもいいかもしれません。
https://github.com/bakunyo/git-pr-release-action

実装方法

GitHub Actionsのワークフローファイルを作成するため、.github/workflows/ ディレクトリに以下のYAMLファイルを配置します。

リリース対象となるブランチの設定

以下の設定では、stagingブランチにプッシュがあった際に自動でワークフローが実行されます。

name: Create a release pull request for production
run-name: 本番リリース用のPRを作成✨

on:
  push:
    branches:
      - staging

権限の設定

プルリクエストの作成に必要な権限を付与します。

permissions:
  id-token: write
  contents: read
  pull-requests: write

コミット履歴の取得

fetch-depth: 0を指定することで、全てのコミット履歴を取得します。これはプルリクエストの検出に必要です。

jobs:
  create-release-pr:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

PRのタイトルの設定

この設定は必須ではないですが、タイムゾーンを日本時間に設定し、プルリクエストのタイトルに作成時刻を含める形式にしています。
独自に用意したリリース用のプルリクエストのテンプレート内で、PR_TITLEという環境変数を参照しているため、タイトルを環境変数に代入しています。

- name: Set up environment variables
        env:
          TZ: 'Asia/Tokyo'
        run: |
          echo "PR_TITLE=【本番リリース】 $(date '+%Y-%m-%d %H:%M:%S')" >> $GITHUB_ENV

環境のセットアップ

git-pr-releaseの実行に必要なRuby環境をセットアップします。

- uses: ruby/setup-ruby@v1
        with:
          ruby-version: .ruby-version
          bundler-cache: true

      - name: Install git-pr-release
        run: gem install --no-document git-pr-release

プルリクエストのテンプレートの作成

  • <%= ENV['PR_TITLE'] %> で、先ほどワークフローで設定した日時入りのタイトルが展開されます。
  • 変更内容のセクションでは、pull_requests.eachでマージされていないプルリクエストを自動で列挙します。to_checklist_itemメソッドにより、各プルリクエストがチェックボックス付きのリスト項目として表示されます。
<%= ENV['PR_TITLE'] %>

## 概要

## チケット

## 変更内容

<% pull_requests.each do |pr| -%>
<%= pr.to_checklist_item %>
<% end -%>

実際には以下のような形でプルリクエストが作成されます。

【本番リリース】 2024-12-21 10:00:00

## 概要

## チケット

## 変更内容

- [ ] #123 機能Aの実装
- [ ] #124 機能Bの修正

git-pr-releaseの設定と実行

  • --squashedオプションを指定することで、マージされていないプルリクエストの一覧をsquashされた状態で取得します。
  • GIT_PR_RELEASE_TOKEN: GitHub APIを利用するための認証トークン
    GIT_PR_RELEASE_BRANCH_PRODUCTION: リリース用PRのマージ先となるブランチ(この例ではmain)
    GIT_PR_RELEASE_BRANCH_STAGING: マージ元のブランチ(この例ではstaging)
    GIT_PR_RELEASE_LABELS: 作成されるPRに自動で付与されるラベル
    GIT_PR_RELEASE_TEMPLATE: PRの説明文に使用されるテンプレートファイルのパス
- name: Create a release pull request
  run: git-pr-release --squashed
  env:
    GIT_PR_RELEASE_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    GIT_PR_RELEASE_BRANCH_PRODUCTION: main # マージ先ブランチ
    GIT_PR_RELEASE_BRANCH_STAGING: ${{ github.ref_name }} # マージ元ブランチ
    GIT_PR_RELEASE_LABELS: release production
    GIT_PR_RELEASE_TEMPLATE: .github/RELEASE_PULL_REQUEST_TEMPLATE.md

ワークフローファイルの全体

最終的なコードは以下のようになります。

name: Create a release pull request for production
run-name: 本番リリース用のPRを作成✨

on:
  push:
    branches:
      - main

permissions:
  id-token: write
  contents: read
  pull-requests: write

jobs:
  create-release-pr:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up environment variables
        env:
          TZ: 'Asia/Tokyo'
        run: |
          echo "PR_TITLE=【本番リリース】 $(date '+%Y-%m-%d %H:%M:%S')" >> $GITHUB_ENV

      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: .ruby-version
          bundler-cache: true

      - name: Install git-pr-release
        run: gem install --no-document git-pr-release

      - name: Create a release pull request
        run: git-pr-release --squashed
        env:
          GIT_PR_RELEASE_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GIT_PR_RELEASE_BRANCH_PRODUCTION: main
          GIT_PR_RELEASE_BRANCH_STAGING: ${{ github.ref_name }}
          GIT_PR_RELEASE_LABELS: release production
          GIT_PR_RELEASE_TEMPLATE: .github/RELEASE_PULL_REQUEST_TEMPLATE.md

もし環境に応じてブランチを動的に変更したい場合は、以下のように設定することで実現できます。

name: Create a release pull request
run-name: リリース用のPRを作成✨

on:
  push:
    branches:
      - develop
      - staging

jobs:
  create-release-pr:
    runs-on: ubuntu-latest
    steps:
    # ... 前述のcheckout や Ruby のセットアップなど ...

      - name: Set environment variables
        run: |
          if [ "${{ github.ref_name }}" = "develop" ]; then
            echo "TARGET_BRANCH=staging" >> $GITHUB_ENV
            echo "PR_TITLE=【stagingリリース】 $(TZ=Asia/Tokyo date '+%Y-%m-%d %H:%M:%S')" >> $GITHUB_ENV
          else
            echo "TARGET_BRANCH=main" >> $GITHUB_ENV
            echo "PR_TITLE=【本番リリース】 $(TZ=Asia/Tokyo date '+%Y-%m-%d %H:%M:%S')" >> $GITHUB_ENV
          fi
    
      - name: Create a release pull request
        run: git-pr-release --squashed
        env:
          GIT_PR_RELEASE_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GIT_PR_RELEASE_BRANCH_PRODUCTION: ${{ env.TARGET_BRANCH }}
          GIT_PR_RELEASE_BRANCH_STAGING: ${{ github.ref_name }}
          GIT_PR_RELEASE_LABELS: release
          GIT_PR_RELEASE_TEMPLATE: .github/RELEASE_PULL_REQUEST_TEMPLATE.md

作成されるPRのイメージ

以下のように、変更内容セクションにマージされていないプルリクエストが自動でチェックリスト化されます。

新しい変更が入った場合は、git-pr-releaseの再実行により説明文が自動更新され、新しいプルリクエストがリストに追加されます。

まとめ

git-pr-releaseGitHub Actionsを組み合わせることで、以下のような効果が得られました。

  • リリースPRの作成作業を自動化し、作業工数を削減
  • プルリクエストの一覧を自動で取得し、変更内容の把握が容易に
  • リリース作業者自身がapproveできるため、追加のレビュー依頼が不要に
  • リリースプロセスの標準化

一方で見えてきた課題としては、チェックリストの活用方法についてです。
変更内容のチェックリストは、頻繁な小規模リリースを行うアジャイル開発では有効に機能しますが、ウォーターフォールのような一度のリリースが大きくなりがちな開発スタイルでは、変更が多すぎて把握が難しくなる可能性があります。

このような場合には、リリースノートの作成や段階的なリリースの導入を検討することで、リリースの複雑さを管理しやすくすることができるかもしれません。

Discussion