😃

Pull RequestコメントでUnity Cloud BuildをトリガーするCI

2024/11/11に公開

Unityプロジェクトの開発において、継続的インテグレーション(CI)と継続的デリバリー(CD)は品質向上と迅速なデプロイに不可欠です。本記事では、GitHub Actionsを使用してUnity Cloud Buildを自動化し、Pull Request(PR)のコメントからビルドをトリガーする方法について詳しく解説します。これにより、開発チームは手動でのビルド操作を減らし、効率的なワークフローを実現できます。

シナリオの概要

以下のGitHub Actionsワークフローは、PRに特定のコメント(例:/build)が追加された際に自動的にUnity Cloud Buildをトリガーします。
本ワークフローを利用する前に、Unity Cloud Buildで必要なビルドターゲットの追加など、事前準備が完了している必要があります。
ビルドのステータスはDiscordのチャンネルに通知されるため、チーム全体でリアルタイムに進捗を把握できます。

GitHub Actionsワークフローの詳細解説

以下に示すunity_build_on_devops.ymlは、上記の自動化を実現するためのGitHub Actionsワークフローです。

name: unity_build_on_devops.yml

on:
  issue_comment:
    types: [created] # 必要に応じて`edited`なども

jobs:
  trigger-build:
    runs-on: ubuntu-latest
    if: >
      github.event.issue.pull_request != null &&
      startsWith(github.event.comment.body, '/build') # コメントが/buildから始まっているかを確認
    steps:
      - name: Check out repository
        uses: actions/checkout@v4

      - name: Install GitHub CLI
        run: |
          type -p curl >/dev/null || (sudo apt update && sudo apt install -y curl)
          curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
          sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg
          echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
          sudo apt update
          sudo apt install gh

      - name: Authenticate GitHub CLI
        env:
          TOKEN_GITHUB: ${{ secrets.TOKEN_GITHUB }}
        run: |
          echo "${TOKEN_GITHUB}" | gh auth login --with-token

      - name: Parse build command
        id: parse
        run: |
          comment="${{ github.event.comment.body }}"
          echo "Comment: $comment"
          if [[ "$comment" =~ ^/build[[:space:]]*([a-fA-F0-9]{7,40})?$ ]]; then
            commit="${BASH_REMATCH[1]}"
            if [ -z "$commit" ]; then
              # PRの最新コミットSHAを取得
              commit=$(gh pr view ${{ github.event.issue.number }} --json headRefOid -q .headRefOid)
              echo "No commit specified. Using latest commit: $commit"
            else
              echo "Using specified commit: $commit"
            fi
            echo "commit=$commit" >> $GITHUB_OUTPUT
          else
            echo "No valid build command found."
            exit 1
          fi

      - name: Trigger Unity Cloud Build
        id: trigger-build
        run: |
          commit_sha=${{ steps.parse.outputs.commit }}
          echo "Triggering build for commit: $commit_sha"

          # jq がインストールされていることを確認
          sudo apt-get install -y jq

          # ペイロードの準備
          payload=$(jq -n \
            --arg commit "$commit_sha" \
            --arg platform "standalonewindows64" \
            --arg machineTypeLabel "win_premium_v1" \
            '{
              clean: false,
              delay: 0,
              commit: $commit
            }')

          # Unity Cloud Build API を介してビルドをトリガー
          response=$(curl -s -w "%{http_code}" -o response.json -X POST "https://build-api.cloud.unity3d.com/api/v1/orgs/${{ secrets.UNITY_ORG_ID }}/projects/${{ secrets.UNITY_PROJECT_ID }}/buildtargets/${{ secrets.BUILD_TARGET_ID }}/builds" \
            -H "${{ secrets.AUTHORIZATION_HEADER }}" \
            -H "Content-Type: application/json" \
            -d "$payload")

          echo "HTTP Status Code: $response"

          if [[ "$response" =~ ^2 ]]; then
            echo "Build triggered successfully."
            # レスポンスからビルドIDを抽出(配列の最初の要素)
            build_id=$(jq -r '.[0].build' response.json)
            if [[ "$build_id" != "null" ]]; then
              echo "build_id=$build_id" >> $GITHUB_OUTPUT
            else
              echo "Failed to trigger build. HTTP status code: $response"
              # レスポンスからエラーメッセージを抽出
              error_message=$(jq -r '.[0].error' response.json)
              echo "error_message=$error_message" >> $GITHUB_OUTPUT
            fi
          else
            echo "Failed to trigger build. HTTP status code: $response"
            # レスポンスからエラーメッセージを抽出
            error_message=$(jq -r '.[0].error' response.json)
            echo "error_message=$error_message" >> $GITHUB_OUTPUT
          fi

      - name: Comment on PR
        uses: peter-evans/create-or-update-comment@v3
        with:
          token: ${{ secrets.TOKEN_GITHUB }}
          issue-number: ${{ github.event.issue.number }}
          body: |
            ✅ ビルドをqueueに追加しました。
            コミット: `${{ steps.parse.outputs.commit }}`
            ビルドID: `${{ steps.trigger-build.outputs.build_id }}`
            状況はDiscordの#unity-buildチャンネルで確認してください。(完了すると自動でリンクが貼られます)

