feat: cleanup parameters part 1/*
parent
bfb847dc81
commit
fa479f532a
|
|
@ -5,6 +5,7 @@ import { CommandFactory } from './commands/command-factory.ts';
|
|||
import { ArgumentsParser } from './core/cli/arguments-parser.ts';
|
||||
import { Environment } from './core/env/environment.ts';
|
||||
import { EngineDetector } from './core/engine/engine-detector.ts';
|
||||
import { ParameterOptions } from './model/parameter-options.ts';
|
||||
|
||||
export class GameCI {
|
||||
private readonly env: Environment;
|
||||
|
|
@ -20,6 +21,10 @@ export class GameCI {
|
|||
const { commandName, subCommands, args, verbosity } = new ArgumentsParser().parse(this.args);
|
||||
await configureLogger(verbosity);
|
||||
|
||||
// Todo - set default values for parameters to restore functionality.
|
||||
// Todo - investigate how fitting a CLI lib will be for us
|
||||
// (now that things are starting to be more separated)
|
||||
|
||||
// Determine which command to run
|
||||
const { engine, engineVersion } = await new EngineDetector(subCommands, args).detect();
|
||||
const command = new CommandFactory().selectEngine(engine, engineVersion).createCommand(commandName, subCommands);
|
||||
|
|
|
|||
|
|
@ -43,29 +43,29 @@ class SetupMac {
|
|||
}
|
||||
}
|
||||
|
||||
private static async setEnvironmentVariables(buildParameters: Parameters, actionFolder: string) {
|
||||
private static async setEnvironmentVariables(parameters: Parameters, actionFolder: string) {
|
||||
// Need to set environment variables from here because we execute
|
||||
// the scripts on the host for mac
|
||||
Deno.env.set('ACTION_FOLDER', actionFolder);
|
||||
Deno.env.set('UNITY_VERSION', buildParameters.editorVersion);
|
||||
Deno.env.set('UNITY_SERIAL', buildParameters.unitySerial);
|
||||
Deno.env.set('PROJECT_PATH', buildParameters.projectPath);
|
||||
Deno.env.set('BUILD_TARGET', buildParameters.targetPlatform);
|
||||
Deno.env.set('BUILD_NAME', buildParameters.buildName);
|
||||
Deno.env.set('BUILD_PATH', buildParameters.buildPath);
|
||||
Deno.env.set('BUILD_FILE', buildParameters.buildFile);
|
||||
Deno.env.set('BUILD_METHOD', buildParameters.buildMethod);
|
||||
Deno.env.set('VERSION', buildParameters.buildVersion);
|
||||
Deno.env.set('ANDROID_VERSION_CODE', buildParameters.androidVersionCode);
|
||||
Deno.env.set('ANDROID_KEYSTORE_NAME', buildParameters.androidKeystoreName);
|
||||
Deno.env.set('ANDROID_KEYSTORE_BASE64', buildParameters.androidKeystoreBase64);
|
||||
Deno.env.set('ANDROID_KEYSTORE_PASS', buildParameters.androidKeystorePass);
|
||||
Deno.env.set('ANDROID_KEYALIAS_NAME', buildParameters.androidKeyaliasName);
|
||||
Deno.env.set('ANDROID_KEYALIAS_PASS', buildParameters.androidKeyaliasPass);
|
||||
Deno.env.set('ANDROID_TARGET_SDK_VERSION', buildParameters.androidTargetSdkVersion);
|
||||
Deno.env.set('ANDROID_SDK_MANAGER_PARAMETERS', buildParameters.androidSdkManagerParameters);
|
||||
Deno.env.set('CUSTOM_PARAMETERS', buildParameters.customParameters);
|
||||
Deno.env.set('CHOWN_FILES_TO', buildParameters.chownFilesTo);
|
||||
Deno.env.set('UNITY_VERSION', parameters.editorVersion);
|
||||
Deno.env.set('UNITY_SERIAL', parameters.unitySerial);
|
||||
Deno.env.set('PROJECT_PATH', parameters.projectPath);
|
||||
Deno.env.set('BUILD_TARGET', parameters.targetPlatform);
|
||||
Deno.env.set('BUILD_NAME', parameters.buildName);
|
||||
Deno.env.set('BUILD_PATH', parameters.buildPath);
|
||||
Deno.env.set('BUILD_FILE', parameters.buildFile);
|
||||
Deno.env.set('BUILD_METHOD', parameters.buildMethod);
|
||||
Deno.env.set('VERSION', parameters.buildVersion);
|
||||
Deno.env.set('ANDROID_VERSION_CODE', parameters.androidVersionCode);
|
||||
Deno.env.set('ANDROID_KEYSTORE_NAME', parameters.androidKeystoreName);
|
||||
Deno.env.set('ANDROID_KEYSTORE_BASE64', parameters.androidKeystoreBase64);
|
||||
Deno.env.set('ANDROID_KEYSTORE_PASS', parameters.androidKeystorePass);
|
||||
Deno.env.set('ANDROID_KEYALIAS_NAME', parameters.androidKeyaliasName);
|
||||
Deno.env.set('ANDROID_KEYALIAS_PASS', parameters.androidKeyaliasPass);
|
||||
Deno.env.set('ANDROID_TARGET_SDK_VERSION', parameters.androidTargetSdkVersion);
|
||||
Deno.env.set('ANDROID_SDK_MANAGER_PARAMETERS', parameters.androidSdkManagerParameters);
|
||||
Deno.env.set('CUSTOM_PARAMETERS', parameters.customParameters);
|
||||
Deno.env.set('CHOWN_FILES_TO', parameters.chownFilesTo);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -93,9 +93,7 @@ describe('BuildParameters', () => {
|
|||
async (targetPlatform) => {
|
||||
jest.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(targetPlatform);
|
||||
jest.spyOn(Input, 'buildName', 'get').mockReturnValue(targetPlatform);
|
||||
expect(Parameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ buildFile: `${targetPlatform}.exe` }),
|
||||
);
|
||||
expect(Parameters.create()).resolves.toEqual(expect.objectContaining({ buildFile: `${targetPlatform}.exe` }));
|
||||
},
|
||||
);
|
||||
|
||||
|
|
@ -103,18 +101,14 @@ describe('BuildParameters', () => {
|
|||
jest.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(targetPlatform);
|
||||
jest.spyOn(Input, 'buildName', 'get').mockReturnValue(targetPlatform);
|
||||
jest.spyOn(Input, 'androidAppBundle', 'get').mockReturnValue(false);
|
||||
expect(Parameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ buildFile: `${targetPlatform}.apk` }),
|
||||
);
|
||||
expect(Parameters.create()).resolves.toEqual(expect.objectContaining({ buildFile: `${targetPlatform}.apk` }));
|
||||
});
|
||||
|
||||
test.each([Platform.types.Android])('appends aab for %s', async (targetPlatform) => {
|
||||
jest.spyOn(Input, 'targetPlatform', 'get').mockReturnValue(targetPlatform);
|
||||
jest.spyOn(Input, 'buildName', 'get').mockReturnValue(targetPlatform);
|
||||
jest.spyOn(Input, 'androidAppBundle', 'get').mockReturnValue(true);
|
||||
expect(Parameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ buildFile: `${targetPlatform}.aab` }),
|
||||
);
|
||||
expect(Parameters.create()).resolves.toEqual(expect.objectContaining({ buildFile: `${targetPlatform}.aab` }));
|
||||
});
|
||||
|
||||
it('returns the build method', async () => {
|
||||
|
|
@ -156,9 +150,7 @@ describe('BuildParameters', () => {
|
|||
it('returns the android target sdk version', async () => {
|
||||
const mockValue = 'AndroidApiLevelAuto';
|
||||
jest.spyOn(Input, 'androidTargetSdkVersion', 'get').mockReturnValue(mockValue);
|
||||
expect(Parameters.create()).resolves.toEqual(
|
||||
expect.objectContaining({ androidTargetSdkVersion: mockValue }),
|
||||
);
|
||||
expect(Parameters.create()).resolves.toEqual(expect.objectContaining({ androidTargetSdkVersion: mockValue }));
|
||||
});
|
||||
|
||||
it('returns the custom parameters', async () => {
|
||||
|
|
|
|||
|
|
@ -3,19 +3,43 @@ import { path, fsSync as fs } from '../dependencies.ts';
|
|||
import System from './system.ts';
|
||||
|
||||
class Docker {
|
||||
static async run(image, parameters, silent = false) {
|
||||
log.warning('running docker process for', process.platform, silent);
|
||||
static async run(image, parameters) {
|
||||
log.warning('running docker process for', process.platform);
|
||||
let command = '';
|
||||
switch (process.platform) {
|
||||
switch (Deno.build.os) {
|
||||
case 'windows': {
|
||||
// Todo: check if docker daemon is set for Windows or Linux containers.
|
||||
command = await this.getWindowsCommand(image, parameters);
|
||||
break;
|
||||
}
|
||||
case 'linux':
|
||||
case 'darwin': {
|
||||
command = await this.getLinuxCommand(image, parameters);
|
||||
break;
|
||||
case 'win32':
|
||||
command = await this.getWindowsCommand(image, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
const test = await System.newRun(`docker`, command.replace(/\s\s+/, ' ').split(' '), { silent, verbose: true });
|
||||
log.error('test', test);
|
||||
try {
|
||||
const test = await System.run(command, { attach: true });
|
||||
log.warning('test', test);
|
||||
} catch (error) {
|
||||
if (error.message.includes('docker: image operating system "windows" cannot be used on this platform')) {
|
||||
throw new Error(String.dedent`
|
||||
Docker daemon is not set to run Windows containers.
|
||||
|
||||
To enable the Hyper-V container backend run:
|
||||
Enable-WindowsOptionalFeature -Online -FeatureName $("Microsoft-Hyper-V", "Containers") -All
|
||||
|
||||
To switch the docker daemon to run Windows containers run:
|
||||
& $Env:ProgramFiles\\Docker\\Docker\\DockerCli.exe -SwitchDaemon .
|
||||
|
||||
For more information see:
|
||||
https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/set-up-environment?tabs=dockerce#prerequisites
|
||||
`);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
static async getLinuxCommand(image, parameters): string {
|
||||
|
|
@ -28,8 +52,8 @@ class Docker {
|
|||
|
||||
return String.dedent`
|
||||
docker run \
|
||||
--workdir /github/workspace \
|
||||
--rm \
|
||||
--workdir /github/workspace \
|
||||
${ImageEnvironmentFactory.getEnvVarString(parameters)} \
|
||||
--env UNITY_SERIAL \
|
||||
--env GITHUB_WORKSPACE=/github/workspace \
|
||||
|
|
@ -51,25 +75,23 @@ class Docker {
|
|||
static async getWindowsCommand(image: any, parameters: any): string {
|
||||
const { workspace, actionFolder, unitySerial, gitPrivateToken, cliStoragePath } = parameters;
|
||||
|
||||
// Todo - get this to work on a non-github runner local machine
|
||||
// Note: difference between `docker run` and `run`
|
||||
return String.dedent`run ${image} powershell c:/steps/entrypoint.ps1`;
|
||||
// Note: the equals sign (=) is needed in Powershell.
|
||||
return String.dedent`
|
||||
docker run \
|
||||
--workdir /github/workspace \
|
||||
--rm \
|
||||
--workdir="c:/github/workspace" \
|
||||
${ImageEnvironmentFactory.getEnvVarString(parameters)} \
|
||||
--env UNITY_SERIAL="${unitySerial}" \
|
||||
--env GITHUB_WORKSPACE=c:/github/workspace \
|
||||
${gitPrivateToken ? `--env GIT_PRIVATE_TOKEN="${gitPrivateToken}"` : ''} \
|
||||
--volume "${workspace}":"c:/github/workspace" \
|
||||
--volume "${cliStoragePath}/registry-keys":"c:/registry-keys" \
|
||||
--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" \
|
||||
--volume "${actionFolder}/default-build-script":"c:/UnityBuilderAction" \
|
||||
--volume "${actionFolder}/platforms/windows":"c:/steps" \
|
||||
--volume "${actionFolder}/BlankProject":"c:/BlankProject" \
|
||||
--env GIT_PRIVATE_TOKEN="${gitPrivateToken}" \
|
||||
--volume="${workspace}":"c:/github/workspace" \
|
||||
--volume="${cliStoragePath}/registry-keys":"c:/registry-keys" \
|
||||
--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" \
|
||||
--volume="${actionFolder}/default-build-script":"c:/UnityBuilderAction" \
|
||||
--volume="${actionFolder}/platforms/windows":"c:/steps" \
|
||||
--volume="${actionFolder}/BlankProject":"c:/BlankProject" \
|
||||
${image} \
|
||||
powershell c:/steps/entrypoint.ps1
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -21,15 +21,12 @@ class Input {
|
|||
return this;
|
||||
}
|
||||
|
||||
// Todo - read something from environment instead and make that into a parameter, then use that.
|
||||
public static githubInputEnabled: boolean = true;
|
||||
|
||||
// Todo - Note that this is now invoked both statically and dynamically - which is a temporary mess.
|
||||
public getInput(query: string) {
|
||||
public get(query: string) {
|
||||
if (this && this.arguments) {
|
||||
const value = this.arguments.get(query);
|
||||
|
||||
if (log.isVeryVerbose) log.debug('arg', query, '=', value);
|
||||
|
||||
return this.arguments.get(query);
|
||||
}
|
||||
|
||||
|
|
@ -64,25 +61,25 @@ class Input {
|
|||
}
|
||||
|
||||
public get region(): string {
|
||||
return this.getInput('region') || 'eu-west-2';
|
||||
return this.get('region');
|
||||
}
|
||||
|
||||
public get githubRepo() {
|
||||
return this.getInput('GITHUB_REPOSITORY') || this.getInput('GITHUB_REPO') || undefined;
|
||||
return this.get('GITHUB_REPOSITORY') || this.get('GITHUB_REPO') || undefined;
|
||||
}
|
||||
|
||||
public get branch() {
|
||||
if (this.getInput(`GITHUB_REF`)) {
|
||||
return this.getInput(`GITHUB_REF`).replace('refs/', '').replace(`head/`, '').replace(`heads/`, '');
|
||||
} else if (this.getInput('branch')) {
|
||||
return this.getInput('branch').replace('/head', '');
|
||||
if (this.get(`GITHUB_REF`)) {
|
||||
return this.get(`GITHUB_REF`).replace('refs/', '').replace(`head/`, '').replace(`heads/`, '');
|
||||
} else if (this.get('branch')) {
|
||||
return this.get('branch').replace('/head', '');
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
public get cloudRunnerBuilderPlatform() {
|
||||
const input = this.getInput('cloudRunnerBuilderPlatform');
|
||||
const input = this.get('cloudRunnerBuilderPlatform');
|
||||
if (input) {
|
||||
return input;
|
||||
}
|
||||
|
|
@ -94,55 +91,55 @@ class Input {
|
|||
}
|
||||
|
||||
public get gitSha() {
|
||||
if (this.getInput(`GITHUB_SHA`)) {
|
||||
return this.getInput(`GITHUB_SHA`);
|
||||
} else if (this.getInput(`GitSHA`)) {
|
||||
return this.getInput(`GitSHA`);
|
||||
if (this.get(`GITHUB_SHA`)) {
|
||||
return this.get(`GITHUB_SHA`);
|
||||
} else if (this.get(`GitSHA`)) {
|
||||
return this.get(`GitSHA`);
|
||||
}
|
||||
}
|
||||
|
||||
public get runNumber() {
|
||||
return this.getInput('GITHUB_RUN_NUMBER') || '0';
|
||||
return this.get('GITHUB_RUN_NUMBER') || '0';
|
||||
}
|
||||
|
||||
public get targetPlatform() {
|
||||
return this.getInput('targetPlatform') || Platform.default;
|
||||
return this.get('targetPlatform') || Platform.default;
|
||||
}
|
||||
|
||||
public get unityVersion() {
|
||||
return this.getInput('unityVersion') || 'auto';
|
||||
return this.get('unityVersion') || 'auto';
|
||||
}
|
||||
|
||||
public get unityEmail() {
|
||||
return this.getInput('unityEmail') || '';
|
||||
return this.get('unityEmail') || '';
|
||||
}
|
||||
|
||||
public get unityPassword() {
|
||||
return this.getInput('unityPassword') || '';
|
||||
return this.get('unityPassword') || '';
|
||||
}
|
||||
|
||||
public get unityLicense() {
|
||||
return this.getInput('unityLicense') || '';
|
||||
return this.get('unityLicense') || '';
|
||||
}
|
||||
|
||||
public get unityLicenseFile() {
|
||||
return this.getInput('unityLicenseFile') || '';
|
||||
return this.get('unityLicenseFile') || '';
|
||||
}
|
||||
|
||||
public get unitySerial() {
|
||||
return this.getInput('unitySerial') || '';
|
||||
return this.get('unitySerial') || '';
|
||||
}
|
||||
|
||||
public get usymUploadAuthToken() {
|
||||
return this.getInput('usymUploadAuthToken') || '';
|
||||
return this.get('usymUploadAuthToken') || '';
|
||||
}
|
||||
|
||||
public get customImage() {
|
||||
return this.getInput('customImage') || '';
|
||||
return this.get('customImage') || '';
|
||||
}
|
||||
|
||||
public get projectPath() {
|
||||
let input = this.getInput('projectPath');
|
||||
let input = this.get('projectPath');
|
||||
|
||||
// Todo - remove hardcoded test project reference
|
||||
const isTestProject =
|
||||
|
|
@ -156,172 +153,169 @@ class Input {
|
|||
}
|
||||
|
||||
public get buildName() {
|
||||
return this.getInput('buildName') || this.targetPlatform;
|
||||
return this.get('buildName');
|
||||
}
|
||||
|
||||
public get buildsPath() {
|
||||
return this.getInput('buildsPath') || 'build';
|
||||
return this.get('buildsPath') || 'build';
|
||||
}
|
||||
|
||||
public get buildMethod() {
|
||||
return this.getInput('buildMethod') || ''; // Processed in docker file
|
||||
return this.get('buildMethod') || ''; // Processed in docker file
|
||||
}
|
||||
|
||||
public get customParameters() {
|
||||
return this.getInput('customParameters') || '';
|
||||
return this.get('customParameters') || '';
|
||||
}
|
||||
|
||||
public get versioningStrategy() {
|
||||
return this.getInput('versioning') || 'Semantic';
|
||||
return this.get('versioning') || 'Semantic';
|
||||
}
|
||||
|
||||
public get specifiedVersion() {
|
||||
return this.getInput('version') || '';
|
||||
return this.get('version') || '';
|
||||
}
|
||||
|
||||
public get androidVersionCode() {
|
||||
return this.getInput('androidVersionCode');
|
||||
return this.get('androidVersionCode');
|
||||
}
|
||||
|
||||
public get androidAppBundle() {
|
||||
const input = this.getInput('androidAppBundle') || false;
|
||||
const input = this.get('androidAppBundle') || false;
|
||||
|
||||
return input === 'true';
|
||||
}
|
||||
|
||||
public get androidKeystoreName() {
|
||||
return this.getInput('androidKeystoreName') || '';
|
||||
return this.get('androidKeystoreName') || '';
|
||||
}
|
||||
|
||||
public get androidKeystoreBase64() {
|
||||
return this.getInput('androidKeystoreBase64') || '';
|
||||
return this.get('androidKeystoreBase64') || '';
|
||||
}
|
||||
|
||||
public get androidKeystorePass() {
|
||||
return this.getInput('androidKeystorePass') || '';
|
||||
return this.get('androidKeystorePass') || '';
|
||||
}
|
||||
|
||||
public get androidKeyaliasName() {
|
||||
return this.getInput('androidKeyaliasName') || '';
|
||||
return this.get('androidKeyaliasName') || '';
|
||||
}
|
||||
|
||||
public get androidKeyaliasPass() {
|
||||
return this.getInput('androidKeyaliasPass') || '';
|
||||
return this.get('androidKeyaliasPass') || '';
|
||||
}
|
||||
|
||||
public get androidTargetSdkVersion() {
|
||||
return this.getInput('androidTargetSdkVersion') || '';
|
||||
return this.get('androidTargetSdkVersion') || '';
|
||||
}
|
||||
|
||||
public get sshAgent() {
|
||||
return this.getInput('sshAgent') || '';
|
||||
return this.get('sshAgent') || '';
|
||||
}
|
||||
|
||||
public get gitPrivateToken() {
|
||||
return core.getInput('gitPrivateToken') || false;
|
||||
return this.get('gitPrivateToken') || '';
|
||||
}
|
||||
|
||||
public get customJob() {
|
||||
return this.getInput('customJob') || '';
|
||||
return this.get('customJob') || '';
|
||||
}
|
||||
|
||||
public customJobHooks() {
|
||||
return this.getInput('customJobHooks') || '';
|
||||
return this.get('customJobHooks') || '';
|
||||
}
|
||||
|
||||
public cachePushOverrideCommand() {
|
||||
return this.getInput('cachePushOverrideCommand') || '';
|
||||
return this.get('cachePushOverrideCommand') || '';
|
||||
}
|
||||
|
||||
public cachePullOverrideCommand() {
|
||||
return this.getInput('cachePullOverrideCommand') || '';
|
||||
return this.get('cachePullOverrideCommand') || '';
|
||||
}
|
||||
|
||||
public readInputFromOverrideList() {
|
||||
return this.getInput('readInputFromOverrideList') || '';
|
||||
return this.get('readInputFromOverrideList') || '';
|
||||
}
|
||||
|
||||
public readInputOverrideCommand() {
|
||||
return this.getInput('readInputOverrideCommand') || '';
|
||||
return this.get('readInputOverrideCommand') || '';
|
||||
}
|
||||
|
||||
public get cloudRunnerBranch() {
|
||||
return this.getInput('cloudRunnerBranch') || 'cloud-runner-develop';
|
||||
return this.get('cloudRunnerBranch') || 'cloud-runner-develop';
|
||||
}
|
||||
|
||||
public get chownFilesTo() {
|
||||
return this.getInput('chownFilesTo') || '';
|
||||
return this.get('chownFilesTo') || '';
|
||||
}
|
||||
|
||||
public get allowDirtyBuild() {
|
||||
const input = this.getInput('allowDirtyBuild');
|
||||
const input = this.get('allowDirtyBuild');
|
||||
log.debug('input === ', input);
|
||||
|
||||
return input || false === true;
|
||||
}
|
||||
|
||||
public get postBuildSteps() {
|
||||
return this.getInput('postBuildSteps') || '';
|
||||
return this.get('postBuildSteps') || '';
|
||||
}
|
||||
|
||||
public get preBuildSteps() {
|
||||
return this.getInput('preBuildSteps') || '';
|
||||
return this.get('preBuildSteps') || '';
|
||||
}
|
||||
|
||||
public get awsBaseStackName() {
|
||||
return this.getInput('awsBaseStackName') || 'game-ci';
|
||||
return this.get('awsBaseStackName') || 'game-ci';
|
||||
}
|
||||
|
||||
public get cloudRunnerCpu() {
|
||||
return this.getInput('cloudRunnerCpu');
|
||||
return this.get('cloudRunnerCpu');
|
||||
}
|
||||
|
||||
public get cloudRunnerMemory() {
|
||||
return this.getInput('cloudRunnerMemory');
|
||||
return this.get('cloudRunnerMemory');
|
||||
}
|
||||
|
||||
public get kubeConfig() {
|
||||
return this.getInput('kubeConfig') || '';
|
||||
return this.get('kubeConfig') || '';
|
||||
}
|
||||
|
||||
public get kubeVolume() {
|
||||
return this.getInput('kubeVolume') || '';
|
||||
return this.get('kubeVolume') || '';
|
||||
}
|
||||
|
||||
public get kubeVolumeSize() {
|
||||
return this.getInput('kubeVolumeSize') || '5Gi';
|
||||
return this.get('kubeVolumeSize') || '5Gi';
|
||||
}
|
||||
|
||||
public get kubeStorageClass(): string {
|
||||
return this.getInput('kubeStorageClass') || '';
|
||||
return this.get('kubeStorageClass') || '';
|
||||
}
|
||||
|
||||
public get checkDependencyHealthOverride(): string {
|
||||
return this.getInput('checkDependencyHealthOverride') || '';
|
||||
return this.get('checkDependencyHealthOverride') || '';
|
||||
}
|
||||
|
||||
public get startDependenciesOverride(): string {
|
||||
return this.getInput('startDependenciesOverride') || '';
|
||||
return this.get('startDependenciesOverride') || '';
|
||||
}
|
||||
|
||||
public get cacheKey(): string {
|
||||
return this.getInput('cacheKey') || Input.branch;
|
||||
return this.get('cacheKey') || Input.branch;
|
||||
}
|
||||
|
||||
public get cloudRunnerTests(): boolean {
|
||||
return this.getInput(`cloudRunnerTests`) || false;
|
||||
return this.get(`cloudRunnerTests`) || false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use Parameter.toEnvFormat
|
||||
*/
|
||||
public static toEnvVarFormat(input: string) {
|
||||
if (input.toUpperCase() === input) {
|
||||
return input;
|
||||
}
|
||||
if (input.toUpperCase() === input) return input;
|
||||
|
||||
return input
|
||||
.replace(/([A-Z])/g, ' $1')
|
||||
.trim()
|
||||
.toUpperCase()
|
||||
.replace(/ /g, '_');
|
||||
return input.replace(/([\da-z])([A-Z])/g, '$1_$2').toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import Versioning from './versioning.ts';
|
|||
import { GitRepoReader } from './input-readers/git-repo.ts';
|
||||
import { CommandInterface } from '../commands/command/command-interface.ts';
|
||||
import { Environment } from '../core/env/environment.ts';
|
||||
import { Parameter } from './parameter.ts';
|
||||
|
||||
class Parameters {
|
||||
private command: CommandInterface;
|
||||
|
|
@ -64,85 +65,70 @@ class Parameters {
|
|||
public cloudRunnerBuilderPlatform!: string | undefined;
|
||||
public isCliMode!: boolean;
|
||||
|
||||
private defaults: Partial<Parameters> = {
|
||||
region: 'eu-west-2',
|
||||
};
|
||||
|
||||
private readonly input: Input;
|
||||
private readonly env: Environment;
|
||||
|
||||
constructor(input: Input, env: Environment) {
|
||||
this.input = input;
|
||||
this.env = env;
|
||||
|
||||
// Todo - ~/.gameci should hold a config with default settings, like cloud region = 'eu-west-2'
|
||||
// this.config = config;
|
||||
}
|
||||
|
||||
public get(query, useDefault = true) {
|
||||
const defaultValue = useDefault ? this.default(query) : undefined;
|
||||
const value = this.input.get(query) || this.env.get(Parameter.toUpperSnakeCase(query)) || defaultValue;
|
||||
|
||||
if (log.isVeryVerbose) log.debug('Argument:', query, '=', value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private default(query) {
|
||||
return this.defaults[query];
|
||||
}
|
||||
|
||||
public async parse(): Promise<Parameters> {
|
||||
const cliStoragePath = `${getHomeDir()}/.game-ci`;
|
||||
const targetPlatform = this.input.get('targetPlatform');
|
||||
const buildsPath = this.input.get('buildsPath');
|
||||
const projectPath = this.get('projectPath');
|
||||
const unityVersion = this.get('unityVersion');
|
||||
const versioningStrategy = this.get('versioningStrategy');
|
||||
const specifiedVersion = this.get('specifiedVersion');
|
||||
const allowDirtyBuild = this.get('allowDirtyBuild');
|
||||
const androidTargetSdkVersion = this.get('androidTargetSdkVersion');
|
||||
|
||||
const buildFile = Parameters.parseBuildFile(
|
||||
this.input.buildName,
|
||||
this.input.targetPlatform,
|
||||
this.input.androidAppBundle,
|
||||
);
|
||||
log.debug('buildFile:', buildFile);
|
||||
const editorVersion = UnityVersioning.determineUnityVersion(this.input.projectPath, this.input.unityVersion);
|
||||
log.info('Detected editorVersion', editorVersion);
|
||||
const buildVersion = await Versioning.determineBuildVersion(
|
||||
this.input.versioningStrategy,
|
||||
this.input.specifiedVersion,
|
||||
this.input.allowDirtyBuild,
|
||||
);
|
||||
log.debug('buildVersion', buildVersion);
|
||||
const androidVersionCode = AndroidVersioning.determineVersionCode(buildVersion, this.input.androidVersionCode);
|
||||
log.debug('androidVersionCode', androidVersionCode);
|
||||
const androidSdkManagerParameters = AndroidVersioning.determineSdkManagerParameters(
|
||||
this.input.androidTargetSdkVersion,
|
||||
);
|
||||
log.debug('androidSdkManagerParameters', androidSdkManagerParameters);
|
||||
|
||||
// Commandline takes precedence over environment variables
|
||||
const unityEmail = this.input.unityEmail || this.env.get('UNITY_EMAIL');
|
||||
const unityPassword = this.input.unityPassword || this.env.get('UNITY_PASSWORD');
|
||||
const unityLicense = this.input.unityLicense || this.env.get('UNITY_LICENSE');
|
||||
const unityLicenseFile = this.input.unityLicenseFile || this.env.get('UNITY_LICENSE_FILE');
|
||||
let unitySerial = this.input.unitySerial || this.env.get('UNITY_SERIAL');
|
||||
|
||||
// For Windows, we need to use the serial from the license file
|
||||
if (!unitySerial && this.input.githubInputEnabled) {
|
||||
// No serial was present, so it is a personal license that we need to convert
|
||||
if (!unityLicense) {
|
||||
throw new Error(String.dedent`
|
||||
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 variable or enter
|
||||
a Unity serial number inside the UNITY_SERIAL variable.
|
||||
`);
|
||||
}
|
||||
|
||||
unitySerial = this.getSerialFromLicenseFile(this.env.UNITY_LICENSE);
|
||||
} else {
|
||||
unitySerial = this.env.UNITY_SERIAL!;
|
||||
}
|
||||
|
||||
const buildName = this.input.get('buildName') || targetPlatform;
|
||||
const buildFile = Parameters.parseBuildFile(buildName, targetPlatform, this.get('androidAppBundle'));
|
||||
const buildPath = `${buildsPath}/${targetPlatform}`;
|
||||
const editorVersion = UnityVersioning.determineUnityVersion(projectPath, unityVersion);
|
||||
const buildVersion = await Versioning.determineBuildVersion(versioningStrategy, specifiedVersion, allowDirtyBuild);
|
||||
const androidVersionCode = AndroidVersioning.determineVersionCode(buildVersion, this.get('androidVersionCode'));
|
||||
const androidSdkManagerParameters = AndroidVersioning.determineSdkManagerParameters(androidTargetSdkVersion);
|
||||
const branch = (await Versioning.getCurrentBranch()) || (await GitRepoReader.GetBranch());
|
||||
log.info(`branch: "${branch}"`);
|
||||
|
||||
const projectPath = this.input.projectPath;
|
||||
log.info(`projectPath: "${projectPath}"`);
|
||||
|
||||
const targetPlatform = this.input.targetPlatform;
|
||||
log.info(`targetPlatform: "${targetPlatform}"`);
|
||||
|
||||
const parameters = {
|
||||
branch,
|
||||
unityEmail: this.get('unityEmail'),
|
||||
unityPassword: this.get('unityPassword'),
|
||||
unityLicense: this.get('unityLicense'),
|
||||
unityLicenseFile: this.get('unityLicenseFile'),
|
||||
unitySerial: this.getUnitySerial(),
|
||||
cliStoragePath,
|
||||
editorVersion,
|
||||
customImage: this.input.customImage,
|
||||
unityEmail,
|
||||
unityPassword,
|
||||
unityLicense,
|
||||
unityLicenseFile,
|
||||
unitySerial,
|
||||
usymUploadAuthToken: this.input.usymUploadAuthToken || this.env.get('USYM_UPLOAD_AUTH_TOKEN'),
|
||||
runnerTempPath: this.env.RUNNER_TEMP,
|
||||
customImage: this.get('customImage'),
|
||||
usymUploadAuthToken: this.get('usymUploadAuthToken'),
|
||||
runnerTempPath: this.env.get('RUNNER_TEMP'),
|
||||
targetPlatform,
|
||||
projectPath,
|
||||
buildName: this.input.buildName,
|
||||
buildPath: `${this.input.buildsPath}/${this.input.targetPlatform}`,
|
||||
buildName,
|
||||
buildPath,
|
||||
buildFile,
|
||||
buildMethod: this.input.buildMethod,
|
||||
buildVersion,
|
||||
|
|
@ -152,14 +138,13 @@ class Parameters {
|
|||
androidKeystorePass: this.input.androidKeystorePass,
|
||||
androidKeyaliasName: this.input.androidKeyaliasName,
|
||||
androidKeyaliasPass: this.input.androidKeyaliasPass,
|
||||
androidTargetSdkVersion: this.input.androidTargetSdkVersion,
|
||||
androidTargetSdkVersion,
|
||||
androidSdkManagerParameters,
|
||||
customParameters: this.input.customParameters,
|
||||
customParameters: this.get('customParameters'),
|
||||
sshAgent: this.input.sshAgent,
|
||||
gitPrivateToken: this.input.gitPrivateToken,
|
||||
gitPrivateToken: this.get('gitPrivateToken'),
|
||||
chownFilesTo: this.input.chownFilesTo,
|
||||
customJob: this.input.customJob,
|
||||
branch,
|
||||
};
|
||||
|
||||
const commandParameterOverrides = await this.command.parseParameters(this.input, parameters);
|
||||
|
|
@ -183,7 +168,27 @@ class Parameters {
|
|||
return filename;
|
||||
}
|
||||
|
||||
static getSerialFromLicenseFile(license) {
|
||||
static getUnitySerial() {
|
||||
let unitySerial = this.get('unitySerial');
|
||||
|
||||
if (!unitySerial && this.env.getOS() === 'windows') {
|
||||
const unityLicense = this.get('unityLicense');
|
||||
|
||||
unitySerial = this.getSerialFromLicense(unityLicense);
|
||||
}
|
||||
|
||||
return unitySerial;
|
||||
}
|
||||
|
||||
static getSerialFromLicense(license) {
|
||||
if (!license) {
|
||||
throw new Error(String.dedent`
|
||||
Missing Unity License File and no Unity Serial was found. If this is a personal license,
|
||||
make sure to follow the activation steps and set the UNITY_LICENSE variable or enter
|
||||
a Unity serial number inside the UNITY_SERIAL variable.
|
||||
`);
|
||||
}
|
||||
|
||||
const startKey = `<DeveloperData Value="`;
|
||||
const endKey = `"/>`;
|
||||
const startIndex = license.indexOf(startKey) + startKey.length;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
export interface RunOptions {
|
||||
pwd: string;
|
||||
attach: boolean;
|
||||
}
|
||||
|
||||
class System {
|
||||
|
|
@ -7,7 +8,7 @@ class System {
|
|||
* Run any command as if you're typing in shell.
|
||||
* Make sure it's Windows/MacOS/Ubuntu compatible or has alternative commands.
|
||||
*
|
||||
* Intended to always be silent and capture the output.
|
||||
* Intended to always be silent and capture the output, unless attach is passed.
|
||||
*
|
||||
* @returns {string} output of the command on success or failure
|
||||
*
|
||||
|
|
@ -28,11 +29,15 @@ class System {
|
|||
}
|
||||
|
||||
static async shellRun(command: string, options: RunOptions = {}): Promise<string> {
|
||||
return System.newRun('sh', ['-c', command]);
|
||||
const { attach } = options;
|
||||
|
||||
return attach ? System.runAndAttach('sh', ['-c', command]) : System.runAndCapture('sh', ['-c', command]);
|
||||
}
|
||||
|
||||
static async powershellRun(command: string, options: RunOptions = {}): Promise<string> {
|
||||
return System.newRun('powershell', [command]);
|
||||
const { attach } = options;
|
||||
|
||||
return attach ? System.runAndAttach('powershell', [command]) : System.runAndCapture('powershell', [command]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -51,7 +56,7 @@ class System {
|
|||
*
|
||||
* @deprecated not really deprecated, but please use System.run instead because this method will be made private.
|
||||
*/
|
||||
public static async newRun(command, args: string | string[] = []): Promise<string> {
|
||||
public static async runAndCapture(command, args: string | string[] = []): Promise<string> {
|
||||
if (!Array.isArray(args)) args = [args];
|
||||
|
||||
const argsString = args.join(' ');
|
||||
|
|
@ -92,6 +97,26 @@ class System {
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output stdout and stderr to the terminal and attach to the process.
|
||||
*
|
||||
* Note that the return signature is slightly different from runAndCapture, because we don't have stderrOutput.
|
||||
*
|
||||
* Todo - it would be nice to pipe the output to both stdout and capture it in the result object, but this doesn't seem possible yet.
|
||||
*/
|
||||
private static async runAndAttach(command, args: string | string[] = []): Promise<string> {
|
||||
if (!Array.isArray(args)) args = [args];
|
||||
|
||||
const process = Deno.run({ cmd: [command, ...args] });
|
||||
const status = await process.status();
|
||||
|
||||
process.close();
|
||||
|
||||
if (!status.success) throw new Error(`Command failed with code ${status.code}`);
|
||||
|
||||
return { status, output: 'runAndAttach has access to the output stream' };
|
||||
}
|
||||
}
|
||||
|
||||
export default System;
|
||||
|
|
|
|||
Loading…
Reference in New Issue