LoginSignup
1

More than 1 year has passed since last update.

【GameCI】指定した複数のUnityバージョンでテストを走らせるワークフロー【GitHub Actions】

Posted at

はじめに

いろんなUnityバージョンに対応したライブラリを作ってて手元でテストするのが面倒だったので、

  • GitHub Actionsで
  • Unityのバージョンを複数指定して
  • すべてのバージョンでUnity Test Framework(旧:Unity Test Runner)によるテストを走らせる

ようなワークフローを書いたので紹介します。

ちなみに冒頭のツイートの画像の内容だとバグっていて、単一のUnityバージョンでしかテストが走らないのでご注意ください。

事前準備

予めUnityのライセンス周りの下準備をしておく必要があります。

自分は以下の記事を参考にしました。

複数のUnityバージョンでテストを走らせる場合でも、条件的にPersonalライセンスが使用可能であれば1つでOKです。

ワークフローを実行する

Unityのライセンス情報をSecretsに登録した状態で↓のファイルを

 {リポジトリのルート}/.github/workflows/

以下に置くと、GitHubにpushされたときにテストが実行されます。

run-test.yml
name: Run Test

on: [push]

jobs:
  test:
    name: Test in Unity${{ matrix.unityVersion }}
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        unityVersion:
          - 2021.3.0f1  # 好きなバージョンを指定
          - 2022.1.0f1  # 好きなバージョンを指定
    steps:
      - uses: actions/checkout@v3
        with:
          lfs: true
          path: Unity${{ matrix.unityVersion }}
      - uses: actions/cache@v3
        with:
          path: Unity${{ matrix.unityVersion }}/Library
          key: Library-Unity${{ matrix.unityVersion }}
          restore-keys: |
            Library-
      - uses: game-ci/unity-test-runner@5263cf0ab1d1c310c57c1861c71324b7e273909c
        id: tests
        env:
          UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
        with:
          unityVersion: ${{ matrix.unityVersion }}
          projectPath: Unity${{ matrix.unityVersion }}
          artifactsPath: Unity${{ matrix.unityVersion }}-artifacts
          githubToken: ${{ secrets.GITHUB_TOKEN }}
          checkName: Unity${{ matrix.unityVersion }} Test Results
      - uses: actions/upload-artifact@v3
        if: always()
        with:
          name: Test results for Unity${{ matrix.unityVersion }}
          path: ${{ steps.tests.outputs.artifactsPath }}

このワークフローを実行すると

  • Unity2021.3.0f1
  • Unity2022.1.0f1

の2つのバージョンでそれぞれテストが実行されます。

使うときは # 好きなバージョンを指定 の行を適当に追加/削除/変更してください。

 
そもそもUnity Test Frameworkがわからない場合は、以下が大変参考になります。

GameCIのサンプルコードはちょっと古い

先に紹介したワークフローは GameCIのドキュメント に記載の以下を参考にしてます。

name: Test project

on: [push, pull_request]

jobs:
  testAllModes:
    name: Test in ${{ matrix.testMode }}
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        projectPath:
          - test-project
        testMode:
          - playmode
          - editmode
    steps:
      - uses: actions/checkout@v2
        with:
          lfs: true
      - uses: actions/cache@v2
        with:
          path: ${{ matrix.projectPath }}/Library
          key: Library-${{ matrix.projectPath }}
          restore-keys: |
            Library-
      - uses: game-ci/unity-test-runner@v2
        id: tests
        env:
          UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
        with:
          projectPath: ${{ matrix.projectPath }}
          testMode: ${{ matrix.testMode }}
          artifactsPath: ${{ matrix.testMode }}-artifacts
          githubToken: ${{ secrets.GITHUB_TOKEN }}
          checkName: ${{ matrix.testMode }} Test Results
          coverageOptions: 'generateAdditionalMetrics;generateHtmlReport;generateBadgeReport;assemblyFilters:+my.assembly.*'
      - uses: actions/upload-artifact@v2
        if: always()
        with:
          name: Test results for ${{ matrix.testMode }}
          path: ${{ steps.tests.outputs.artifactsPath }}
      - uses: actions/upload-artifact@v2
        if: always()
        with:
          name: Coverage results for ${{ matrix.testMode }}
          path: ${{ steps.tests.outputs.coveragePath }}

これを変更して使うにあたってはいくつか注意点があったのでそちらもご紹介します。

Node.js 12に関する警告が出る

そのままだとワークフロー実行時に以下のような警告が出ます。

Node.js 12 actions are deprecated. For more information see: https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/. Please update the following actions to use Node.js 16: actions/checkout, actions/cache, game-ci/unity-test-runner, actions/upload-artifact, actions/upload-artifact, actions/cache, actions/checkout

