WinCNT

Github Actions 사용해보기! 본문

Unity/Unity 관련

Github Actions 사용해보기!

WinCNT_SSS 2023. 10. 31. 10:10

서론

Unity 카테고리에 작성할 건 아닌 것 같지만 최종적으로는 Unity와 같이 쓸 예정이니 일단 여기에 정리해본다

PowerShell 스크립트가 있으니 금방할 수 있을 줄 알았는데 역시나 많은 삽질이 있었다(…)


이번에 작성한 Github Actions의 기본 구조

Github Actions에 대한 자세한 설명은 훨씬 좋은 글이 많으니 사용한 부분에 대해서만 간략하게 정리해 가려고 한다

job과 step의 이름은 Action의 Summary 표시되니 잘 설정하는 게 좋다

참고로 필자의 경우 runs-on: [ self-hosted ]에서 설정된 빌드 머신은 Windows 운영 체제이다

(GitHub Actions 작성 전에 PowerShell이나 CMD로 테스트한 이유)

# Github Actions의 이름
name: Test

# Github Actions이 실행되는 타이밍
on:
  # workflow_dispatch는 Actions의 Workflow에서 버튼으로 실행
  workflow_dispatch:
  # main 브랜치에 pull request가 생성되거나 병합되는 타이밍에 실행
  pull_request:
    branches:
      - main
    types: [opened, closed]

# job은 Github Actions의 일련의 처리 단위
jobs:
  # job의 이름(첫번째)
  build:
    # Job을 실행할 환경(필수)
    # 주로 우분투 최신 버전(ubuntu-latest)을 설정하는 경우가 많지만, 독자적인 환경이 있는 경우는 self-hosted를 지정한다
    runs-on: [self-hosted]
    # Job은 하나 이상의 Step으로 정의된다
    steps:
      # step의 이름, step은 반드시 uses나 run이 있어야 한다
      # Action(GitHub Actions용 앱)일 때는 uses, 커맨드일 때는 run를 사용한다
      - name: Checkout
        uses: actions/checkout@v3
      - name: Test
        run: echo Hello, World!
		# ...생략...

  # job의 이름(두번째)
  test-rendering:
    # needs는 특정 job이 완료되면 실행하도록 설정
    needs: build
    runs-on: [ self-hosted ]
    steps:
			# ...생략...
      - name: Check Build File
        run: |
          if((Test-Path $env:APK_PATH)){
              Write-Host APK file exists!
          } else {
              Write-Host APK file does not exist!
              exit -1
          }
			# ...생략...

변수와 if문 분기 관련!

step(의 run) 내부에서 사용되는 변수는 PowerShell과 똑같이 변수명 앞에 $를 붙인다

다만 환경 변수의 경우에는 PowerShell 구문에 따라 앞에 env:를 붙여야 한다

(우분투의 경우에는 붙일 필요가 없는 것 같다)

 

만약 step의 변수를 다른 step에서도 참고하고 싶으면 GITHUB_OUTPUT을 사용하면 되는데, GITHUB_OUTPUT도 일종의 환경 변수이므로 앞에 env:를 붙여야 한다

# 변수에 대입 시
  run: echo "{name}={value}" >> $env:GITHUB_OUTPUT
# 참조
  steps.step_id.outputs.name

전에는 참고로 set-output란 키워드를 사용했다고 하는데 이쪽은 폐지될 가능성이 있다고 한다

 

GitHub Actions에서는 if문을 사용해서 다음 step을 실행하지 말지 분기할 수도 있다

# 예시
- name: if_statement
  if: 조건문1
  run: Write-Host "조건문1"

 

이를 이용해서 연결된 Android 디바이스가 있는지 ADB로 체크하고, 그 결과에 따라 다음 step를 실행할지 분기하는 코드를 짜봤다

name: Test

on:
  workflow_dispatch:

env:
  APK_PATH: ".\\\\Build\\\\Application.apk"
  ADB_PATH: "C:\\\\android\\\\platform-tools\\\\adb"
  OUTPUT_PATH: ".\\\\"

jobs:
  build:
    runs-on: [self-hosted]
    steps:
