0
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?

Releaseの流れをGtiHub Actionsで自動化してみた

Posted at

学生プロジェクトでリリース作業を自動化したいという話になり、GitHub Actionsを使って、リリースPRの作成からマージ済みPRのチェックリスト生成まで、ボタン一つで完結するワークフローを構築しました。

やりたいこと

リリース作業で自動化したい内容は以下の2点です。

  1. PRタイトルの自動生成
    形式:RELEASE 202508081423(日時を含む)

  2. 動作確認チェックリストの自動生成
    前回リリース以降にマージされたPRを一覧表示

実装したワークフロー

全体像

以下がワークフロー全体のコードです。workflow_dispatchトリガーにより、手動実行でリリースPRを作成します。リリースが確定したタイミングでボタン一つでRELEASE PRが立つようにしています。

name: Deploy for Production
on:
  workflow_dispatch:

jobs:
  release:
    runs-on: ubuntu-latest
    concurrency:
        group: 'deploy-prod'
        cancel-in-progress: true
    permissions:
      contents: read
      pull-requests: write
    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
      
      - name: Get Latest RELEASE PR Number
        id: get-pr-number
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          LATEST_RELEASE_PR=$(gh pr list --state merged --base main --limit 1 --json number,mergedAt)
          echo "LATEST_RELEASE_PR=$LATEST_RELEASE_PR" >> $GITHUB_OUTPUT
          echo "Latest Release PR Number: $(echo "$LATEST_RELEASE_PR" | jq -r '.[0].number')"
          echo "Latest Release PR MergedAt: $(echo "$LATEST_RELEASE_PR" | jq -r '.[0].mergedAt')"
      
      - name: Get Latest PR LIST from Commits
        id: get-latest-pr
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          LATEST_MERGED_PR=$(gh pr list --state merged --base develop --search 'merged:>${{fromJSON(steps.get-pr-number.outputs.LATEST_RELEASE_PR)[0].mergedAt}}' --json url)
          echo "Latest Merged PR: $LATEST_MERGED_PR"
          PRLIST=$(echo "$LATEST_MERGED_PR" | jq -r '.[] | "- [ ] " + .url')
          echo "PRLIST<<EOF" >> $GITHUB_OUTPUT
          echo "$PRLIST" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT
          echo "Latest PR LIST from Commits: $PRLIST"
      
      - name: Set Timestamp
        id: set-timestamp
        run: echo "TIMESTAMP=$(date +%Y%m%d%H%M%S)" >> $GITHUB_OUTPUT
      
      - name: Create RELEASE PR
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |          
          gh pr create \
          --title "RELEASE ${{ steps.set-timestamp.outputs.TIMESTAMP }}" \
          --base main --head develop \
          --body "$(cat << EOF
          
          ## リリース内容:
          ${{ steps.get-latest-pr.outputs.PRLIST }}
          EOF
          )"

各ステップの解説

1. 最新のリリースPRを取得

まず、最新のリリースPRを取得します。意図としては、リリースPRがマージされた日付を取得して、その日付以降にdevelopブランチにマージされた内容をチェックリストとして表示するためです。

- name: Get Latest RELEASE PR Number
  id: get-pr-number
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  run: |
    LATEST_RELEASE_PR=$(gh pr list --state merged --base main --limit 1 --json number,mergedAt)
    echo "LATEST_RELEASE_PR=$LATEST_RELEASE_PR" >> $GITHUB_OUTPUT
    echo "Latest Release PR Number: $(echo "$LATEST_RELEASE_PR" | jq -r '.[0].number')"
    echo "Latest Release PR MergedAt: $(echo "$LATEST_RELEASE_PR" | jq -r '.[0].mergedAt')"

ポイント:

  • gh pr listコマンドで最新のマージ済みPRを取得
  • --json number,mergedAtで必要な情報(PR番号とマージ日時)のみをJSON形式で取得
  • 今後メンテナンスする人のために、PR番号や日付をechoコマンドでログ出力してデバッグしやすくしています

