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?

More than 1 year has passed since last update.

[GitHub Actions] リリースノートの自動化の仕組み

1
Last updated at Posted at 2023-12-22

はじめに

  • この記事では、GitHub Actionsを使用して、特定のブランチ(この場合はprodブランチ)にマージされたPRからリリースノートを自動生成し、ログ保管する方法について説明します
  • このプロセスは、PRがマージされると自動的にトリガーされ、リリースプロセスを効率化します
  • 保管する意図として、後で誰が何をいつリリースしたかを検索できるようにすることです
  • 例えばAというリポジトリで該当ブランチにPRを作成してマージしたとします
  • そのPRの内容は後で見返す時にGitHub上で検索して調べる時に結構めんどくさいです
  • PRの内容がどこかに日付ごとに記載されていればすぐ分かります

結論と成果物

  • 別のリポジトリのPRの内容を日付ごとに記載して保管したファイル
  • 該当ファイル

スクリーンショット 2023-12-22 15.32.36.png

基本的な設定

  • 今回使用するリポジトリは下記です
  • auto-release-pr
    • リリースPRを自動生成するActions
  • auto_release_note_log
    • リリースPRの内容をMarkdown形式にして保管
  • メインのブランチを決めます。今回はprodブランチですが、main、developと自分が使用しているメインブランチをチェックしてください
  • 今回2つのブランチ間でActionsの実行をしますので、GitHub Actions でのシークレットの使用こちらの設定を2つのブランチに設定する必要があります
  • SettingsからActions permissionsの変更する部分も忘れずに

スクリーンショット 2023-12-22 17.16.54.png

GitHub Actions でのシークレットの設定方法

  • 異なるリポジトリ間では、secrets.GITHUB_TOKENは使用できなく、これは単一リポジトリでしか使用できません
  • よって、secrets.<自分で設定したもの>を使用することでActionsを使用することができます
  • 2つのリポジトリで設定している図
    スクリーンショット 2023-12-22 15.38.33.png
    スクリーンショット 2023-12-22 15.41.03.png
  • SecretKey自体は同じ値を設定

自動リリースPR作成について

.github/workflows/create-release-pr.yml
name: Create Release Note

on:
  pull_request:
    branches:
      - prod
    types:
      - closed

jobs:
  call-create-release-note-workflow:
    runs-on: ubuntu-latest
    steps:

      - name: Create Release Note Call
        if: github.event.pull_request.merged == true
        env:
          GITHUB_TOKEN: ${{ secrets.ACTIONS_TOKEN }}
          PR_NUMBER: ${{ github.event.pull_request.number }}
          RELEASED_REPOSITORY: "auto-release-pr"
        run: |
          curl \
          -X POST \
          -H "Accept: application/vnd.github.v3+json" \
          -H "Authorization: token $GITHUB_TOKEN" \
          -d "{\"ref\": \"main\", \"inputs\": {\"prNumber\": \"$PR_NUMBER\", \"releasedRepository\": \"$RELEASED_REPOSITORY\"}}" \
          https://api.github.com/repos/atsutama2/auto_release_note_log/actions/workflows/make-release-note-call.yml/dispatches
  • developへのマージが完了すると自動生成されたPRが作成されます。(prod向け)
  • イメージとしてはこんな感じ

スクリーンショット 2023-12-22 17.08.46.png

  • このPRをマージしたタイミングで走るリリースノート生成Actionsを呼ぶのがこちら
  • 別のリポジトリで管理しているリリースノートの生成・更新をします
.github/workflows/create-release-note.yml
name: Create Release Note

on:
  pull_request:
    branches:
      - prod
    types:
      - closed

jobs:
  call-create-release-note-workflow:
    runs-on: ubuntu-latest
    steps:

      - name: Create Release Note Call
        if: github.event.pull_request.merged == true
        env:
          GITHUB_TOKEN: ${{ secrets.ACTIONS_TOKEN }}
          PR_NUMBER: ${{ github.event.pull_request.number }}
          RELEASED_REPOSITORY: "auto-release-pr"
        run: |
          curl \
          -X POST \
          -H "Accept: application/vnd.github.v3+json" \
          -H "Authorization: token $GITHUB_TOKEN" \
          -d "{\"ref\": \"main\", \"inputs\": {\"prNumber\": \"$PR_NUMBER\", \"releasedRepository\": \"$RELEASED_REPOSITORY\"}}" \
          https://api.github.com/repos/atsutama2/auto_release_note_log/actions/workflows/make-release-note-call.yml/dispatches

リリースノートの生成/更新について

  • 該当コード
  • こちらでPRの詳細からリリースノートを自動生成し、Markdownファイルとして保管するためのものです
.github/workflows/make-release-note-call.yml
name: Make Release Note Call

on:
  workflow_dispatch:
    inputs:
      prNumber:
        type: string
        description: "release pr number"
        required: true
      releasedRepository:
        type: string
        description: "released repository name"
        required: true