# ...(생략)...
      - name: Check Android Device Connected
        # 현재 step의 id를 지정(GITHUB_OUTPUT을 위해 필요)
        id: check_device
        run: |
          # 위에서 선언한 환경 변수 ADB_PATH를 사용하기 위해서는 "env:"를 앞에 붙여야 한다
          $adbDevicesOutput = & $env:ADB_PATH devices
          $numConnectedDevices = ($adbDevicesOutput | Select-String -Pattern "^(?!List).*device$").Count
          # $numConnectedDevices의 값을 GITHUB_OUTPUT의 numConnectedDevices에 저장한다
          "numConnectedDevices=$numConnectedDevices" >> $env:GITHUB_OUTPUT
      - name: No Connected Android Devices
        # if문으로 다음 스텝을 실행할지 말지 판단한다
        # GITHUB_OUTPUT의 변수는 스텝의 id와 저장할 때 설정한 name으로 참조할 수 있다
        if: steps.check_device.outputs.numConnectedDevices == 0
        run: |
          Write-Host "No Connected Android Devices!"
          exit 1
      - name: Two or more Connected Android Devices
        if: steps.check_device.outputs.numConnectedDevices > 1
        run: |
          Write-Host "Two or more Connected Android Devices!"
          exit 1
      - name: Build
        if: steps.check_device.outputs.numConnectedDevices == 1
        run: |
# ...(생략)...

환경을 지정해서 스크립트를 실행하기

현재의 빌드 머신 환경이 PowerShell로 설정되어 있으므로 GitHub Actions에 작성한 스크립트로 기본적으로 PowerShell로 실행되지만, shell:란 커맨드를 이용하면 특정 step이 실행되는 환경을 지정할 수 있다

다음은 이번에 작성한 Unity.exe를 CMD로 실행해서 빌드하는 메소드를 호출하는 스크립트이다

# 예시
- name: Build
  shell: cmd
  run: |
    "C:\\Program Files\\Unity\\Hub\\Editor\\<version>\\Editor\\Unity.exe" -batchmode -nographics -buildTarget Android -quit -logfile - -projectPath . -executeMethod UnityEditor.ScreenShotCI.Build

왜 굳이 CMD로 지정했냐고 하면 PowerShell인 경우 에러가 발생하거나, 에러가 발생하지 않아도 빌드가 제대로 되지 않는다는 여러 문제점이 발생했기 때문이다

다만 이것이 PowerShell이여서 그런 것인지, 빌드 머신과의 통신의 문제인지, 빌드 머신 쪽 Unity는 Pro가 아니라 Personal이라서 그런 것인지, -buildTarget Android란 인수를 빼먹어서인지(Local에서는 없어도 문제 없었음), 아니면 모든 것이 원인이었는지는 모르겠다…움직이면 됐지


GitHub Actions에서 Bot으로 Commit하기

GitHub Actions에서는 봇으로 Commit하는 스크립트를 작성할 수 있다

(최종적으로는 다른 방법을 택하게 되었지만 조사한 것이 아까워서 정리함)

- name: example
  run: |
    # Bot를 지정
    git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
    git config --local user.name "github-actions[bot]"
    # Commit하고 Push
    git add .\\Runner\\
    git commit -m "Automated report2"
    git push

봇으로 Commit하면 다음과 같이 표시된다

사실 제대로 하려면 GITHUB_TOKEN이나 액세스 권한 등도 제대로 알 필요가 있지만, 우선 간단하게 사용하려면 위의 코드로 충분하지 않을까?


실행 순서에 대한 주의점

마지막으로 job들에 의한 실행 순서에 대한 주의점 하나를 정리하려고 한다

GitHub Actions에서는 동시에 여러 액션이 실행되면 큐로 실행 순서를 관리한다

 

만약 다음과 같은 job을 가진 액션이 연속으로 실행되었다고 하자

# ...(생략)...
jobs:
  # 첫번째 job
  build:
		# ...(생략)...

  # 두번째 job
  test-rendering:
		# ...(생략)...

이 경우 잡의 실행 순서는 build(첫번째) → test-rendering(첫번째) → build(두번째) → test-rendering(두번째)가 아니다

실제로 실행되는 순서는 build(첫번째) → build(두번째) → test-rendering(첫번째) → test-rendering(두번째)가 된다


샘플 코드

아래는 이번에 작성한 Github Actions 스크립트의 코드의 전문이다

name: Test

on:
  workflow_dispatch:

env:
  APK_PATH: ".\\\\Build\\\\Application.apk"
  ADB_PATH: "C:\\\\android\\\\platform-tools\\\\adb"
  OUTPUT_PATH: ".\\\\"

