mirror of
https://github.com/game-ci/unity-builder.git
synced 2026-02-04 16:19:09 +08:00
Cloud runner develop - latest fixes (#524)
Cloud runner develop - latest fixes (#524)
This commit is contained in:
47
src/model/cloud-runner/services/core/cloud-runner-logger.ts
Normal file
47
src/model/cloud-runner/services/core/cloud-runner-logger.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import * as core from '@actions/core';
|
||||
|
||||
class CloudRunnerLogger {
|
||||
private static timestamp: number;
|
||||
private static globalTimestamp: number;
|
||||
|
||||
public static setup() {
|
||||
this.timestamp = this.createTimestamp();
|
||||
this.globalTimestamp = this.timestamp;
|
||||
}
|
||||
|
||||
public static log(message: string) {
|
||||
core.info(message);
|
||||
}
|
||||
|
||||
public static logWarning(message: string) {
|
||||
core.warning(message);
|
||||
}
|
||||
|
||||
public static logLine(message: string) {
|
||||
core.info(`${message}\n`);
|
||||
}
|
||||
|
||||
public static error(message: string) {
|
||||
core.error(message);
|
||||
}
|
||||
|
||||
public static logWithTime(message: string) {
|
||||
const newTimestamp = this.createTimestamp();
|
||||
core.info(
|
||||
`${message} (Since previous: ${this.calculateTimeDiff(
|
||||
newTimestamp,
|
||||
this.timestamp,
|
||||
)}, Total time: ${this.calculateTimeDiff(newTimestamp, this.globalTimestamp)})`,
|
||||
);
|
||||
this.timestamp = newTimestamp;
|
||||
}
|
||||
|
||||
private static calculateTimeDiff(x: number, y: number) {
|
||||
return Math.floor((x - y) / 1000);
|
||||
}
|
||||
|
||||
private static createTimestamp() {
|
||||
return Date.now();
|
||||
}
|
||||
}
|
||||
export default CloudRunnerLogger;
|
||||
60
src/model/cloud-runner/services/core/cloud-runner-system.ts
Normal file
60
src/model/cloud-runner/services/core/cloud-runner-system.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { exec } from 'child_process';
|
||||
import { RemoteClientLogger } from '../../remote-client/remote-client-logger';
|
||||
|
||||
export class CloudRunnerSystem {
|
||||
public static async RunAndReadLines(command: string): Promise<string[]> {
|
||||
const result = await CloudRunnerSystem.Run(command, false, true);
|
||||
|
||||
return result
|
||||
.split(`\n`)
|
||||
.map((x) => x.replace(`\r`, ``))
|
||||
.filter((x) => x !== ``)
|
||||
.map((x) => {
|
||||
const lineValues = x.split(` `);
|
||||
|
||||
return lineValues[lineValues.length - 1];
|
||||
});
|
||||
}
|
||||
|
||||
public static async Run(command: string, suppressError = false, suppressLogs = false) {
|
||||
for (const element of command.split(`\n`)) {
|
||||
if (!suppressLogs) {
|
||||
RemoteClientLogger.log(element);
|
||||
}
|
||||
}
|
||||
|
||||
return await new Promise<string>((promise, throwError) => {
|
||||
let output = '';
|
||||
const child = exec(command, (error, stdout, stderr) => {
|
||||
if (!suppressError && error) {
|
||||
RemoteClientLogger.log(error.toString());
|
||||
throwError(error);
|
||||
}
|
||||
if (stderr) {
|
||||
const diagnosticOutput = `${stderr.toString()}`;
|
||||
if (!suppressLogs) {
|
||||
RemoteClientLogger.logCliDiagnostic(diagnosticOutput);
|
||||
}
|
||||
output += diagnosticOutput;
|
||||
}
|
||||
const outputChunk = `${stdout}`;
|
||||
output += outputChunk;
|
||||
});
|
||||
child.on('close', (code) => {
|
||||
if (!suppressLogs) {
|
||||
RemoteClientLogger.log(`[${code}]`);
|
||||
}
|
||||
if (code !== 0 && !suppressError) {
|
||||
throwError(output);
|
||||
}
|
||||
const outputLines = output.split(`\n`);
|
||||
for (const element of outputLines) {
|
||||
if (!suppressLogs) {
|
||||
RemoteClientLogger.log(element);
|
||||
}
|
||||
}
|
||||
promise(output);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import GitHub from '../../../github';
|
||||
import CloudRunner from '../../cloud-runner';
|
||||
import { CloudRunnerStatics } from '../../options/cloud-runner-statics';
|
||||
import CloudRunnerLogger from './cloud-runner-logger';
|
||||
import * as core from '@actions/core';
|
||||
|
||||
export class FollowLogStreamService {
|
||||
static Reset() {
|
||||
FollowLogStreamService.DidReceiveEndOfTransmission = false;
|
||||
}
|
||||
static errors = ``;
|
||||
public static DidReceiveEndOfTransmission = false;
|
||||
public static handleIteration(message: string, shouldReadLogs: boolean, shouldCleanup: boolean, output: string) {
|
||||
if (message.includes(`---${CloudRunner.buildParameters.logId}`)) {
|
||||
CloudRunnerLogger.log('End of log transmission received');
|
||||
FollowLogStreamService.DidReceiveEndOfTransmission = true;
|
||||
shouldReadLogs = false;
|
||||
} else if (message.includes('Rebuilding Library because the asset database could not be found!')) {
|
||||
GitHub.updateGitHubCheck(`Library was not found, importing new Library`, ``);
|
||||
core.warning('LIBRARY NOT FOUND!');
|
||||
core.setOutput('library-found', 'false');
|
||||
} else if (message.includes('Build succeeded')) {
|
||||
GitHub.updateGitHubCheck(`Build succeeded`, `Build succeeded`);
|
||||
core.setOutput('build-result', 'success');
|
||||
} else if (message.includes('Build fail')) {
|
||||
GitHub.updateGitHubCheck(
|
||||
`Build failed\n${FollowLogStreamService.errors}`,
|
||||
`Build failed`,
|
||||
`failure`,
|
||||
`completed`,
|
||||
);
|
||||
core.setOutput('build-result', 'failed');
|
||||
core.setFailed('unity build failed');
|
||||
core.error('BUILD FAILED!');
|
||||
} else if (message.toLowerCase().includes('error ')) {
|
||||
core.error(message);
|
||||
FollowLogStreamService.errors += `\n${message}`;
|
||||
} else if (message.toLowerCase().includes('error: ')) {
|
||||
core.error(message);
|
||||
FollowLogStreamService.errors += `\n${message}`;
|
||||
} else if (message.toLowerCase().includes('command failed: ')) {
|
||||
FollowLogStreamService.errors += `\n${message}`;
|
||||
} else if (message.toLowerCase().includes('invalid ')) {
|
||||
FollowLogStreamService.errors += `\n${message}`;
|
||||
} else if (message.toLowerCase().includes('incompatible ')) {
|
||||
FollowLogStreamService.errors += `\n${message}`;
|
||||
} else if (message.toLowerCase().includes('cannot be found')) {
|
||||
FollowLogStreamService.errors += `\n${message}`;
|
||||
}
|
||||
if (CloudRunner.buildParameters.cloudRunnerDebug) {
|
||||
output += `${message}\n`;
|
||||
}
|
||||
CloudRunnerLogger.log(`[${CloudRunnerStatics.logPrefix}] ${message}`);
|
||||
|
||||
return { shouldReadLogs, shouldCleanup, output };
|
||||
}
|
||||
}
|
||||
300
src/model/cloud-runner/services/core/shared-workspace-locking.ts
Normal file
300
src/model/cloud-runner/services/core/shared-workspace-locking.ts
Normal file
@@ -0,0 +1,300 @@
|
||||
import { CloudRunnerSystem } from './cloud-runner-system';
|
||||
import fs from 'node:fs';
|
||||
import CloudRunnerLogger from './cloud-runner-logger';
|
||||
import BuildParameters from '../../../build-parameters';
|
||||
import CloudRunner from '../../cloud-runner';
|
||||
export class SharedWorkspaceLocking {
|
||||
public static get workspaceBucketRoot() {
|
||||
return `s3://${CloudRunner.buildParameters.awsStackName}/`;
|
||||
}
|
||||
public static get workspaceRoot() {
|
||||
return `${SharedWorkspaceLocking.workspaceBucketRoot}locks/`;
|
||||
}
|
||||
public static async GetAllWorkspaces(buildParametersContext: BuildParameters): Promise<string[]> {
|
||||
if (!(await SharedWorkspaceLocking.DoesCacheKeyTopLevelExist(buildParametersContext))) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return (
|
||||
await SharedWorkspaceLocking.ReadLines(
|
||||
`aws s3 ls ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/`,
|
||||
)
|
||||
)
|
||||
.map((x) => x.replace(`/`, ``))
|
||||
.filter((x) => x.endsWith(`_workspace`))
|
||||
.map((x) => x.split(`_`)[1]);
|
||||
}
|
||||
public static async DoesCacheKeyTopLevelExist(buildParametersContext: BuildParameters) {
|
||||
try {
|
||||
const rootLines = await SharedWorkspaceLocking.ReadLines(
|
||||
`aws s3 ls ${SharedWorkspaceLocking.workspaceBucketRoot}`,
|
||||
);
|
||||
const lockFolderExists = rootLines.map((x) => x.replace(`/`, ``)).includes(`locks`);
|
||||
|
||||
if (lockFolderExists) {
|
||||
const lines = await SharedWorkspaceLocking.ReadLines(`aws s3 ls ${SharedWorkspaceLocking.workspaceRoot}`);
|
||||
|
||||
return lines.map((x) => x.replace(`/`, ``)).includes(buildParametersContext.cacheKey);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static NewWorkspaceName() {
|
||||
return `${CloudRunner.retainedWorkspacePrefix}-${CloudRunner.buildParameters.buildGuid}`;
|
||||
}
|
||||
public static async GetAllLocksForWorkspace(
|
||||
workspace: string,
|
||||
buildParametersContext: BuildParameters,
|
||||
): Promise<string[]> {
|
||||
if (!(await SharedWorkspaceLocking.DoesWorkspaceExist(workspace, buildParametersContext))) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return (
|
||||
await SharedWorkspaceLocking.ReadLines(
|
||||
`aws s3 ls ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/`,
|
||||
)
|
||||
)
|
||||
.map((x) => x.replace(`/`, ``))
|
||||
.filter((x) => x.includes(workspace) && x.endsWith(`_lock`));
|
||||
}
|
||||
public static async GetLockedWorkspace(workspace: string, runId: string, buildParametersContext: BuildParameters) {
|
||||
if (buildParametersContext.maxRetainedWorkspaces === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (await SharedWorkspaceLocking.DoesCacheKeyTopLevelExist(buildParametersContext)) {
|
||||
const workspaces = await SharedWorkspaceLocking.GetFreeWorkspaces(buildParametersContext);
|
||||
CloudRunnerLogger.log(`run agent ${runId} is trying to access a workspace, free: ${JSON.stringify(workspaces)}`);
|
||||
for (const element of workspaces) {
|
||||
const lockResult = await SharedWorkspaceLocking.LockWorkspace(element, runId, buildParametersContext);
|
||||
CloudRunnerLogger.log(
|
||||
`run agent: ${runId} try lock workspace: ${element} locking attempt result: ${lockResult}`,
|
||||
);
|
||||
|
||||
if (lockResult) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (await SharedWorkspaceLocking.DoesWorkspaceExist(workspace, buildParametersContext)) {
|
||||
workspace = SharedWorkspaceLocking.NewWorkspaceName();
|
||||
CloudRunner.lockedWorkspace = workspace;
|
||||
}
|
||||
|
||||
const createResult = await SharedWorkspaceLocking.CreateWorkspace(workspace, buildParametersContext);
|
||||
const lockResult = await SharedWorkspaceLocking.LockWorkspace(workspace, runId, buildParametersContext);
|
||||
CloudRunnerLogger.log(
|
||||
`run agent ${runId} didn't find a free workspace so created: ${workspace} createWorkspaceSuccess: ${createResult} Lock:${lockResult}`,
|
||||
);
|
||||
|
||||
return createResult && lockResult;
|
||||
}
|
||||
|
||||
public static async DoesWorkspaceExist(workspace: string, buildParametersContext: BuildParameters) {
|
||||
return (
|
||||
(await SharedWorkspaceLocking.GetAllWorkspaces(buildParametersContext)).filter((x) => x.includes(workspace))
|
||||
.length > 0
|
||||
);
|
||||
}
|
||||
public static async HasWorkspaceLock(
|
||||
workspace: string,
|
||||
runId: string,
|
||||
buildParametersContext: BuildParameters,
|
||||
): Promise<boolean> {
|
||||
const locks = (await SharedWorkspaceLocking.GetAllLocksForWorkspace(workspace, buildParametersContext))
|
||||
.map((x) => {
|
||||
return {
|
||||
name: x,
|
||||
timestamp: Number(x.split(`_`)[0]),
|
||||
};
|
||||
})
|
||||
.sort((x) => x.timestamp);
|
||||
const lockMatches = locks.filter((x) => x.name.includes(runId));
|
||||
const includesRunLock = lockMatches.length > 0 && locks.indexOf(lockMatches[0]) === 0;
|
||||
CloudRunnerLogger.log(
|
||||
`Checking has workspace lock, runId: ${runId}, workspace: ${workspace}, success: ${includesRunLock} \n- Num of locks created by Run Agent: ${
|
||||
lockMatches.length
|
||||
} Num of Locks: ${locks.length}, Time ordered index for Run Agent: ${locks.indexOf(lockMatches[0])} \n \n`,
|
||||
);
|
||||
|
||||
return includesRunLock;
|
||||
}
|
||||
|
||||
public static async GetFreeWorkspaces(buildParametersContext: BuildParameters): Promise<string[]> {
|
||||
const result: string[] = [];
|
||||
const workspaces = await SharedWorkspaceLocking.GetAllWorkspaces(buildParametersContext);
|
||||
for (const element of workspaces) {
|
||||
const isLocked = await SharedWorkspaceLocking.IsWorkspaceLocked(element, buildParametersContext);
|
||||
const isBelowMax = await SharedWorkspaceLocking.IsWorkspaceBelowMax(element, buildParametersContext);
|
||||
CloudRunnerLogger.log(`workspace ${element} locked:${isLocked} below max:${isBelowMax}`);
|
||||
if (!isLocked && isBelowMax) {
|
||||
result.push(element);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async IsWorkspaceBelowMax(
|
||||
workspace: string,
|
||||
buildParametersContext: BuildParameters,
|
||||
): Promise<boolean> {
|
||||
const workspaces = await SharedWorkspaceLocking.GetAllWorkspaces(buildParametersContext);
|
||||
if (workspace === ``) {
|
||||
return (
|
||||
workspaces.length < buildParametersContext.maxRetainedWorkspaces ||
|
||||
buildParametersContext.maxRetainedWorkspaces === 0
|
||||
);
|
||||
}
|
||||
const ordered: any[] = [];
|
||||
for (const ws of workspaces) {
|
||||
ordered.push({
|
||||
name: ws,
|
||||
timestamp: await SharedWorkspaceLocking.GetWorkspaceTimestamp(ws, buildParametersContext),
|
||||
});
|
||||
}
|
||||
ordered.sort((x) => x.timestamp);
|
||||
const matches = ordered.filter((x) => x.name.includes(workspace));
|
||||
const isWorkspaceBelowMax =
|
||||
matches.length > 0 &&
|
||||
(ordered.indexOf(matches[0]) < buildParametersContext.maxRetainedWorkspaces ||
|
||||
buildParametersContext.maxRetainedWorkspaces === 0);
|
||||
|
||||
return isWorkspaceBelowMax;
|
||||
}
|
||||
|
||||
public static async GetWorkspaceTimestamp(
|
||||
workspace: string,
|
||||
buildParametersContext: BuildParameters,
|
||||
): Promise<Number> {
|
||||
if (workspace.split(`_`).length > 0) {
|
||||
return Number(workspace.split(`_`)[1]);
|
||||
}
|
||||
|
||||
if (!(await SharedWorkspaceLocking.DoesWorkspaceExist(workspace, buildParametersContext))) {
|
||||
throw new Error("Workspace doesn't exist, can't call get all locks");
|
||||
}
|
||||
|
||||
return (
|
||||
await SharedWorkspaceLocking.ReadLines(
|
||||
`aws s3 ls ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/`,
|
||||
)
|
||||
)
|
||||
.map((x) => x.replace(`/`, ``))
|
||||
.filter((x) => x.includes(workspace) && x.endsWith(`_workspace`))
|
||||
.map((x) => Number(x))[0];
|
||||
}
|
||||
|
||||
public static async IsWorkspaceLocked(workspace: string, buildParametersContext: BuildParameters): Promise<boolean> {
|
||||
if (!(await SharedWorkspaceLocking.DoesWorkspaceExist(workspace, buildParametersContext))) {
|
||||
throw new Error(`workspace doesn't exist ${workspace}`);
|
||||
}
|
||||
const files = await SharedWorkspaceLocking.ReadLines(
|
||||
`aws s3 ls ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/`,
|
||||
);
|
||||
|
||||
const lockFilesExist =
|
||||
files.filter((x) => {
|
||||
return x.includes(workspace) && x.endsWith(`_lock`);
|
||||
}).length > 0;
|
||||
|
||||
return lockFilesExist;
|
||||
}
|
||||
|
||||
public static async CreateWorkspace(workspace: string, buildParametersContext: BuildParameters): Promise<boolean> {
|
||||
if (await SharedWorkspaceLocking.DoesWorkspaceExist(workspace, buildParametersContext)) {
|
||||
throw new Error(`${workspace} already exists`);
|
||||
}
|
||||
const timestamp = Date.now();
|
||||
const file = `${timestamp}_${workspace}_workspace`;
|
||||
fs.writeFileSync(file, '');
|
||||
await CloudRunnerSystem.Run(
|
||||
`aws s3 cp ./${file} ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/${file}`,
|
||||
false,
|
||||
true,
|
||||
);
|
||||
fs.rmSync(file);
|
||||
|
||||
const workspaces = await SharedWorkspaceLocking.GetAllWorkspaces(buildParametersContext);
|
||||
|
||||
CloudRunnerLogger.log(`All workspaces ${workspaces}`);
|
||||
if (!(await SharedWorkspaceLocking.IsWorkspaceBelowMax(workspace, buildParametersContext))) {
|
||||
CloudRunnerLogger.log(`Workspace is above max ${workspaces} ${buildParametersContext.maxRetainedWorkspaces}`);
|
||||
await SharedWorkspaceLocking.CleanupWorkspace(workspace, buildParametersContext);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static async LockWorkspace(
|
||||
workspace: string,
|
||||
runId: string,
|
||||
buildParametersContext: BuildParameters,
|
||||
): Promise<boolean> {
|
||||
const existingWorkspace = workspace.endsWith(`_workspace`);
|
||||
const ending = existingWorkspace ? workspace : `${workspace}_workspace`;
|
||||
const file = `${Date.now()}_${runId}_${ending}_lock`;
|
||||
fs.writeFileSync(file, '');
|
||||
await CloudRunnerSystem.Run(
|
||||
`aws s3 cp ./${file} ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/${file}`,
|
||||
false,
|
||||
true,
|
||||
);
|
||||
fs.rmSync(file);
|
||||
|
||||
const hasLock = await SharedWorkspaceLocking.HasWorkspaceLock(workspace, runId, buildParametersContext);
|
||||
|
||||
if (hasLock) {
|
||||
CloudRunner.lockedWorkspace = workspace;
|
||||
} else {
|
||||
await CloudRunnerSystem.Run(
|
||||
`aws s3 rm ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/${file}`,
|
||||
false,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
return hasLock;
|
||||
}
|
||||
|
||||
public static async ReleaseWorkspace(
|
||||
workspace: string,
|
||||
runId: string,
|
||||
buildParametersContext: BuildParameters,
|
||||
): Promise<boolean> {
|
||||
const files = await SharedWorkspaceLocking.GetAllLocksForWorkspace(workspace, buildParametersContext);
|
||||
const file = files.find((x) => x.includes(workspace) && x.endsWith(`_lock`) && x.includes(runId));
|
||||
CloudRunnerLogger.log(`All Locks ${files} ${workspace} ${runId}`);
|
||||
CloudRunnerLogger.log(`Deleting lock ${workspace}/${file}`);
|
||||
CloudRunnerLogger.log(`rm ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/${file}`);
|
||||
await CloudRunnerSystem.Run(
|
||||
`aws s3 rm ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/${file}`,
|
||||
false,
|
||||
true,
|
||||
);
|
||||
|
||||
return !(await SharedWorkspaceLocking.HasWorkspaceLock(workspace, runId, buildParametersContext));
|
||||
}
|
||||
|
||||
public static async CleanupWorkspace(workspace: string, buildParametersContext: BuildParameters) {
|
||||
await CloudRunnerSystem.Run(
|
||||
`aws s3 rm ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey} --exclude "*" --include "*_${workspace}_*"`,
|
||||
false,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
public static async ReadLines(command: string): Promise<string[]> {
|
||||
return CloudRunnerSystem.RunAndReadLines(command);
|
||||
}
|
||||
}
|
||||
|
||||
export default SharedWorkspaceLocking;
|
||||
@@ -0,0 +1,174 @@
|
||||
import BuildParameters from '../../../build-parameters';
|
||||
import Input from '../../../input';
|
||||
import CloudRunnerOptions from '../../options/cloud-runner-options';
|
||||
import CloudRunnerEnvironmentVariable from '../../options/cloud-runner-environment-variable';
|
||||
import CloudRunnerOptionsReader from '../../options/cloud-runner-options-reader';
|
||||
import CloudRunnerQueryOverride from '../../options/cloud-runner-query-override';
|
||||
import CloudRunnerSecret from '../../options/cloud-runner-secret';
|
||||
import { CommandHookService } from '../hooks/command-hook-service';
|
||||
|
||||
export class TaskParameterSerializer {
|
||||
static readonly blockedParameterNames: Set<string> = new Set([
|
||||
'0',
|
||||
'length',
|
||||
'prototype',
|
||||
'',
|
||||
'unityVersion',
|
||||
'CACHE_UNITY_INSTALLATION_ON_MAC',
|
||||
'RUNNER_TEMP_PATH',
|
||||
'NAME',
|
||||
'CUSTOM_JOB',
|
||||
]);
|
||||
public static createCloudRunnerEnvironmentVariables(
|
||||
buildParameters: BuildParameters,
|
||||
): CloudRunnerEnvironmentVariable[] {
|
||||
const result: CloudRunnerEnvironmentVariable[] = this.uniqBy(
|
||||
[
|
||||
...[
|
||||
{ name: 'BUILD_TARGET', value: buildParameters.targetPlatform },
|
||||
{ name: 'UNITY_VERSION', value: buildParameters.editorVersion },
|
||||
{ name: 'GITHUB_TOKEN', value: process.env.GITHUB_TOKEN },
|
||||
],
|
||||
...TaskParameterSerializer.serializeFromObject(buildParameters),
|
||||
...TaskParameterSerializer.serializeInput(),
|
||||
...TaskParameterSerializer.serializeCloudRunnerOptions(),
|
||||
...CommandHookService.getSecrets(CommandHookService.getHooks(buildParameters.commandHooks)),
|
||||
]
|
||||
.filter(
|
||||
(x) =>
|
||||
!TaskParameterSerializer.blockedParameterNames.has(x.name) &&
|
||||
x.value !== '' &&
|
||||
x.value !== undefined &&
|
||||
x.value !== `undefined`,
|
||||
)
|
||||
.map((x) => {
|
||||
x.name = `${TaskParameterSerializer.ToEnvVarFormat(x.name)}`;
|
||||
x.value = `${x.value}`;
|
||||
|
||||
return x;
|
||||
}),
|
||||
(item: CloudRunnerEnvironmentVariable) => item.name,
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
static uniqBy(a: CloudRunnerEnvironmentVariable[], key: (parameters: CloudRunnerEnvironmentVariable) => string) {
|
||||
const seen: { [key: string]: boolean } = {};
|
||||
|
||||
return a.filter(function (item) {
|
||||
const k = key(item);
|
||||
|
||||
return seen.hasOwnProperty(k) ? false : (seen[k] = true);
|
||||
});
|
||||
}
|
||||
|
||||
public static readBuildParameterFromEnvironment(): BuildParameters {
|
||||
const buildParameters = new BuildParameters();
|
||||
const keys = [
|
||||
...new Set(
|
||||
Object.getOwnPropertyNames(process.env)
|
||||
.filter((x) => !this.blockedParameterNames.has(x) && x.startsWith(''))
|
||||
.map((x) => TaskParameterSerializer.UndoEnvVarFormat(x)),
|
||||
),
|
||||
];
|
||||
|
||||
for (const element of keys) {
|
||||
if (element !== `customJob`) {
|
||||
buildParameters[element] = process.env[`${TaskParameterSerializer.ToEnvVarFormat(element)}`];
|
||||
}
|
||||
}
|
||||
|
||||
return buildParameters;
|
||||
}
|
||||
|
||||
private static serializeInput() {
|
||||
return TaskParameterSerializer.serializeFromType(Input);
|
||||
}
|
||||
|
||||
private static serializeCloudRunnerOptions() {
|
||||
return TaskParameterSerializer.serializeFromType(CloudRunnerOptions);
|
||||
}
|
||||
|
||||
public static ToEnvVarFormat(input: string): string {
|
||||
return CloudRunnerOptions.ToEnvVarFormat(input);
|
||||
}
|
||||
|
||||
public static UndoEnvVarFormat(element: string): string {
|
||||
return this.camelize(element.toLowerCase().replace(/_+/g, ' '));
|
||||
}
|
||||
|
||||
private static camelize(string: string) {
|
||||
return TaskParameterSerializer.uncapitalizeFirstLetter(
|
||||
string
|
||||
.replace(/(^\w)|([A-Z])|(\b\w)/g, function (word: string, index: number) {
|
||||
return index === 0 ? word.toLowerCase() : word.toUpperCase();
|
||||
})
|
||||
.replace(/\s+/g, ''),
|
||||
);
|
||||
}
|
||||
|
||||
private static uncapitalizeFirstLetter(string: string) {
|
||||
return string.charAt(0).toLowerCase() + string.slice(1);
|
||||
}
|
||||
|
||||
private static serializeFromObject(buildParameters: any) {
|
||||
const array: any[] = [];
|
||||
const keys = Object.getOwnPropertyNames(buildParameters).filter((x) => !this.blockedParameterNames.has(x));
|
||||
for (const element of keys) {
|
||||
array.push({
|
||||
name: TaskParameterSerializer.ToEnvVarFormat(element),
|
||||
value: buildParameters[element],
|
||||
});
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
private static serializeFromType(type: any) {
|
||||
const array: any[] = [];
|
||||
const input = CloudRunnerOptionsReader.GetProperties();
|
||||
for (const element of input) {
|
||||
if (typeof type[element] !== 'function' && array.filter((x) => x.name === element).length === 0) {
|
||||
array.push({
|
||||
name: element,
|
||||
value: `${type[element]}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
public static readDefaultSecrets(): CloudRunnerSecret[] {
|
||||
let array = new Array();
|
||||
array = TaskParameterSerializer.tryAddInput(array, 'UNITY_SERIAL');
|
||||
array = TaskParameterSerializer.tryAddInput(array, 'UNITY_EMAIL');
|
||||
array = TaskParameterSerializer.tryAddInput(array, 'UNITY_PASSWORD');
|
||||
array = TaskParameterSerializer.tryAddInput(array, 'UNITY_LICENSE');
|
||||
array = TaskParameterSerializer.tryAddInput(array, 'GIT_PRIVATE_TOKEN');
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
private static getValue(key: string) {
|
||||
return CloudRunnerQueryOverride.queryOverrides !== undefined &&
|
||||
CloudRunnerQueryOverride.queryOverrides[key] !== undefined
|
||||
? CloudRunnerQueryOverride.queryOverrides[key]
|
||||
: process.env[key];
|
||||
}
|
||||
|
||||
private static tryAddInput(array: CloudRunnerSecret[], key: string): CloudRunnerSecret[] {
|
||||
const value = TaskParameterSerializer.getValue(key);
|
||||
if (value !== undefined && value !== '' && value !== 'null') {
|
||||
array.push({
|
||||
ParameterKey: key,
|
||||
EnvironmentVariable: key,
|
||||
ParameterValue: value,
|
||||
});
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user