From 441be815437f3b77cb65f15adfe09cc3d7447682 Mon Sep 17 00:00:00 2001 From: Webber Takken Date: Sun, 3 Apr 2022 17:59:14 +0200 Subject: [PATCH] Switch to version 1 images (#374) * feat: upgrade to images of version 1 (rolling tag) * chore: indicate what needs to move out of the input class --- dist/index.js | Bin 21806372 -> 21807428 bytes dist/index.js.map | Bin 16174344 -> 16175504 bytes src/model/__mocks__/input.ts | 2 +- .../__snapshots__/versioning.test.ts.snap | 2 +- src/model/build-parameters.test.ts | 6 +- src/model/build-parameters.ts | 13 ++-- .../k8s/kubernetes-job-spec-factory.ts | 2 +- .../services/task-parameter-serializer.ts | 2 +- src/model/image-environment-factory.ts | 4 +- src/model/image-tag.test.ts | 53 +++++++------- src/model/image-tag.ts | 68 ++++++++++-------- src/model/input.ts | 12 ++++ src/model/platform-setup/setup-mac.ts | 10 +-- src/model/platform-setup/setup-windows.ts | 13 ++-- .../platform-validation/validate-windows.ts | 2 +- src/model/versioning.test.ts | 18 ++--- src/model/versioning.ts | 2 +- 17 files changed, 116 insertions(+), 93 deletions(-) diff --git a/dist/index.js b/dist/index.js index 9ba0dda06c67f58d6b72cc15b0985c5f46e627da..f12bb8baef79e37aa0e5d38bfac140b43b535cd1 100644 GIT binary patch delta 3282 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 diff --git a/dist/index.js.map b/dist/index.js.map index 72c9eac17fa26c71eb15a5e95567babd44a3f768..48c1482a3de51c2ed5236601388fc7904747aebd 100644 GIT binary patch delta 3028 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 JrrX(?{{Y6bYb*c& diff --git a/src/model/__mocks__/input.ts b/src/model/__mocks__/input.ts index 438496a1..72645c0f 100644 --- a/src/model/__mocks__/input.ts +++ b/src/model/__mocks__/input.ts @@ -2,7 +2,7 @@ import Platform from '../platform'; export const mockGetFromUser = jest.fn().mockResolvedValue({ - version: '', + editorVersion: '', targetPlatform: Platform.types.Test, projectPath: '.', buildName: Platform.types.Test, diff --git a/src/model/__snapshots__/versioning.test.ts.snap b/src/model/__snapshots__/versioning.test.ts.snap index d5be7149..4e636047 100644 --- a/src/model/__snapshots__/versioning.test.ts.snap +++ b/src/model/__snapshots__/versioning.test.ts.snap @@ -1,3 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Versioning determineVersion throws for invalid strategy somethingRandom 1`] = `"Versioning strategy should be one of None, Semantic, Tag, Custom."`; +exports[`Versioning determineBuildVersion throws for invalid strategy somethingRandom 1`] = `"Versioning strategy should be one of None, Semantic, Tag, Custom."`; diff --git a/src/model/build-parameters.test.ts b/src/model/build-parameters.test.ts index 5b3075c0..1cb37ae5 100644 --- a/src/model/build-parameters.test.ts +++ b/src/model/build-parameters.test.ts @@ -10,7 +10,7 @@ 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 determineVersion = jest.spyOn(Versioning, 'determineBuildVersion').mockImplementation(async () => '1.3.37'); const determineUnityVersion = jest .spyOn(UnityVersioning, 'determineUnityVersion') .mockImplementation(() => '2019.2.11f1'); @@ -55,10 +55,10 @@ describe('BuildParameters', () => { expect(determineSdkManagerParameters).toHaveBeenCalledTimes(1); }); - it('returns the platform', async () => { + it('returns the targetPlatform', async () => { const mockValue = 'somePlatform'; jest.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(mockValue); - expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ platform: mockValue })); + expect(BuildParameters.create()).resolves.toEqual(expect.objectContaining({ targetPlatform: mockValue })); }); it('returns the project path', async () => { diff --git a/src/model/build-parameters.ts b/src/model/build-parameters.ts index 17b650a9..064c5080 100644 --- a/src/model/build-parameters.ts +++ b/src/model/build-parameters.ts @@ -9,11 +9,11 @@ import UnityVersioning from './unity-versioning'; import Versioning from './versioning'; class BuildParameters { - public version!: string; + public editorVersion!: string; public customImage!: string; public unitySerial!: string; public runnerTempPath: string | undefined; - public platform!: string; + public targetPlatform!: string; public projectPath!: string; public buildName!: string; public buildPath!: string; @@ -55,8 +55,8 @@ class BuildParameters { static async create(): Promise { const buildFile = this.parseBuildFile(Input.buildName, Input.targetPlatform, Input.androidAppBundle); - const unityVersion = UnityVersioning.determineUnityVersion(Input.projectPath, Input.unityVersion); - const buildVersion = await Versioning.determineVersion(Input.versioningStrategy, Input.specifiedVersion); + const editorVersion = UnityVersioning.determineUnityVersion(Input.projectPath, Input.unityVersion); + const buildVersion = await Versioning.determineBuildVersion(Input.versioningStrategy, Input.specifiedVersion); const androidVersionCode = AndroidVersioning.determineVersionCode(buildVersion, Input.androidVersionCode); const androidSdkManagerParameters = AndroidVersioning.determineSdkManagerParameters(Input.androidTargetSdkVersion); @@ -79,12 +79,12 @@ class BuildParameters { // --- return { - version: unityVersion, + editorVersion, customImage: Input.customImage, unitySerial, runnerTempPath: process.env.RUNNER_TEMP, - platform: Input.targetPlatform, + targetPlatform: Input.targetPlatform, projectPath: Input.projectPath, buildName: Input.buildName, buildPath: `${Input.buildsPath}/${Input.targetPlatform}`, @@ -116,6 +116,7 @@ class BuildParameters { customJob: Input.customJob, runNumber: Input.runNumber, branch: await Input.branch(), + // Todo - move this out of UserInput and into some class that determines additional information (as needed) githubRepo: await Input.githubRepo(), remoteBuildCluster: Input.cloudRunnerCluster, awsStackName: Input.awsBaseStackName, diff --git a/src/model/cloud-runner/k8s/kubernetes-job-spec-factory.ts b/src/model/cloud-runner/k8s/kubernetes-job-spec-factory.ts index 9b4765af..cfee9b93 100644 --- a/src/model/cloud-runner/k8s/kubernetes-job-spec-factory.ts +++ b/src/model/cloud-runner/k8s/kubernetes-job-spec-factory.ts @@ -60,7 +60,7 @@ class KubernetesJobSpecFactory { }, { name: 'BUILD_TARGET', - value: buildParameters.platform, + value: buildParameters.targetPlatform, }, { name: 'ANDROID_VERSION_CODE', diff --git a/src/model/cloud-runner/services/task-parameter-serializer.ts b/src/model/cloud-runner/services/task-parameter-serializer.ts index e1bdcc4a..5e85a34a 100644 --- a/src/model/cloud-runner/services/task-parameter-serializer.ts +++ b/src/model/cloud-runner/services/task-parameter-serializer.ts @@ -18,7 +18,7 @@ export class TaskParameterSerializer { }, { name: 'BUILD_TARGET', - value: CloudRunnerState.buildParams.platform, + value: CloudRunnerState.buildParams.targetPlatform, }, ...TaskParameterSerializer.serializeBuildParamsAndInput, ]; diff --git a/src/model/image-environment-factory.ts b/src/model/image-environment-factory.ts index b8620c7c..f9a7dfb9 100644 --- a/src/model/image-environment-factory.ts +++ b/src/model/image-environment-factory.ts @@ -30,10 +30,10 @@ class ImageEnvironmentFactory { { name: 'UNITY_EMAIL', value: process.env.UNITY_EMAIL }, { name: 'UNITY_PASSWORD', value: process.env.UNITY_PASSWORD }, { name: 'UNITY_SERIAL', value: parameters.unitySerial }, - { name: 'UNITY_VERSION', value: parameters.version }, + { name: 'UNITY_VERSION', value: parameters.editorVersion }, { name: 'USYM_UPLOAD_AUTH_TOKEN', value: process.env.USYM_UPLOAD_AUTH_TOKEN }, { name: 'PROJECT_PATH', value: parameters.projectPath }, - { name: 'BUILD_TARGET', value: parameters.platform }, + { name: 'BUILD_TARGET', value: parameters.targetPlatform }, { name: 'BUILD_NAME', value: parameters.buildName }, { name: 'BUILD_PATH', value: parameters.buildPath }, { name: 'BUILD_FILE', value: parameters.buildFile }, diff --git a/src/model/image-tag.test.ts b/src/model/image-tag.test.ts index 62d6e24b..f7ac2e2b 100644 --- a/src/model/image-tag.test.ts +++ b/src/model/image-tag.test.ts @@ -2,10 +2,8 @@ import ImageTag from './image-tag'; describe('ImageTag', () => { const some = { - repository: 'test1', - name: 'test2', - version: '2099.9.f9f9', - platform: 'Test', + editorVersion: '2099.9.f9f9', + targetPlatform: 'Test', builderPlatform: '', }; @@ -17,50 +15,51 @@ describe('ImageTag', () => { describe('constructor', () => { it('can be called', () => { - const { platform } = some; - expect(() => new ImageTag({ platform })).not.toThrow(); + const { targetPlatform } = some; + + expect(() => new ImageTag({ targetPlatform })).not.toThrow(); }); it('accepts parameters and sets the right properties', () => { const image = new ImageTag(some); - expect(image.repository).toStrictEqual(some.repository); - expect(image.name).toStrictEqual(some.name); - expect(image.version).toStrictEqual(some.version); - expect(image.platform).toStrictEqual(some.platform); + expect(image.repository).toStrictEqual('unityci'); + expect(image.name).toStrictEqual('editor'); + expect(image.editorVersion).toStrictEqual(some.editorVersion); + expect(image.targetPlatform).toStrictEqual(some.targetPlatform); expect(image.builderPlatform).toStrictEqual(some.builderPlatform); }); test.each(['2000.0.0f0', '2011.1.11f1'])('accepts %p version format', (version) => { - expect(() => new ImageTag({ version, platform: some.platform })).not.toThrow(); + expect(() => new ImageTag({ editorVersion: version, targetPlatform: some.targetPlatform })).not.toThrow(); }); - test.each(['some version', '', 1])('throws for incorrect versions %p', (version) => { - const { platform } = some; - expect(() => new ImageTag({ version, platform })).toThrow(); + test.each(['some version', ''])('throws for incorrect version %p', (editorVersion) => { + const { targetPlatform } = some; + expect(() => new ImageTag({ editorVersion, targetPlatform })).toThrow(); }); - test.each([undefined, 'nonExisting'])('throws for unsupported target %p', (platform) => { - expect(() => new ImageTag({ platform })).toThrow(); + test.each([undefined, 'nonExisting'])('throws for unsupported target %p', (targetPlatform) => { + expect(() => new ImageTag({ targetPlatform })).toThrow(); }); }); describe('toString', () => { it('returns the correct version', () => { - const image = new ImageTag({ version: '2099.1.1111', platform: some.platform }); + const image = new ImageTag({ editorVersion: '2099.1.1111', targetPlatform: some.targetPlatform }); switch (process.platform) { case 'win32': - expect(image.toString()).toStrictEqual(`${defaults.image}:windows-2099.1.1111-0`); + expect(image.toString()).toStrictEqual(`${defaults.image}:windows-2099.1.1111-1`); break; case 'linux': - expect(image.toString()).toStrictEqual(`${defaults.image}:2099.1.1111-0`); + expect(image.toString()).toStrictEqual(`${defaults.image}:ubuntu-2099.1.1111-1`); break; } }); it('returns customImage if given', () => { const image = new ImageTag({ - version: '2099.1.1111', - platform: some.platform, + editorVersion: '2099.1.1111', + targetPlatform: some.targetPlatform, customImage: `${defaults.image}:2099.1.1111@347598437689743986`, }); @@ -68,27 +67,27 @@ describe('ImageTag', () => { }); it('returns the specific build platform', () => { - const image = new ImageTag({ version: '2019.2.11f1', platform: 'WebGL' }); + const image = new ImageTag({ editorVersion: '2019.2.11f1', targetPlatform: 'WebGL' }); switch (process.platform) { case 'win32': - expect(image.toString()).toStrictEqual(`${defaults.image}:windows-2019.2.11f1-webgl-0`); + expect(image.toString()).toStrictEqual(`${defaults.image}:windows-2019.2.11f1-webgl-1`); break; case 'linux': - expect(image.toString()).toStrictEqual(`${defaults.image}:2019.2.11f1-webgl-0`); + expect(image.toString()).toStrictEqual(`${defaults.image}:ubuntu-2019.2.11f1-webgl-1`); break; } }); it('returns no specific build platform for generic targetPlatforms', () => { - const image = new ImageTag({ platform: 'NoTarget' }); + const image = new ImageTag({ targetPlatform: 'NoTarget' }); switch (process.platform) { case 'win32': - expect(image.toString()).toStrictEqual(`${defaults.image}:windows-2019.2.11f1-0`); + expect(image.toString()).toStrictEqual(`${defaults.image}:windows-2019.2.11f1-1`); break; case 'linux': - expect(image.toString()).toStrictEqual(`${defaults.image}:2019.2.11f1-0`); + expect(image.toString()).toStrictEqual(`${defaults.image}:ubuntu-2019.2.11f1-1`); break; } }); diff --git a/src/model/image-tag.ts b/src/model/image-tag.ts index 72f9f742..a28cf265 100644 --- a/src/model/image-tag.ts +++ b/src/model/image-tag.ts @@ -1,35 +1,42 @@ import Platform from './platform'; +import BuildParameters from './build-parameters'; class ImageTag { public repository: string; public name: string; - public version: string; - public platform: any; + public editorVersion: string; + public targetPlatform: any; public builderPlatform: string; public customImage: any; + public imageRollingVersion: number; + public imagePlatformPrefix: string; - constructor(imageProperties) { - const { repository = 'unityci', name = 'editor', version = '2019.2.11f1', platform, customImage } = imageProperties; + constructor(imageProperties: Partial) { + const { editorVersion = '2019.2.11f1', targetPlatform, customImage } = imageProperties; - if (!ImageTag.versionPattern.test(version)) { - throw new Error(`Invalid version "${version}".`); + if (!ImageTag.versionPattern.test(editorVersion)) { + throw new Error(`Invalid version "${editorVersion}".`); } - const builderPlatform = ImageTag.getTargetPlatformToImageSuffixMap(platform, version); - - this.repository = repository; - this.name = name; - this.version = version; - this.platform = platform; - this.builderPlatform = builderPlatform; + // Todo we might as well skip this class for customImage. + // Either this.customImage = customImage; + + // Or + this.repository = 'unityci'; + this.name = 'editor'; + this.editorVersion = editorVersion; + this.targetPlatform = targetPlatform; + this.builderPlatform = ImageTag.getTargetPlatformToTargetPlatformSuffixMap(targetPlatform, editorVersion); + this.imagePlatformPrefix = ImageTag.getImagePlatformPrefixes(process.platform); + this.imageRollingVersion = 1; // will automatically roll to the latest non-breaking version. } static get versionPattern() { return /^20\d{2}\.\d\.\w{3,4}|3$/; } - static get imageSuffixes() { + static get targetPlatformSuffixes() { return { generic: '', webgl: 'webgl', @@ -46,9 +53,20 @@ class ImageTag { }; } - static getTargetPlatformToImageSuffixMap(platform, version) { + static getImagePlatformPrefixes(platform) { + switch (platform) { + case 'win32': + return 'windows'; + case 'linux': + return 'ubuntu'; + default: + throw new Error('The Operating System of this runner is not yet supported.'); + } + } + + static getTargetPlatformToTargetPlatformSuffixMap(platform, version) { const { generic, webgl, mac, windows, windowsIl2cpp, wsaPlayer, linux, linuxIl2cpp, android, ios, tvos, facebook } = - ImageTag.imageSuffixes; + ImageTag.targetPlatformSuffixes; const [major, minor] = version.split('.').map((digit) => Number(digit)); // @see: https://docs.unity3d.com/ScriptReference/BuildTarget.html @@ -120,15 +138,9 @@ class ImageTag { } get tag() { - //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; - } + const versionAndPlatform = `${this.editorVersion}-${this.builderPlatform}`.replace(/-+$/, ''); + + return `${this.imagePlatformPrefix}-${versionAndPlatform}-${this.imageRollingVersion}`; } get image() { @@ -138,11 +150,9 @@ class ImageTag { toString() { const { image, tag, customImage } = this; - if (customImage && customImage !== '') { - return customImage; - } + if (customImage) return customImage; - return `${image}:${tag}-0`; // '0' here represents the docker repo version + return `${image}:${tag}`; // '0' here represents the docker repo version } } diff --git a/src/model/input.ts b/src/model/input.ts index cee2ec47..2c52abd9 100644 --- a/src/model/input.ts +++ b/src/model/input.ts @@ -10,6 +10,8 @@ const core = require('@actions/core'); * Input variables specified in workflows using "with" prop. * * Note that input is always passed as a string, even booleans. + * + * Todo: rename to UserInput and remove anything that is not direct input from the user / ci workflow */ class Input { public static cliOptions; @@ -19,6 +21,7 @@ class Input { static get cloudRunnerTests(): boolean { return Input.getInput(`cloudRunnerTests`) || Input.getInput(`CloudRunnerTests`) || false; } + private static getInput(query) { const coreInput = core.getInput(query); if (Input.githubInputEnabled && coreInput && coreInput !== '') { @@ -33,19 +36,24 @@ class Input { ? process.env[Input.ToEnvVarFormat(query)] : ''; } + static get region(): string { return Input.getInput('region') || 'eu-west-2'; } + static async githubRepo() { return ( Input.getInput('GITHUB_REPOSITORY') || Input.getInput('GITHUB_REPO') || + // todo - move this to some class specific for determining additional information (await GitRepoReader.GetRemote()) || 'game-ci/unity-builder' ); } + static async branch() { if (await GitRepoReader.GetBranch()) { + // todo - move this to some class specific for determining additional information return await GitRepoReader.GetBranch(); } else if (Input.getInput(`GITHUB_REF`)) { return Input.getInput(`GITHUB_REF`).replace('refs/', '').replace(`head/`, ''); @@ -62,9 +70,11 @@ class Input { } else if (Input.getInput(`GitSHA`)) { return Input.getInput(`GitSHA`); } else if (GitRepoReader.GetSha()) { + // todo - move this to some class specific for determining additional information return GitRepoReader.GetSha(); } } + static get runNumber() { return Input.getInput('GITHUB_RUN_NUMBER') || '0'; } @@ -89,6 +99,7 @@ class Input { !fs.existsSync(path.join('ProjectSettings', 'ProjectVersion.txt')) ? 'test-project' : '.'; + return rawProjectPath.replace(/\/$/, ''); } @@ -197,6 +208,7 @@ class Input { } static async githubToken() { + // Todo - move GitHubCLI out of the simple input class. It is in fact not input from the user. return Input.getInput('githubToken') || (await GithubCliReader.GetGitHubAuthToken()) || ''; } diff --git a/src/model/platform-setup/setup-mac.ts b/src/model/platform-setup/setup-mac.ts index 33175424..beb55195 100644 --- a/src/model/platform-setup/setup-mac.ts +++ b/src/model/platform-setup/setup-mac.ts @@ -7,7 +7,7 @@ class SetupMac { static unityHubPath = `"/Applications/Unity Hub.app/Contents/MacOS/Unity Hub"`; public static async setup(buildParameters: BuildParameters, actionFolder: string) { - const unityEditorPath = `/Applications/Unity/Hub/Editor/${buildParameters.version}/Unity.app/Contents/MacOS/Unity`; + const unityEditorPath = `/Applications/Unity/Hub/Editor/${buildParameters.editorVersion}/Unity.app/Contents/MacOS/Unity`; // Only install unity if the editor doesn't already exist if (!fs.existsSync(unityEditorPath)) { @@ -31,9 +31,9 @@ class SetupMac { } private static async installUnity(buildParameters: BuildParameters, silent = false) { - const unityChangeset = await getUnityChangeset(buildParameters.version); + const unityChangeset = await getUnityChangeset(buildParameters.editorVersion); const command = `${this.unityHubPath} -- --headless install \ - --version ${buildParameters.version} \ + --version ${buildParameters.editorVersion} \ --changeset ${unityChangeset.changeset} \ --module mac-il2cpp \ --childModules`; @@ -50,10 +50,10 @@ class SetupMac { // Need to set environment variables from here because we execute // the scripts on the host for mac process.env.ACTION_FOLDER = actionFolder; - process.env.UNITY_VERSION = buildParameters.version; + process.env.UNITY_VERSION = buildParameters.editorVersion; process.env.UNITY_SERIAL = buildParameters.unitySerial; process.env.PROJECT_PATH = buildParameters.projectPath; - process.env.BUILD_TARGET = buildParameters.platform; + process.env.BUILD_TARGET = buildParameters.targetPlatform; process.env.BUILD_NAME = buildParameters.buildName; process.env.BUILD_PATH = buildParameters.buildPath; process.env.BUILD_FILE = buildParameters.buildFile; diff --git a/src/model/platform-setup/setup-windows.ts b/src/model/platform-setup/setup-windows.ts index ae38acbf..12f5a612 100644 --- a/src/model/platform-setup/setup-windows.ts +++ b/src/model/platform-setup/setup-windows.ts @@ -4,26 +4,27 @@ import { BuildParameters } from '..'; class SetupWindows { public static async setup(buildParameters: BuildParameters) { - await SetupWindows.setupWindowsRun(buildParameters.platform); + const { targetPlatform } = buildParameters; + + await SetupWindows.setupWindowsRun(targetPlatform); } - //Setup prerequisite files/folders for a windows-based docker run - private static async setupWindowsRun(platform, silent = false) { + private static async setupWindowsRun(targetPlatform, silent = false) { if (!fs.existsSync('c:/regkeys')) { fs.mkdirSync('c:/regkeys'); } - switch (platform) { + switch (targetPlatform) { //These all need the Windows 10 SDK case 'StandaloneWindows': case 'StandaloneWindows64': case 'WSAPlayer': - this.generateWinSDKRegKeys(silent); + await this.generateWinSDKRegKeys(silent); break; } } private static async generateWinSDKRegKeys(silent = false) { - // Export registry keys that point to the location of the windows 10 sdk + // Export registry keys that point to 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 }); diff --git a/src/model/platform-validation/validate-windows.ts b/src/model/platform-validation/validate-windows.ts index c05b1e62..904502d2 100644 --- a/src/model/platform-validation/validate-windows.ts +++ b/src/model/platform-validation/validate-windows.ts @@ -3,7 +3,7 @@ import { BuildParameters } from '..'; class ValidateWindows { public static validate(buildParameters: BuildParameters) { - ValidateWindows.validateWindowsPlatformRequirements(buildParameters.platform); + ValidateWindows.validateWindowsPlatformRequirements(buildParameters.targetPlatform); 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 diff --git a/src/model/versioning.test.ts b/src/model/versioning.test.ts index 84f1f550..a5760562 100644 --- a/src/model/versioning.test.ts +++ b/src/model/versioning.test.ts @@ -116,7 +116,7 @@ describe('Versioning', () => { }); }); - describe('descriptionRegex', () => { + describe('descriptionRegex1', () => { it('is a valid regex', () => { expect(Versioning.descriptionRegex1).toBeInstanceOf(RegExp); }); @@ -137,19 +137,19 @@ describe('Versioning', () => { test.each(['v0', 'v0.1', 'v0.1.2', 'v0.1-2', 'v0.1-2-g'])('does not like %s', (description) => { expect(Versioning.descriptionRegex1.test(description)).toBeFalsy(); - // Also never expect without the v to work for any of these cases. + // Also, never expect without the v to work for any of these cases. expect(Versioning.descriptionRegex1.test(description?.slice(1))).toBeFalsy(); }); }); - describe('determineVersion', () => { + describe('determineBuildVersion', () => { test.each(['somethingRandom'])('throws for invalid strategy %s', async (strategy) => { - await expect(Versioning.determineVersion(strategy, '')).rejects.toThrowErrorMatchingSnapshot(); + await expect(Versioning.determineBuildVersion(strategy, '')).rejects.toThrowErrorMatchingSnapshot(); }); describe('opt out strategy', () => { it("returns 'none'", async () => { - await expect(Versioning.determineVersion('None', 'v1.0')).resolves.toMatchInlineSnapshot(`"none"`); + await expect(Versioning.determineBuildVersion('None', 'v1.0')).resolves.toMatchInlineSnapshot(`"none"`); }); }); @@ -157,7 +157,7 @@ describe('Versioning', () => { test.each(['v0.1', '1', 'CamelCase', 'dashed-version'])( 'returns the inputVersion for %s', async (inputVersion) => { - await expect(Versioning.determineVersion('Custom', inputVersion)).resolves.toStrictEqual(inputVersion); + await expect(Versioning.determineBuildVersion('Custom', inputVersion)).resolves.toStrictEqual(inputVersion); }, ); }); @@ -166,7 +166,7 @@ describe('Versioning', () => { it('refers to generateSemanticVersion', async () => { const generateSemanticVersion = jest.spyOn(Versioning, 'generateSemanticVersion').mockResolvedValue('1.3.37'); - await expect(Versioning.determineVersion('Semantic', '')).resolves.toStrictEqual('1.3.37'); + await expect(Versioning.determineBuildVersion('Semantic', '')).resolves.toStrictEqual('1.3.37'); expect(generateSemanticVersion).toHaveBeenCalledTimes(1); }); }); @@ -175,7 +175,7 @@ describe('Versioning', () => { it('refers to generateTagVersion', async () => { const generateTagVersion = jest.spyOn(Versioning, 'generateTagVersion').mockResolvedValue('0.1'); - await expect(Versioning.determineVersion('Tag', '')).resolves.toStrictEqual('0.1'); + await expect(Versioning.determineBuildVersion('Tag', '')).resolves.toStrictEqual('0.1'); expect(generateTagVersion).toHaveBeenCalledTimes(1); }); }); @@ -185,7 +185,7 @@ describe('Versioning', () => { const strategy = 'Test'; // @ts-ignore jest.spyOn(Versioning, 'strategies', 'get').mockReturnValue({ [strategy]: strategy }); - await expect(Versioning.determineVersion(strategy, '')).rejects.toThrowError(NotImplementedException); + await expect(Versioning.determineBuildVersion(strategy, '')).rejects.toThrowError(NotImplementedException); }); }); }); diff --git a/src/model/versioning.ts b/src/model/versioning.ts index 79f43749..210d5b37 100644 --- a/src/model/versioning.ts +++ b/src/model/versioning.ts @@ -79,7 +79,7 @@ export default class Versioning { return /^v?([\d.]+-\w+\.\d+)-(\d+)-g(\w+)-?(\w+)*/g; } - static async determineVersion(strategy: string, inputVersion: string) { + static async determineBuildVersion(strategy: string, inputVersion: string) { // Validate input if (!Object.hasOwnProperty.call(this.strategies, strategy)) { throw new ValidationError(`Versioning strategy should be one of ${Object.values(this.strategies).join(', ')}.`);