jobs:
  build:
    runs-on: [self-hosted]
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Generate gh token
        id: get_token
        uses: getsentry/action-github-app-token@v2
        with:
          app_id: ${{ secrets.APP_ID }}
          private_key: ${{ secrets.APP_PRIVATE_KEY }}
      - name: Checkout actions-library
        uses: actions/checkout@v3
        with:
          repository: company/actions-library
          token: ${{ steps.get_token.outputs.token }}
          path: actions-library
      - name: Check Android Device Connected
        id: check_device
        run: |
          $adbDevicesOutput = & $env:ADB_PATH devices
          $numConnectedDevices = ($adbDevicesOutput | Select-String -Pattern "^(?!List).*device$").Count
          "numConnectedDevices=$numConnectedDevices" >> $env:GITHUB_OUTPUT
      - name: No Connected Android Devices
        if: steps.check_device.outputs.numConnectedDevices == 0
        run: |
          Write-Host "No Connected Android Devices!"
          exit 1
      - name: Two or more Connected Android Devices
        if: steps.check_device.outputs.numConnectedDevices > 1
        run: |
          Write-Host "Two or more Connected Android Devices!"
          exit 1
      - name: Build
        if: steps.check_device.outputs.numConnectedDevices == 1
        shell: cmd
        run: |
          "C:\\Program Files\\Unity\\Hub\\Editor\\<version>\\Editor\\Unity.exe" -batchmode -nographics -buildTarget Android -quit -logfile - -projectPath . -executeMethod UnityEditor.ScreenShotCI.Build
  test-rendering:
    needs: build
    runs-on: [ self-hosted ]
    steps:
      - name: Check Build File
        run: |
          if((Test-Path $env:APK_PATH)){
              Write-Host APK file exists!
          } else {
              Write-Host APK file does not exist!
              exit -1
          }
      - name: Install App
        run: |
          & $env:ADB_PATH install -g $env:APK_PATH
          Start-Sleep -Seconds 10
      - name: Start App
        run: |
          & $env:ADB_PATH shell am broadcast -a com.oculus.vrpowermanager.prox_close
          & $env:ADB_PATH shell am start -n com.company.Graphics/com.unity3d.player.UnityPlayerActivity
          Start-Sleep -Seconds 10
          while ($null -ne (& $env:ADB_PATH shell ps | Select-String -Pattern "com.company.Graphics")) {
              Write-Host "-Application is Running!"
              Start-Sleep -Seconds 10
          }
          Write-Host "-Application is not Running!"
          & $env:ADB_PATH shell am broadcast -a com.oculus.vrpowermanager.automation_disable
      - name: Copy Screenshots Images
        run: |
          & $env:ADB_PATH pull /sdcard/Oculus/Screenshots/Runner $env:OUTPUT_PATH
          & $env:ADB_PATH shell rm -r /sdcard/Oculus/Screenshots/Runner
      - name: Commit Screenshots Images
        run: |
          if((Test-Path $env:OUTPUT_PATH)){
            git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
            git config --local user.name "github-actions[bot]"
            git add .\\Runner\\
            git commit -m "Rendering Test Images Commit"
            git push
          } else {
              Write-Host Screenshots Images do not exist!
              exit -1
          }

마무리

이걸로 길었던 작업이 일단락되었다

작업 전에는 GitHub Actions에 대해서 1도 몰랐지만 어떻게든 되는 법이군


참고 사이트

이번엔 좀 많네…얼마나 고생했는지 알겠다

GitHub Actions를 이용한 CI/CD 구축하기

 

GitHub Actions를 이용한 CI/CD 구축하기

Github Actions를 통해 어떻게 React 애플리케이션을 자동으로 배포할 수 있는지 알아봅시다.

ji5485.github.io

UnityプロジェクトにおけるGitHub Actions活用

 

UnityプロジェクトにおけるGitHub Actions活用 | QualiArtsエンジニアブログ

Unityプロジェクトにおいて現状どのようにGitHub Actionsを活用しているかを紹介します

technote.qualiarts.jp

Github Actionsにて自動的にビルドする環境作成(Unity編) - Qiita

 

Github Actionsにて自動的にビルドする環境作成(Unity編) - Qiita

