diff --git a/.github/workflows/build-tests.yml b/.github/workflows/build-tests.yml index 69ef69e3..239f2b0f 100644 --- a/.github/workflows/build-tests.yml +++ b/.github/workflows/build-tests.yml @@ -10,7 +10,7 @@ env: UNITY_LICENSE: "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \nm0Db8UK+ktnOLJBtHybkfetpcKo=o/pUbSQAukz7+ZYAWhnA0AJbIlyyCPL7bKVEM2lVqbrXt7cyey+umkCXamuOgsWPVUKBMkXtMH8L\n5etLmD0getWIhTGhzOnDCk+gtIPfL4jMo9tkEuOCROQAXCci23VFscKcrkB+3X6h4wEOtA2APhOY\nB+wvC794o8/82ffjP79aVAi57rp3Wmzx+9pe9yMwoJuljAy2sc2tIMgdQGWVmOGBpQm3JqsidyzI\nJWG2kjnc7pDXK9pwYzXoKiqUqqrut90d+kQqRyv7MSZXR50HFqD/LI69h68b7P8Bjo3bPXOhNXGR\n9YCoemH6EkfCJxp2gIjzjWW+l2Hj2EsFQi8YXw==" jobs: - buildForAllPlatforms: + buildForAllPlatformsUbuntu: name: Build for ${{ matrix.targetPlatform }} on version ${{ matrix.unityVersion }} runs-on: ubuntu-latest strategy: @@ -48,9 +48,9 @@ jobs: - uses: actions/cache@v2 with: path: ${{ matrix.projectPath }}/Library - key: Library-${{ matrix.projectPath }}-${{ matrix.targetPlatform }} + key: Library-${{ matrix.projectPath }}-ubuntu-${{ matrix.targetPlatform }} restore-keys: | - Library-${{ matrix.projectPath }}- + Library-${{ matrix.projectPath }}-ubuntu- Library- ########################### @@ -68,6 +68,6 @@ jobs: ########################### - uses: actions/upload-artifact@v2 with: - name: Build (${{ matrix.unityVersion }}) + name: Build Ubuntu (${{ matrix.unityVersion }}) path: build retention-days: 14 diff --git a/.github/workflows/windows-build-tests.yml b/.github/workflows/windows-build-tests.yml new file mode 100644 index 00000000..e9f264df --- /dev/null +++ b/.github/workflows/windows-build-tests.yml @@ -0,0 +1,77 @@ +name: Windows Builds + +on: + push: + branches: + - main + +env: + UNITY_LICENSE: "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \nm0Db8UK+ktnOLJBtHybkfetpcKo=o/pUbSQAukz7+ZYAWhnA0AJbIlyyCPL7bKVEM2lVqbrXt7cyey+umkCXamuOgsWPVUKBMkXtMH8L\n5etLmD0getWIhTGhzOnDCk+gtIPfL4jMo9tkEuOCROQAXCci23VFscKcrkB+3X6h4wEOtA2APhOY\nB+wvC794o8/82ffjP79aVAi57rp3Wmzx+9pe9yMwoJuljAy2sc2tIMgdQGWVmOGBpQm3JqsidyzI\nJWG2kjnc7pDXK9pwYzXoKiqUqqrut90d+kQqRyv7MSZXR50HFqD/LI69h68b7P8Bjo3bPXOhNXGR\n9YCoemH6EkfCJxp2gIjzjWW+l2Hj2EsFQi8YXw==" + +jobs: + buildForAllPlatformsWindows: + name: Build for ${{ matrix.targetPlatform }} on version ${{ matrix.unityVersion }} + runs-on: windows-2019 + strategy: + fail-fast: false + matrix: + projectPath: + - test-project + unityVersion: + - 2020.3.24f1 + targetPlatform: + - StandaloneWindows64 # Build a Windows 64-bit standalone. + - StandaloneWindows # Build a Windows 32-bit standalone. + - WSAPlayer # Build a UWP App + - tvOS # Build an Apple TV XCode project + + steps: + ########################### + # Checkout # + ########################### + - uses: actions/checkout@v2 + with: + lfs: true + + ########################### + # Cache # + ########################### + - uses: actions/cache@v2 + with: + path: ${{ matrix.projectPath }}/Library + key: Library-${{ matrix.projectPath }}-windows-${{ matrix.targetPlatform }} + restore-keys: | + Library-${{ matrix.projectPath }}-windows- + Library- + + ########################### + # Set Scripting Backend # + ########################### + - name: Set Scripting Backend To il2cpp + run: | + Move-Item -Path "./test-project/ProjectSettings/ProjectSettingsWindows.asset" -Destination "./test-project/ProjectSettings/ProjectSettings.asset" -Force + + ########################### + # Build # + ########################### + - uses: ./ + env: + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + with: + projectPath: ${{ matrix.projectPath }} + unityVersion: ${{ matrix.unityVersion }} + targetPlatform: ${{ matrix.targetPlatform }} + customParameters: -profile SomeProfile -someBoolean -someValue exampleValue + allowDirtyBuild: true + # We use dirty build because we are replacing the default project settings file above + + ########################### + # Upload # + ########################### + - uses: actions/upload-artifact@v2 + with: + name: Build Windows (${{ matrix.unityVersion }}) + path: build + retention-days: 14 diff --git a/.gitignore b/.gitignore index f1fde5e9..3fbcc036 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules coverage/ lib/ +.vsconfig diff --git a/dist/default-build-script/Assets/Editor/UnityBuilderAction/Builder.cs b/dist/default-build-script/Assets/Editor/UnityBuilderAction/Builder.cs index 5510ecda..50e25fb7 100644 --- a/dist/default-build-script/Assets/Editor/UnityBuilderAction/Builder.cs +++ b/dist/default-build-script/Assets/Editor/UnityBuilderAction/Builder.cs @@ -39,12 +39,14 @@ namespace UnityBuilderAction // Set version for this build VersionApplicator.SetVersion(options["buildVersion"]); - VersionApplicator.SetAndroidVersionCode(options["androidVersionCode"]); // Apply Android settings if (buildPlayerOptions.target == BuildTarget.Android) + { + VersionApplicator.SetAndroidVersionCode(options["androidVersionCode"]); AndroidSettings.Apply(options); - + } + // Execute default AddressableAsset content build, if the package is installed. // Version defines would be the best solution here, but Unity 2018 doesn't support that, // so we fall back to using reflection instead. diff --git a/dist/index.js b/dist/index.js index 70417aa2..459ce17c 100644 Binary files a/dist/index.js and b/dist/index.js differ diff --git a/dist/index.js.map b/dist/index.js.map index d94b0d79..bbd86d36 100644 Binary files a/dist/index.js.map and b/dist/index.js.map differ diff --git a/dist/Dockerfile b/dist/platforms/ubuntu/Dockerfile similarity index 60% rename from dist/Dockerfile rename to dist/platforms/ubuntu/Dockerfile index 85da52f6..2cb677c3 100644 --- a/dist/Dockerfile +++ b/dist/platforms/ubuntu/Dockerfile @@ -6,14 +6,14 @@ LABEL "com.github.actions.description"="Build Unity projects for different platf LABEL "com.github.actions.icon"="box" LABEL "com.github.actions.color"="gray-dark" -LABEL "repository"="http://github.com/webbertakken/unity-actions" -LABEL "homepage"="http://github.com/webbertakken/unity-actions" +LABEL "repository"="http://github.com/game-ci/unity-actions" +LABEL "homepage"="http://github.com/game-ci/unity-actions" LABEL "maintainer"="Webber Takken " -ADD default-build-script /UnityBuilderAction -ADD steps /steps +COPY default-build-script /UnityBuilderAction +COPY platforms/ubuntu/steps /steps RUN chmod -R +x /steps -ADD entrypoint.sh /entrypoint.sh +COPY platforms/ubuntu/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh RUN ls diff --git a/dist/entrypoint.sh b/dist/platforms/ubuntu/entrypoint.sh old mode 100755 new mode 100644 similarity index 100% rename from dist/entrypoint.sh rename to dist/platforms/ubuntu/entrypoint.sh diff --git a/dist/steps/activate.sh b/dist/platforms/ubuntu/steps/activate.sh old mode 100755 new mode 100644 similarity index 100% rename from dist/steps/activate.sh rename to dist/platforms/ubuntu/steps/activate.sh diff --git a/dist/steps/build.sh b/dist/platforms/ubuntu/steps/build.sh old mode 100755 new mode 100644 similarity index 100% rename from dist/steps/build.sh rename to dist/platforms/ubuntu/steps/build.sh diff --git a/dist/steps/return_license.sh b/dist/platforms/ubuntu/steps/return_license.sh old mode 100755 new mode 100644 similarity index 100% rename from dist/steps/return_license.sh rename to dist/platforms/ubuntu/steps/return_license.sh diff --git a/dist/steps/set_gitcredential.sh b/dist/platforms/ubuntu/steps/set_gitcredential.sh old mode 100755 new mode 100644 similarity index 100% rename from dist/steps/set_gitcredential.sh rename to dist/platforms/ubuntu/steps/set_gitcredential.sh diff --git a/dist/platforms/windows/Dockerfile b/dist/platforms/windows/Dockerfile new file mode 100644 index 00000000..37169cdd --- /dev/null +++ b/dist/platforms/windows/Dockerfile @@ -0,0 +1,18 @@ +ARG IMAGE +FROM $IMAGE + +LABEL "com.github.actions.name"="Unity - Builder" +LABEL "com.github.actions.description"="Build Unity projects for different platforms." +LABEL "com.github.actions.icon"="box" +LABEL "com.github.actions.color"="gray-dark" + +LABEL "repository"="http://github.com/game-ci/unity-actions" +LABEL "homepage"="http://github.com/game-ci/unity-actions" +LABEL "maintainer"="Webber Takken " + +COPY default-build-script c:/UnityBuilderAction +COPY platforms/windows/steps c:/steps +COPY platforms/windows/entrypoint.ps1 c:/entrypoint.ps1 +RUN dir + +ENTRYPOINT ["powershell", "c:/entrypoint.ps1"] diff --git a/dist/platforms/windows/entrypoint.ps1 b/dist/platforms/windows/entrypoint.ps1 new file mode 100644 index 00000000..b5255d11 --- /dev/null +++ b/dist/platforms/windows/entrypoint.ps1 @@ -0,0 +1,15 @@ +# Activate Unity +& "c:\steps\activate.ps1" + +# Import any necessary registry keys, ie: location of windows 10 sdk +# No guarantee that there will be any necessary registry keys, ie: tvOS +Get-ChildItem -Path c:\regkeys -File | Foreach {reg import $_.fullname} + +# Register the Visual Studio installation so Unity can find it +regsvr32 C:\ProgramData\Microsoft\VisualStudio\Setup\x64\Microsoft.VisualStudio.Setup.Configuration.Native.dll + +# Build the project +& "c:\steps\build.ps1" + +# Free the seat for the activated license +& "c:\steps\return_license.ps1" diff --git a/dist/platforms/windows/steps/activate.ps1 b/dist/platforms/windows/steps/activate.ps1 new file mode 100644 index 00000000..d2e1a5ab --- /dev/null +++ b/dist/platforms/windows/steps/activate.ps1 @@ -0,0 +1,6 @@ +# Activates Unity +& "C:\Program Files\Unity\Hub\Editor\$Env:UNITY_VERSION\Editor\Unity.exe" -batchmode -quit -nographics ` + -username $Env:UNITY_EMAIL ` + -password $Env:UNITY_PASSWORD ` + -serial $Env:UNITY_SERIAL ` + -logfile | Out-Host diff --git a/dist/platforms/windows/steps/build.ps1 b/dist/platforms/windows/steps/build.ps1 new file mode 100644 index 00000000..91c304fe --- /dev/null +++ b/dist/platforms/windows/steps/build.ps1 @@ -0,0 +1,147 @@ +# +# Set project path +# +$Env:UNITY_PROJECT_PATH="$Env:GITHUB_WORKSPACE\$Env:PROJECT_PATH" +Write-Output "$('Using project path "')$($Env:UNITY_PROJECT_PATH)$('".')" + +# +# Display the name for the build, doubles as the output name +# + +Write-Output "$('Using build name "')$($Env:BUILD_NAME)$('".')" + +# +# Display the build's target platform; +# + +Write-Output "$('Using build target "')$($Env:BUILD_TARGET)$('".')" + +# +# Display build path and file +# + +Write-Output "$('Using build path "')$($Env:BUILD_PATH)$('" to save file "')$($Env:BUILD_FILE)$('".')" +$Env:BUILD_PATH_FULL="$Env:GITHUB_WORKSPACE\$Env:BUILD_PATH" +$Env:CUSTOM_BUILD_PATH="$Env:BUILD_PATH_FULL\$Env:BUILD_FILE" + +# +# Set the build method, must reference one of: +# +# - +# - +# +# For example: `BuildCommand.PerformBuild` +# +# The method must be declared static and placed in project/Assets/Editor +# +if ($Env:BUILD_METHOD) +{ + # User has provided their own build method. + # Assume they also bring their own script. + Write-Output "$('Using build method "')$($Env:BUILD_METHOD)$('".')" +} +else +{ + # User has not provided their own build command. + # + # Use the script from this action which builds the scenes that are enabled in + # the project. + # + Write-Output "Using built-in build method." + + # Create Editor directory if it does not exist + if(-Not (Test-Path -Path $Env:UNITY_PROJECT_PATH\Assets\Editor)) + { + # We use -Force to suppress output, doesn't overwrite anything + New-Item -ItemType Directory -Force -Path $Env:UNITY_PROJECT_PATH\Assets\Editor + } + + # Copy the build script of Unity Builder action + Copy-Item -Path "c:\UnityBuilderAction" -Destination $Env:UNITY_PROJECT_PATH\Assets\Editor -Recurse + + # Set the Build method to that of UnityBuilder Action + $Env:BUILD_METHOD="UnityBuilderAction.Builder.BuildProject" + + # Verify recursive paths + Get-ChildItem -Path $UNITY_PROJECT_PATH\Assets\Editor -Recurse +} + +# +# Pre-build debug information +# + +Write-Output "" +Write-Output "###########################" +Write-Output "# Custom parameters #" +Write-Output "###########################" +Write-Output "" + +Write-Output "$('"')$($Env:CUSTOM_PARAMETERS)$('"')" + +Write-Output "" +Write-Output "###########################" +Write-Output "# Current build dir #" +Write-Output "###########################" +Write-Output "" + +Write-Output "$('Creating "')$($Env:BUILD_PATH_FULL)$('" if it does not exist.')" +if (-Not (Test-Path -Path $Env:BUILD_PATH_FULL)) +{ + mkdir "$Env:BUILD_PATH_FULL" +} +Get-ChildItem $Env:BUILD_PATH_FULL + +Write-Output "" +Write-Output "###########################" +Write-Output "# Project directory #" +Write-Output "###########################" +Write-Output "" + +Get-ChildItem $Env:UNITY_PROJECT_PATH + +# +# Build +# + +Write-Output "" +Write-Output "###########################" +Write-Output "# Building project #" +Write-Output "###########################" +Write-Output "" + +& "C:\Program Files\Unity\Hub\Editor\$Env:UNITY_VERSION\Editor\Unity.exe" -quit -batchmode -nographics ` + -projectPath $Env:UNITY_PROJECT_PATH ` + -executeMethod $Env:BUILD_METHOD ` + -buildTarget $Env:BUILD_TARGET ` + -customBuildTarget $Env:BUILD_TARGET ` + -customBuildPath $Env:CUSTOM_BUILD_PATH ` + -buildVersion $Env:VERSION ` + $Env:CUSTOM_PARAMETERS ` + -logfile | Out-Host + +# Catch exit code +$Env:BUILD_EXIT_CODE=$? + +# Display results +if ($Env:BUILD_EXIT_CODE -eq 0) +{ + Write-Output "Build Succeeded!" +} else +{ + Write-Output "$('Build failed, with exit code ')$($Env:BUILD_EXIT_CODE)$('"')" +} + +# TODO: Determine if we need to set permissions on any files + +# +# Results +# + +Write-Output "" +Write-Output "###########################" +Write-Output "# Build output #" +Write-Output "###########################" +Write-Output "" + +Get-ChildItem $Env:BUILD_PATH_FULL +Write-Output "" diff --git a/dist/platforms/windows/steps/return_license.ps1 b/dist/platforms/windows/steps/return_license.ps1 new file mode 100644 index 00000000..126b6f62 --- /dev/null +++ b/dist/platforms/windows/steps/return_license.ps1 @@ -0,0 +1,6 @@ +# Return the active Unity license +& "C:\Program Files\Unity\Hub\Editor\$Env:UNITY_VERSION\Editor\Unity.exe" -batchmode -quit -nographics ` + -username $Env:UNITY_EMAIL ` + -password $Env:UNITY_PASSWORD ` + -returnlicense ` + -logfile | Out-Host diff --git a/src/index.ts b/src/index.ts index 2d5687af..156ef238 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,6 @@ import * as core from '@actions/core'; import { Action, BuildParameters, Cache, Docker, ImageTag, Kubernetes, Output, RemoteBuilder } from './model'; +import PlatformSetup from './model/platform-setup'; async function run() { try { @@ -26,6 +27,7 @@ async function run() { // default and local case default: core.info('Building locally'); + PlatformSetup.setup(buildParameters); builtImage = await Docker.build({ path: actionFolder, dockerfile, baseImage }); await Docker.run(builtImage, { workspace, ...buildParameters }); break; diff --git a/src/model/action.test.ts b/src/model/action.test.ts index ba1582da..ba25876f 100644 --- a/src/model/action.test.ts +++ b/src/model/action.test.ts @@ -4,8 +4,8 @@ import Action from './action'; describe('Action', () => { describe('compatibility check', () => { - it('throws for anything other than linux', () => { - if (process.platform !== 'linux') { + it('throws for anything other than linux or windows', () => { + if (process.platform !== 'linux' && process.platform !== 'win32') { expect(() => Action.checkCompatibility()).toThrow(); } else { expect(() => Action.checkCompatibility()).not.toThrow(); diff --git a/src/model/action.ts b/src/model/action.ts index b7703e8b..3e2c4cc4 100644 --- a/src/model/action.ts +++ b/src/model/action.ts @@ -2,7 +2,7 @@ import path from 'path'; class Action { static get supportedPlatforms() { - return ['linux']; + return ['linux', 'win32']; } static get isRunningLocally() { @@ -30,7 +30,15 @@ class Action { } static get dockerfile() { - return `${Action.actionFolder}/Dockerfile`; + const currentPlatform = process.platform; + switch (currentPlatform) { + case 'linux': + return `${Action.actionFolder}/platforms/ubuntu/Dockerfile`; + case 'win32': + return `${Action.actionFolder}/platforms/windows/Dockerfile`; + default: + throw new Error(`No Dockerfile for currently unsupported platform: ${currentPlatform}`); + } } static get workspace() { diff --git a/src/model/build-parameters.test.ts b/src/model/build-parameters.test.ts index 6413ce9b..edd98c93 100644 --- a/src/model/build-parameters.test.ts +++ b/src/model/build-parameters.test.ts @@ -5,6 +5,10 @@ import BuildParameters from './build-parameters'; import Input from './input'; import Platform from './platform'; +const testLicense = + '\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \nm0Db8UK+ktnOLJBtHybkfetpcKo=o/pUbSQAukz7+ZYAWhnA0AJbIlyyCPL7bKVEM2lVqbrXt7cyey+umkCXamuOgsWPVUKBMkXtMH8L\n5etLmD0getWIhTGhzOnDCk+gtIPfL4jMo9tkEuOCROQAXCci23VFscKcrkB+3X6h4wEOtA2APhOY\nB+wvC794o8/82ffjP79aVAi57rp3Wmzx+9pe9yMwoJuljAy2sc2tIMgdQGWVmOGBpQm3JqsidyzI\nJWG2kjnc7pDXK9pwYzXoKiqUqqrut90d+kQqRyv7MSZXR50HFqD/LI69h68b7P8Bjo3bPXOhNXGR\n9YCoemH6EkfCJxp2gIjzjWW+l2Hj2EsFQi8YXw=='; +process.env.UNITY_LICENSE = testLicense; + const determineVersion = jest.spyOn(Versioning, 'determineVersion').mockImplementation(async () => '1.3.37'); const determineUnityVersion = jest diff --git a/src/model/build-parameters.ts b/src/model/build-parameters.ts index 62352246..bc4c4ca3 100644 --- a/src/model/build-parameters.ts +++ b/src/model/build-parameters.ts @@ -1,3 +1,4 @@ +import * as core from '@actions/core'; import AndroidVersioning from './android-versioning'; import Input from './input'; import Platform from './platform'; @@ -7,6 +8,7 @@ import Versioning from './versioning'; class BuildParameters { public version!: string; public customImage!: string; + public unitySerial!: string; public runnerTempPath: string | undefined; public platform!: string; public projectPath!: string; @@ -47,9 +49,25 @@ class BuildParameters { const androidSdkManagerParameters = AndroidVersioning.determineSdkManagerParameters(Input.androidTargetSdkVersion); + let unitySerial = ''; + if (!process.env.UNITY_SERIAL) { + //No serial was present so it is a personal license that we need to convert + if (!process.env.UNITY_LICENSE) { + throw new Error(`Missing Unity License File and no Serial was found. If this + is a personal license, make sure to follow the activation + steps and set the UNITY_LICENSE GitHub secret or enter a Unity + serial number inside the UNITY_SERIAL GitHub secret.`); + } + unitySerial = this.getSerialFromLicenseFile(process.env.UNITY_LICENSE); + } else { + unitySerial = process.env.UNITY_SERIAL!; + } + core.setSecret(unitySerial); + return { version: unityVersion, customImage: Input.customImage, + unitySerial, runnerTempPath: process.env.RUNNER_TEMP, platform: Input.targetPlatform, @@ -93,6 +111,18 @@ class BuildParameters { return filename; } + + static getSerialFromLicenseFile(license) { + const startKey = ``; + const startIndex = license.indexOf(startKey) + startKey.length; + if (startIndex < 0) { + throw new Error(`License File was corrupted, unable to locate serial`); + } + const endIndex = license.indexOf(endKey, startIndex); + // Slice off the first 4 characters as they are garbage values + return Buffer.from(license.slice(startIndex, endIndex), 'base64').toString('binary').slice(4); + } } export default BuildParameters; diff --git a/src/model/docker.ts b/src/model/docker.ts index 29a8b9f0..7f82ab5e 100644 --- a/src/model/docker.ts +++ b/src/model/docker.ts @@ -21,6 +21,7 @@ class Docker { const { version, workspace, + unitySerial, runnerTempPath, platform, projectPath, @@ -43,59 +44,83 @@ class Docker { chownFilesTo, } = parameters; - const command = `docker run \ - --workdir /github/workspace \ - --rm \ - --env UNITY_LICENSE \ - --env UNITY_LICENSE_FILE \ - --env UNITY_EMAIL \ - --env UNITY_PASSWORD \ - --env UNITY_SERIAL \ - --env UNITY_VERSION="${version}" \ - --env USYM_UPLOAD_AUTH_TOKEN \ - --env PROJECT_PATH="${projectPath}" \ - --env BUILD_TARGET="${platform}" \ - --env BUILD_NAME="${buildName}" \ - --env BUILD_PATH="${buildPath}" \ - --env BUILD_FILE="${buildFile}" \ - --env BUILD_METHOD="${buildMethod}" \ - --env VERSION="${buildVersion}" \ - --env ANDROID_VERSION_CODE="${androidVersionCode}" \ - --env ANDROID_KEYSTORE_NAME="${androidKeystoreName}" \ - --env ANDROID_KEYSTORE_BASE64="${androidKeystoreBase64}" \ - --env ANDROID_KEYSTORE_PASS="${androidKeystorePass}" \ - --env ANDROID_KEYALIAS_NAME="${androidKeyaliasName}" \ - --env ANDROID_KEYALIAS_PASS="${androidKeyaliasPass}" \ - --env ANDROID_TARGET_SDK_VERSION="${androidTargetSdkVersion}" \ - --env ANDROID_SDK_MANAGER_PARAMETERS="${androidSdkManagerParameters}" \ - --env CUSTOM_PARAMETERS="${customParameters}" \ - --env CHOWN_FILES_TO="${chownFilesTo}" \ - --env GITHUB_REF \ - --env GITHUB_SHA \ - --env GITHUB_REPOSITORY \ - --env GITHUB_ACTOR \ - --env GITHUB_WORKFLOW \ - --env GITHUB_HEAD_REF \ - --env GITHUB_BASE_REF \ - --env GITHUB_EVENT_NAME \ - --env GITHUB_WORKSPACE=/github/workspace \ - --env GITHUB_ACTION \ - --env GITHUB_EVENT_PATH \ - --env RUNNER_OS \ - --env RUNNER_TOOL_CACHE \ - --env RUNNER_TEMP \ - --env RUNNER_WORKSPACE \ - --env GIT_PRIVATE_TOKEN="${gitPrivateToken}" \ - ${sshAgent ? '--env SSH_AUTH_SOCK=/ssh-agent' : ''} \ - --volume "/var/run/docker.sock":"/var/run/docker.sock" \ - --volume "${runnerTempPath}/_github_home":"/root" \ - --volume "${runnerTempPath}/_github_workflow":"/github/workflow" \ - --volume "${workspace}":"/github/workspace" \ - ${sshAgent ? `--volume ${sshAgent}:/ssh-agent` : ''} \ - ${sshAgent ? '--volume /home/runner/.ssh/known_hosts:/root/.ssh/known_hosts:ro' : ''} \ - ${image}`; + const baseOsSpecificArguments = this.getBaseOsSpecificArguments( + process.platform, + workspace, + unitySerial, + runnerTempPath, + sshAgent, + ); - await exec(command, undefined, { silent }); + const runCommand = `docker run \ + --workdir /github/workspace \ + --rm \ + --env UNITY_LICENSE \ + --env UNITY_LICENSE_FILE \ + --env UNITY_EMAIL \ + --env UNITY_PASSWORD \ + --env UNITY_VERSION="${version}" \ + --env USYM_UPLOAD_AUTH_TOKEN \ + --env PROJECT_PATH="${projectPath}" \ + --env BUILD_TARGET="${platform}" \ + --env BUILD_NAME="${buildName}" \ + --env BUILD_PATH="${buildPath}" \ + --env BUILD_FILE="${buildFile}" \ + --env BUILD_METHOD="${buildMethod}" \ + --env VERSION="${buildVersion}" \ + --env ANDROID_VERSION_CODE="${androidVersionCode}" \ + --env ANDROID_KEYSTORE_NAME="${androidKeystoreName}" \ + --env ANDROID_KEYSTORE_BASE64="${androidKeystoreBase64}" \ + --env ANDROID_KEYSTORE_PASS="${androidKeystorePass}" \ + --env ANDROID_KEYALIAS_NAME="${androidKeyaliasName}" \ + --env ANDROID_KEYALIAS_PASS="${androidKeyaliasPass}" \ + --env ANDROID_TARGET_SDK_VERSION="${androidTargetSdkVersion}" \ + --env ANDROID_SDK_MANAGER_PARAMETERS="${androidSdkManagerParameters}" \ + --env CUSTOM_PARAMETERS="${customParameters}" \ + --env CHOWN_FILES_TO="${chownFilesTo}" \ + --env GITHUB_REF \ + --env GITHUB_SHA \ + --env GITHUB_REPOSITORY \ + --env GITHUB_ACTOR \ + --env GITHUB_WORKFLOW \ + --env GITHUB_HEAD_REF \ + --env GITHUB_BASE_REF \ + --env GITHUB_EVENT_NAME \ + --env GITHUB_WORKSPACE=/github/workspace \ + --env GITHUB_ACTION \ + --env GITHUB_EVENT_PATH \ + --env RUNNER_OS \ + --env RUNNER_TOOL_CACHE \ + --env RUNNER_TEMP \ + --env RUNNER_WORKSPACE \ + --env GIT_PRIVATE_TOKEN="${gitPrivateToken}" \ + ${baseOsSpecificArguments} \ + ${image}`; + + await exec(runCommand, undefined, { silent }); + } + + static getBaseOsSpecificArguments(baseOs, workspace, unitySerial, runnerTemporaryPath, sshAgent): string { + switch (baseOs) { + case 'linux': + return `--env UNITY_SERIAL \ + ${sshAgent ? '--env SSH_AUTH_SOCK=/ssh-agent' : ''} \ + --volume "/var/run/docker.sock":"/var/run/docker.sock" \ + --volume "${runnerTemporaryPath}/_github_home":"/root" \ + --volume "${runnerTemporaryPath}/_github_workflow":"/github/workflow" \ + --volume "${workspace}":"/github/workspace" \ + ${sshAgent ? `--volume ${sshAgent}:/ssh-agent` : ''} \ + ${sshAgent ? '--volume /home/runner/.ssh/known_hosts:/root/.ssh/known_hosts:ro' : ''}`; + case 'win32': + return `--env UNITY_SERIAL="${unitySerial}" \ + --volume "${workspace}":"c:/github/workspace" \ + --volume "c:/regkeys":"c:/regkeys" \ + --volume "C:/Program Files (x86)/Microsoft Visual Studio":"C:/Program Files (x86)/Microsoft Visual Studio" \ + --volume "C:/Program Files (x86)/Windows Kits":"C:/Program Files (x86)/Windows Kits" \ + --volume "C:/ProgramData/Microsoft/VisualStudio":"C:/ProgramData/Microsoft/VisualStudio"`; + //Note: When upgrading to Server 2022, we will need to move to just "program files" since VS will be 64-bit + } + return ''; } } diff --git a/src/model/image-tag.test.ts b/src/model/image-tag.test.ts index e348488c..62d6e24b 100644 --- a/src/model/image-tag.test.ts +++ b/src/model/image-tag.test.ts @@ -48,8 +48,14 @@ describe('ImageTag', () => { describe('toString', () => { it('returns the correct version', () => { const image = new ImageTag({ version: '2099.1.1111', platform: some.platform }); - - expect(image.toString()).toStrictEqual(`${defaults.image}:2099.1.1111-0`); + switch (process.platform) { + case 'win32': + expect(image.toString()).toStrictEqual(`${defaults.image}:windows-2099.1.1111-0`); + break; + case 'linux': + expect(image.toString()).toStrictEqual(`${defaults.image}:2099.1.1111-0`); + break; + } }); it('returns customImage if given', () => { const image = new ImageTag({ @@ -64,13 +70,27 @@ describe('ImageTag', () => { it('returns the specific build platform', () => { const image = new ImageTag({ version: '2019.2.11f1', platform: 'WebGL' }); - expect(image.toString()).toStrictEqual(`${defaults.image}:2019.2.11f1-webgl-0`); + switch (process.platform) { + case 'win32': + expect(image.toString()).toStrictEqual(`${defaults.image}:windows-2019.2.11f1-webgl-0`); + break; + case 'linux': + expect(image.toString()).toStrictEqual(`${defaults.image}:2019.2.11f1-webgl-0`); + break; + } }); it('returns no specific build platform for generic targetPlatforms', () => { const image = new ImageTag({ platform: 'NoTarget' }); - expect(image.toString()).toStrictEqual(`${defaults.image}:2019.2.11f1-0`); + switch (process.platform) { + case 'win32': + expect(image.toString()).toStrictEqual(`${defaults.image}:windows-2019.2.11f1-0`); + break; + case 'linux': + expect(image.toString()).toStrictEqual(`${defaults.image}:2019.2.11f1-0`); + break; + } }); }); }); diff --git a/src/model/image-tag.ts b/src/model/image-tag.ts index 5d070df2..4fe74764 100644 --- a/src/model/image-tag.ts +++ b/src/model/image-tag.ts @@ -35,16 +35,32 @@ class ImageTag { webgl: 'webgl', mac: 'mac-mono', windows: 'windows-mono', + windowsIl2cpp: 'windows-il2cpp', + wsaPlayer: 'universal-windows-platform', linux: 'base', linuxIl2cpp: 'linux-il2cpp', android: 'android', ios: 'ios', + tvos: 'appletv', facebook: 'facebook', }; } static getTargetPlatformToImageSuffixMap(platform, version) { - const { generic, webgl, mac, windows, linux, linuxIl2cpp, android, ios, facebook } = ImageTag.imageSuffixes; + const { + generic, + webgl, + mac, + windows, + windowsIl2cpp, + wsaPlayer, + linux, + linuxIl2cpp, + android, + ios, + tvos, + facebook, + } = ImageTag.imageSuffixes; const [major, minor] = version.split('.').map((digit) => Number(digit)); // @see: https://docs.unity3d.com/ScriptReference/BuildTarget.html @@ -52,8 +68,17 @@ class ImageTag { case Platform.types.StandaloneOSX: return mac; case Platform.types.StandaloneWindows: - return windows; case Platform.types.StandaloneWindows64: + // Can only build windows-il2cpp on a windows based system + if (process.platform === 'win32') { + // Unity versions before 2019.3 do not support il2cpp + if (major >= 2020 || (major === 2019 && minor >= 3)) { + return windowsIl2cpp; + } else { + throw new Error(`Windows-based builds are only supported on 2019.3.X+ versions of Unity. + If you are trying to build for windows-mono, please use a Linux based OS.`); + } + } return windows; case Platform.types.StandaloneLinux64: { // Unity versions before 2019.3 do not support il2cpp @@ -69,13 +94,19 @@ class ImageTag { case Platform.types.WebGL: return webgl; case Platform.types.WSAPlayer: - return windows; + if (process.platform !== 'win32') { + throw new Error(`WSAPlayer can only be built on a windows base OS`); + } + return wsaPlayer; case Platform.types.PS4: return windows; case Platform.types.XboxOne: return windows; case Platform.types.tvOS: - return windows; + if (process.platform !== 'win32') { + throw new Error(`tvOS can only be built on a windows base OS`); + } + return tvos; case Platform.types.Switch: return windows; // Unsupported @@ -101,7 +132,15 @@ class ImageTag { } get tag() { - return `${this.version}-${this.builderPlatform}`.replace(/-+$/, ''); + //We check the host os so we know what type of the images we need to pull + switch (process.platform) { + case 'win32': + return `windows-${this.version}-${this.builderPlatform}`.replace(/-+$/, ''); + case 'linux': + return `${this.version}-${this.builderPlatform}`.replace(/-+$/, ''); + default: + break; + } } get image() { diff --git a/src/model/platform-setup.ts b/src/model/platform-setup.ts new file mode 100644 index 00000000..19e3b928 --- /dev/null +++ b/src/model/platform-setup.ts @@ -0,0 +1,17 @@ +import { BuildParameters } from '.'; +import SetupWindows from './platform-setup/setup-windows'; +import ValidateWindows from './platform-validation/validate-windows'; + +class PlatformSetup { + static async setup(buildParameters: BuildParameters) { + switch (process.platform) { + case 'win32': + ValidateWindows.validate(buildParameters); + SetupWindows.setup(buildParameters); + break; + //Add other baseOS's here + } + } +} + +export default PlatformSetup; diff --git a/src/model/platform-setup/setup-windows.ts b/src/model/platform-setup/setup-windows.ts new file mode 100644 index 00000000..ae38acbf --- /dev/null +++ b/src/model/platform-setup/setup-windows.ts @@ -0,0 +1,33 @@ +import { exec } from '@actions/exec'; +import fs from 'fs'; +import { BuildParameters } from '..'; + +class SetupWindows { + public static async setup(buildParameters: BuildParameters) { + await SetupWindows.setupWindowsRun(buildParameters.platform); + } + + //Setup prerequisite files/folders for a windows-based docker run + private static async setupWindowsRun(platform, silent = false) { + if (!fs.existsSync('c:/regkeys')) { + fs.mkdirSync('c:/regkeys'); + } + switch (platform) { + //These all need the Windows 10 SDK + case 'StandaloneWindows': + case 'StandaloneWindows64': + case 'WSAPlayer': + this.generateWinSDKRegKeys(silent); + break; + } + } + + private static async generateWinSDKRegKeys(silent = false) { + // Export registry keys that point to the location of the windows 10 sdk + const exportWinSDKRegKeysCommand = + 'reg export "HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0" c:/regkeys/winsdk.reg /y'; + await exec(exportWinSDKRegKeysCommand, undefined, { silent }); + } +} + +export default SetupWindows; diff --git a/src/model/platform-validation/validate-windows.ts b/src/model/platform-validation/validate-windows.ts new file mode 100644 index 00000000..c05b1e62 --- /dev/null +++ b/src/model/platform-validation/validate-windows.ts @@ -0,0 +1,57 @@ +import fs from 'fs'; +import { BuildParameters } from '..'; + +class ValidateWindows { + public static validate(buildParameters: BuildParameters) { + ValidateWindows.validateWindowsPlatformRequirements(buildParameters.platform); + if (!(process.env.UNITY_EMAIL && process.env.UNITY_PASSWORD)) { + throw new Error(`Unity email and password must be set for Windows based builds to + authenticate the license. Make sure to set them inside UNITY_EMAIL + and UNITY_PASSWORD in Github Secrets and pass them into the environment.`); + } + } + + private static validateWindowsPlatformRequirements(platform) { + switch (platform) { + case 'StandaloneWindows': + this.checkForVisualStudio(); + this.checkForWin10SDK(); + break; + case 'StandaloneWindows64': + this.checkForVisualStudio(); + this.checkForWin10SDK(); + break; + case 'WSAPlayer': + this.checkForVisualStudio(); + this.checkForWin10SDK(); + break; + case 'tvOS': + this.checkForVisualStudio(); + break; + } + } + + private static checkForWin10SDK() { + //Check for Windows 10 SDK on runner + const windows10SDKPathExists = fs.existsSync('C:/Program Files (x86)/Windows Kits'); + if (!windows10SDKPathExists) { + throw new Error(`Windows 10 SDK not found in default location. Make sure + the runner has a Windows 10 SDK installed in the default + location.`); + } + } + + private static checkForVisualStudio() { + //Note: When upgrading to Server 2022, we will need to move to just "program files" since VS will be 64-bit + const visualStudioInstallPathExists = fs.existsSync('C:/Program Files (x86)/Microsoft Visual Studio'); + const visualStudioDataPathExists = fs.existsSync('C:/ProgramData/Microsoft/VisualStudio'); + + if (!visualStudioInstallPathExists || !visualStudioDataPathExists) { + throw new Error(`Visual Studio not found at the default location. + Make sure the runner has Visual Studio installed in the + default location`); + } + } +} + +export default ValidateWindows; diff --git a/test-project/ProjectSettings/ProjectSettingsWindows.asset b/test-project/ProjectSettings/ProjectSettingsWindows.asset new file mode 100644 index 00000000..d62e93ca --- /dev/null +++ b/test-project/ProjectSettings/ProjectSettingsWindows.asset @@ -0,0 +1,673 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!129 &1 +PlayerSettings: + m_ObjectHideFlags: 0 + serializedVersion: 22 + productGUID: d9e9dde8e7ed4cf4bac4c6f2dffe7ef4 + AndroidProfiler: 0 + AndroidFilterTouchesWhenObscured: 0 + AndroidEnableSustainedPerformanceMode: 0 + defaultScreenOrientation: 4 + targetDevice: 2 + useOnDemandResources: 0 + accelerometerFrequency: 60 + companyName: DefaultCompany + productName: simple-test-project + defaultCursor: {fileID: 0} + cursorHotspot: {x: 0, y: 0} + m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} + m_ShowUnitySplashScreen: 1 + m_ShowUnitySplashLogo: 1 + m_SplashScreenOverlayOpacity: 1 + m_SplashScreenAnimation: 1 + m_SplashScreenLogoStyle: 1 + m_SplashScreenDrawMode: 0 + m_SplashScreenBackgroundAnimationZoom: 1 + m_SplashScreenLogoAnimationZoom: 1 + m_SplashScreenBackgroundLandscapeAspect: 1 + m_SplashScreenBackgroundPortraitAspect: 1 + m_SplashScreenBackgroundLandscapeUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenBackgroundPortraitUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenLogos: [] + m_VirtualRealitySplashScreen: {fileID: 0} + m_HolographicTrackingLossScreen: {fileID: 0} + defaultScreenWidth: 1024 + defaultScreenHeight: 768 + defaultScreenWidthWeb: 960 + defaultScreenHeightWeb: 600 + m_StereoRenderingPath: 0 + m_ActiveColorSpace: 0 + m_MTRendering: 1 + mipStripping: 0 + numberOfMipsStripped: 0 + m_StackTraceTypes: 010000000100000001000000010000000100000001000000 + iosShowActivityIndicatorOnLoading: -1 + androidShowActivityIndicatorOnLoading: -1 + iosUseCustomAppBackgroundBehavior: 0 + iosAllowHTTPDownload: 1 + allowedAutorotateToPortrait: 1 + allowedAutorotateToPortraitUpsideDown: 1 + allowedAutorotateToLandscapeRight: 1 + allowedAutorotateToLandscapeLeft: 1 + useOSAutorotation: 1 + use32BitDisplayBuffer: 1 + preserveFramebufferAlpha: 0 + disableDepthAndStencilBuffers: 0 + androidStartInFullscreen: 1 + androidRenderOutsideSafeArea: 1 + androidUseSwappy: 0 + androidBlitType: 0 + androidResizableWindow: 0 + androidDefaultWindowWidth: 1920 + androidDefaultWindowHeight: 1080 + androidMinimumWindowWidth: 400 + androidMinimumWindowHeight: 300 + androidFullscreenMode: 1 + defaultIsNativeResolution: 1 + macRetinaSupport: 1 + runInBackground: 1 + captureSingleScreen: 0 + muteOtherAudioSources: 0 + Prepare IOS For Recording: 0 + Force IOS Speakers When Recording: 0 + deferSystemGesturesMode: 0 + hideHomeButton: 0 + submitAnalytics: 1 + usePlayerLog: 1 + bakeCollisionMeshes: 0 + forceSingleInstance: 0 + useFlipModelSwapchain: 1 + resizableWindow: 0 + useMacAppStoreValidation: 0 + macAppStoreCategory: public.app-category.games + gpuSkinning: 0 + xboxPIXTextureCapture: 0 + xboxEnableAvatar: 0 + xboxEnableKinect: 0 + xboxEnableKinectAutoTracking: 0 + xboxEnableFitness: 0 + visibleInBackground: 1 + allowFullscreenSwitch: 1 + fullscreenMode: 1 + xboxSpeechDB: 0 + xboxEnableHeadOrientation: 0 + xboxEnableGuest: 0 + xboxEnablePIXSampling: 0 + metalFramebufferOnly: 0 + xboxOneResolution: 0 + xboxOneSResolution: 0 + xboxOneXResolution: 3 + xboxOneMonoLoggingLevel: 0 + xboxOneLoggingLevel: 1 + xboxOneDisableEsram: 0 + xboxOneEnableTypeOptimization: 0 + xboxOnePresentImmediateThreshold: 0 + switchQueueCommandMemory: 0 + switchQueueControlMemory: 16384 + switchQueueComputeMemory: 262144 + switchNVNShaderPoolsGranularity: 33554432 + switchNVNDefaultPoolsGranularity: 16777216 + switchNVNOtherPoolsGranularity: 16777216 + switchNVNMaxPublicTextureIDCount: 0 + switchNVNMaxPublicSamplerIDCount: 0 + stadiaPresentMode: 0 + stadiaTargetFramerate: 0 + vulkanNumSwapchainBuffers: 3 + vulkanEnableSetSRGBWrite: 0 + vulkanEnablePreTransform: 0 + vulkanEnableLateAcquireNextImage: 0 + vulkanEnableCommandBufferRecycling: 1 + m_SupportedAspectRatios: + 4:3: 1 + 5:4: 1 + 16:10: 1 + 16:9: 1 + Others: 1 + bundleVersion: 0.1 + preloadedAssets: [] + metroInputSource: 0 + wsaTransparentSwapchain: 0 + m_HolographicPauseOnTrackingLoss: 1 + xboxOneDisableKinectGpuReservation: 1 + xboxOneEnable7thCore: 1 + vrSettings: + enable360StereoCapture: 0 + isWsaHolographicRemotingEnabled: 0 + enableFrameTimingStats: 0 + useHDRDisplay: 0 + D3DHDRBitDepth: 0 + m_ColorGamuts: 00000000 + targetPixelDensity: 30 + resolutionScalingMode: 0 + androidSupportedAspectRatio: 1 + androidMaxAspectRatio: 2.1 + applicationIdentifier: + Standalone: com.Company.ProductName + buildNumber: + Standalone: 0 + iPhone: 0 + tvOS: 0 + overrideDefaultApplicationIdentifier: 1 + AndroidBundleVersionCode: 1 + AndroidMinSdkVersion: 19 + AndroidTargetSdkVersion: 0 + AndroidPreferredInstallLocation: 1 + aotOptions: + stripEngineCode: 1 + iPhoneStrippingLevel: 0 + iPhoneScriptCallOptimization: 0 + ForceInternetPermission: 0 + ForceSDCardPermission: 0 + CreateWallpaper: 0 + APKExpansionFiles: 0 + keepLoadedShadersAlive: 0 + StripUnusedMeshComponents: 1 + VertexChannelCompressionMask: 4054 + iPhoneSdkVersion: 988 + iOSTargetOSVersionString: 11.0 + tvOSSdkVersion: 0 + tvOSRequireExtendedGameController: 0 + tvOSTargetOSVersionString: 11.0 + uIPrerenderedIcon: 0 + uIRequiresPersistentWiFi: 0 + uIRequiresFullScreen: 1 + uIStatusBarHidden: 1 + uIExitOnSuspend: 0 + uIStatusBarStyle: 0 + appleTVSplashScreen: {fileID: 0} + appleTVSplashScreen2x: {fileID: 0} + tvOSSmallIconLayers: [] + tvOSSmallIconLayers2x: [] + tvOSLargeIconLayers: [] + tvOSLargeIconLayers2x: [] + tvOSTopShelfImageLayers: [] + tvOSTopShelfImageLayers2x: [] + tvOSTopShelfImageWideLayers: [] + tvOSTopShelfImageWideLayers2x: [] + iOSLaunchScreenType: 0 + iOSLaunchScreenPortrait: {fileID: 0} + iOSLaunchScreenLandscape: {fileID: 0} + iOSLaunchScreenBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreenFillPct: 100 + iOSLaunchScreenSize: 100 + iOSLaunchScreenCustomXibPath: + iOSLaunchScreeniPadType: 0 + iOSLaunchScreeniPadImage: {fileID: 0} + iOSLaunchScreeniPadBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreeniPadFillPct: 100 + iOSLaunchScreeniPadSize: 100 + iOSLaunchScreeniPadCustomXibPath: + iOSLaunchScreenCustomStoryboardPath: + iOSLaunchScreeniPadCustomStoryboardPath: + iOSDeviceRequirements: [] + iOSURLSchemes: [] + iOSBackgroundModes: 0 + iOSMetalForceHardShadows: 0 + metalEditorSupport: 1 + metalAPIValidation: 1 + iOSRenderExtraFrameOnPause: 0 + iosCopyPluginsCodeInsteadOfSymlink: 0 + appleDeveloperTeamID: + iOSManualSigningProvisioningProfileID: + tvOSManualSigningProvisioningProfileID: + iOSManualSigningProvisioningProfileType: 0 + tvOSManualSigningProvisioningProfileType: 0 + appleEnableAutomaticSigning: 0 + iOSRequireARKit: 0 + iOSAutomaticallyDetectAndAddCapabilities: 1 + appleEnableProMotion: 0 + shaderPrecisionModel: 0 + clonedFromGUID: 5f34be1353de5cf4398729fda238591b + templatePackageId: com.unity.template.2d@3.2.3 + templateDefaultScene: Assets/Scenes/SampleScene.unity + useCustomMainManifest: 0 + useCustomLauncherManifest: 0 + useCustomMainGradleTemplate: 0 + useCustomLauncherGradleManifest: 0 + useCustomBaseGradleTemplate: 0 + useCustomGradlePropertiesTemplate: 0 + useCustomProguardFile: 0 + AndroidTargetArchitectures: 1 + AndroidTargetDevices: 0 + AndroidSplashScreenScale: 0 + androidSplashScreen: {fileID: 0} + AndroidKeystoreName: '{inproject}: ' + AndroidKeyaliasName: + AndroidBuildApkPerCpuArchitecture: 0 + AndroidTVCompatibility: 0 + AndroidIsGame: 1 + AndroidEnableTango: 0 + androidEnableBanner: 1 + androidUseLowAccuracyLocation: 0 + androidUseCustomKeystore: 0 + m_AndroidBanners: + - width: 320 + height: 180 + banner: {fileID: 0} + androidGamepadSupportLevel: 0 + chromeosInputEmulation: 1 + AndroidMinifyWithR8: 0 + AndroidMinifyRelease: 0 + AndroidMinifyDebug: 0 + AndroidValidateAppBundleSize: 1 + AndroidAppBundleSizeToValidate: 150 + m_BuildTargetIcons: [] + m_BuildTargetPlatformIcons: [] + m_BuildTargetBatching: [] + m_BuildTargetGraphicsJobs: + - m_BuildTarget: GameCoreScarlettSupport + m_GraphicsJobs: 0 + - m_BuildTarget: Switch + m_GraphicsJobs: 0 + - m_BuildTarget: iOSSupport + m_GraphicsJobs: 0 + - m_BuildTarget: LuminSupport + m_GraphicsJobs: 0 + - m_BuildTarget: MacStandaloneSupport + m_GraphicsJobs: 0 + - m_BuildTarget: PS5Player + m_GraphicsJobs: 0 + - m_BuildTarget: WebGLSupport + m_GraphicsJobs: 0 + - m_BuildTarget: AppleTVSupport + m_GraphicsJobs: 0 + - m_BuildTarget: GameCoreXboxOneSupport + m_GraphicsJobs: 0 + - m_BuildTarget: CloudRendering + m_GraphicsJobs: 0 + - m_BuildTarget: WindowsStandaloneSupport + m_GraphicsJobs: 0 + - m_BuildTarget: PS4Player + m_GraphicsJobs: 0 + - m_BuildTarget: MetroSupport + m_GraphicsJobs: 0 + - m_BuildTarget: AndroidPlayer + m_GraphicsJobs: 0 + - m_BuildTarget: BJMSupport + m_GraphicsJobs: 0 + - m_BuildTarget: LinuxStandaloneSupport + m_GraphicsJobs: 0 + - m_BuildTarget: XboxOnePlayer + m_GraphicsJobs: 0 + m_BuildTargetGraphicsJobMode: + - m_BuildTarget: PS4Player + m_GraphicsJobMode: 0 + - m_BuildTarget: XboxOnePlayer + m_GraphicsJobMode: 0 + m_BuildTargetGraphicsAPIs: + - m_BuildTarget: AndroidPlayer + m_APIs: 150000000b000000 + m_Automatic: 0 + - m_BuildTarget: iOSSupport + m_APIs: 10000000 + m_Automatic: 1 + m_BuildTargetVRSettings: [] + openGLRequireES31: 0 + openGLRequireES31AEP: 0 + openGLRequireES32: 0 + m_TemplateCustomTags: {} + mobileMTRendering: + Android: 1 + iPhone: 1 + tvOS: 1 + m_BuildTargetGroupLightmapEncodingQuality: [] + m_BuildTargetGroupLightmapSettings: [] + m_BuildTargetNormalMapEncoding: [] + playModeTestRunnerEnabled: 0 + runPlayModeTestAsEditModeTest: 0 + actionOnDotNetUnhandledException: 1 + enableInternalProfiler: 0 + logObjCUncaughtExceptions: 1 + enableCrashReportAPI: 0 + cameraUsageDescription: + locationUsageDescription: + microphoneUsageDescription: + bluetoothUsageDescription: + switchNMETAOverride: + switchNetLibKey: + switchSocketMemoryPoolSize: 6144 + switchSocketAllocatorPoolSize: 128 + switchSocketConcurrencyLimit: 14 + switchScreenResolutionBehavior: 2 + switchUseCPUProfiler: 0 + switchUseGOLDLinker: 0 + switchApplicationID: 0x01004b9000490000 + switchNSODependencies: + switchTitleNames_0: + switchTitleNames_1: + switchTitleNames_2: + switchTitleNames_3: + switchTitleNames_4: + switchTitleNames_5: + switchTitleNames_6: + switchTitleNames_7: + switchTitleNames_8: + switchTitleNames_9: + switchTitleNames_10: + switchTitleNames_11: + switchTitleNames_12: + switchTitleNames_13: + switchTitleNames_14: + switchTitleNames_15: + switchPublisherNames_0: + switchPublisherNames_1: + switchPublisherNames_2: + switchPublisherNames_3: + switchPublisherNames_4: + switchPublisherNames_5: + switchPublisherNames_6: + switchPublisherNames_7: + switchPublisherNames_8: + switchPublisherNames_9: + switchPublisherNames_10: + switchPublisherNames_11: + switchPublisherNames_12: + switchPublisherNames_13: + switchPublisherNames_14: + switchPublisherNames_15: + switchIcons_0: {fileID: 0} + switchIcons_1: {fileID: 0} + switchIcons_2: {fileID: 0} + switchIcons_3: {fileID: 0} + switchIcons_4: {fileID: 0} + switchIcons_5: {fileID: 0} + switchIcons_6: {fileID: 0} + switchIcons_7: {fileID: 0} + switchIcons_8: {fileID: 0} + switchIcons_9: {fileID: 0} + switchIcons_10: {fileID: 0} + switchIcons_11: {fileID: 0} + switchIcons_12: {fileID: 0} + switchIcons_13: {fileID: 0} + switchIcons_14: {fileID: 0} + switchIcons_15: {fileID: 0} + switchSmallIcons_0: {fileID: 0} + switchSmallIcons_1: {fileID: 0} + switchSmallIcons_2: {fileID: 0} + switchSmallIcons_3: {fileID: 0} + switchSmallIcons_4: {fileID: 0} + switchSmallIcons_5: {fileID: 0} + switchSmallIcons_6: {fileID: 0} + switchSmallIcons_7: {fileID: 0} + switchSmallIcons_8: {fileID: 0} + switchSmallIcons_9: {fileID: 0} + switchSmallIcons_10: {fileID: 0} + switchSmallIcons_11: {fileID: 0} + switchSmallIcons_12: {fileID: 0} + switchSmallIcons_13: {fileID: 0} + switchSmallIcons_14: {fileID: 0} + switchSmallIcons_15: {fileID: 0} + switchManualHTML: + switchAccessibleURLs: + switchLegalInformation: + switchMainThreadStackSize: 1048576 + switchPresenceGroupId: + switchLogoHandling: 0 + switchReleaseVersion: 0 + switchDisplayVersion: 1.0.0 + switchStartupUserAccount: 0 + switchTouchScreenUsage: 0 + switchSupportedLanguagesMask: 0 + switchLogoType: 0 + switchApplicationErrorCodeCategory: + switchUserAccountSaveDataSize: 0 + switchUserAccountSaveDataJournalSize: 0 + switchApplicationAttribute: 0 + switchCardSpecSize: -1 + switchCardSpecClock: -1 + switchRatingsMask: 0 + switchRatingsInt_0: 0 + switchRatingsInt_1: 0 + switchRatingsInt_2: 0 + switchRatingsInt_3: 0 + switchRatingsInt_4: 0 + switchRatingsInt_5: 0 + switchRatingsInt_6: 0 + switchRatingsInt_7: 0 + switchRatingsInt_8: 0 + switchRatingsInt_9: 0 + switchRatingsInt_10: 0 + switchRatingsInt_11: 0 + switchRatingsInt_12: 0 + switchLocalCommunicationIds_0: + switchLocalCommunicationIds_1: + switchLocalCommunicationIds_2: + switchLocalCommunicationIds_3: + switchLocalCommunicationIds_4: + switchLocalCommunicationIds_5: + switchLocalCommunicationIds_6: + switchLocalCommunicationIds_7: + switchParentalControl: 0 + switchAllowsScreenshot: 1 + switchAllowsVideoCapturing: 1 + switchAllowsRuntimeAddOnContentInstall: 0 + switchDataLossConfirmation: 0 + switchUserAccountLockEnabled: 0 + switchSystemResourceMemory: 16777216 + switchSupportedNpadStyles: 22 + switchNativeFsCacheSize: 32 + switchIsHoldTypeHorizontal: 0 + switchSupportedNpadCount: 8 + switchSocketConfigEnabled: 0 + switchTcpInitialSendBufferSize: 32 + switchTcpInitialReceiveBufferSize: 64 + switchTcpAutoSendBufferSizeMax: 256 + switchTcpAutoReceiveBufferSizeMax: 256 + switchUdpSendBufferSize: 9 + switchUdpReceiveBufferSize: 42 + switchSocketBufferEfficiency: 4 + switchSocketInitializeEnabled: 1 + switchNetworkInterfaceManagerInitializeEnabled: 1 + switchPlayerConnectionEnabled: 1 + switchUseNewStyleFilepaths: 0 + switchUseMicroSleepForYield: 1 + switchMicroSleepForYieldTime: 25 + ps4NPAgeRating: 12 + ps4NPTitleSecret: + ps4NPTrophyPackPath: + ps4ParentalLevel: 11 + ps4ContentID: ED1633-NPXX51362_00-0000000000000000 + ps4Category: 0 + ps4MasterVersion: 01.00 + ps4AppVersion: 01.00 + ps4AppType: 0 + ps4ParamSfxPath: + ps4VideoOutPixelFormat: 0 + ps4VideoOutInitialWidth: 1920 + ps4VideoOutBaseModeInitialWidth: 1920 + ps4VideoOutReprojectionRate: 60 + ps4PronunciationXMLPath: + ps4PronunciationSIGPath: + ps4BackgroundImagePath: + ps4StartupImagePath: + ps4StartupImagesFolder: + ps4IconImagesFolder: + ps4SaveDataImagePath: + ps4SdkOverride: + ps4BGMPath: + ps4ShareFilePath: + ps4ShareOverlayImagePath: + ps4PrivacyGuardImagePath: + ps4ExtraSceSysFile: + ps4NPtitleDatPath: + ps4RemotePlayKeyAssignment: -1 + ps4RemotePlayKeyMappingDir: + ps4PlayTogetherPlayerCount: 0 + ps4EnterButtonAssignment: 1 + ps4ApplicationParam1: 0 + ps4ApplicationParam2: 0 + ps4ApplicationParam3: 0 + ps4ApplicationParam4: 0 + ps4DownloadDataSize: 0 + ps4GarlicHeapSize: 2048 + ps4ProGarlicHeapSize: 2560 + playerPrefsMaxSize: 32768 + ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ + ps4pnSessions: 1 + ps4pnPresence: 1 + ps4pnFriends: 1 + ps4pnGameCustomData: 1 + playerPrefsSupport: 0 + enableApplicationExit: 0 + resetTempFolder: 1 + restrictedAudioUsageRights: 0 + ps4UseResolutionFallback: 0 + ps4ReprojectionSupport: 0 + ps4UseAudio3dBackend: 0 + ps4UseLowGarlicFragmentationMode: 1 + ps4SocialScreenEnabled: 0 + ps4ScriptOptimizationLevel: 0 + ps4Audio3dVirtualSpeakerCount: 14 + ps4attribCpuUsage: 0 + ps4PatchPkgPath: + ps4PatchLatestPkgPath: + ps4PatchChangeinfoPath: + ps4PatchDayOne: 0 + ps4attribUserManagement: 0 + ps4attribMoveSupport: 0 + ps4attrib3DSupport: 0 + ps4attribShareSupport: 0 + ps4attribExclusiveVR: 0 + ps4disableAutoHideSplash: 0 + ps4videoRecordingFeaturesUsed: 0 + ps4contentSearchFeaturesUsed: 0 + ps4CompatibilityPS5: 0 + ps4AllowPS5Detection: 0 + ps4GPU800MHz: 1 + ps4attribEyeToEyeDistanceSettingVR: 0 + ps4IncludedModules: [] + ps4attribVROutputEnabled: 0 + monoEnv: + splashScreenBackgroundSourceLandscape: {fileID: 0} + splashScreenBackgroundSourcePortrait: {fileID: 0} + blurSplashScreenBackground: 1 + spritePackerPolicy: + webGLMemorySize: 16 + webGLExceptionSupport: 1 + webGLNameFilesAsHashes: 0 + webGLDataCaching: 1 + webGLDebugSymbols: 0 + webGLEmscriptenArgs: + webGLModulesDirectory: + webGLTemplate: APPLICATION:Default + webGLAnalyzeBuildSize: 0 + webGLUseEmbeddedResources: 0 + webGLCompressionFormat: 1 + webGLWasmArithmeticExceptions: 0 + webGLLinkerTarget: 1 + webGLThreadsSupport: 0 + webGLDecompressionFallback: 0 + scriptingDefineSymbols: {} + additionalCompilerArguments: {} + platformArchitecture: {} + scriptingBackend: + Standalone: 1 + il2cppCompilerConfiguration: {} + managedStrippingLevel: {} + incrementalIl2cppBuild: {} + suppressCommonWarnings: 1 + allowUnsafeCode: 0 + useDeterministicCompilation: 1 + useReferenceAssemblies: 1 + enableRoslynAnalyzers: 1 + additionalIl2CppArgs: + scriptingRuntimeVersion: 1 + gcIncremental: 0 + assemblyVersionValidation: 1 + gcWBarrierValidation: 0 + apiCompatibilityLevelPerPlatform: {} + m_RenderingPath: 1 + m_MobileRenderingPath: 1 + metroPackageName: Template2D + metroPackageVersion: 1.0.0.0 + metroCertificatePath: + metroCertificatePassword: + metroCertificateSubject: + metroCertificateIssuer: + metroCertificateNotAfter: 0000000000000000 + metroApplicationDescription: Template_2D + wsaImages: {} + metroTileShortName: simple-test-project + metroTileShowName: 0 + metroMediumTileShowName: 0 + metroLargeTileShowName: 0 + metroWideTileShowName: 0 + metroSupportStreamingInstall: 0 + metroLastRequiredScene: 0 + metroDefaultTileSize: 1 + metroTileForegroundText: 2 + metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} + metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, + a: 1} + metroSplashScreenUseBackgroundColor: 0 + platformCapabilities: {} + metroTargetDeviceFamilies: {} + metroFTAName: + metroFTAFileTypes: [] + metroProtocolName: + XboxOneProductId: + XboxOneUpdateKey: + XboxOneSandboxId: + XboxOneContentId: + XboxOneTitleId: + XboxOneSCId: + XboxOneGameOsOverridePath: + XboxOnePackagingOverridePath: + XboxOneAppManifestOverridePath: + XboxOneVersion: 1.0.0.0 + XboxOnePackageEncryption: 0 + XboxOnePackageUpdateGranularity: 2 + XboxOneDescription: + XboxOneLanguage: + - enus + XboxOneCapability: [] + XboxOneGameRating: {} + XboxOneIsContentPackage: 0 + XboxOneEnhancedXboxCompatibilityMode: 0 + XboxOneEnableGPUVariability: 1 + XboxOneSockets: {} + XboxOneSplashScreen: {fileID: 0} + XboxOneAllowedProductIds: [] + XboxOnePersistentLocalStorageSize: 0 + XboxOneXTitleMemory: 8 + XboxOneOverrideIdentityName: + XboxOneOverrideIdentityPublisher: + vrEditorSettings: {} + cloudServicesEnabled: + UNet: 1 + luminIcon: + m_Name: + m_ModelFolderPath: + m_PortalFolderPath: + luminCert: + m_CertPath: + m_SignPackage: 1 + luminIsChannelApp: 0 + luminVersion: + m_VersionCode: 1 + m_VersionName: + apiCompatibilityLevel: 6 + activeInputHandler: 0 + cloudProjectId: + framebufferDepthMemorylessMode: 0 + qualitySettingsNames: [] + projectName: + organizationId: + cloudEnabled: 0 + legacyClampBlendShapeWeights: 0 + virtualTexturingSupportEnabled: 0