2. 動作確認チェックリストの作成

先ほど取得したPRのマージ日時以降に、developブランチにマージされたPRを取得し、マークダウンのチェックリスト形式に整形します。

- name: Get Latest PR LIST from Commits
  id: get-latest-pr
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  run: |
    LATEST_MERGED_PR=$(gh pr list --state merged --base develop --search 'merged:>${{fromJSON(steps.get-pr-number.outputs.LATEST_RELEASE_PR)[0].mergedAt}}' --json url)
    echo "Latest Merged PR: $LATEST_MERGED_PR"
    PRLIST=$(echo "$LATEST_MERGED_PR" | jq -r '.[] | "- [ ] " + .url')
    echo "PRLIST<<EOF" >> $GITHUB_OUTPUT
    echo "$PRLIST" >> $GITHUB_OUTPUT
    echo "EOF" >> $GITHUB_OUTPUT
    echo "Latest PR LIST from Commits: $PRLIST"

ポイント:

マージ日時以降のPRを検索

gh pr list --state merged --base develop --search 'merged:>${{fromJSON(steps.get-pr-number.outputs.LATEST_RELEASE_PR)[0].mergedAt}}' --json url

fromJSONはGitHub Actionsの標準関数で、JSON文字列をオブジェクトに変換します。これにより、前のステップで取得したJSON形式のデータからmergedAtプロパティにアクセスできます。

チェックリスト形式への整形

PRLIST=$(echo "$LATEST_MERGED_PR" | jq -r '.[] | "- [ ] " + .url')

jqコマンドの-rオプションで生の文字列として出力し、.[]で配列の各要素にアクセスして"- [ ] " + .urlの形式に整形しています。

複数行の出力

echo "PRLIST<<EOF" >> $GITHUB_OUTPUT
echo "$PRLIST" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

複数行の文字列をGITHUB_OUTPUTに出力する際は、ヒアドキュメント形式https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_3766230_43492d2a-edca-450f-938f-1cee633916f2.avif
<<EOF ... EOF)を使用します。

3. 日時の取得

リリースPRのタイトルに使用する日時を取得します。

- name: Set Timestamp
  id: set-timestamp
  run: echo "TIMESTAMP=$(date +%Y%m%d%H%M%S)" >> $GITHUB_OUTPUT

dateコマンドで現在時刻をYYYYMMDDHHmmss形式で取得し、ステップ間で共有できるように出力しています。

4. リリースPRの作成

最後に、取得した情報を使ってリリースPRを作成します。

- name: Create RELEASE PR
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  run: |          
    gh pr create \
    --title "RELEASE ${{ steps.set-timestamp.outputs.TIMESTAMP }}" \
    --base main --head develop \
    --body "$(cat << EOF
    
    ## リリース内容:
    ${{ steps.get-latest-pr.outputs.PRLIST }}
    EOF
    )"

ポイント:

  • --titleで日時を含むタイトルを設定
  • --base main --head developでdevelopブランチからmainブランチへのPRを作成
  • --bodyでヒアドキュメントを使い、チェックリスト形式のリリース内容を本文に含める

完成イメージ

実行すると、以下のようなリリースPRが自動生成されます:

https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_3766230_43492d2a-edca-450f-938f-1cee633916f2.avif

タイトルには実行日時が含まれ、本文には前回リリース以降にマージされたPRがチェックリスト形式で一覧表示されます。これにより、動作確認が必要な項目が一目で分かります。

まとめ

GitHub Actionsを使ってリリース作業を自動化することで、以下のメリットがあるかなと思います。

  • 属人化の解消 - リリースフローを知らなくてもボタン一つで実行可能
  • 確認漏れの防止 - マージ済みPRが自動でリスト化されるため、動作確認漏れを防げる
  • 引き継ぎの簡易化 - ワークフローとして残るため、後任への引き継ぎが容易

ぜひ参考にしてみてください

0
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
0
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?