結論と概要Github Actions を使用してGithubに git push が行われたら自動的にUnityビルドを行いその成果物をダウンロードできる仕組みを構築することができたので紹介しま…

qiita.com

GitHub Actions を理解する - GitHub Docs

 

GitHub Actions を理解する - GitHub Docs

コア概念や重要な用語など、GitHub Actions の基本について説明します。

docs.github.com

workflow_dispatch の使い方、使い所 - Qiita

 

workflow_dispatch の使い方、使い所 - Qiita

はじめにこちらの記事は GitHub Actions Advent Calendar 2021の18日目の記事となります。他の皆様の投稿もぜひご覧ください!今回は GitHub Actions …

qiita.com

GitHub Actionsでself-hosted runnersを試す - Qiita

 

GitHub Actionsでself-hosted runnersを試す - Qiita

こんにちは。LIFULL株式会社の花岡です。11/05から、GitHub Actionsでself-hosted runnersが使えるようになりました。この機能を使用すると、GithHub Ac…

qiita.com

GitHub ActionsのセルフホストランナーでUnityビルドする

 

GitHub ActionsのセルフホストランナーでUnityビルドする

Meta Questのプロジェクトのビルドのためにセルフホストランナーを導入してみたので、基本的なところをメモ書きです。

tech.framesynthesis.co.jp

Github Actionsのset-outputは廃止されるってよ - Qiita

 

Github Actionsのset-outputは廃止されるってよ - Qiita

追記: 廃止されるのが廃止されるってよコメントで新たな情報をいただきました。さきほどGitHubActionsの通知記事の原文見てきたのですが廃止時期が2023/06/01から延期されるそうです。以上

qiita.com

GitHub Actions에서 output 변수의 문법 변경 :: Outsider's Dev Story

 

GitHub Actions에서 output 변수의 문법 변경 :: Outsider's Dev Story

GitHub Actions에서 워크플로우를 작성할 때 각 스텝이나 잡 간의 결과를 공유해야 하는 경우가 있다. 코드에서 변수를 사용하듯이 앞의 단계에서 출력값을 저장해 두고 이후에 참고해야 하는 상황

blog.outsider.ne.kr

Oculus/Meta Quest 2 - Adjust Video Capture Settings Through ADB

 

Oculus/Meta Quest 2 - Adjust Video Capture Settings Through ADB

In the latest Oculus Developer Hub update, you can now record video on the Meta Quest 2 at a higher resolution, framerate, and bitrate. This allows significantly higher quality video capture than possible previously. While the Oculus Developer Hub is a fan

blog.jamie.holdings

Quest 2 ADB Commands (List & Examples) | Smart Glasses Hub

 

Quest 2 ADB Commands (List & Examples) | Smart Glasses Hub

The table below lists the most common and useful Android system properties of the Quest 2 that can be used to change various settings and…

smartglasseshub.com

GitHub Actions上でgit commitするときにgit userをどうするか - Qiita

 

GitHub Actions上でgit commitするときにgit userをどうするか - Qiita

GitHub Actions上で変更をコミットしたいGitHub Actions上で変更をコミットしたいケースがある。例えばGitHub Actions上でlintを実行して修正を自動反映したいケ…

qiita.com

Push to origin from GitHub action

 

Push to origin from GitHub action

I'm trying to push to origin remote from GitHub action. The logic of my action is: handle pull_request_review events and filter by comment message checkout to master, merge PR branch, run some che...

stackoverflow.com

GitHub Apps + GitHub Actionsで必要なアクセス権限のみ付与した一時的なアクセストークンを発行する | DevelopersIO

 

GitHub Apps + GitHub Actionsで必要なアクセス権限のみ付与した一時的なアクセストークンを発行する

こんにちは、CX事業本部 IoT事業部の若槻です。 今回は、GitHub Apps + GitHub Actionsで必要なアクセス権限のみ付与した一時的なアクセストークンを発行してみました。 なぜGitHub Apps …

dev.classmethod.jp

GitHub Actions中でpushする際にgithub-actions[bot]をユーザーとして使う

 

GitHub Actions中でpushする際にgithub-actions[bot]をユーザーとして使う

GitHub Actionsの中でレポジトリに対してcommitしてpushするような場合、 ユーザーを自分にせずにgithub-actions[bot]をユーザーとして使うと 実際に手元で変更したものと区別が出来るので便利という

rcmdnk.com