LoginSignup
7
2

More than 1 year has passed since last update.

特定のファイルの変更を検知してPull RequestのDescriptionに加筆する

Last updated at Posted at 2022-12-09

現在、GitHubでは複数のIssueテンプレートを作成することができますが、複数のPull Requestテンプレートを作ることはできません。
コメントアウトを活用して、うまく誤魔化す手法などが取られますがそうすると、テンプレートが肥大しがちです。
そこで、今回はRailsアプリケーションのmigrationを例に、GitHub Actionsを使ってdescriptionに加筆することで肥大化を解決してみましょう。

今回加筆したいもの

db/schema.rbが更新された時に、下記をdescriptionに追記するものとします。

## Migration list
- Migration time: s
- Record size: 

Migrationにかかる時間と、レコードサイズを記入する部分をDescriptionに追記するというわけですね。(レコードサイズは本来カラムやインデックスの追加・削除時だけで良さそうですが、今回はそこが本題ではないので考えないこととする)

作成したもの

下記のymlファイルです。

.github/workflows/description-migration.yml
name: Add Migration list

on:
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
    paths:
      - 'db/schema.rb'
env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:  
  add_migration_lists:
    name: Add migration lists to description of pull request
    runs-on: ubuntu-latest
    outputs:
      replaced_description1: ${{ steps.get_description.outputs.replaced_description }}
    steps:  
      - name: checkout
        uses: actions/checkout@v3
      - name: Get current pull request description
        id: get_description
        run: |
          DESCRIPTION=$(gh pr view ${{ github.event.pull_request.number }} --json body --jq .body)
          REPLACED_DESCRIPTION=$(echo $DESCRIPTION | sed 's/\n/;;;:::;;;/g')
          echo "replaced_description=$REPLACED_DESCRIPTION" >> $GITHUB_OUTPUT 
      - name: URL to Pull Request description
        if: contains(steps.get_description.outputs.replaced_description, '## Migration Lists') == false
        run: |
          DESCRIPTION=$(echo $REPLACED_DESCRIPTION | sed 's/;;;:::;;;/\n/g')
          gh pr edit ${{ github.event.pull_request.number }} --body "$DESCRIPTION
          ## Migration Lists
          - Migration time: s
          - Record size: "
        env:
          REPLACED_DESCRIPTION: ${{ steps.get_description.outputs.replaced_description }}

特定のファイル変更が起きたときにだけワークフローが走るようにする

まず、db/schema.rbに変更が起きたときだけ走るようにします。
下記のような記述で、PRをOpenしたとき、Pull Requestが追跡しているブランチがPull Requestのソースブランチと同期されたとき、再度Openしたとき、Draftから変更した時をトリガーとしています。

name: Add Migration list

on:
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
    paths:
      - 'db/schema.rb'

Pull Requestのdescriptionを取得して一時保存するr。

まず、現在のPull Requestのdescriptionに追記する形を取るので、現在のPull Requestの情報を取得しましょう。
checkoutでリポジトリのソースコードを引っ張ってきた後に、ghコマンドを利用してpull requestの情報を取得します。

DESCRIPTION=$(gh pr view ${{ github.event.pull_request.number }} --json body --jq .body)

--json bodyでdescriptionを取得し、--jq .bodyでjson形式になっているのを平文に直しています。

また、このテキストは次のステップで使うので一時保存しましょう。

    outputs:
      replaced_description1: ${{ steps.get_description.outputs.replaced_description }}

この記述で、idがget_descriptionのステップで、replaced_descriptionとして保存したものを別ステップで ${{ steps.get_description.outputs.replaced_description }} のような記述で取り出せます。
格納はecho "outputs.の後に指定した文字列=格納したい文字列" >> $GITHUB_OUTPUTの形式で行います。
格納する際、sedで置換していますが、これはoutputsを使うためには一行にする必要があるためです。

containsを使って何度もMigration listsを作らないようにする

さて、更新する前にまずPull RequestにMigration listsが既に作られてないかチェックします。

- name: URL to Pull Request description
        if: contains(steps.get_description.outputs.replaced_description, '## Migration Lists') == false

runなどの前にifを置いて条件式を書くわけですが、今回は## Migration Listsという文字列がなかったらとします。
否定はcontainsの場合は contains(捜索する文字列, 含まれてるか確認したい文字列) == false形式で書きましょう。 !containsのような形式で書いたりしても普通にエラーになります。

descriptionの更新をする

それでは、実際に更新をしていきましょう。まずはenvから先ほど格納した値を呼べるようにします。

        env:
          REPLACED_DESCRIPTION: ${{ steps.get_description.outputs.replaced_description }}

まず、再度sedで改行が置換された文字列を再度置換しなおします。
その後、ghコマンドで、今度はPRを更新するためのコマンドを打ちます。 --bodyオプションでdescriptionを更新することができます。

        run: |
          DESCRIPTION=$(echo $REPLACED_DESCRIPTION | sed 's/;;;:::;;;/\n/g')
          gh pr edit ${{ github.event.pull_request.number }} --body "$DESCRIPTION
          ## Migration Lists
          - Migration time: s
          - Record size: "

まとめ

今回は特定条件でPull RequestのDescriptionを更新するというスクリプトを書いてみました。
GitHub Actionsではghコマンドを組み合わせることでPRを作成したり、編集したりかなり色々とできるので、是非何かやりたいことがあれば自作してみてください。

7
2
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
7
2