警告に従って、使用されている以下のアクションのバージョンを上げます。 v2v3 に書き換えるだけです。

  • actions/checkout@v2     → actions/checkout@v3
  • actions/cache@v2       → actions/cache@v3
  • actions/upload-artifact@v2actions/upload-artifact@v3

参考:GitHub ActionsでNode.js 12のサポートが終了します

set-output に関する警告が出る

まだ以下の警告が出ます。

The set-output command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/

参考:GitHub Actionsで save-stateset-output が廃止されるようです。

これはGameCIの game-ci/unity-test-runner@v2 に起因するものなので、こちらのバージョンを上げます。

game-ci/unity-test-runner の最新のリリースは現時点で v2.0.3 なのですが、修正が現状 main ブランチにしか入ってない(#193,#194)ので、最新のコミットのハッシュを直接指定します。

  • game-ci/unity-test-runner@v2
    game-ci/unity-test-runner@5263cf0ab1d1c310c57c1861c71324b7e273909c

もしこの記事を読んだ時点で v2.0.4 がリリースされてたらコミットハッシュの代わりにそちらを指定すると良いと思います。

注意点

複数のUnityバージョンでテストを回すと実行時間が嵩むので、無料枠で動かす場合は注意が必要です。

参考:

おまけ:すべてのプラットフォームでコンパイルが通るかどうかのテスト

複数のUnityバージョンで動作を保証するライブラリ/アセット/フレームワークを作っていて、最低限ほしいのは「サポートするUnityバージョンでビルドが通るかどうかのテスト」です。

ということでC#9.0のUnityで動くテストを書いてみました。 Scriptable Build Pipeline のパッケージが必要です。

CompilationTest.cs
using System.IO;
using NUnit.Framework;
using UnityEditor;
using UnityEditor.Build.Player;

public class CompilationTest
{
    private static readonly string OutputPath = $"Temp/{nameof(CompilationTest)}";

    [Test] public void StandaloneOSX() => Assert.IsTrue(Compile(BuildTarget.StandaloneOSX));
    [Test] public void StandaloneWindows() => Assert.IsTrue(Compile(BuildTarget.StandaloneWindows));
    [Test] public void iOS() => Assert.IsTrue(Compile(BuildTarget.iOS));
    [Test] public void Android() => Assert.IsTrue(Compile(BuildTarget.Android));
    [Test] public void StandaloneWindows64() => Assert.IsTrue(Compile(BuildTarget.StandaloneWindows64));
    [Test] public void WebGL() => Assert.IsTrue(Compile(BuildTarget.WebGL));
    [Test] public void WSAPlayer() => Assert.IsTrue(Compile(BuildTarget.WSAPlayer));
    [Test] public void StandaloneLinux64() => Assert.IsTrue(Compile(BuildTarget.StandaloneLinux64));
    [Test] public void PS4() => Assert.IsTrue(Compile(BuildTarget.PS4));
    [Test] public void XboxOne() => Assert.IsTrue(Compile(BuildTarget.XboxOne));
    [Test] public void tvOS() => Assert.IsTrue(Compile(BuildTarget.tvOS));
    [Test] public void Switch() => Assert.IsTrue(Compile(BuildTarget.Switch));
    [Test] public void Lumin() => Assert.IsTrue(Compile(BuildTarget.Lumin));
    [Test] public void Stadia() => Assert.IsTrue(Compile(BuildTarget.Stadia));
    [Test] public void CloudRendering() => Assert.IsTrue(Compile(BuildTarget.CloudRendering));
    [Test] public void GameCoreXboxSeries() => Assert.IsTrue(Compile(BuildTarget.GameCoreXboxSeries));
    [Test] public void GameCoreXboxOne() => Assert.IsTrue(Compile(BuildTarget.GameCoreXboxOne));
    [Test] public void PS5() => Assert.IsTrue(Compile(BuildTarget.PS5));
    [Test] public void EmbeddedLinux() => Assert.IsTrue(Compile(BuildTarget.EmbeddedLinux));

    private static bool Compile(BuildTarget target)
    {
        var input = new ScriptCompilationSettings
        {
            target = target,
            group = BuildPipeline.GetBuildTargetGroup(target),
        };

        var result = PlayerBuildInterface.CompilePlayerScripts(input, OutputPath);
        var assemblies = result.assemblies;
        var passed = (assemblies is { Count: > 0 } && (result.typeDB != null));

        if (Directory.Exists(OutputPath)) Directory.Delete(OutputPath, true);

        return passed;
    }
}

参考:

その他参考になりそうなリンク

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