1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SmartHRAdvent Calendar 2024

Day 5

Github Actionsを使ってリリース用のPRを自動で作成してみる

Last updated at Posted at 2024-12-04

この記事は、SmartHR Advent Calendar 2024 シリーズ1の5日目の記事です。

こんにちは!最近はSmartHRでスキル管理というプロダクトを開発しているs.miyoshiデス。

今回は日々の運用がちょっとだけ楽になるかもしれないスクリプトをご紹介したいと思います。

はじめに

スキル管理プロダクトでは通常以下のようなステップで開発を進めています。

  1. それぞれのブランチで開発
  2. PRを出して、レビューokならstagingブランチにマージ
  3. stagingブランチにマージされると、自動でstaging環境にデプロイ
  4. staging環境でのチェックが問題なければ、PRを作成してmainブランチにマージ
  5. 自動で本番環境にデプロイ

いわゆるGitHub Flowにstagingブランチが追加されている感じです。

今回はこの手順4でstagingブランチからmainブランチへマージするためのPRを自動作成する試みです。

成果物

スクリーンショット 2024-12-04 17.48.42.png

このようなPRを自動で作成するようにしました。
[release] 2024-12-05というPRが自動で作成され、そこにリリースされる内容が一覧で見えるようになっています。

リリースされる内容が表示されていると、いつどんな内容がリリースされたのか一目でわかるので、後から振り返りやすかったり不具合発生時の原因特定がやりやすかったりと色々メリットがあります。

では、実際にどのようなコードなのかを解説していきたいと思います。

コード全体像

name: Create a pull request for release.

on:
  push:
    branches: [staging]

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

    env:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      PR_TITLE: "[release]"
      BASE_BRANCH: main

    steps:
      - uses: actions/checkout@v4

      # リリース用PRが既に存在するかどうかをチェック
      - name: Check if pr exists
        id: check_pr
        run: |
          echo "count=$(gh pr list -S ${PR_TITLE}' in:title' -B $BASE_BRANCH | wc -l)" >> $GITHUB_OUTPUT
      # リリース用PRを作成
      - name: Create release pr
        if: ${{ steps.check_pr.outputs.count == 0 }}
        run: |
          today=`TZ=JST date +"%Y-%m-%d"`
          gh pr create -B ${BASE_BRANCH} -t "${PR_TITLE} ${today}" -b "" -d
      - name: Set description
        run: |
          today=`TZ=JST date +"%Y-%m-%d"`
          pr_number=`gh pr list -S ${PR_TITLE}' in:title' -B $BASE_BRANCH --json number --jq '.[0].number'`
          pr=`gh api /repos/kufu/sample-product/pulls/${pr_number}/commits --paginate | jq '.[] | select(.commit.message | contains("Merge pull request")) | .commit.message' | awk '{print "- "$4}'`
          tmpfile=$(mktemp)
          cat << EOF > $tmpfile
          ## 関連リンク
          $pr
          EOF
          gh pr edit staging --title "${PR_TITLE} ${today}"
          gh pr edit staging --body-file $tmpfile
          rm -f $tmpfile

コードの解説

このコードがどのように動くかもうちょっと詳しく解説していきたいと思います。

まず、Github Actionはstagingブランチにpushされた時に発火するようにします。
つまりstagingブランチにpushされるごとにcreate-release-pr jobが走るようになっています。

on:
  push:
    branches: [staging]

create-release-pr jobでは最終的に[release] 2024-12-05みたいなPRを作成します。
既存の同タイトルのPRがあるかをチェックして、あればその内容を編集、なければ作るといった作戦です。

各ステップの解説

Check if pr existsステップでまずはすでにPRがあるかをチェックしています。

echo "count=$(gh pr list -S ${PR_TITLE}' in:title' -B $BASE_BRANCH | wc -l)" >> $GITHUB_OUTPUT

ghコマンドでPRを見ていって[release]がタイトルに含まれているPRが存在するかをチェックします。
最後に書き出しているのは次のstepのif分岐させるためですね。

Create release prのstepは単にghコマンドでPRを作成しているだけです
-dでdraft PRにし、-b ""で空のPRを作成してます。
このあたりはgh pr create --helpで調べると詳しくチェックできます。(ghコマンドはヘルプが充実しててほんと便利)

そしてその後Set description stepで中身を埋めていきます。
descriptionにはこのPRに含まれるすべてのPRの内容を表示するようにしたいのでその取得部分がこれです。

gh api /repos/kufu/sample-product/pulls/${pr_number}/commits --paginate | jq '.[] | select(.commit.message | contains("Merge pull request")) | .commit.message' | awk '{print "- "$4}'

GithubでPRをマージすると以下のようなマージコミットが作成されます。
Merge pull request #88 from sh-miyoshi/split-damage-type
つまりリリースPRに含まれる全てのcommitを確認して、そのコミットメッセージにMerge pull requestが含まれるPRを取得していけばいいのです。

実はcommitを全て取得するにはgh pr list --json commitsとやれば取得できます。
しかし、このコマンドの場合commitsが100件を超えているとページネーションの関係で取得できないという問題がありました。
そこでgh api /repos/kufu/sample-product/pulls/${pr_number}/commits --paginateコマンドによりページネーションを考慮して取得するようにしています。
(基本的にcommitsが100件を超えることはないのですが、たまに大きい機能のリリースやライブラリのバージョンアップなどが重なると超えたことがありました)

取得したcommitsはjqコマンドによってMerge pull requestがコミットメッセージに含まれるcommitだけにフィルタリングし、awkコマンドでPR番号を取得しています。

ちなみにGithubはPR番号を記載すると成果物のスクショのようにPRのタイトルを表示してくれるので便利ですね。

おわりに

自動化は正義!
あと何かゴニョゴニョやりたいときにjqコマンドは便利すぎる・・・

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?