各環境変数

  • TOKEN_GITHUB
    GitHub CLI (gh) の認証に使用されるトークンです。このトークンにより、ワークフローがリポジトリやPull Requestにアクセスし、必要な操作を実行できます。
  • UNITY_ORG_ID
    UnityCloud->管理->組織の設定->組織ID
    Unity組織のID。Unity Cloud Build APIにアクセスする際に組織を指定します。
  • UNITY_PROJECT_ID
    UnityCloud->プロジェクト->{プロジェクト名}->プロジェクト ID
    UnityプロジェクトのID。特定のプロジェクトを指定してビルドをトリガーします。
  • BUILD_TARGET_ID
    ビルドターゲットのID。ビルドするプラットフォームや設定を指定します。
curl https://build-api.cloud.unity3d.com/api/v1/orgs/{UNITY_ORG_ID}/projects/{UNITY_PROJECT_ID}/buildtargets \
-H "Authorization: Basic [API KEY]"

のAPIから取得できます。APIに関する詳細は、こちらから

  • AUTHORIZATION_HEADER
    以下の形式になります。
Authorization: Basic [API KEY]

**API KEY**は、
DevOps->BuildAutomation->設定->General->Organization settings->API settings->API Key
に記載があります。

各ステップの詳細

  1. イベントトリガーの設定
on:
  issue_comment:
    types: [created]
  • 説明: PRにコメントが追加されたときにワークフローがトリガーされます。
  • 条件: コメントが/buildで始まり、対象がPull Requestである場合のみ実行されます。
  1. ジョブの定義
jobs:
  trigger-build:
    runs-on: ubuntu-latest
    if: >
      github.event.issue.pull_request != null &&
      startsWith(github.event.comment.body, '/build')

trigger-buildジョブは最新のUbuntuランナー上で実行されます。
コメントがPRに対して行われ、内容が/buildで始まる場合にのみ実行されます。

  1. リポジトリのチェックアウト
- name: Check out repository
  uses: actions/checkout@v4

現在のリポジトリのコードをチェックアウトします。
4. GitHub CLIのインストール

- name: Install GitHub CLI
  run: |
    type -p curl >/dev/null || (sudo apt update && sudo apt install -y curl)
    curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
    sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
    sudo apt update
    sudo apt install gh

GitHub CLI(gh)をインストールします。これはPRの詳細取得や認証に使用されます。

  1. GitHub CLIの認証
- name: Authenticate GitHub CLI
  env:
    TOKEN_GITHUB: ${{ secrets.TOKEN_GITHUB }}
  run: |
    echo "${TOKEN_GITHUB}" | gh auth login --with-token

GitHub CLIを使用して認証を行います。TOKEN_GITHUBはリポジトリのシークレットに保存されています。

  1. ビルドコマンドの解析
- name: Parse build command
  id: parse
  run: |
    comment="${{ github.event.comment.body }}"
    echo "Comment: $comment"
    if [[ "$comment" =~ ^/build[[:space:]]*([a-fA-F0-9]{7,40})?$ ]]; then
      commit="${BASH_REMATCH[1]}"
      if [ -z "$commit" ]; then
        # PRの最新コミットSHAを取得
        commit=$(gh pr view ${{ github.event.issue.number }} --json headRefOid -q .headRefOid)
        echo "No commit specified. Using latest commit: $commit"
      else
        echo "Using specified commit: $commit"
      fi
      echo "commit=$commit" >> $GITHUB_OUTPUT
    else
      echo "No valid build command found."
      exit 1
    fi

