Compare commits

...

8 Commits

Author SHA1 Message Date
Frostebite
7c6f03998d feat: add providerPackage input for CloudRunner configuration 2025-09-03 21:11:55 +01:00
Frostebite
ebb637d57e feat: add dynamic provider loader 2025-09-03 20:34:08 +01:00
Frostebite
c6c8236152 fix: mock github checks in tests (#724)
* fix: load fetch polyfill before tests

* refactor: extract cloud runner test helpers

* fix: load fetch polyfill before tests
2025-08-06 06:07:52 +01:00
David Finol
9e91ca9749 Update unity version for macOS (#712)
* Update Unity version

* Test updating unity version for mac
2025-06-10 09:03:26 -04:00
Eric_Lian
9cd9f7e0e7 fix: androidCreateSymbols has been deprecated (#701) 2025-06-08 21:21:32 -05:00
David Finol
0b822c28fb Update Unity version (#711) 2025-06-08 11:00:16 -04:00
Daniel Lupiañez Casares
65607f9ebb Adds support for .upmconfig.toml in Windows Docker images (#705)
* Supports github_home in windows-latest

* Attempt at copying from specific volume

* Adding some more logging

* Fix and compiles index.js

* Debugging and some other approach

* Another attempt at debugging

* Testing two more approaches

* Try only copying the file

* Cleanup

* Updates index.js, index.js.map and licenses.txt

After `yarn` + `npm run build`

* Update index.js.map
2025-06-07 16:11:18 -05:00
Daniel Lupiañez Casares
a1ebdb7abd Adds support for VisionOS in UnityHub in macos (#710)
* Adds support for VisionOS in UnityHub in macos

* Adds support for VisionOS in UnityHub in macos

* Syncs index.js.map
2025-06-07 20:20:18 +02:00
28 changed files with 1724 additions and 88 deletions

View File

@@ -18,7 +18,7 @@ jobs:
projectPath: projectPath:
- test-project - test-project
unityVersion: unityVersion:
- 2021.3.32f1 - 2021.3.45f1
- 2022.3.13f1 - 2022.3.13f1
- 2023.2.2f1 - 2023.2.2f1
targetPlatform: targetPlatform:

View File

@@ -3,6 +3,11 @@ name: Cloud Runner CI Pipeline
on: on:
push: { branches: [cloud-runner-develop, cloud-runner-preview, main] } push: { branches: [cloud-runner-develop, cloud-runner-preview, main] }
workflow_dispatch: workflow_dispatch:
inputs:
runGithubIntegrationTests:
description: 'Run GitHub Checks integration tests'
required: false
default: 'false'
permissions: permissions:
checks: write checks: write
@@ -207,3 +212,20 @@ jobs:
name: ${{ matrix.providerStrategy }} Build (${{ matrix.targetPlatform }}) name: ${{ matrix.providerStrategy }} Build (${{ matrix.targetPlatform }})
path: ${{ steps.unity-build.outputs.BUILD_ARTIFACT }} path: ${{ steps.unity-build.outputs.BUILD_ARTIFACT }}
retention-days: 14 retention-days: 14
githubChecksIntegration:
name: GitHub Checks Integration
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' && github.event.inputs.runGithubIntegrationTests == 'true'
env:
RUN_GITHUB_INTEGRATION_TESTS: true
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'yarn'
- run: yarn install --frozen-lockfile
- run: yarn test cloud-runner-github-checks-integration-test --detectOpenHandles --forceExit --runInBand
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -194,6 +194,10 @@ inputs:
description: description:
'[CloudRunner] Either local, k8s or aws can be used to run builds on a remote cluster. Additional parameters must '[CloudRunner] Either local, k8s or aws can be used to run builds on a remote cluster. Additional parameters must
be configured.' be configured.'
providerPackage:
default: ''
required: false
description: '[CloudRunner] Override the provider package name used to load the provider'
containerCpu: containerCpu:
default: '' default: ''
required: false required: false

View File

@@ -74,7 +74,20 @@ namespace UnityBuilderAction.Input
string symbolType; string symbolType;
if (options.TryGetValue("androidSymbolType", out symbolType) && !string.IsNullOrEmpty(symbolType)) if (options.TryGetValue("androidSymbolType", out symbolType) && !string.IsNullOrEmpty(symbolType))
{ {
#if UNITY_2021_1_OR_NEWER #if UNITY_6000_0_OR_NEWER
switch (symbolType)
{
case "public":
SetDebugSymbols("SymbolTable");
break;
case "debugging":
SetDebugSymbols("Full");
break;
case "none":
SetDebugSymbols("None");
break;
}
#elif UNITY_2021_1_OR_NEWER
switch (symbolType) switch (symbolType)
{ {
case "public": case "public":
@@ -101,5 +114,35 @@ namespace UnityBuilderAction.Input
#endif #endif
} }
} }
private static void SetDebugSymbols(string enumValueName)
{
// UnityEditor.Android.UserBuildSettings and Unity.Android.Types.DebugSymbolLevel are part of the Unity Android module.
// Reflection is used here to ensure the code works even if the module is not installed.
var debugSymbolsType = Type.GetType("UnityEditor.Android.UserBuildSettings+DebugSymbols, UnityEditor.Android.Extensions");
if (debugSymbolsType == null)
{
return;
}
var levelProp = debugSymbolsType.GetProperty("level", BindingFlags.Static | BindingFlags.Public);
if (levelProp == null)
{
return;
}
var enumType = Type.GetType("Unity.Android.Types.DebugSymbolLevel, Unity.Android.Types");
if (enumType == null)
{
return;
}
if (!Enum.TryParse(enumType, enumValueName, false , out var enumValue))
{
return;
}
levelProp.SetValue(null, enumValue);
}
} }
} }

103
dist/index.js generated vendored
View File

@@ -327,6 +327,7 @@ class BuildParameters {
containerRegistryRepository: input_1.default.containerRegistryRepository, containerRegistryRepository: input_1.default.containerRegistryRepository,
containerRegistryImageVersion: input_1.default.containerRegistryImageVersion, containerRegistryImageVersion: input_1.default.containerRegistryImageVersion,
providerStrategy: cloud_runner_options_1.default.providerStrategy, providerStrategy: cloud_runner_options_1.default.providerStrategy,
providerPackage: cloud_runner_options_1.default.providerPackage,
buildPlatform: cloud_runner_options_1.default.buildPlatform, buildPlatform: cloud_runner_options_1.default.buildPlatform,
kubeConfig: cloud_runner_options_1.default.kubeConfig, kubeConfig: cloud_runner_options_1.default.kubeConfig,
containerMemory: cloud_runner_options_1.default.containerMemory, containerMemory: cloud_runner_options_1.default.containerMemory,
@@ -751,6 +752,7 @@ const core = __importStar(__nccwpck_require__(42186));
const test_1 = __importDefault(__nccwpck_require__(63007)); const test_1 = __importDefault(__nccwpck_require__(63007));
const local_1 = __importDefault(__nccwpck_require__(66575)); const local_1 = __importDefault(__nccwpck_require__(66575));
const docker_1 = __importDefault(__nccwpck_require__(42802)); const docker_1 = __importDefault(__nccwpck_require__(42802));
const provider_loader_1 = __importDefault(__nccwpck_require__(45788));
const github_1 = __importDefault(__nccwpck_require__(83654)); const github_1 = __importDefault(__nccwpck_require__(83654));
const shared_workspace_locking_1 = __importDefault(__nccwpck_require__(71372)); const shared_workspace_locking_1 = __importDefault(__nccwpck_require__(71372));
const follow_log_stream_service_1 = __nccwpck_require__(40266); const follow_log_stream_service_1 = __nccwpck_require__(40266);
@@ -769,7 +771,7 @@ class CloudRunner {
if (CloudRunner.buildParameters.githubCheckId === ``) { if (CloudRunner.buildParameters.githubCheckId === ``) {
CloudRunner.buildParameters.githubCheckId = await github_1.default.createGitHubCheck(CloudRunner.buildParameters.buildGuid); CloudRunner.buildParameters.githubCheckId = await github_1.default.createGitHubCheck(CloudRunner.buildParameters.buildGuid);
} }
CloudRunner.setupSelectedBuildPlatform(); await CloudRunner.setupSelectedBuildPlatform();
CloudRunner.defaultSecrets = task_parameter_serializer_1.TaskParameterSerializer.readDefaultSecrets(); CloudRunner.defaultSecrets = task_parameter_serializer_1.TaskParameterSerializer.readDefaultSecrets();
CloudRunner.cloudRunnerEnvironmentVariables = CloudRunner.cloudRunnerEnvironmentVariables =
task_parameter_serializer_1.TaskParameterSerializer.createCloudRunnerEnvironmentVariables(buildParameters); task_parameter_serializer_1.TaskParameterSerializer.createCloudRunnerEnvironmentVariables(buildParameters);
@@ -787,7 +789,7 @@ class CloudRunner {
} }
follow_log_stream_service_1.FollowLogStreamService.Reset(); follow_log_stream_service_1.FollowLogStreamService.Reset();
} }
static setupSelectedBuildPlatform() { static async setupSelectedBuildPlatform() {
cloud_runner_logger_1.default.log(`Cloud Runner platform selected ${CloudRunner.buildParameters.providerStrategy}`); cloud_runner_logger_1.default.log(`Cloud Runner platform selected ${CloudRunner.buildParameters.providerStrategy}`);
switch (CloudRunner.buildParameters.providerStrategy) { switch (CloudRunner.buildParameters.providerStrategy) {
case 'k8s': case 'k8s':
@@ -805,6 +807,10 @@ class CloudRunner {
case 'local-system': case 'local-system':
CloudRunner.Provider = new local_1.default(); CloudRunner.Provider = new local_1.default();
break; break;
default:
if (CloudRunner.buildParameters.providerStrategy !== 'local') {
CloudRunner.Provider = await (0, provider_loader_1.default)(CloudRunner.buildParameters.providerPackage, CloudRunner.buildParameters);
}
} }
} }
static async run(buildParameters, baseImage) { static async run(buildParameters, baseImage) {
@@ -1214,6 +1220,9 @@ class CloudRunnerOptions {
} }
return provider || 'local'; return provider || 'local';
} }
static get providerPackage() {
return (CloudRunnerOptions.getInput('providerPackage') || `unity-builder-provider-${CloudRunnerOptions.providerStrategy}`);
}
static get containerCpu() { static get containerCpu() {
return CloudRunnerOptions.getInput('containerCpu') || `1024`; return CloudRunnerOptions.getInput('containerCpu') || `1024`;
} }
@@ -4214,6 +4223,78 @@ class LocalCloudRunner {
exports["default"] = LocalCloudRunner; exports["default"] = LocalCloudRunner;
/***/ }),
/***/ 45788:
/***/ (function(__unused_webpack_module, exports) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
/**
* Dynamically load a provider package by name.
* @param providerName Name of the provider package to load
* @param buildParameters Build parameters passed to the provider constructor
* @throws Error when the provider cannot be loaded or does not implement ProviderInterface
*/
async function loadProvider(providerName, buildParameters) {
let importedModule;
try {
importedModule = await Promise.resolve().then(() => __importStar(require(providerName)));
}
catch (error) {
throw new Error(`Failed to load provider package '${providerName}': ${error.message}`);
}
const Provider = importedModule.default || importedModule;
let instance;
try {
instance = new Provider(buildParameters);
}
catch (error) {
throw new Error(`Failed to instantiate provider '${providerName}': ${error.message}`);
}
const requiredMethods = [
'cleanupWorkflow',
'setupWorkflow',
'runTaskInWorkflow',
'garbageCollect',
'listResources',
'listWorkflow',
'watchWorkflow',
];
for (const method of requiredMethods) {
if (typeof instance[method] !== 'function') {
throw new Error(`Provider package '${providerName}' does not implement ProviderInterface. Missing method '${method}'.`);
}
}
return instance;
}
exports["default"] = loadProvider;
/***/ }), /***/ }),
/***/ 63007: /***/ 63007:
@@ -6103,7 +6184,10 @@ class Docker {
"${overrideCommands !== '' ? overrideCommands : `/entrypoint.sh`}"`; "${overrideCommands !== '' ? overrideCommands : `/entrypoint.sh`}"`;
} }
static getWindowsCommand(image, parameters) { static getWindowsCommand(image, parameters) {
const { workspace, actionFolder, gitPrivateToken, dockerWorkspacePath, dockerCpuLimit, dockerMemoryLimit, dockerIsolationMode, } = parameters; const { workspace, actionFolder, runnerTempPath, gitPrivateToken, dockerWorkspacePath, dockerCpuLimit, dockerMemoryLimit, dockerIsolationMode, } = parameters;
const githubHome = node_path_1.default.join(runnerTempPath, '_github_home');
if (!(0, node_fs_1.existsSync)(githubHome))
(0, node_fs_1.mkdirSync)(githubHome);
return `docker run \ return `docker run \
--workdir c:${dockerWorkspacePath} \ --workdir c:${dockerWorkspacePath} \
--rm \ --rm \
@@ -6111,6 +6195,7 @@ class Docker {
--env GITHUB_WORKSPACE=c:${dockerWorkspacePath} \ --env GITHUB_WORKSPACE=c:${dockerWorkspacePath} \
${gitPrivateToken ? `--env GIT_PRIVATE_TOKEN="${gitPrivateToken}"` : ''} \ ${gitPrivateToken ? `--env GIT_PRIVATE_TOKEN="${gitPrivateToken}"` : ''} \
--volume "${workspace}":"c:${dockerWorkspacePath}" \ --volume "${workspace}":"c:${dockerWorkspacePath}" \
--volume "${githubHome}":"C:/githubhome" \
--volume "c:/regkeys":"c:/regkeys" \ --volume "c:/regkeys":"c:/regkeys" \
--volume "C:/Program Files/Microsoft Visual Studio":"C:/Program Files/Microsoft Visual Studio" \ --volume "C:/Program Files/Microsoft Visual Studio":"C:/Program Files/Microsoft Visual Studio" \
--volume "C:/Program Files (x86)/Microsoft Visual Studio":"C:/Program Files (x86)/Microsoft Visual Studio" \ --volume "C:/Program Files (x86)/Microsoft Visual Studio":"C:/Program Files (x86)/Microsoft Visual Studio" \
@@ -6548,6 +6633,7 @@ class ImageTag {
android: 'android', android: 'android',
ios: 'ios', ios: 'ios',
tvos: 'appletv', tvos: 'appletv',
visionos: 'visionos',
facebook: 'facebook', facebook: 'facebook',
}; };
} }
@@ -6565,7 +6651,7 @@ class ImageTag {
} }
} }
static getTargetPlatformToTargetPlatformSuffixMap(platform, version, providerStrategy) { static getTargetPlatformToTargetPlatformSuffixMap(platform, version, providerStrategy) {
const { generic, webgl, mac, windows, windowsIl2cpp, wsaPlayer, linux, linuxIl2cpp, android, ios, tvos, facebook } = ImageTag.targetPlatformSuffixes; const { generic, webgl, mac, windows, windowsIl2cpp, wsaPlayer, linux, linuxIl2cpp, android, ios, tvos, visionos, facebook, } = ImageTag.targetPlatformSuffixes;
const [major, minor] = version.split('.').map((digit) => Number(digit)); const [major, minor] = version.split('.').map((digit) => Number(digit));
// @see: https://docs.unity3d.com/ScriptReference/BuildTarget.html // @see: https://docs.unity3d.com/ScriptReference/BuildTarget.html
switch (platform) { switch (platform) {
@@ -6617,6 +6703,11 @@ class ImageTag {
throw new Error(`tvOS can only be built on Windows or macOS base OS`); throw new Error(`tvOS can only be built on Windows or macOS base OS`);
} }
return tvos; return tvos;
case platform_1.default.types.VisionOS:
if (process.platform !== 'darwin') {
throw new Error(`visionOS can only be built on a macOS base OS`);
}
return visionos;
case platform_1.default.types.Switch: case platform_1.default.types.Switch:
return windows; return windows;
// Unsupported // Unsupported
@@ -7398,6 +7489,9 @@ class SetupMac {
case 'tvOS': case 'tvOS':
moduleArgument.push('--module', 'appletv'); moduleArgument.push('--module', 'appletv');
break; break;
case 'VisionOS':
moduleArgument.push('--module', 'visionos');
break;
case 'StandaloneOSX': case 'StandaloneOSX':
moduleArgument.push('--module', 'mac-il2cpp'); moduleArgument.push('--module', 'mac-il2cpp');
break; break;
@@ -7610,6 +7704,7 @@ class Platform {
PS4: 'PS4', PS4: 'PS4',
XboxOne: 'XboxOne', XboxOne: 'XboxOne',
tvOS: 'tvOS', tvOS: 'tvOS',
VisionOS: 'VisionOS',
Switch: 'Switch', Switch: 'Switch',
// Unsupported // Unsupported
Lumin: 'Lumin', Lumin: 'Lumin',

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,13 @@
Get-Process Get-Process
# Copy .upmconfig.toml if it exists
if (Test-Path "C:\githubhome\.upmconfig.toml") {
Write-Host "Copying .upmconfig.toml to $Env:USERPROFILE\.upmconfig.toml"
Copy-Item -Path "C:\githubhome\.upmconfig.toml" -Destination "$Env:USERPROFILE\.upmconfig.toml" -Force
} else {
Write-Host "No .upmconfig.toml found at C:\githubhome"
}
# Import any necessary registry keys, ie: location of windows 10 sdk # Import any necessary registry keys, ie: location of windows 10 sdk
# No guarantee that there will be any necessary registry keys, ie: tvOS # No guarantee that there will be any necessary registry keys, ie: tvOS
Get-ChildItem -Path c:\regkeys -File | ForEach-Object { reg import $_.fullname } Get-ChildItem -Path c:\regkeys -File | ForEach-Object { reg import $_.fullname }

View File

@@ -25,6 +25,8 @@ module.exports = {
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
modulePathIgnorePatterns: ['<rootDir>/lib/', '<rootDir>/dist/'], modulePathIgnorePatterns: ['<rootDir>/lib/', '<rootDir>/dist/'],
// A list of paths to modules that run some code to configure or set up the testing framework before each test // Files that will be run before Jest is loaded to set globals like fetch
setupFiles: ['<rootDir>/src/jest.globals.ts'],
// A list of paths to modules that run some code to configure or set up the testing framework after the environment is ready
setupFilesAfterEnv: ['<rootDir>/src/jest.setup.ts'], setupFilesAfterEnv: ['<rootDir>/src/jest.setup.ts'],
}; };

View File

@@ -0,0 +1,29 @@
// Integration test for exercising real GitHub check creation and updates.
import CloudRunner from '../model/cloud-runner/cloud-runner';
import UnityVersioning from '../model/unity-versioning';
import GitHub from '../model/github';
import { TIMEOUT_INFINITE, createParameters } from '../test-utils/cloud-runner-test-helpers';
const runIntegration = process.env.RUN_GITHUB_INTEGRATION_TESTS === 'true';
const describeOrSkip = runIntegration ? describe : describe.skip;
describeOrSkip('Cloud Runner Github Checks Integration', () => {
it(
'creates and updates a real GitHub check',
async () => {
const buildParameter = await createParameters({
versioning: 'None',
projectPath: 'test-project',
unityVersion: UnityVersioning.read('test-project'),
asyncCloudRunner: `true`,
githubChecks: `true`,
});
await CloudRunner.setup(buildParameter);
const checkId = await GitHub.createGitHubCheck(`integration create`);
expect(checkId).not.toEqual('');
await GitHub.updateGitHubCheck(`1 ${new Date().toISOString()}`, `integration`);
await GitHub.updateGitHubCheck(`2 ${new Date().toISOString()}`, `integration`, `success`, `completed`);
},
TIMEOUT_INFINITE,
);
});

3
src/jest.globals.ts Normal file
View File

@@ -0,0 +1,3 @@
import { fetch as undiciFetch, Headers, Request, Response } from 'undici';
Object.assign(globalThis, { fetch: undiciFetch, Headers, Request, Response });

View File

@@ -54,6 +54,7 @@ class BuildParameters {
public sshAgent!: string; public sshAgent!: string;
public sshPublicKeysDirectoryPath!: string; public sshPublicKeysDirectoryPath!: string;
public providerStrategy!: string; public providerStrategy!: string;
public providerPackage!: string;
public gitPrivateToken!: string; public gitPrivateToken!: string;
public awsStackName!: string; public awsStackName!: string;
public kubeConfig!: string; public kubeConfig!: string;
@@ -183,6 +184,7 @@ class BuildParameters {
containerRegistryRepository: Input.containerRegistryRepository, containerRegistryRepository: Input.containerRegistryRepository,
containerRegistryImageVersion: Input.containerRegistryImageVersion, containerRegistryImageVersion: Input.containerRegistryImageVersion,
providerStrategy: CloudRunnerOptions.providerStrategy, providerStrategy: CloudRunnerOptions.providerStrategy,
providerPackage: CloudRunnerOptions.providerPackage,
buildPlatform: CloudRunnerOptions.buildPlatform, buildPlatform: CloudRunnerOptions.buildPlatform,
kubeConfig: CloudRunnerOptions.kubeConfig, kubeConfig: CloudRunnerOptions.kubeConfig,
containerMemory: CloudRunnerOptions.containerMemory, containerMemory: CloudRunnerOptions.containerMemory,

View File

@@ -13,6 +13,7 @@ import CloudRunnerEnvironmentVariable from './options/cloud-runner-environment-v
import TestCloudRunner from './providers/test'; import TestCloudRunner from './providers/test';
import LocalCloudRunner from './providers/local'; import LocalCloudRunner from './providers/local';
import LocalDockerCloudRunner from './providers/docker'; import LocalDockerCloudRunner from './providers/docker';
import loadProvider from './providers/provider-loader';
import GitHub from '../github'; import GitHub from '../github';
import SharedWorkspaceLocking from './services/core/shared-workspace-locking'; import SharedWorkspaceLocking from './services/core/shared-workspace-locking';
import { FollowLogStreamService } from './services/core/follow-log-stream-service'; import { FollowLogStreamService } from './services/core/follow-log-stream-service';
@@ -38,7 +39,7 @@ class CloudRunner {
if (CloudRunner.buildParameters.githubCheckId === ``) { if (CloudRunner.buildParameters.githubCheckId === ``) {
CloudRunner.buildParameters.githubCheckId = await GitHub.createGitHubCheck(CloudRunner.buildParameters.buildGuid); CloudRunner.buildParameters.githubCheckId = await GitHub.createGitHubCheck(CloudRunner.buildParameters.buildGuid);
} }
CloudRunner.setupSelectedBuildPlatform(); await CloudRunner.setupSelectedBuildPlatform();
CloudRunner.defaultSecrets = TaskParameterSerializer.readDefaultSecrets(); CloudRunner.defaultSecrets = TaskParameterSerializer.readDefaultSecrets();
CloudRunner.cloudRunnerEnvironmentVariables = CloudRunner.cloudRunnerEnvironmentVariables =
TaskParameterSerializer.createCloudRunnerEnvironmentVariables(buildParameters); TaskParameterSerializer.createCloudRunnerEnvironmentVariables(buildParameters);
@@ -62,7 +63,7 @@ class CloudRunner {
FollowLogStreamService.Reset(); FollowLogStreamService.Reset();
} }
private static setupSelectedBuildPlatform() { private static async setupSelectedBuildPlatform() {
CloudRunnerLogger.log(`Cloud Runner platform selected ${CloudRunner.buildParameters.providerStrategy}`); CloudRunnerLogger.log(`Cloud Runner platform selected ${CloudRunner.buildParameters.providerStrategy}`);
switch (CloudRunner.buildParameters.providerStrategy) { switch (CloudRunner.buildParameters.providerStrategy) {
case 'k8s': case 'k8s':
@@ -80,6 +81,13 @@ class CloudRunner {
case 'local-system': case 'local-system':
CloudRunner.Provider = new LocalCloudRunner(); CloudRunner.Provider = new LocalCloudRunner();
break; break;
default:
if (CloudRunner.buildParameters.providerStrategy !== 'local') {
CloudRunner.Provider = await loadProvider(
CloudRunner.buildParameters.providerPackage,
CloudRunner.buildParameters,
);
}
} }
} }

View File

@@ -127,6 +127,12 @@ class CloudRunnerOptions {
return provider || 'local'; return provider || 'local';
} }
static get providerPackage(): string {
return (
CloudRunnerOptions.getInput('providerPackage') || `unity-builder-provider-${CloudRunnerOptions.providerStrategy}`
);
}
static get containerCpu(): string { static get containerCpu(): string {
return CloudRunnerOptions.getInput('containerCpu') || `1024`; return CloudRunnerOptions.getInput('containerCpu') || `1024`;
} }

View File

@@ -0,0 +1 @@
export default class InvalidProvider {}

View File

@@ -0,0 +1,19 @@
import loadProvider from './provider-loader';
import { ProviderInterface } from './provider-interface';
describe('provider-loader', () => {
it('loads a provider dynamically', async () => {
const provider: ProviderInterface = await loadProvider('./test', {} as any);
expect(typeof provider.runTaskInWorkflow).toBe('function');
});
it('throws when provider package is missing', async () => {
await expect(loadProvider('non-existent-package', {} as any)).rejects.toThrow('non-existent-package');
});
it('throws when provider does not implement ProviderInterface', async () => {
await expect(loadProvider('./fixtures/invalid-provider', {} as any)).rejects.toThrow(
'does not implement ProviderInterface',
);
});
});

View File

@@ -0,0 +1,48 @@
import { ProviderInterface } from './provider-interface';
import BuildParameters from '../../build-parameters';
/**
* Dynamically load a provider package by name.
* @param providerName Name of the provider package to load
* @param buildParameters Build parameters passed to the provider constructor
* @throws Error when the provider cannot be loaded or does not implement ProviderInterface
*/
export default async function loadProvider(
providerName: string,
buildParameters: BuildParameters,
): Promise<ProviderInterface> {
let importedModule: any;
try {
importedModule = await import(providerName);
} catch (error) {
throw new Error(`Failed to load provider package '${providerName}': ${(error as Error).message}`);
}
const Provider = importedModule.default || importedModule;
let instance: any;
try {
instance = new Provider(buildParameters);
} catch (error) {
throw new Error(`Failed to instantiate provider '${providerName}': ${(error as Error).message}`);
}
const requiredMethods = [
'cleanupWorkflow',
'setupWorkflow',
'runTaskInWorkflow',
'garbageCollect',
'listResources',
'listWorkflow',
'watchWorkflow',
];
for (const method of requiredMethods) {
if (typeof instance[method] !== 'function') {
throw new Error(
`Provider package '${providerName}' does not implement ProviderInterface. Missing method '${method}'.`,
);
}
}
return instance as ProviderInterface;
}

View File

@@ -1,59 +1,65 @@
import { BuildParameters } from '../..';
import CloudRunner from '../cloud-runner'; import CloudRunner from '../cloud-runner';
import UnityVersioning from '../../unity-versioning'; import UnityVersioning from '../../unity-versioning';
import { Cli } from '../../cli/cli';
import CloudRunnerOptions from '../options/cloud-runner-options';
import setups from './cloud-runner-suite.test'; import setups from './cloud-runner-suite.test';
import { OptionValues } from 'commander';
import GitHub from '../../github'; import GitHub from '../../github';
export const TIMEOUT_INFINITE = 1e9; import { TIMEOUT_INFINITE, createParameters } from '../../../test-utils/cloud-runner-test-helpers';
async function CreateParameters(overrides: OptionValues | undefined) {
if (overrides) Cli.options = overrides;
return BuildParameters.create();
}
describe('Cloud Runner Github Checks', () => { describe('Cloud Runner Github Checks', () => {
setups(); setups();
it('Responds', () => {}); it('Responds', () => {});
if (CloudRunnerOptions.cloudRunnerDebug) { beforeEach(() => {
it( // Mock GitHub API requests to avoid real network calls
'Check Handling Direct', jest.spyOn(GitHub as any, 'createGitHubCheckRequest').mockResolvedValue({
async () => { status: 201,
// Setup parameters data: { id: '1' },
const buildParameter = await CreateParameters({ });
versioning: 'None', jest.spyOn(GitHub as any, 'updateGitHubCheckRequest').mockResolvedValue({
projectPath: 'test-project', status: 200,
unityVersion: UnityVersioning.read('test-project'), data: {},
asyncCloudRunner: `true`, });
githubChecks: `true`, jest.spyOn(GitHub as any, 'runUpdateAsyncChecksWorkflow').mockResolvedValue(undefined);
}); });
await CloudRunner.setup(buildParameter);
CloudRunner.buildParameters.githubCheckId = await GitHub.createGitHubCheck(`direct create`); afterEach(() => {
await GitHub.updateGitHubCheck(`1 ${new Date().toISOString()}`, `direct`); jest.restoreAllMocks();
await GitHub.updateGitHubCheck(`2 ${new Date().toISOString()}`, `direct`, `success`, `completed`); });
},
TIMEOUT_INFINITE, it(
); 'Check Handling Direct',
it( async () => {
'Check Handling Via Async Workflow', // Setup parameters
async () => { const buildParameter = await createParameters({
// Setup parameters versioning: 'None',
const buildParameter = await CreateParameters({ projectPath: 'test-project',
versioning: 'None', unityVersion: UnityVersioning.read('test-project'),
projectPath: 'test-project', asyncCloudRunner: `true`,
unityVersion: UnityVersioning.read('test-project'), githubChecks: `true`,
asyncCloudRunner: `true`, });
githubChecks: `true`, await CloudRunner.setup(buildParameter);
}); CloudRunner.buildParameters.githubCheckId = await GitHub.createGitHubCheck(`direct create`);
GitHub.forceAsyncTest = true; await GitHub.updateGitHubCheck(`1 ${new Date().toISOString()}`, `direct`);
await CloudRunner.setup(buildParameter); await GitHub.updateGitHubCheck(`2 ${new Date().toISOString()}`, `direct`, `success`, `completed`);
CloudRunner.buildParameters.githubCheckId = await GitHub.createGitHubCheck(`async create`); },
await GitHub.updateGitHubCheck(`1 ${new Date().toISOString()}`, `async`); TIMEOUT_INFINITE,
await GitHub.updateGitHubCheck(`2 ${new Date().toISOString()}`, `async`, `success`, `completed`); );
GitHub.forceAsyncTest = false; it(
}, 'Check Handling Via Async Workflow',
TIMEOUT_INFINITE, async () => {
); // Setup parameters
} const buildParameter = await createParameters({
versioning: 'None',
projectPath: 'test-project',
unityVersion: UnityVersioning.read('test-project'),
asyncCloudRunner: `true`,
githubChecks: `true`,
});
GitHub.forceAsyncTest = true;
await CloudRunner.setup(buildParameter);
CloudRunner.buildParameters.githubCheckId = await GitHub.createGitHubCheck(`async create`);
await GitHub.updateGitHubCheck(`1 ${new Date().toISOString()}`, `async`);
await GitHub.updateGitHubCheck(`2 ${new Date().toISOString()}`, `async`, `success`, `completed`);
GitHub.forceAsyncTest = false;
},
TIMEOUT_INFINITE,
);
}); });

View File

@@ -92,6 +92,7 @@ class Docker {
const { const {
workspace, workspace,
actionFolder, actionFolder,
runnerTempPath,
gitPrivateToken, gitPrivateToken,
dockerWorkspacePath, dockerWorkspacePath,
dockerCpuLimit, dockerCpuLimit,
@@ -99,6 +100,9 @@ class Docker {
dockerIsolationMode, dockerIsolationMode,
} = parameters; } = parameters;
const githubHome = path.join(runnerTempPath, '_github_home');
if (!existsSync(githubHome)) mkdirSync(githubHome);
return `docker run \ return `docker run \
--workdir c:${dockerWorkspacePath} \ --workdir c:${dockerWorkspacePath} \
--rm \ --rm \
@@ -106,6 +110,7 @@ class Docker {
--env GITHUB_WORKSPACE=c:${dockerWorkspacePath} \ --env GITHUB_WORKSPACE=c:${dockerWorkspacePath} \
${gitPrivateToken ? `--env GIT_PRIVATE_TOKEN="${gitPrivateToken}"` : ''} \ ${gitPrivateToken ? `--env GIT_PRIVATE_TOKEN="${gitPrivateToken}"` : ''} \
--volume "${workspace}":"c:${dockerWorkspacePath}" \ --volume "${workspace}":"c:${dockerWorkspacePath}" \
--volume "${githubHome}":"C:/githubhome" \
--volume "c:/regkeys":"c:/regkeys" \ --volume "c:/regkeys":"c:/regkeys" \
--volume "C:/Program Files/Microsoft Visual Studio":"C:/Program Files/Microsoft Visual Studio" \ --volume "C:/Program Files/Microsoft Visual Studio":"C:/Program Files/Microsoft Visual Studio" \
--volume "C:/Program Files (x86)/Microsoft Visual Studio":"C:/Program Files (x86)/Microsoft Visual Studio" \ --volume "C:/Program Files (x86)/Microsoft Visual Studio":"C:/Program Files (x86)/Microsoft Visual Studio" \

View File

@@ -58,6 +58,7 @@ class ImageTag {
android: 'android', android: 'android',
ios: 'ios', ios: 'ios',
tvos: 'appletv', tvos: 'appletv',
visionos: 'visionos',
facebook: 'facebook', facebook: 'facebook',
}; };
} }
@@ -82,8 +83,21 @@ class ImageTag {
version: string, version: string,
providerStrategy: string, providerStrategy: string,
): string { ): string {
const { generic, webgl, mac, windows, windowsIl2cpp, wsaPlayer, linux, linuxIl2cpp, android, ios, tvos, facebook } = const {
ImageTag.targetPlatformSuffixes; generic,
webgl,
mac,
windows,
windowsIl2cpp,
wsaPlayer,
linux,
linuxIl2cpp,
android,
ios,
tvos,
visionos,
facebook,
} = ImageTag.targetPlatformSuffixes;
const [major, minor] = version.split('.').map((digit) => Number(digit)); const [major, minor] = version.split('.').map((digit) => Number(digit));
@@ -141,6 +155,12 @@ class ImageTag {
} }
return tvos; return tvos;
case Platform.types.VisionOS:
if (process.platform !== 'darwin') {
throw new Error(`visionOS can only be built on a macOS base OS`);
}
return visionos;
case Platform.types.Switch: case Platform.types.Switch:
return windows; return windows;

View File

@@ -103,6 +103,9 @@ class SetupMac {
case 'tvOS': case 'tvOS':
moduleArgument.push('--module', 'appletv'); moduleArgument.push('--module', 'appletv');
break; break;
case 'VisionOS':
moduleArgument.push('--module', 'visionos');
break;
case 'StandaloneOSX': case 'StandaloneOSX':
moduleArgument.push('--module', 'mac-il2cpp'); moduleArgument.push('--module', 'mac-il2cpp');
break; break;

View File

@@ -16,6 +16,7 @@ class Platform {
PS4: 'PS4', PS4: 'PS4',
XboxOne: 'XboxOne', XboxOne: 'XboxOne',
tvOS: 'tvOS', tvOS: 'tvOS',
VisionOS: 'VisionOS',
Switch: 'Switch', Switch: 'Switch',
// Unsupported // Unsupported

View File

@@ -7,9 +7,9 @@ describe('Unity Versioning', () => {
}); });
it('parses from ProjectVersion.txt', () => { it('parses from ProjectVersion.txt', () => {
const projectVersionContents = `m_EditorVersion: 2021.3.4f1 const projectVersionContents = `m_EditorVersion: 2021.3.45f1
m_EditorVersionWithRevision: 2021.3.4f1 (cb45f9cae8b7)`; m_EditorVersionWithRevision: 2021.3.45f1 (cb45f9cae8b7)`;
expect(UnityVersioning.parse(projectVersionContents)).toBe('2021.3.4f1'); expect(UnityVersioning.parse(projectVersionContents)).toBe('2021.3.45f1');
}); });
it('parses Unity 6000 and newer from ProjectVersion.txt', () => { it('parses Unity 6000 and newer from ProjectVersion.txt', () => {
@@ -25,13 +25,13 @@ describe('Unity Versioning', () => {
}); });
it('reads from test-project', () => { it('reads from test-project', () => {
expect(UnityVersioning.read('./test-project')).toBe('2021.3.4f1'); expect(UnityVersioning.read('./test-project')).toBe('2021.3.45f1');
}); });
}); });
describe('determineUnityVersion', () => { describe('determineUnityVersion', () => {
it('defaults to parsed version', () => { it('defaults to parsed version', () => {
expect(UnityVersioning.determineUnityVersion('./test-project', 'auto')).toBe('2021.3.4f1'); expect(UnityVersioning.determineUnityVersion('./test-project', 'auto')).toBe('2021.3.45f1');
}); });
it('use specified unityVersion', () => { it('use specified unityVersion', () => {

View File

@@ -0,0 +1,11 @@
import { BuildParameters } from '../model';
import { Cli } from '../model/cli/cli';
import { OptionValues } from 'commander';
export const TIMEOUT_INFINITE = 1e9;
export async function createParameters(overrides?: OptionValues) {
if (overrides) Cli.options = overrides;
return BuildParameters.create();
}

View File

@@ -1,7 +1,7 @@
{ {
"dependencies": { "dependencies": {
"com.unity.burst": "1.6.6", "com.unity.burst": "1.8.22",
"com.unity.ide.visualstudio": "2.0.22", "com.unity.ide.visualstudio": "2.0.23",
"com.unity.modules.ai": "1.0.0", "com.unity.modules.ai": "1.0.0",
"com.unity.modules.androidjni": "1.0.0", "com.unity.modules.androidjni": "1.0.0",
"com.unity.modules.animation": "1.0.0", "com.unity.modules.animation": "1.0.0",

View File

@@ -1,11 +1,12 @@
{ {
"dependencies": { "dependencies": {
"com.unity.burst": { "com.unity.burst": {
"version": "1.6.6", "version": "1.8.22",
"depth": 0, "depth": 0,
"source": "registry", "source": "registry",
"dependencies": { "dependencies": {
"com.unity.mathematics": "1.2.1" "com.unity.mathematics": "1.2.1",
"com.unity.modules.jsonserialize": "1.0.0"
}, },
"url": "https://packages.unity.com" "url": "https://packages.unity.com"
}, },
@@ -17,7 +18,7 @@
"url": "https://packages.unity.com" "url": "https://packages.unity.com"
}, },
"com.unity.ide.visualstudio": { "com.unity.ide.visualstudio": {
"version": "2.0.22", "version": "2.0.23",
"depth": 0, "depth": 0,
"source": "registry", "source": "registry",
"dependencies": { "dependencies": {
@@ -33,7 +34,7 @@
"url": "https://packages.unity.com" "url": "https://packages.unity.com"
}, },
"com.unity.test-framework": { "com.unity.test-framework": {
"version": "1.1.31", "version": "1.1.33",
"depth": 1, "depth": 1,
"source": "registry", "source": "registry",
"dependencies": { "dependencies": {

View File

@@ -3,7 +3,7 @@
--- !u!129 &1 --- !u!129 &1
PlayerSettings: PlayerSettings:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
serializedVersion: 23 serializedVersion: 24
productGUID: f3f6a917a3bba0046bb55998f8678f8c productGUID: f3f6a917a3bba0046bb55998f8678f8c
AndroidProfiler: 0 AndroidProfiler: 0
AndroidFilterTouchesWhenObscured: 0 AndroidFilterTouchesWhenObscured: 0
@@ -48,6 +48,7 @@ PlayerSettings:
defaultScreenHeightWeb: 600 defaultScreenHeightWeb: 600
m_StereoRenderingPath: 0 m_StereoRenderingPath: 0
m_ActiveColorSpace: 0 m_ActiveColorSpace: 0
unsupportedMSAAFallback: 0
m_MTRendering: 1 m_MTRendering: 1
mipStripping: 0 mipStripping: 0
numberOfMipsStripped: 0 numberOfMipsStripped: 0
@@ -74,6 +75,7 @@ PlayerSettings:
androidMinimumWindowWidth: 400 androidMinimumWindowWidth: 400
androidMinimumWindowHeight: 300 androidMinimumWindowHeight: 300
androidFullscreenMode: 1 androidFullscreenMode: 1
androidAutoRotationBehavior: 1
defaultIsNativeResolution: 1 defaultIsNativeResolution: 1
macRetinaSupport: 1 macRetinaSupport: 1
runInBackground: 1 runInBackground: 1
@@ -121,6 +123,7 @@ PlayerSettings:
switchNVNOtherPoolsGranularity: 16777216 switchNVNOtherPoolsGranularity: 16777216
switchNVNMaxPublicTextureIDCount: 0 switchNVNMaxPublicTextureIDCount: 0
switchNVNMaxPublicSamplerIDCount: 0 switchNVNMaxPublicSamplerIDCount: 0
switchMaxWorkerMultiple: 8
stadiaPresentMode: 0 stadiaPresentMode: 0
stadiaTargetFramerate: 0 stadiaTargetFramerate: 0
vulkanNumSwapchainBuffers: 3 vulkanNumSwapchainBuffers: 3
@@ -180,10 +183,10 @@ PlayerSettings:
StripUnusedMeshComponents: 1 StripUnusedMeshComponents: 1
VertexChannelCompressionMask: 4054 VertexChannelCompressionMask: 4054
iPhoneSdkVersion: 988 iPhoneSdkVersion: 988
iOSTargetOSVersionString: 11.0 iOSTargetOSVersionString: 12.0
tvOSSdkVersion: 0 tvOSSdkVersion: 0
tvOSRequireExtendedGameController: 0 tvOSRequireExtendedGameController: 0
tvOSTargetOSVersionString: 11.0 tvOSTargetOSVersionString: 12.0
uIPrerenderedIcon: 0 uIPrerenderedIcon: 0
uIRequiresPersistentWiFi: 0 uIRequiresPersistentWiFi: 0
uIRequiresFullScreen: 1 uIRequiresFullScreen: 1
@@ -247,6 +250,7 @@ PlayerSettings:
useCustomLauncherGradleManifest: 0 useCustomLauncherGradleManifest: 0
useCustomBaseGradleTemplate: 0 useCustomBaseGradleTemplate: 0
useCustomGradlePropertiesTemplate: 0 useCustomGradlePropertiesTemplate: 0
useCustomGradleSettingsTemplate: 0
useCustomProguardFile: 0 useCustomProguardFile: 0
AndroidTargetArchitectures: 3 AndroidTargetArchitectures: 3
AndroidTargetDevices: 0 AndroidTargetDevices: 0
@@ -267,7 +271,6 @@ PlayerSettings:
banner: {fileID: 0} banner: {fileID: 0}
androidGamepadSupportLevel: 0 androidGamepadSupportLevel: 0
chromeosInputEmulation: 1 chromeosInputEmulation: 1
AndroidMinifyWithR8: 0
AndroidMinifyRelease: 0 AndroidMinifyRelease: 0
AndroidMinifyDebug: 0 AndroidMinifyDebug: 0
AndroidValidateAppBundleSize: 1 AndroidValidateAppBundleSize: 1
@@ -516,6 +519,7 @@ PlayerSettings:
- m_BuildTarget: WebGL - m_BuildTarget: WebGL
m_StaticBatching: 0 m_StaticBatching: 0
m_DynamicBatching: 0 m_DynamicBatching: 0
m_BuildTargetShaderSettings: []
m_BuildTargetGraphicsJobs: m_BuildTargetGraphicsJobs:
- m_BuildTarget: MacStandaloneSupport - m_BuildTarget: MacStandaloneSupport
m_GraphicsJobs: 0 m_GraphicsJobs: 0
@@ -567,6 +571,8 @@ PlayerSettings:
m_Devices: m_Devices:
- Oculus - Oculus
- OpenVR - OpenVR
m_DefaultShaderChunkSizeInMB: 16
m_DefaultShaderChunkCount: 0
openGLRequireES31: 0 openGLRequireES31: 0
openGLRequireES31AEP: 0 openGLRequireES31AEP: 0
openGLRequireES32: 0 openGLRequireES32: 0
@@ -610,7 +616,7 @@ PlayerSettings:
switchSocketConcurrencyLimit: 14 switchSocketConcurrencyLimit: 14
switchScreenResolutionBehavior: 2 switchScreenResolutionBehavior: 2
switchUseCPUProfiler: 0 switchUseCPUProfiler: 0
switchUseGOLDLinker: 0 switchEnableFileSystemTrace: 0
switchLTOSetting: 0 switchLTOSetting: 0
switchApplicationID: 0x01004b9000490000 switchApplicationID: 0x01004b9000490000
switchNSODependencies: switchNSODependencies:
@@ -687,7 +693,6 @@ PlayerSettings:
switchReleaseVersion: 0 switchReleaseVersion: 0
switchDisplayVersion: 1.0.0 switchDisplayVersion: 1.0.0
switchStartupUserAccount: 0 switchStartupUserAccount: 0
switchTouchScreenUsage: 0
switchSupportedLanguagesMask: 0 switchSupportedLanguagesMask: 0
switchLogoType: 0 switchLogoType: 0
switchApplicationErrorCodeCategory: switchApplicationErrorCodeCategory:
@@ -729,6 +734,7 @@ PlayerSettings:
switchNativeFsCacheSize: 32 switchNativeFsCacheSize: 32
switchIsHoldTypeHorizontal: 0 switchIsHoldTypeHorizontal: 0
switchSupportedNpadCount: 8 switchSupportedNpadCount: 8
switchEnableTouchScreen: 1
switchSocketConfigEnabled: 0 switchSocketConfigEnabled: 0
switchTcpInitialSendBufferSize: 32 switchTcpInitialSendBufferSize: 32
switchTcpInitialReceiveBufferSize: 64 switchTcpInitialReceiveBufferSize: 64
@@ -739,8 +745,8 @@ PlayerSettings:
switchSocketBufferEfficiency: 4 switchSocketBufferEfficiency: 4
switchSocketInitializeEnabled: 1 switchSocketInitializeEnabled: 1
switchNetworkInterfaceManagerInitializeEnabled: 1 switchNetworkInterfaceManagerInitializeEnabled: 1
switchPlayerConnectionEnabled: 1
switchUseNewStyleFilepaths: 0 switchUseNewStyleFilepaths: 0
switchUseLegacyFmodPriorities: 1
switchUseMicroSleepForYield: 1 switchUseMicroSleepForYield: 1
switchEnableRamDiskSupport: 0 switchEnableRamDiskSupport: 0
switchMicroSleepForYieldTime: 25 switchMicroSleepForYieldTime: 25
@@ -815,6 +821,7 @@ PlayerSettings:
ps4videoRecordingFeaturesUsed: 0 ps4videoRecordingFeaturesUsed: 0
ps4contentSearchFeaturesUsed: 0 ps4contentSearchFeaturesUsed: 0
ps4CompatibilityPS5: 0 ps4CompatibilityPS5: 0
ps4AllowPS5Detection: 0
ps4GPU800MHz: 1 ps4GPU800MHz: 1
ps4attribEyeToEyeDistanceSettingVR: 0 ps4attribEyeToEyeDistanceSettingVR: 0
ps4IncludedModules: [] ps4IncludedModules: []
@@ -839,6 +846,7 @@ PlayerSettings:
webGLLinkerTarget: 1 webGLLinkerTarget: 1
webGLThreadsSupport: 0 webGLThreadsSupport: 0
webGLDecompressionFallback: 0 webGLDecompressionFallback: 0
webGLPowerPreference: 2
scriptingDefineSymbols: {} scriptingDefineSymbols: {}
additionalCompilerArguments: {} additionalCompilerArguments: {}
platformArchitecture: {} platformArchitecture: {}
@@ -847,7 +855,21 @@ PlayerSettings:
Server: 0 Server: 0
Standalone: 0 Standalone: 0
il2cppCompilerConfiguration: {} il2cppCompilerConfiguration: {}
managedStrippingLevel: {} managedStrippingLevel:
Android: 1
EmbeddedLinux: 1
GameCoreScarlett: 1
GameCoreXboxOne: 1
Lumin: 1
Nintendo Switch: 1
PS4: 1
PS5: 1
Stadia: 1
WebGL: 1
Windows Store Apps: 1
XboxOne: 1
iPhone: 1
tvOS: 1
incrementalIl2cppBuild: {} incrementalIl2cppBuild: {}
suppressCommonWarnings: 1 suppressCommonWarnings: 1
allowUnsafeCode: 0 allowUnsafeCode: 0
@@ -863,11 +885,11 @@ PlayerSettings:
m_MobileRenderingPath: 1 m_MobileRenderingPath: 1
metroPackageName: Template3D metroPackageName: Template3D
metroPackageVersion: 1.0.0.0 metroPackageVersion: 1.0.0.0
metroCertificatePath: metroCertificatePath: C:\Users\david\Documents\GitHub\unity-builder\test-project\Assets\WSATestCertificate.pfx
metroCertificatePassword: metroCertificatePassword:
metroCertificateSubject: metroCertificateSubject: GameCI
metroCertificateIssuer: metroCertificateIssuer: GameCI
metroCertificateNotAfter: 0000000000000000 metroCertificateNotAfter: 00b8ac9241f7dc01
metroApplicationDescription: Template_3D metroApplicationDescription: Template_3D
wsaImages: {} wsaImages: {}
metroTileShortName: TestProject metroTileShortName: TestProject
@@ -882,6 +904,7 @@ PlayerSettings:
metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0}
metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, a: 1} metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, a: 1}
metroSplashScreenUseBackgroundColor: 0 metroSplashScreenUseBackgroundColor: 0
syncCapabilities: 0
platformCapabilities: {} platformCapabilities: {}
metroTargetDeviceFamilies: {} metroTargetDeviceFamilies: {}
metroFTAName: metroFTAName:
@@ -931,6 +954,7 @@ PlayerSettings:
m_VersionName: m_VersionName:
apiCompatibilityLevel: 6 apiCompatibilityLevel: 6
activeInputHandler: 0 activeInputHandler: 0
windowsGamepadBackendHint: 0
cloudProjectId: cloudProjectId:
framebufferDepthMemorylessMode: 0 framebufferDepthMemorylessMode: 0
qualitySettingsNames: [] qualitySettingsNames: []

View File

@@ -1,2 +1,2 @@
m_EditorVersion: 2021.3.4f1 m_EditorVersion: 2021.3.45f1
m_EditorVersionWithRevision: 2021.3.4f1 (cb45f9cae8b7) m_EditorVersionWithRevision: 2021.3.45f1 (0da89fac8e79)

1277
yarn.lock

File diff suppressed because it is too large Load Diff