From 3d0eb0805bbe2df90e319abbe42e41d0b9105625 Mon Sep 17 00:00:00 2001 From: AndrewKahr <22359829+AndrewKahr@users.noreply.github.com> Date: Tue, 25 Jan 2022 13:18:15 -0800 Subject: [PATCH] Initial Support for Windows Based Builds (#305) * Implemented logic for windows based docker builds. Moved dockerfiles and scripts to platform specific folders. * Add missing newline character * Add build-tests for windows and a unity project configured to output il2cpp * Add additional build targets (uwp and tvOS) Adjustments to build scripts to not require win10 sdk when not needed (tvOS) Platform-based prereq setup Setup image tags for the new platforms with errors if building on the wrong base os Rename test-project-il2cpp to test-project-windows to be used for all windows based project building (IL2CPP backend selected instead of mono) Fix tests to be platform based * Update dist/platforms/windows/steps/return_license.ps1 Co-authored-by: Webber Takken * Update src/model/docker.ts Co-authored-by: Webber Takken * Update src/model/docker.ts Co-authored-by: Webber Takken * Update src/model/docker.ts Co-authored-by: Webber Takken * Fix outdated repository and homepage links in dockerfiles * Fix comment style and rename validateWindowsPrereqs to validateWindowsPlatformRequirements * Remove redundant comment * Remove windows unity test project, add ProjectSettings for the il2cpp backend, and add logic to replace the projectsettings file with the il2cpp one on windows test builds. * Fix action.test.ts to accept windows as a base platform * Fix camelcase for wsaPlayer * Switch from add to copy in windows dockerfile * Change slash direction * Switch ADD to COPY to conform with best practices, change ls to dir on windows dockerfile * Improve error message for unset UNITY_EMAIL and UNITY_PASSWORD * Further improve missing email and password error. Remove temppaths being mounted to docker image * Add debug statement. TODO: Remove these * Add more debug * Explicitly pass in unity email to docker run * Remove debug and fix environment variables for activation/deactivation scripts * Prevent Unity serial from leaking to console * Debug folder listings * More debug print dirs * fix debug print path * fix reg export command * Remove debug directory listings and try setSecret to mask serial * Update src/model/action.ts Co-authored-by: Webber Takken * Update src/model/docker.ts Co-authored-by: Webber Takken * Update src/model/image-tag.ts Co-authored-by: David Finol * Update .github/workflows/build-tests.yml Co-authored-by: David Finol * Move platform validation and setup out of docker and into its own layer, remove branching on docker run command * Fix test failure due to missing license * Fix camelCase and duplicate variables * Fix lint issues and make paths more understandable * Fix typo in build-tests.yml * Fix move command in build-tests.yml * Different method to force move file * Fix missing quote and backslash * Pass unity email and password to builder action for windows build tests * Push serial to windows test builds * Make windows build tests only run on push to main Co-authored-by: Webber Takken Co-authored-by: David Finol --- .github/workflows/build-tests.yml | 8 +- .github/workflows/windows-build-tests.yml | 77 ++ .gitignore | 1 + .../Editor/UnityBuilderAction/Builder.cs | 6 +- dist/index.js | Bin 14737199 -> 14750075 bytes dist/index.js.map | Bin 8959139 -> 8972874 bytes dist/{ => platforms/ubuntu}/Dockerfile | 10 +- dist/{ => platforms/ubuntu}/entrypoint.sh | 0 dist/{ => platforms/ubuntu}/steps/activate.sh | 0 dist/{ => platforms/ubuntu}/steps/build.sh | 0 .../ubuntu}/steps/return_license.sh | 0 .../ubuntu}/steps/set_gitcredential.sh | 0 dist/platforms/windows/Dockerfile | 18 + dist/platforms/windows/entrypoint.ps1 | 15 + dist/platforms/windows/steps/activate.ps1 | 6 + dist/platforms/windows/steps/build.ps1 | 147 ++++ .../windows/steps/return_license.ps1 | 6 + src/index.ts | 2 + src/model/action.test.ts | 4 +- src/model/action.ts | 12 +- src/model/build-parameters.test.ts | 4 + src/model/build-parameters.ts | 30 + src/model/docker.ts | 129 ++-- src/model/image-tag.test.ts | 28 +- src/model/image-tag.ts | 49 +- src/model/platform-setup.ts | 17 + src/model/platform-setup/setup-windows.ts | 33 + .../platform-validation/validate-windows.ts | 57 ++ .../ProjectSettingsWindows.asset | 673 ++++++++++++++++++ 29 files changed, 1256 insertions(+), 76 deletions(-) create mode 100644 .github/workflows/windows-build-tests.yml rename dist/{ => platforms/ubuntu}/Dockerfile (60%) rename dist/{ => platforms/ubuntu}/entrypoint.sh (100%) mode change 100755 => 100644 rename dist/{ => platforms/ubuntu}/steps/activate.sh (100%) mode change 100755 => 100644 rename dist/{ => platforms/ubuntu}/steps/build.sh (100%) mode change 100755 => 100644 rename dist/{ => platforms/ubuntu}/steps/return_license.sh (100%) mode change 100755 => 100644 rename dist/{ => platforms/ubuntu}/steps/set_gitcredential.sh (100%) mode change 100755 => 100644 create mode 100644 dist/platforms/windows/Dockerfile create mode 100644 dist/platforms/windows/entrypoint.ps1 create mode 100644 dist/platforms/windows/steps/activate.ps1 create mode 100644 dist/platforms/windows/steps/build.ps1 create mode 100644 dist/platforms/windows/steps/return_license.ps1 create mode 100644 src/model/platform-setup.ts create mode 100644 src/model/platform-setup/setup-windows.ts create mode 100644 src/model/platform-validation/validate-windows.ts create mode 100644 test-project/ProjectSettings/ProjectSettingsWindows.asset 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 70417aa2f2ffedf55fab628607ddb3eb481e98ad..459ce17c8b69c1be91a9d46175597b8c2a80e738 100644 GIT binary patch delta 8568 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 GB=)~6YqEa; delta 1971 zcmbuphXU8q_d9Md4@#-(Ybs&G}H{NvcVg#+=MTb8&ihN@iAf(ShutUR?!Z zYhkFklpQVZU}%nBWaf+%wK=h(6^HO0Ip5q^5uckRba{cInfUJ7OLXMMbjR!SA_L?osfBE)>dSh25F+{)gbRJa1W{iU zAkG%*h1QrN3XB7V!x;77su;(K-;Lu%V^JTGToli047m43*Xxl>?KPGPTT_Y17l9&h z=6G?nz*pp+43u}8FRI0LOS4#3x>=01Mrg_{R$HmlStXZQm#Do5A) z0;O$7RqA^Qt^9q(qaHmOud2iMH*#xrif8Ltm0I$>VAF_OwUcGX!d8pC=ce@sDMV3e zT2jxe-~mr~!5h7xM%Q_7XyF52^g&24OIUAQ&MCMHq%chj2t- z7$PwoQHVwiMj#d=F$$xh$0HbnIK*Qt5-<+qF#(B~h)I}?DM-SjNXAs8AQjV)hICBF z3}he^GcgNU$VLuwk%xR3P=G=hQKY1ve{AC)<1E#+3oLG@t4^1syB}+9i)%@__4hOO z2aoN_$rGmGDk;jx7%r8>nZ2c?PSa|YUCLWi7T~F`b4m@aDxL2ln`@fIZHpN(Lfa(C zou)+Pw@%Zq-pb!+Ovlv0Zd-M^-r=-Tp-b**ZP!iGDMzlDg8E8985NN#mlPgj8zgNQ zW1g*K{bY((CEuTkk*v;|8mFUYOl^b3_263%SJ)ND&!*eaierGe!&6BJGIs<>w?>+O zQErYhul0Per$W!{|J_caU9u7!Z{9ahIhSG1@KhqQ%>I7T#JT1_TN37(F&lF*7xOS5 z#VCOVrLdw5Hk6|R3t(3g=2f<3`IWo%i(K|P+jRc71&t1?bZ1wkUNcG;U0+w87_G$a zuI%(`iEFDw6{=AK2b`$ILb%{o;@avuZg`hA*4f<3KU?Yz9$s$y5?jlh?e%EDA}mHD zmS8C!M-!Ie2{hwLEXNA0#40?67Cen-uo}u>-GSCtkzrcmr?ZExe6)unW8KF7{wA-a{K?ypMhO01EcwLma?C9KvC= z<0E{G4jjQze1c>66rbU9e1YRQfiKaClQ@O1a2j9Z49?;l&f@|u;u0?73ckTrT*J4@ KobA_jwf_PqO+Fp~ diff --git a/dist/index.js.map b/dist/index.js.map index d94b0d7955401c86d759588bd27e39024491cd88..bbd86d360dd7d25a5fb6e8d8e2448b8c0c17a8f3 100644 GIT binary patch delta 8020 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 +# - +# +# 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