コメント内容を解析し、/buildコマンドに続くオプションのコミットSHAを取得します。SHAが指定されていない場合は、PRの最新コミットを使用します。

  1. Unity Cloud Buildのトリガー
- name: Trigger Unity Cloud Build
  id: trigger-build
  run: |
    commit_sha=${{ steps.parse.outputs.commit }}
    echo "Triggering build for commit: $commit_sha"

    # jq がインストールされていることを確認
    sudo apt-get install -y jq

    # ペイロードの準備
    payload=$(jq -n \
      --arg commit "$commit_sha" \
      --arg platform "standalonewindows64" \
      --arg machineTypeLabel "win_premium_v1" \
      '{
        clean: false,
        delay: 0,
        commit: $commit
      }')
    # Unity Cloud Build API を介してビルドをトリガー
    response=$(curl -s -w "%{http_code}" -o response.json -X POST "https://build-api.cloud.unity3d.com/api/v1/orgs/${{ secrets.UNITY_ORG_ID }}/projects/${{ secrets.UNITY_PROJECT_ID }}/buildtargets/${{ secrets.BUILD_TARGET_ID }}/builds" \
      -H "${{ secrets.AUTHORIZATION_HEADER }}" \
      -H "Content-Type: application/json" \
      -d "$payload")

    echo "HTTP Status Code: $response"

    if [[ "$response" =~ ^2 ]]; then
      echo "Build triggered successfully."
      # レスポンスからビルドIDを抽出(配列の最初の要素)
      build_id=$(jq -r '.[0].build' response.json)
      if [[ "$build_id" != "null" ]]; then
        echo "build_id=$build_id" >> $GITHUB_OUTPUT
      else
        echo "Failed to trigger build. HTTP status code: $response"
        # レスポンスからエラーメッセージを抽出
        error_message=$(jq -r '.[0].error' response.json)
        echo "error_message=$error_message" >> $GITHUB_OUTPUT
      fi
    else
      echo "Failed to trigger build. HTTP status code: $response"
      # レスポンスからエラーメッセージを抽出
      error_message=$(jq -r '.[0].error' response.json)
      echo "error_message=$error_message" >> $GITHUB_OUTPUT
    fi

指定されたコミットSHAに基づいてUnity Cloud Build APIを呼び出し、ビルドをトリガーします。jqを使用してJSONペイロードを作成し、curlでAPIにリクエストを送信します。ビルドIDを取得し、後続のステップで使用できるように出力します。

  1. PRへのコメント
- name: Comment on PR
  uses: peter-evans/create-or-update-comment@v3
  with:
    token: ${{ secrets.TOKEN_GITHUB }}
    issue-number: ${{ github.event.issue.number }}
    body: |
      ✅ ビルドをqueueに追加しました。
      コミット: `${{ steps.parse.outputs.commit }}`
      ビルドID: `${{ steps.trigger-build.outputs.build_id }}`
      状況はDiscordの#unity-buildチャンネルで確認してください。(完了すると自動でリンクが貼られます)

ビルドが正常にトリガーされたことをPRにコメントとして投稿します。コメントには使用されたコミットSHAとビルドIDが含まれ、Discordチャンネルでの状況確認も案内されています。
7のAPIのresponseで、status表示やcancel時のリンクが返されるので、それらもコメントに記載すると良いかもしれません。

Unity Cloudとの連携とDiscord通知

このワークフローでは、Unity Cloud BuildのAPIを直接呼び出してビルドをトリガーしています。ビルドのステータスや結果は、Unity Cloudのインテグレーション機能を通じてDiscordの特定のチャンネル(例:#unity-build)に通知されます。これにより、開発チームはビルドの進捗や結果をリアルタイムで把握でき、迅速なフィードバックが可能となります。

UnityCloudAPIのreference: https://build-api.cloud.unity3d.com/docs/1.0.0/index.html

まとめ

GitHub Actionsを活用することで、Unity Cloud Buildの自動化が容易になり、開発フローの効率化と品質向上が期待できます。本記事で紹介したワークフローは、PRコメントからのビルドトリガーを実現し、チーム全体での迅速なフィードバックを可能にします。さらに、Discordとの連携により、ビルドの状況をリアルタイムで共有できるため、コミュニケーションの円滑化にも寄与します。ぜひ、プロジェクトに取り入れてみてください。orgが無料アカウントの場合、ビルド時間等に制限がある点に注意してください。

Discussion