concurrency: make-release-note
jobs:
  make-release-note:
    runs-on: ubuntu-latest
    env:
      RELEASED_REPOSITORY: ${{ github.event.inputs.releasedRepository }}
      PR_NUMBER: ${{ github.event.inputs.prNumber }}
      ORGANIZATION: "atsutama2"
      DIRECTORY_NAME: "releases"
    steps:
      - uses: actions/checkout@v4

      - name: Create Date and Directory Path
        run: |
          YEAR=$(TZ=Asia/Tokyo date +'%Y')
          MONTH=$(TZ=Asia/Tokyo date +'%m')
          echo "YEAR=$YEAR" >> $GITHUB_ENV
          echo "MONTH=$MONTH" >> $GITHUB_ENV
          echo "FILE_PATH=${DIRECTORY_NAME}/$YEAR/$MONTH.md" >> $GITHUB_ENV

      - name: Make File
        id: make-file
        run: |
          if [ ! -d "${DIRECTORY_NAME}/$YEAR" ]; then
            mkdir -p "${DIRECTORY_NAME}/$YEAR"
          fi

          if [ ! -f "$FILE_PATH" ]; then
            touch "$FILE_PATH"
          fi

      - name: Get Pull Request Details
        run: |
          API_URL="https://api.github.com/repos/${ORGANIZATION}/${RELEASED_REPOSITORY}/pulls/${PR_NUMBER}"

          PR_DATA=$(curl -H "Authorization: token ${{ secrets.ACTIONS_TOKEN }}" $API_URL)
          echo PR_TITLE=$(echo "$PR_DATA" | jq -r '.title') >> $GITHUB_ENV
          PR_BODY=$(echo "$PR_DATA" | jq -r '.body')

          # すべてのラベル名をカンマ区切りの文字列として保存
          LABEL_NAMES=$(echo "$PR_DATA" | jq -r '.labels | map(.name) | join(", ")')
          echo "LABEL_NAMES=$LABEL_NAMES" >> $GITHUB_ENV

          IFS=$'\n' PR_NUMBERS=($(echo "$PR_BODY" | grep -oP '(?<=#)\d+'))
          echo "PR_NUMBERS=$(IFS=,; echo "${PR_NUMBERS[*]}")" >> $GITHUB_ENV
          echo "API_URL=$API_URL" >> $GITHUB_ENV

      - name: Fetch and Store PR Details as Sets
        if: ${{ env.PR_NUMBERS != '' }}
        run: |
          IFS=',' read -r -a PR_NUMBERS_ARRAY <<< "${PR_NUMBERS}"

          for PR_NUM in "${PR_NUMBERS_ARRAY[@]}"; do
            PR_API_URL="https://api.github.com/repos/${ORGANIZATION}/${RELEASED_REPOSITORY}/pulls/${PR_NUM}"
            PR_DETAILS=$(curl -H "Authorization: token ${{ secrets.ACTIONS_TOKEN }}" $PR_API_URL)
            PR_TITLE=$(echo "$PR_DETAILS" | jq -r '.title')
            PR_URL=$(echo "$PR_DETAILS" | jq -r '.html_url')
            PR_AUTHOR=$(echo "$PR_DETAILS" | jq -r '.user.login')
            PR_DETAILS_SETS+=("$PR_TITLE###$PR_URL###$PR_AUTHOR")  # '###'を区切り文字として使用
            echo "Added to PR Details Sets: $PR_TITLE ### $PR_URL ### $PR_AUTHOR"
          done

          echo "PR_DETAILS_SETS=$(IFS='@@@'; echo "${PR_DETAILS_SETS[*]}")" >> $GITHUB_ENV

      - name: Create Markdown Content
        run: |
          # PR_DETAILS_SETSを配列に変換
          IFS='@@@' read -r -a PR_DETAILS_SETS_ARRAY <<< "${PR_DETAILS_SETS}"

          RELEASE_DATETIME=$(TZ=Asia/Tokyo date +'%Y/%m/%d %H:%M:%S')

          # 一時ファイルにMarkdown文字列を作成
          echo "## [${RELEASE_DATETIME}](https://github.com/${ORGANIZATION}/${RELEASED_REPOSITORY}/pull/${PR_NUMBER})" > temp_markdown_content.txt
          echo "Labels: $LABEL_NAMES" >> temp_markdown_content.txt
          for PR_SET in "${PR_DETAILS_SETS_ARRAY[@]}"; do
            # '###'を区切り文字として使用
            TITLE=$(echo "$PR_SET" | awk -F '###' '{print $1}')
            URL=$(echo "$PR_SET" | awk -F '###' '{print $2}')
            AUTHOR=$(echo "$PR_SET" | awk -F '###' '{print $3}')

            # Markdownフォーマットに従ってファイルに書き込み
            echo "- (${AUTHOR}) ${TITLE}" >> temp_markdown_content.txt
            echo "  - ${URL}" >> temp_markdown_content.txt
          done

          # 既存のファイル内容の先頭に新しい内容を追加
          if [ -f "$FILE_PATH" ]; then
              cat temp_markdown_content.txt "$FILE_PATH" > temp_file && mv temp_file "$FILE_PATH"
          fi

      - name: Commit Change
        run: |
          git config --local user.email "action@github.com"
          git config --local user.name "GitHub Action"
          git add "$FILE_PATH"
          git commit -m "make release note: ${FILE_PATH}" -a

      - name: Push Changes
        uses: ad-m/github-push-action@v0.6.0
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          branch: ${{ github.ref }}

まとめ

GitHub Actionsを使ってリリースノートを自動生成する便利な方法をご紹介しました。PRがマージされるとリリースノートが出来上がり、整理されたログが手元に残ります。めんどうな手作業から解放されて、どんな変更がいつ行われたかをパッと見ることができるようになります。このやり方を取り入れれば、プロジェクトの進行状況をスムーズに追跡できるようになり、チームの作業効率もアップすると思います。

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?