Refactor and cleanup - no async input, combined setup/build, removed github logs for cli runs

pull/353/head
Frostebite 2022-04-03 00:12:35 +01:00
parent b7590245fa
commit 8dffcc1c5c
22 changed files with 332 additions and 281 deletions

305
dist/index.js vendored
View File

@ -46,6 +46,10 @@ const platform_setup_1 = __importDefault(__nccwpck_require__(64423));
function runMain() {
return __awaiter(this, void 0, void 0, function* () {
try {
if (cli_1.CLI.InitCliMode()) {
yield cli_1.CLI.RunCli();
return;
}
model_1.Action.checkCompatibility();
model_1.Cache.verify();
const { dockerfile, workspace, actionFolder } = model_1.Action;
@ -76,13 +80,7 @@ function runMain() {
}
});
}
const options = cli_1.CLI.SetupCli();
if (cli_1.CLI.isCliMode(options)) {
cli_1.CLI.RunCli(options);
}
else {
runMain();
}
runMain();
/***/ }),
@ -256,6 +254,8 @@ const input_1 = __importDefault(__nccwpck_require__(91933));
const platform_1 = __importDefault(__nccwpck_require__(9707));
const unity_versioning_1 = __importDefault(__nccwpck_require__(17146));
const versioning_1 = __importDefault(__nccwpck_require__(88729));
const git_repo_1 = __nccwpck_require__(24271);
const github_cli_1 = __nccwpck_require__(44990);
class BuildParameters {
static create() {
return __awaiter(this, void 0, void 0, function* () {
@ -264,7 +264,6 @@ class BuildParameters {
const buildVersion = yield versioning_1.default.determineVersion(input_1.default.versioningStrategy, input_1.default.specifiedVersion);
const androidVersionCode = android_versioning_1.default.determineVersionCode(buildVersion, input_1.default.androidVersionCode);
const androidSdkManagerParameters = android_versioning_1.default.determineSdkManagerParameters(input_1.default.androidTargetSdkVersion);
yield input_1.default.PopulateQueryOverrideInput();
let unitySerial = '';
if (!process.env.UNITY_SERIAL && input_1.default.githubInputEnabled && input_1.default.cliOptions === undefined) {
//No serial was present so it is a personal license that we need to convert
@ -279,7 +278,9 @@ class BuildParameters {
else {
unitySerial = process.env.UNITY_SERIAL;
}
core.setSecret(unitySerial);
if (!input_1.default.cliMode) {
core.setSecret(unitySerial);
}
return {
version: unityVersion,
customImage: input_1.default.customImage,
@ -302,7 +303,7 @@ class BuildParameters {
androidSdkManagerParameters,
customParameters: input_1.default.customParameters,
sshAgent: input_1.default.sshAgent,
gitPrivateToken: yield input_1.default.gitPrivateToken(),
gitPrivateToken: input_1.default.gitPrivateToken || (yield github_cli_1.GithubCliReader.GetGitHubAuthToken()),
chownFilesTo: input_1.default.chownFilesTo,
cloudRunnerCluster: input_1.default.cloudRunnerCluster,
awsBaseStackName: input_1.default.awsBaseStackName,
@ -315,9 +316,12 @@ class BuildParameters {
preBuildSteps: input_1.default.preBuildSteps,
customJob: input_1.default.customJob,
runNumber: input_1.default.runNumber,
branch: yield input_1.default.branch(),
githubRepo: yield input_1.default.githubRepo(),
branch: input_1.default.branch || (yield git_repo_1.GitRepoReader.GetBranch()),
cloudRunnerBranch: input_1.default.cloudRunnerBranch.split('/').reverse()[0],
cloudRunnerIntegrationTests: input_1.default.cloudRunnerTests,
githubRepo: input_1.default.githubRepo || (yield git_repo_1.GitRepoReader.GetRemote()) || 'game-ci/unity-builder',
remoteBuildCluster: input_1.default.cloudRunnerCluster,
cliMode: input_1.default.cliMode,
awsStackName: input_1.default.awsBaseStackName,
gitSha: input_1.default.gitSha,
logId: nanoid_1.customAlphabet(cloud_runner_constants_1.default.alphabet, 9)(),
@ -435,7 +439,11 @@ function CliFunction(key, description) {
}
exports.CliFunction = CliFunction;
function GetCliFunctions(key) {
return targets.find((x) => x.key === key);
const results = targets.find((x) => x.key === key);
if (results === undefined || results.length === 0) {
throw new Error('no CLI mode found');
}
return results;
}
exports.GetCliFunctions = GetCliFunctions;
function GetAllCliModes() {
@ -506,41 +514,48 @@ const cloud_runner_state_1 = __nccwpck_require__(70912);
const setup_cloud_runner_repository_1 = __nccwpck_require__(39656);
const SDK = __importStar(__nccwpck_require__(71786));
class CLI {
static RunCli(options) {
static RunCli() {
return __awaiter(this, void 0, void 0, function* () {
__1.Input.githubInputEnabled = false;
const results = cli_decorator_1.GetCliFunctions(options.mode);
if (results === undefined || results.length === 0) {
throw new Error('no CLI mode found');
}
yield __1.Input.PopulateQueryOverrideInput();
CLI.logInput();
const results = cli_decorator_1.GetCliFunctions(CLI.options.mode);
cloud_runner_logger_1.default.log(`Entrypoint: ${results.key}`);
options.versioning = 'None';
__1.Input.cliOptions = options;
CLI.options.versioning = 'None';
return yield results.target[results.propertyKey]();
});
}
static isCliMode(options) {
return options.mode !== undefined && options.mode !== '';
}
static SetupCli() {
static InitCliMode() {
const program = new commander_ts_1.Command();
program.version('0.0.1');
const properties = Object.getOwnPropertyNames(__1.Input);
core.info(`\n`);
core.info(`INPUT:`);
const actionYamlReader = new action_yaml_1.ActionYamlReader();
for (const element of properties) {
program.option(`--${element} <${element}>`, actionYamlReader.GetActionYamlValue(element));
if (__1.Input[element] !== undefined && __1.Input[element] !== '' && typeof __1.Input[element] !== `function`) {
core.info(`${element} ${__1.Input[element]}`);
}
}
core.info(`\n`);
program.option('-m, --mode <mode>', cli_decorator_1.GetAllCliModes()
.map((x) => `${x.key} (${x.description})`)
.join(` | `));
program.parse(process.argv);
return program.opts();
CLI.options = program.opts();
__1.Input.cliOptions = CLI.options;
return __1.Input.cliMode;
}
static logInput() {
core.info(`\n`);
core.info(`INPUT:`);
const properties = Object.getOwnPropertyNames(__1.Input);
for (const element of properties) {
if (__1.Input[element] !== undefined &&
__1.Input[element] !== '' &&
typeof __1.Input[element] !== `function` &&
element !== 'length' &&
element !== 'cliOptions' &&
element !== 'prototype') {
core.info(`${element} ${__1.Input[element]}`);
}
}
core.info(`\n`);
}
static CLIBuild() {
return __awaiter(this, void 0, void 0, function* () {
@ -616,7 +631,6 @@ exports.Caching = void 0;
const console_1 = __nccwpck_require__(96206);
const fs_1 = __importDefault(__nccwpck_require__(57147));
const path_1 = __importDefault(__nccwpck_require__(71017));
const __1 = __nccwpck_require__(41359);
const cloud_runner_logger_1 = __importDefault(__nccwpck_require__(22855));
const cloud_runner_state_1 = __nccwpck_require__(70912);
const cloud_runner_system_1 = __nccwpck_require__(66879);
@ -632,10 +646,10 @@ class Caching {
yield cloud_runner_system_1.CloudRunnerSystem.Run(`mkdir -p ${cacheFolder}`);
}
process.chdir(path_1.default.resolve(sourceFolder, '..'));
if (__1.Input.cloudRunnerTests) {
if (cloud_runner_state_1.CloudRunnerState.buildParams.cloudRunnerIntegrationTests) {
cloud_runner_logger_1.default.log(`Hashed cache folder ${yield lfs_hashing_1.LFSHashing.hashAllFiles(sourceFolder)} ${sourceFolder} ${path_1.default.basename(sourceFolder)}`);
}
if (__1.Input.cloudRunnerTests) {
if (cloud_runner_state_1.CloudRunnerState.buildParams.cloudRunnerIntegrationTests) {
yield cloud_runner_system_1.CloudRunnerSystem.Run(`ls ${path_1.default.basename(sourceFolder)}`);
}
// eslint-disable-next-line func-style
@ -654,7 +668,7 @@ class Caching {
cloud_runner_system_1.CloudRunnerSystem.Run(`mv ${cacheKey}.zip ${cacheFolder}`);
remote_client_logger_1.RemoteClientLogger.log(`moved ${cacheKey}.zip to ${cacheFolder}`);
console_1.assert(fs_1.default.existsSync(`${path_1.default.join(cacheFolder, cacheKey)}.zip`), 'cache zip exists inside cache folder');
if (__1.Input.cloudRunnerTests) {
if (cloud_runner_state_1.CloudRunnerState.buildParams.cloudRunnerIntegrationTests) {
yield cloud_runner_system_1.CloudRunnerSystem.Run(`ls ${cacheFolder}`);
}
}
@ -780,7 +794,9 @@ class CloudRunnerSystem {
output += outputChunk;
});
child.on('close', function (code) {
remote_client_logger_1.RemoteClientLogger.log(`[Exit code ${code}]`);
if (!suppressLogs) {
remote_client_logger_1.RemoteClientLogger.log(`[Exit code ${code}]`);
}
if (code !== 0 && !suppressError) {
throw new Error(output);
}
@ -920,7 +936,6 @@ const cloud_runner_state_1 = __nccwpck_require__(70912);
const caching_1 = __nccwpck_require__(38759);
const lfs_hashing_1 = __nccwpck_require__(31938);
const cloud_runner_system_1 = __nccwpck_require__(66879);
const __1 = __nccwpck_require__(41359);
const remote_client_logger_1 = __nccwpck_require__(28082);
const path_1 = __importDefault(__nccwpck_require__(71017));
const console_1 = __nccwpck_require__(96206);
@ -972,7 +987,7 @@ class SetupCloudRunnerRepository {
}
static pullLatestLFS() {
return __awaiter(this, void 0, void 0, function* () {
if (__1.Input.cloudRunnerTests) {
if (cloud_runner_state_1.CloudRunnerState.buildParams.cloudRunnerIntegrationTests) {
yield cloud_runner_system_1.CloudRunnerSystem.Run(`ls -lh ${cloud_runner_state_1.CloudRunnerState.lfsDirectoryFull}/..`);
}
process.chdir(cloud_runner_state_1.CloudRunnerState.repoPathFull);
@ -981,7 +996,7 @@ class SetupCloudRunnerRepository {
yield cloud_runner_system_1.CloudRunnerSystem.Run(`git lfs pull`);
remote_client_logger_1.RemoteClientLogger.log(`pulled latest LFS files`);
console_1.assert(fs_1.default.existsSync(cloud_runner_state_1.CloudRunnerState.lfsDirectoryFull));
if (__1.Input.cloudRunnerTests) {
if (cloud_runner_state_1.CloudRunnerState.buildParams.cloudRunnerIntegrationTests) {
yield cloud_runner_system_1.CloudRunnerSystem.Run(`ls -lh ${cloud_runner_state_1.CloudRunnerState.lfsDirectoryFull}/..`);
}
});
@ -1177,13 +1192,13 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.AWSError = void 0;
const cloud_runner_logger_1 = __importDefault(__nccwpck_require__(22855));
const core = __importStar(__nccwpck_require__(42186));
const __1 = __nccwpck_require__(41359);
const cloud_runner_state_1 = __nccwpck_require__(70912);
class AWSError {
static handleStackCreationFailure(error, CF, taskDefStackName) {
return __awaiter(this, void 0, void 0, function* () {
cloud_runner_logger_1.default.log('aws error: ');
core.error(JSON.stringify(error, undefined, 4));
if (__1.Input.cloudRunnerTests) {
if (cloud_runner_state_1.CloudRunnerState.buildParams.cloudRunnerIntegrationTests) {
cloud_runner_logger_1.default.log('Getting events and resources for task stack');
const events = (yield CF.describeStackEvents({ StackName: taskDefStackName }).promise()).StackEvents;
cloud_runner_logger_1.default.log(JSON.stringify(events, undefined, 4));
@ -1397,31 +1412,40 @@ class AWSTaskRunner {
},
},
}).promise();
cloud_runner_logger_1.default.log('Cloud runner job is starting');
const taskArn = ((_o = task.tasks) === null || _o === void 0 ? void 0 : _o[0].taskArn) || '';
cloud_runner_logger_1.default.log('Cloud runner job is starting');
yield AWSTaskRunner.waitUntilTaskRunning(ECS, taskArn, cluster);
cloud_runner_logger_1.default.log(`Cloud runner job status is running ${(_p = (yield AWSTaskRunner.describeTasks(ECS, cluster, taskArn))) === null || _p === void 0 ? void 0 : _p.lastStatus}`);
const output = yield this.streamLogsUntilTaskStops(ECS, CF, taskDef, cluster, taskArn, streamName);
const taskData = yield AWSTaskRunner.describeTasks(ECS, cluster, taskArn);
const exitCode = (_q = taskData.containers) === null || _q === void 0 ? void 0 : _q[0].exitCode;
const wasSuccessful = exitCode === 0 || (exitCode === undefined && taskData.lastStatus === 'RUNNING');
if (wasSuccessful) {
cloud_runner_logger_1.default.log(`Cloud runner job has finished successfully`);
return output;
}
else {
const message = `Cloud runner job exit code ${exitCode}`;
taskData.overrides = undefined;
taskData.attachments = undefined;
cloud_runner_logger_1.default.log(`${message} ${JSON.stringify(taskData, undefined, 4)}`);
throw new Error(message);
}
});
}
static waitUntilTaskRunning(ECS, taskArn, cluster) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
try {
yield ECS.waitFor('tasksRunning', { tasks: [taskArn], cluster }).promise();
}
catch (error_) {
const error = error_;
yield new Promise((resolve) => setTimeout(resolve, 3000));
cloud_runner_logger_1.default.log(`Cloud runner job has ended ${(_p = (yield AWSTaskRunner.describeTasks(ECS, cluster, taskArn)).containers) === null || _p === void 0 ? void 0 : _p[0].lastStatus}`);
cloud_runner_logger_1.default.log(`Cloud runner job has ended ${(_a = (yield AWSTaskRunner.describeTasks(ECS, cluster, taskArn)).containers) === null || _a === void 0 ? void 0 : _a[0].lastStatus}`);
core.setFailed(error);
core.error(error);
}
cloud_runner_logger_1.default.log(`Cloud runner job is running`);
const output = yield this.streamLogsUntilTaskStops(ECS, CF, taskDef, cluster, taskArn, streamName);
const exitCode = (_q = (yield AWSTaskRunner.describeTasks(ECS, cluster, taskArn)).containers) === null || _q === void 0 ? void 0 : _q[0].exitCode;
cloud_runner_logger_1.default.log(`Cloud runner job exit code ${exitCode}`);
cloud_runner_logger_1.default.log(`job failed with exit code ${exitCode} ${JSON.stringify(yield ECS.describeTasks({ tasks: [taskArn], cluster }).promise(), undefined, 4)}`);
if (exitCode !== 0 && exitCode !== undefined) {
core.error(`job failed with exit code ${exitCode} "exitCode !== 0 && exitCode !== undefined"`);
throw new Error(`job failed with exit code ${exitCode}`);
}
else {
cloud_runner_logger_1.default.log(`Cloud runner job has finished successfully`);
return output;
}
});
}
static describeTasks(ECS, clusterName, taskArn) {
@ -1440,12 +1464,10 @@ class AWSTaskRunner {
});
}
static streamLogsUntilTaskStops(ECS, CF, taskDef, clusterName, taskArn, kinesisStreamName) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
const kinesis = new AWS.Kinesis();
const stream = yield AWSTaskRunner.getLogStream(kinesis, kinesisStreamName);
let iterator = yield AWSTaskRunner.getLogIterator(kinesis, stream);
cloud_runner_logger_1.default.log(`Cloud runner job status is ${(_a = (yield AWSTaskRunner.describeTasks(ECS, clusterName, taskArn))) === null || _a === void 0 ? void 0 : _a.lastStatus}`);
const logBaseUrl = `https://${__1.Input.region}.console.aws.amazon.com/cloudwatch/home?region=${CF.config.region}#logsV2:log-groups/log-group/${taskDef.taskDefStackName}`;
cloud_runner_logger_1.default.log(`You can also see the logs at AWS Cloud Watch: ${logBaseUrl}`);
let shouldReadLogs = true;
@ -1473,6 +1495,9 @@ class AWSTaskRunner {
});
}
static checkStreamingShouldContinue(taskData, timestamp, shouldReadLogs) {
if ((taskData === null || taskData === void 0 ? void 0 : taskData.lastStatus) === 'UNKNOWN') {
cloud_runner_logger_1.default.log('## Cloud runner job unknwon');
}
if ((taskData === null || taskData === void 0 ? void 0 : taskData.lastStatus) !== 'RUNNING') {
if (timestamp === 0) {
cloud_runner_logger_1.default.log('## Cloud runner job stopped, streaming end of logs');
@ -1501,7 +1526,7 @@ class AWSTaskRunner {
core.warning('LIBRARY NOT FOUND!');
}
message = `[${cloud_runner_statics_1.CloudRunnerStatics.logPrefix}] ${message}`;
if (__1.Input.cloudRunnerTests) {
if (cloud_runner_state_1.CloudRunnerState.buildParams.cloudRunnerIntegrationTests) {
output += message;
}
cloud_runner_logger_1.default.log(message);
@ -1784,8 +1809,10 @@ class CloudRunner {
cloud_runner_state_1.CloudRunnerState.setup(buildParameters);
CloudRunner.setupBuildPlatform();
const parameters = task_parameter_serializer_1.TaskParameterSerializer.readBuildEnvironmentVariables();
for (const element of parameters) {
core.setOutput(element.name, element.value);
if (!buildParameters.cliMode) {
for (const element of parameters) {
core.setOutput(element.name, element.value);
}
}
}
static setupBuildPlatform() {
@ -1805,18 +1832,23 @@ class CloudRunner {
return __awaiter(this, void 0, void 0, function* () {
CloudRunner.setup(buildParameters);
try {
core.startGroup('Setup remote runner');
if (!cloud_runner_state_1.CloudRunnerState.buildParams.cliMode)
core.startGroup('Setup remote runner');
yield cloud_runner_state_1.CloudRunnerState.CloudRunnerProviderPlatform.setupSharedResources(cloud_runner_state_1.CloudRunnerState.buildParams.buildGuid, cloud_runner_state_1.CloudRunnerState.buildParams, cloud_runner_state_1.CloudRunnerState.branchName, cloud_runner_state_1.CloudRunnerState.defaultSecrets);
core.endGroup();
if (!cloud_runner_state_1.CloudRunnerState.buildParams.cliMode)
core.endGroup();
const output = yield new workflow_composition_root_1.WorkflowCompositionRoot().run(new cloud_runner_step_state_1.CloudRunnerStepState(baseImage, task_parameter_serializer_1.TaskParameterSerializer.readBuildEnvironmentVariables(), cloud_runner_state_1.CloudRunnerState.defaultSecrets));
core.startGroup('Cleanup');
if (!cloud_runner_state_1.CloudRunnerState.buildParams.cliMode)
core.startGroup('Cleanup');
yield cloud_runner_state_1.CloudRunnerState.CloudRunnerProviderPlatform.cleanupSharedResources(cloud_runner_state_1.CloudRunnerState.buildParams.buildGuid, cloud_runner_state_1.CloudRunnerState.buildParams, cloud_runner_state_1.CloudRunnerState.branchName, cloud_runner_state_1.CloudRunnerState.defaultSecrets);
cloud_runner_logger_1.default.log(`Cleanup complete`);
core.endGroup();
if (!cloud_runner_state_1.CloudRunnerState.buildParams.cliMode)
core.endGroup();
return output;
}
catch (error) {
core.endGroup();
if (!cloud_runner_state_1.CloudRunnerState.buildParams.cliMode)
core.endGroup();
yield cloud_runner_error_1.CloudRunnerError.handleException(error);
throw error;
}
@ -2499,7 +2531,9 @@ class KubernetesStorage {
cloud_runner_logger_1.default.log(JSON.stringify(pvcList, undefined, 4));
if (pvcList.includes(pvcName)) {
cloud_runner_logger_1.default.log(`pvc ${pvcName} already exists`);
core.setOutput('volume', pvcName);
if (!buildParameters.cliMode) {
core.setOutput('volume', pvcName);
}
return;
}
cloud_runner_logger_1.default.log(`Creating PVC ${pvcName} (does not exist)`);
@ -2623,7 +2657,7 @@ const cloud_runner_logger_1 = __importDefault(__nccwpck_require__(22855));
const core = __importStar(__nccwpck_require__(42186));
const cloud_runner_statics_1 = __nccwpck_require__(90828);
const async_wait_until_1 = __importDefault(__nccwpck_require__(41299));
const __1 = __nccwpck_require__(41359);
const cloud_runner_state_1 = __nccwpck_require__(70912);
class KubernetesTaskRunner {
static runTask(kubeConfig, kubeClient, jobName, podName, containerName, namespace, logCallback) {
return __awaiter(this, void 0, void 0, function* () {
@ -2635,7 +2669,7 @@ class KubernetesTaskRunner {
didStreamAnyLogs = true;
let message = chunk.toString().trimRight(`\n`);
message = `[${cloud_runner_statics_1.CloudRunnerStatics.logPrefix}] ${message}`;
if (__1.Input.cloudRunnerTests) {
if (cloud_runner_state_1.CloudRunnerState.buildParams.cloudRunnerIntegrationTests) {
output += message;
}
logCallback(message);
@ -2716,19 +2750,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Hook = exports.CloudRunnerBuildCommandProcessor = void 0;
const __1 = __nccwpck_require__(41359);
const yaml_1 = __importDefault(__nccwpck_require__(44603));
const cloud_runner_state_1 = __nccwpck_require__(70912);
class CloudRunnerBuildCommandProcessor {
static ProcessCommands(commands, buildParameters) {
const hooks = CloudRunnerBuildCommandProcessor.getHooks(buildParameters.customJobHooks).filter((x) => x.step.includes(`all`));
return `echo "---"
echo "start cloud runner init"
${__1.Input.cloudRunnerTests ? '' : '#'} printenv
echo "start cloud runner job"
${cloud_runner_state_1.CloudRunnerState.buildParams.cloudRunnerIntegrationTests ? '' : '#'} printenv
echo "start of cloud runner job"
${hooks.filter((x) => x.hook.includes(`before`)).map((x) => x.commands) || ' '}
${commands}
${hooks.filter((x) => x.hook.includes(`after`)).map((x) => x.commands) || ' '}
echo "end of cloud runner job
echo "end of cloud runner job"
---${buildParameters.logId}"
`;
}
@ -3100,7 +3134,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.BuildStep = void 0;
const path_1 = __importDefault(__nccwpck_require__(71017));
const __1 = __nccwpck_require__(41359);
const cloud_runner_build_command_process_1 = __nccwpck_require__(71899);
const cloud_runner_logger_1 = __importDefault(__nccwpck_require__(22855));
const cloud_runner_state_1 = __nccwpck_require__(70912);
@ -3113,10 +3146,18 @@ class BuildStep {
static BuildStep(image, environmentVariables, secrets) {
return __awaiter(this, void 0, void 0, function* () {
cloud_runner_logger_1.default.logLine(` `);
cloud_runner_logger_1.default.logLine('Starting part 2/2 (build unity project)');
cloud_runner_logger_1.default.logLine('Starting build automation job');
const hooks = cloud_runner_build_command_process_1.CloudRunnerBuildCommandProcessor.getHooks(cloud_runner_state_1.CloudRunnerState.buildParams.customJobHooks).filter((x) => x.step.includes(`setup`));
return yield cloud_runner_state_1.CloudRunnerState.CloudRunnerProviderPlatform.runTask(cloud_runner_state_1.CloudRunnerState.buildParams.buildGuid, image, `${hooks.filter((x) => x.hook.includes(`before`)).map((x) => x.commands) || ' '}
return yield cloud_runner_state_1.CloudRunnerState.CloudRunnerProviderPlatform.runTask(cloud_runner_state_1.CloudRunnerState.buildParams.buildGuid, image, `apt-get update
apt-get install -y -q zip tree nodejs git-lfs jq unzip
${hooks.filter((x) => x.hook.includes(`before`)).map((x) => x.commands) || ' '}
export GITHUB_WORKSPACE="${cloud_runner_state_1.CloudRunnerState.repoPathFull}"
export GIT_DISCOVERY_ACROSS_FILESYSTEM=1
mkdir -p ${cloud_runner_state_1.CloudRunnerState.builderPathFull.replace(/\\/g, `/`)}
git clone -q -b ${cloud_runner_state_1.CloudRunnerState.buildParams.cloudRunnerBranch} ${cloud_runner_state_1.CloudRunnerState.unityBuilderRepoUrl} "${cloud_runner_state_1.CloudRunnerState.builderPathFull.replace(/\\/g, `/`)}"
${cloud_runner_state_1.CloudRunnerState.buildParams.cloudRunnerIntegrationTests ? '' : '#'} tree ${cloud_runner_state_1.CloudRunnerState.builderPathFull.replace(/\\/g, `/`)}
chmod +x ${path_1.default.join(cloud_runner_state_1.CloudRunnerState.builderPathFull, 'dist', `index.js`).replace(/\\/g, `/`)}
node ${path_1.default.join(cloud_runner_state_1.CloudRunnerState.builderPathFull, 'dist', `index.js`).replace(/\\/g, `/`)} -m remote-cli
cp -r "${path_1.default
.join(cloud_runner_state_1.CloudRunnerState.builderPathFull, 'dist', 'default-build-script')
.replace(/\\/g, `/`)}" "/UnityBuilderAction"
@ -3129,8 +3170,6 @@ class BuildStep {
chmod -R +x "/entrypoint.sh"
chmod -R +x "/steps"
/entrypoint.sh
apt-get update
apt-get install -y -q zip tree nodejs
cd "${cloud_runner_state_1.CloudRunnerState.libraryFolderFull.replace(/\\/g, `/`)}/.."
zip -r "lib-${cloud_runner_state_1.CloudRunnerState.buildParams.buildGuid}.zip" "Library"
mv "lib-${cloud_runner_state_1.CloudRunnerState.buildParams.buildGuid}.zip" "${cloud_runner_state_1.CloudRunnerState.cacheFolderFull.replace(/\\/g, `/`)}/Library"
@ -3141,7 +3180,7 @@ class BuildStep {
node ${path_1.default
.join(cloud_runner_state_1.CloudRunnerState.builderPathFull, 'dist', `index.js`)
.replace(/\\/g, `/`)} -m cache-push "Library" "lib-${cloud_runner_state_1.CloudRunnerState.buildParams.buildGuid}.zip" "${cloud_runner_state_1.CloudRunnerState.cacheFolderFull.replace(/\\/g, `/`)}/Library"
${__1.Input.cloudRunnerTests ? '' : '#'} tree -lh "${cloud_runner_state_1.CloudRunnerState.cacheFolderFull}"
${cloud_runner_state_1.CloudRunnerState.buildParams.cloudRunnerIntegrationTests ? '' : '#'} tree -lh "${cloud_runner_state_1.CloudRunnerState.cacheFolderFull}"
${hooks.filter((x) => x.hook.includes(`after`)).map((x) => x.commands) || ' '}
`, `/${cloud_runner_state_1.CloudRunnerState.buildVolumeFolder}`, `/${cloud_runner_state_1.CloudRunnerState.projectPathFull}`, environmentVariables, secrets);
});
@ -3172,7 +3211,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SetupStep = void 0;
const path_1 = __importDefault(__nccwpck_require__(71017));
const __1 = __nccwpck_require__(41359);
const cloud_runner_build_command_process_1 = __nccwpck_require__(71899);
const cloud_runner_logger_1 = __importDefault(__nccwpck_require__(22855));
const cloud_runner_state_1 = __nccwpck_require__(70912);
@ -3187,11 +3225,6 @@ class SetupStep {
}
});
}
static getCloudRunnerBranch() {
var _a;
return ((_a = process.env.CLOUD_RUNNER_BRANCH) === null || _a === void 0 ? void 0 : _a.includes('/')) ? process.env.CLOUD_RUNNER_BRANCH.split('/').reverse()[0]
: process.env.CLOUD_RUNNER_BRANCH;
}
static downloadRepository(image, environmentVariables, secrets) {
return __awaiter(this, void 0, void 0, function* () {
try {
@ -3203,8 +3236,8 @@ class SetupStep {
${hooks.filter((x) => x.hook.includes(`before`)).map((x) => x.commands) || ' '}
export GIT_DISCOVERY_ACROSS_FILESYSTEM=1
mkdir -p ${cloud_runner_state_1.CloudRunnerState.builderPathFull.replace(/\\/g, `/`)}
git clone -q -b ${SetupStep.getCloudRunnerBranch()} ${cloud_runner_state_1.CloudRunnerState.unityBuilderRepoUrl} "${cloud_runner_state_1.CloudRunnerState.builderPathFull.replace(/\\/g, `/`)}"
${__1.Input.cloudRunnerTests ? '' : '#'} tree ${cloud_runner_state_1.CloudRunnerState.builderPathFull.replace(/\\/g, `/`)}
git clone -q -b ${cloud_runner_state_1.CloudRunnerState.buildParams.cloudRunnerBranch} ${cloud_runner_state_1.CloudRunnerState.unityBuilderRepoUrl} "${cloud_runner_state_1.CloudRunnerState.builderPathFull.replace(/\\/g, `/`)}"
${cloud_runner_state_1.CloudRunnerState.buildParams.cloudRunnerIntegrationTests ? '' : '#'} tree ${cloud_runner_state_1.CloudRunnerState.builderPathFull.replace(/\\/g, `/`)}
chmod +x ${path_1.default.join(cloud_runner_state_1.CloudRunnerState.builderPathFull, 'dist', `index.js`).replace(/\\/g, `/`)}
node ${path_1.default.join(cloud_runner_state_1.CloudRunnerState.builderPathFull, 'dist', `index.js`).replace(/\\/g, `/`)} -m remote-cli
${hooks.filter((x) => x.hook.includes(`after`)).map((x) => x.commands) || ' '}
@ -3265,7 +3298,6 @@ const task_parameter_serializer_1 = __nccwpck_require__(35346);
const cloud_runner_state_1 = __nccwpck_require__(70912);
const cloud_runner_step_state_1 = __nccwpck_require__(64854);
const build_step_1 = __nccwpck_require__(91491);
const setup_step_1 = __nccwpck_require__(58923);
const custom_workflow_1 = __nccwpck_require__(3786);
const core = __importStar(__nccwpck_require__(42186));
class BuildAutomationWorkflow {
@ -3283,26 +3315,39 @@ class BuildAutomationWorkflow {
return __awaiter(this, void 0, void 0, function* () {
try {
cloud_runner_logger_1.default.log(`Cloud Runner is running standard build automation`);
core.startGroup('pre build steps');
if (!cloud_runner_state_1.CloudRunnerState.buildParams.cliMode)
core.startGroup('pre build steps');
let output = '';
if (cloud_runner_state_1.CloudRunnerState.buildParams.preBuildSteps !== '') {
output += yield custom_workflow_1.CustomWorkflow.runCustomJob(cloud_runner_state_1.CloudRunnerState.buildParams.preBuildSteps);
}
core.endGroup();
if (!cloud_runner_state_1.CloudRunnerState.buildParams.cliMode)
core.endGroup();
cloud_runner_logger_1.default.logWithTime('Configurable pre build step(s) time');
core.startGroup('setup');
output += yield new setup_step_1.SetupStep().run(new cloud_runner_step_state_1.CloudRunnerStepState('alpine/git', task_parameter_serializer_1.TaskParameterSerializer.readBuildEnvironmentVariables(), cloud_runner_state_1.CloudRunnerState.defaultSecrets));
core.endGroup();
cloud_runner_logger_1.default.logWithTime('Download repository step time');
core.startGroup('build');
// core.startGroup('setup');
// output += await new SetupStep().run(
// new CloudRunnerStepState(
// 'alpine/git',
// TaskParameterSerializer.readBuildEnvironmentVariables(),
// CloudRunnerState.defaultSecrets,
// ),
// );
// core.endGroup();
// CloudRunnerLogger.logWithTime('Download repository step time');
if (!cloud_runner_state_1.CloudRunnerState.buildParams.cliMode)
core.startGroup('build');
cloud_runner_logger_1.default.log(baseImage.toString());
output += yield new build_step_1.BuildStep().run(new cloud_runner_step_state_1.CloudRunnerStepState(baseImage, task_parameter_serializer_1.TaskParameterSerializer.readBuildEnvironmentVariables(), cloud_runner_state_1.CloudRunnerState.defaultSecrets));
core.endGroup();
if (!cloud_runner_state_1.CloudRunnerState.buildParams.cliMode)
core.endGroup();
cloud_runner_logger_1.default.logWithTime('Build time');
core.startGroup('post build steps');
if (!cloud_runner_state_1.CloudRunnerState.buildParams.cliMode)
core.startGroup('post build steps');
if (cloud_runner_state_1.CloudRunnerState.buildParams.postBuildSteps !== '') {
output += yield custom_workflow_1.CustomWorkflow.runCustomJob(cloud_runner_state_1.CloudRunnerState.buildParams.postBuildSteps);
}
core.endGroup();
if (!cloud_runner_state_1.CloudRunnerState.buildParams.cliMode)
core.endGroup();
cloud_runner_logger_1.default.logWithTime('Configurable post build step(s) time');
cloud_runner_logger_1.default.log(`Cloud Runner finished running standard build automation`);
return output;
@ -3347,7 +3392,7 @@ class CustomWorkflow {
return __awaiter(this, void 0, void 0, function* () {
try {
cloud_runner_logger_1.default.log(`Cloud Runner is running in custom job mode`);
if (__1.Input.cloudRunnerTests) {
if (cloud_runner_state_1.CloudRunnerState.buildParams.cloudRunnerIntegrationTests) {
cloud_runner_logger_1.default.log(`Parsing build steps: ${buildSteps}`);
}
try {
@ -3887,12 +3932,9 @@ const system_1 = __importDefault(__nccwpck_require__(62177));
const fs_1 = __importDefault(__nccwpck_require__(57147));
const cloud_runner_system_1 = __nccwpck_require__(66879);
class GitRepoReader {
static GetSha() {
return '';
}
static GetRemote() {
return __awaiter(this, void 0, void 0, function* () {
return (yield cloud_runner_system_1.CloudRunnerSystem.Run(`git remote -v`))
return (yield cloud_runner_system_1.CloudRunnerSystem.Run(`git remote -v`, false, true))
.split(' ')[1]
.split('https://github.com/')[1]
.split('.git')[0];
@ -3951,11 +3993,11 @@ class GithubCliReader {
static GetGitHubAuthToken() {
return __awaiter(this, void 0, void 0, function* () {
try {
const authStatus = yield cloud_runner_system_1.CloudRunnerSystem.Run(`gh auth status`, true);
const authStatus = yield cloud_runner_system_1.CloudRunnerSystem.Run(`gh auth status`, false, true);
if (authStatus.includes('You are not logged') || authStatus === '') {
return '';
}
return (yield cloud_runner_system_1.CloudRunnerSystem.Run(`gh auth status -t`))
return (yield cloud_runner_system_1.CloudRunnerSystem.Run(`gh auth status -t`, false, true))
.split(`Token: `)[1]
.replace(/ /g, '')
.replace(/\n/g, '');
@ -4015,8 +4057,6 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
const fs_1 = __importDefault(__nccwpck_require__(57147));
const path_1 = __importDefault(__nccwpck_require__(71017));
const generic_input_reader_1 = __nccwpck_require__(2263);
const git_repo_1 = __nccwpck_require__(24271);
const github_cli_1 = __nccwpck_require__(44990);
const platform_1 = __importDefault(__nccwpck_require__(9707));
const formatFunction = (value, arguments_) => {
let formatted = value;
@ -4048,6 +4088,9 @@ class Input {
}
}
}
static get cliMode() {
return Input.cliOptions !== undefined && Input.cliOptions.mode !== undefined && Input.cliOptions.mode !== '';
}
static queryOverride(query) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.shouldUseOverride(query)) {
@ -4072,7 +4115,7 @@ class Input {
if (Input.githubInputEnabled && coreInput && coreInput !== '') {
return coreInput;
}
if (Input.cliOptions !== undefined && Input.cliOptions[query] !== undefined) {
if (Input.cliMode && Input.cliOptions[query] !== undefined) {
return Input.cliOptions[query];
}
if (Input.queryOverrides !== undefined) {
@ -4094,29 +4137,19 @@ class Input {
static get region() {
return Input.getInput('region') || 'eu-west-2';
}
static githubRepo() {
return __awaiter(this, void 0, void 0, function* () {
return (Input.getInput('GITHUB_REPOSITORY') ||
Input.getInput('GITHUB_REPO') ||
(yield git_repo_1.GitRepoReader.GetRemote()) ||
'game-ci/unity-builder');
});
static get githubRepo() {
return Input.getInput('GITHUB_REPOSITORY') || Input.getInput('GITHUB_REPO') || false;
}
static branch() {
return __awaiter(this, void 0, void 0, function* () {
if (yield git_repo_1.GitRepoReader.GetBranch()) {
return yield git_repo_1.GitRepoReader.GetBranch();
}
else if (Input.getInput(`GITHUB_REF`)) {
return Input.getInput(`GITHUB_REF`).replace('refs/', '').replace(`head/`, '');
}
else if (Input.getInput('branch')) {
return Input.getInput('branch');
}
else {
return 'main';
}
});
static get branch() {
if (Input.getInput(`GITHUB_REF`)) {
return Input.getInput(`GITHUB_REF`).replace('refs/', '').replace(`head/`, '');
}
else if (Input.getInput('branch')) {
return Input.getInput('branch');
}
else {
return '';
}
}
static get gitSha() {
if (Input.getInput(`GITHUB_SHA`)) {
@ -4125,9 +4158,6 @@ class Input {
else if (Input.getInput(`GitSHA`)) {
return Input.getInput(`GitSHA`);
}
else if (git_repo_1.GitRepoReader.GetSha()) {
return git_repo_1.GitRepoReader.GetSha();
}
}
static get runNumber() {
return Input.getInput('GITHUB_RUN_NUMBER') || '0';
@ -4197,10 +4227,8 @@ class Input {
static get sshAgent() {
return Input.getInput('sshAgent') || '';
}
static gitPrivateToken() {
return __awaiter(this, void 0, void 0, function* () {
return core.getInput('gitPrivateToken') || (yield github_cli_1.GithubCliReader.GetGitHubAuthToken()) || '';
});
static get gitPrivateToken() {
return core.getInput('gitPrivateToken') || false;
}
static get customJob() {
return Input.getInput('customJob') || '';
@ -4220,6 +4248,9 @@ class Input {
static readInputOverrideCommand() {
return Input.getInput('readInputOverrideCommand') || '';
}
static get cloudRunnerBranch() {
return Input.getInput('cloudRunnerBranch') || 'cloud-runner-develop';
}
static get chownFilesTo() {
return Input.getInput('chownFilesTo') || '';
}

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,10 @@ import MacBuilder from './model/mac-builder';
import PlatformSetup from './model/platform-setup';
async function runMain() {
try {
if (CLI.InitCliMode()) {
await CLI.RunCli();
return;
}
Action.checkCompatibility();
Cache.verify();
@ -38,9 +42,4 @@ async function runMain() {
core.setFailed((error as Error).message);
}
}
const options = CLI.SetupCli();
if (CLI.isCliMode(options)) {
CLI.RunCli(options);
} else {
runMain();
}
runMain();

View File

@ -7,6 +7,8 @@ import Input from './input';
import Platform from './platform';
import UnityVersioning from './unity-versioning';
import Versioning from './versioning';
import { GitRepoReader } from './input-readers/git-repo';
import { GithubCliReader } from './input-readers/github-cli';
class BuildParameters {
public version!: string;
@ -60,6 +62,9 @@ class BuildParameters {
public gitSha!: string;
public logId!: string;
public buildGuid!: string;
public cloudRunnerBranch!: string;
public cloudRunnerIntegrationTests!: boolean;
public cliMode!: boolean;
static async create(): Promise<BuildParameters> {
const buildFile = this.parseBuildFile(Input.buildName, Input.targetPlatform, Input.androidAppBundle);
@ -72,8 +77,6 @@ class BuildParameters {
const androidSdkManagerParameters = AndroidVersioning.determineSdkManagerParameters(Input.androidTargetSdkVersion);
await Input.PopulateQueryOverrideInput();
let unitySerial = '';
if (!process.env.UNITY_SERIAL && Input.githubInputEnabled && Input.cliOptions === undefined) {
//No serial was present so it is a personal license that we need to convert
@ -87,7 +90,9 @@ class BuildParameters {
} else {
unitySerial = process.env.UNITY_SERIAL!;
}
core.setSecret(unitySerial);
if (!Input.cliMode) {
core.setSecret(unitySerial);
}
return {
version: unityVersion,
@ -112,7 +117,7 @@ class BuildParameters {
androidSdkManagerParameters,
customParameters: Input.customParameters,
sshAgent: Input.sshAgent,
gitPrivateToken: await Input.gitPrivateToken(),
gitPrivateToken: Input.gitPrivateToken || (await GithubCliReader.GetGitHubAuthToken()),
chownFilesTo: Input.chownFilesTo,
cloudRunnerCluster: Input.cloudRunnerCluster,
awsBaseStackName: Input.awsBaseStackName,
@ -125,9 +130,12 @@ class BuildParameters {
preBuildSteps: Input.preBuildSteps,
customJob: Input.customJob,
runNumber: Input.runNumber,
branch: await Input.branch(),
githubRepo: await Input.githubRepo(),
branch: Input.branch || (await GitRepoReader.GetBranch()),
cloudRunnerBranch: Input.cloudRunnerBranch.split('/').reverse()[0],
cloudRunnerIntegrationTests: Input.cloudRunnerTests,
githubRepo: Input.githubRepo || (await GitRepoReader.GetRemote()) || 'game-ci/unity-builder',
remoteBuildCluster: Input.cloudRunnerCluster,
cliMode: Input.cliMode,
awsStackName: Input.awsBaseStackName,
gitSha: Input.gitSha,
logId: customAlphabet(CloudRunnerConstants.alphabet, 9)(),

View File

@ -11,7 +11,11 @@ export function CliFunction(key: string, description: string) {
};
}
export function GetCliFunctions(key) {
return targets.find((x) => x.key === key);
const results = targets.find((x) => x.key === key);
if (results === undefined || results.length === 0) {
throw new Error('no CLI mode found');
}
return results;
}
export function GetAllCliModes() {
return targets.map((x) => {

View File

@ -10,39 +10,25 @@ import { SetupCloudRunnerRepository } from './remote-client/setup-cloud-runner-r
import * as SDK from 'aws-sdk';
export class CLI {
static async RunCli(options: any): Promise<void> {
private static options;
static async RunCli(): Promise<void> {
Input.githubInputEnabled = false;
const results = GetCliFunctions(options.mode);
if (results === undefined || results.length === 0) {
throw new Error('no CLI mode found');
}
await Input.PopulateQueryOverrideInput();
CLI.logInput();
const results = GetCliFunctions(CLI.options.mode);
CloudRunnerLogger.log(`Entrypoint: ${results.key}`);
options.versioning = 'None';
Input.cliOptions = options;
CLI.options.versioning = 'None';
return await results.target[results.propertyKey]();
}
static isCliMode(options: any) {
return options.mode !== undefined && options.mode !== '';
}
public static SetupCli() {
public static InitCliMode() {
const program = new Command();
program.version('0.0.1');
const properties = Object.getOwnPropertyNames(Input);
core.info(`\n`);
core.info(`INPUT:`);
const actionYamlReader: ActionYamlReader = new ActionYamlReader();
for (const element of properties) {
program.option(`--${element} <${element}>`, actionYamlReader.GetActionYamlValue(element));
if (Input[element] !== undefined && Input[element] !== '' && typeof Input[element] !== `function`) {
core.info(`${element} ${Input[element]}`);
}
}
core.info(`\n`);
program.option(
'-m, --mode <mode>',
GetAllCliModes()
@ -50,8 +36,28 @@ export class CLI {
.join(` | `),
);
program.parse(process.argv);
CLI.options = program.opts();
Input.cliOptions = CLI.options;
return Input.cliMode;
}
return program.opts();
private static logInput() {
core.info(`\n`);
core.info(`INPUT:`);
const properties = Object.getOwnPropertyNames(Input);
for (const element of properties) {
if (
Input[element] !== undefined &&
Input[element] !== '' &&
typeof Input[element] !== `function` &&
element !== 'length' &&
element !== 'cliOptions' &&
element !== 'prototype'
) {
core.info(`${element} ${Input[element]}`);
}
}
core.info(`\n`);
}
@CliFunction(`cli`, `runs a cloud runner build`)

View File

@ -1,7 +1,6 @@
import { assert } from 'console';
import fs from 'fs';
import path from 'path';
import { Input } from '../../..';
import CloudRunnerLogger from '../../../cloud-runner/services/cloud-runner-logger';
import { CloudRunnerState } from '../../../cloud-runner/state/cloud-runner-state';
import { CloudRunnerSystem } from './cloud-runner-system';
@ -18,7 +17,7 @@ export class Caching {
}
process.chdir(path.resolve(sourceFolder, '..'));
if (Input.cloudRunnerTests) {
if (CloudRunnerState.buildParams.cloudRunnerIntegrationTests) {
CloudRunnerLogger.log(
`Hashed cache folder ${await LFSHashing.hashAllFiles(sourceFolder)} ${sourceFolder} ${path.basename(
sourceFolder,
@ -26,7 +25,7 @@ export class Caching {
);
}
if (Input.cloudRunnerTests) {
if (CloudRunnerState.buildParams.cloudRunnerIntegrationTests) {
await CloudRunnerSystem.Run(`ls ${path.basename(sourceFolder)}`);
}
// eslint-disable-next-line func-style
@ -46,7 +45,7 @@ export class Caching {
RemoteClientLogger.log(`moved ${cacheKey}.zip to ${cacheFolder}`);
assert(fs.existsSync(`${path.join(cacheFolder, cacheKey)}.zip`), 'cache zip exists inside cache folder');
if (Input.cloudRunnerTests) {
if (CloudRunnerState.buildParams.cloudRunnerIntegrationTests) {
await CloudRunnerSystem.Run(`ls ${cacheFolder}`);
}
} catch (error) {

View File

@ -26,7 +26,9 @@ export class CloudRunnerSystem {
output += outputChunk;
});
child.on('close', function (code) {
RemoteClientLogger.log(`[Exit code ${code}]`);
if (!suppressLogs) {
RemoteClientLogger.log(`[Exit code ${code}]`);
}
if (code !== 0 && !suppressError) {
throw new Error(output);
}

View File

@ -3,7 +3,6 @@ import { CloudRunnerState } from '../../cloud-runner/state/cloud-runner-state';
import { Caching } from './remote-client-services/caching';
import { LFSHashing } from './remote-client-services/lfs-hashing';
import { CloudRunnerSystem } from './remote-client-services/cloud-runner-system';
import { Input } from '../..';
import { RemoteClientLogger } from './remote-client-services/remote-client-logger';
import path from 'path';
import { assert } from 'console';
@ -65,7 +64,7 @@ export class SetupCloudRunnerRepository {
}
private static async pullLatestLFS() {
if (Input.cloudRunnerTests) {
if (CloudRunnerState.buildParams.cloudRunnerIntegrationTests) {
await CloudRunnerSystem.Run(`ls -lh ${CloudRunnerState.lfsDirectoryFull}/..`);
}
process.chdir(CloudRunnerState.repoPathFull);
@ -75,7 +74,7 @@ export class SetupCloudRunnerRepository {
RemoteClientLogger.log(`pulled latest LFS files`);
assert(fs.existsSync(CloudRunnerState.lfsDirectoryFull));
if (Input.cloudRunnerTests) {
if (CloudRunnerState.buildParams.cloudRunnerIntegrationTests) {
await CloudRunnerSystem.Run(`ls -lh ${CloudRunnerState.lfsDirectoryFull}/..`);
}
}

View File

@ -1,13 +1,13 @@
import CloudRunnerLogger from '../services/cloud-runner-logger';
import * as SDK from 'aws-sdk';
import * as core from '@actions/core';
import { Input } from '../..';
import { CloudRunnerState } from '../state/cloud-runner-state';
export class AWSError {
static async handleStackCreationFailure(error: any, CF: SDK.CloudFormation, taskDefStackName: string) {
CloudRunnerLogger.log('aws error: ');
core.error(JSON.stringify(error, undefined, 4));
if (Input.cloudRunnerTests) {
if (CloudRunnerState.buildParams.cloudRunnerIntegrationTests) {
CloudRunnerLogger.log('Getting events and resources for task stack');
const events = (await CF.describeStackEvents({ StackName: taskDefStackName }).promise()).StackEvents;
CloudRunnerLogger.log(JSON.stringify(events, undefined, 4));

View File

@ -52,10 +52,29 @@ class AWSTaskRunner {
},
},
}).promise();
CloudRunnerLogger.log('Cloud runner job is starting');
const taskArn = task.tasks?.[0].taskArn || '';
CloudRunnerLogger.log('Cloud runner job is starting');
await AWSTaskRunner.waitUntilTaskRunning(ECS, taskArn, cluster);
CloudRunnerLogger.log(
`Cloud runner job status is running ${(await AWSTaskRunner.describeTasks(ECS, cluster, taskArn))?.lastStatus}`,
);
const output = await this.streamLogsUntilTaskStops(ECS, CF, taskDef, cluster, taskArn, streamName);
const taskData = await AWSTaskRunner.describeTasks(ECS, cluster, taskArn);
const exitCode = taskData.containers?.[0].exitCode;
const wasSuccessful = exitCode === 0 || (exitCode === undefined && taskData.lastStatus === 'RUNNING');
if (wasSuccessful) {
CloudRunnerLogger.log(`Cloud runner job has finished successfully`);
return output;
} else {
const message = `Cloud runner job exit code ${exitCode}`;
taskData.overrides = undefined;
taskData.attachments = undefined;
CloudRunnerLogger.log(`${message} ${JSON.stringify(taskData, undefined, 4)}`);
throw new Error(message);
}
}
private static async waitUntilTaskRunning(ECS: AWS.ECS, taskArn: string, cluster: string) {
try {
await ECS.waitFor('tasksRunning', { tasks: [taskArn], cluster }).promise();
} catch (error_) {
@ -70,25 +89,6 @@ class AWSTaskRunner {
core.setFailed(error);
core.error(error);
}
CloudRunnerLogger.log(`Cloud runner job is running`);
const output = await this.streamLogsUntilTaskStops(ECS, CF, taskDef, cluster, taskArn, streamName);
const exitCode = (await AWSTaskRunner.describeTasks(ECS, cluster, taskArn)).containers?.[0].exitCode;
CloudRunnerLogger.log(`Cloud runner job exit code ${exitCode}`);
CloudRunnerLogger.log(
`job failed with exit code ${exitCode} ${JSON.stringify(
await ECS.describeTasks({ tasks: [taskArn], cluster }).promise(),
undefined,
4,
)}`,
);
if (exitCode !== 0 && exitCode !== undefined) {
core.error(`job failed with exit code ${exitCode} "exitCode !== 0 && exitCode !== undefined"`);
throw new Error(`job failed with exit code ${exitCode}`);
} else {
CloudRunnerLogger.log(`Cloud runner job has finished successfully`);
return output;
}
}
static async describeTasks(ECS: AWS.ECS, clusterName: string, taskArn: string) {
@ -115,10 +115,6 @@ class AWSTaskRunner {
const stream = await AWSTaskRunner.getLogStream(kinesis, kinesisStreamName);
let iterator = await AWSTaskRunner.getLogIterator(kinesis, stream);
CloudRunnerLogger.log(
`Cloud runner job status is ${(await AWSTaskRunner.describeTasks(ECS, clusterName, taskArn))?.lastStatus}`,
);
const logBaseUrl = `https://${Input.region}.console.aws.amazon.com/cloudwatch/home?region=${CF.config.region}#logsV2:log-groups/log-group/${taskDef.taskDefStackName}`;
CloudRunnerLogger.log(`You can also see the logs at AWS Cloud Watch: ${logBaseUrl}`);
let shouldReadLogs = true;
@ -157,6 +153,9 @@ class AWSTaskRunner {
}
private static checkStreamingShouldContinue(taskData: AWS.ECS.Task, timestamp: number, shouldReadLogs: boolean) {
if (taskData?.lastStatus === 'UNKNOWN') {
CloudRunnerLogger.log('## Cloud runner job unknwon');
}
if (taskData?.lastStatus !== 'RUNNING') {
if (timestamp === 0) {
CloudRunnerLogger.log('## Cloud runner job stopped, streaming end of logs');
@ -193,7 +192,7 @@ class AWSTaskRunner {
core.warning('LIBRARY NOT FOUND!');
}
message = `[${CloudRunnerStatics.logPrefix}] ${message}`;
if (Input.cloudRunnerTests) {
if (CloudRunnerState.buildParams.cloudRunnerIntegrationTests) {
output += message;
}
CloudRunnerLogger.log(message);

View File

@ -15,8 +15,10 @@ class CloudRunner {
CloudRunnerState.setup(buildParameters);
CloudRunner.setupBuildPlatform();
const parameters = TaskParameterSerializer.readBuildEnvironmentVariables();
for (const element of parameters) {
core.setOutput(element.name, element.value);
if (!buildParameters.cliMode) {
for (const element of parameters) {
core.setOutput(element.name, element.value);
}
}
}
@ -37,14 +39,14 @@ class CloudRunner {
static async run(buildParameters: BuildParameters, baseImage: string) {
CloudRunner.setup(buildParameters);
try {
core.startGroup('Setup remote runner');
if (!CloudRunnerState.buildParams.cliMode) core.startGroup('Setup remote runner');
await CloudRunnerState.CloudRunnerProviderPlatform.setupSharedResources(
CloudRunnerState.buildParams.buildGuid,
CloudRunnerState.buildParams,
CloudRunnerState.branchName,
CloudRunnerState.defaultSecrets,
);
core.endGroup();
if (!CloudRunnerState.buildParams.cliMode) core.endGroup();
const output = await new WorkflowCompositionRoot().run(
new CloudRunnerStepState(
baseImage,
@ -52,7 +54,7 @@ class CloudRunner {
CloudRunnerState.defaultSecrets,
),
);
core.startGroup('Cleanup');
if (!CloudRunnerState.buildParams.cliMode) core.startGroup('Cleanup');
await CloudRunnerState.CloudRunnerProviderPlatform.cleanupSharedResources(
CloudRunnerState.buildParams.buildGuid,
CloudRunnerState.buildParams,
@ -60,10 +62,10 @@ class CloudRunner {
CloudRunnerState.defaultSecrets,
);
CloudRunnerLogger.log(`Cleanup complete`);
core.endGroup();
if (!CloudRunnerState.buildParams.cliMode) core.endGroup();
return output;
} catch (error) {
core.endGroup();
if (!CloudRunnerState.buildParams.cliMode) core.endGroup();
await CloudRunnerError.handleException(error);
throw error;
}

View File

@ -25,7 +25,9 @@ class KubernetesStorage {
CloudRunnerLogger.log(JSON.stringify(pvcList, undefined, 4));
if (pvcList.includes(pvcName)) {
CloudRunnerLogger.log(`pvc ${pvcName} already exists`);
core.setOutput('volume', pvcName);
if (!buildParameters.cliMode) {
core.setOutput('volume', pvcName);
}
return;
}
CloudRunnerLogger.log(`Creating PVC ${pvcName} (does not exist)`);

View File

@ -4,7 +4,7 @@ import CloudRunnerLogger from '../services/cloud-runner-logger';
import * as core from '@actions/core';
import { CloudRunnerStatics } from '../cloud-runner-statics';
import waitUntil from 'async-wait-until';
import { Input } from '../..';
import { CloudRunnerState } from '../state/cloud-runner-state';
class KubernetesTaskRunner {
static async runTask(
@ -24,7 +24,7 @@ class KubernetesTaskRunner {
didStreamAnyLogs = true;
let message = chunk.toString().trimRight(`\n`);
message = `[${CloudRunnerStatics.logPrefix}] ${message}`;
if (Input.cloudRunnerTests) {
if (CloudRunnerState.buildParams.cloudRunnerIntegrationTests) {
output += message;
}
logCallback(message);

View File

@ -1,6 +1,7 @@
import { BuildParameters, Input } from '../..';
import { BuildParameters } from '../..';
import YAML from 'yaml';
import CloudRunnerSecret from './cloud-runner-secret';
import { CloudRunnerState } from '../state/cloud-runner-state';
export class CloudRunnerBuildCommandProcessor {
public static ProcessCommands(commands: string, buildParameters: BuildParameters): string {
@ -10,12 +11,12 @@ export class CloudRunnerBuildCommandProcessor {
return `echo "---"
echo "start cloud runner init"
${Input.cloudRunnerTests ? '' : '#'} printenv
echo "start cloud runner job"
${CloudRunnerState.buildParams.cloudRunnerIntegrationTests ? '' : '#'} printenv
echo "start of cloud runner job"
${hooks.filter((x) => x.hook.includes(`before`)).map((x) => x.commands) || ' '}
${commands}
${hooks.filter((x) => x.hook.includes(`after`)).map((x) => x.commands) || ' '}
echo "end of cloud runner job
echo "end of cloud runner job"
---${buildParameters.logId}"
`;
}

View File

@ -1,5 +1,4 @@
import path from 'path';
import { Input } from '../..';
import { CloudRunnerBuildCommandProcessor } from '../services/cloud-runner-build-command-process';
import CloudRunnerEnvironmentVariable from '../services/cloud-runner-environment-variable';
import CloudRunnerLogger from '../services/cloud-runner-logger';
@ -23,15 +22,27 @@ export class BuildStep implements StepInterface {
secrets: CloudRunnerSecret[],
) {
CloudRunnerLogger.logLine(` `);
CloudRunnerLogger.logLine('Starting part 2/2 (build unity project)');
CloudRunnerLogger.logLine('Starting build automation job');
const hooks = CloudRunnerBuildCommandProcessor.getHooks(CloudRunnerState.buildParams.customJobHooks).filter((x) =>
x.step.includes(`setup`),
);
return await CloudRunnerState.CloudRunnerProviderPlatform.runTask(
CloudRunnerState.buildParams.buildGuid,
image,
`${hooks.filter((x) => x.hook.includes(`before`)).map((x) => x.commands) || ' '}
`apt-get update
apt-get install -y -q zip tree nodejs git-lfs jq unzip
${hooks.filter((x) => x.hook.includes(`before`)).map((x) => x.commands) || ' '}
export GITHUB_WORKSPACE="${CloudRunnerState.repoPathFull}"
export GIT_DISCOVERY_ACROSS_FILESYSTEM=1
mkdir -p ${CloudRunnerState.builderPathFull.replace(/\\/g, `/`)}
git clone -q -b ${CloudRunnerState.buildParams.cloudRunnerBranch} ${
CloudRunnerState.unityBuilderRepoUrl
} "${CloudRunnerState.builderPathFull.replace(/\\/g, `/`)}"
${
CloudRunnerState.buildParams.cloudRunnerIntegrationTests ? '' : '#'
} tree ${CloudRunnerState.builderPathFull.replace(/\\/g, `/`)}
chmod +x ${path.join(CloudRunnerState.builderPathFull, 'dist', `index.js`).replace(/\\/g, `/`)}
node ${path.join(CloudRunnerState.builderPathFull, 'dist', `index.js`).replace(/\\/g, `/`)} -m remote-cli
cp -r "${path
.join(CloudRunnerState.builderPathFull, 'dist', 'default-build-script')
.replace(/\\/g, `/`)}" "/UnityBuilderAction"
@ -44,8 +55,6 @@ export class BuildStep implements StepInterface {
chmod -R +x "/entrypoint.sh"
chmod -R +x "/steps"
/entrypoint.sh
apt-get update
apt-get install -y -q zip tree nodejs
cd "${CloudRunnerState.libraryFolderFull.replace(/\\/g, `/`)}/.."
zip -r "lib-${CloudRunnerState.buildParams.buildGuid}.zip" "Library"
mv "lib-${CloudRunnerState.buildParams.buildGuid}.zip" "${CloudRunnerState.cacheFolderFull.replace(
@ -64,7 +73,9 @@ export class BuildStep implements StepInterface {
.replace(/\\/g, `/`)} -m cache-push "Library" "lib-${
CloudRunnerState.buildParams.buildGuid
}.zip" "${CloudRunnerState.cacheFolderFull.replace(/\\/g, `/`)}/Library"
${Input.cloudRunnerTests ? '' : '#'} tree -lh "${CloudRunnerState.cacheFolderFull}"
${CloudRunnerState.buildParams.cloudRunnerIntegrationTests ? '' : '#'} tree -lh "${
CloudRunnerState.cacheFolderFull
}"
${hooks.filter((x) => x.hook.includes(`after`)).map((x) => x.commands) || ' '}
`,
`/${CloudRunnerState.buildVolumeFolder}`,

View File

@ -1,5 +1,4 @@
import path from 'path';
import { Input } from '../..';
import { CloudRunnerBuildCommandProcessor } from '../services/cloud-runner-build-command-process';
import CloudRunnerEnvironmentVariable from '../services/cloud-runner-environment-variable';
import CloudRunnerLogger from '../services/cloud-runner-logger';
@ -21,12 +20,6 @@ export class SetupStep implements StepInterface {
}
}
private static getCloudRunnerBranch() {
return process.env.CLOUD_RUNNER_BRANCH?.includes('/')
? process.env.CLOUD_RUNNER_BRANCH.split('/').reverse()[0]
: process.env.CLOUD_RUNNER_BRANCH;
}
private static async downloadRepository(
image: string,
environmentVariables: CloudRunnerEnvironmentVariable[],
@ -46,10 +39,12 @@ export class SetupStep implements StepInterface {
${hooks.filter((x) => x.hook.includes(`before`)).map((x) => x.commands) || ' '}
export GIT_DISCOVERY_ACROSS_FILESYSTEM=1
mkdir -p ${CloudRunnerState.builderPathFull.replace(/\\/g, `/`)}
git clone -q -b ${SetupStep.getCloudRunnerBranch()} ${
git clone -q -b ${CloudRunnerState.buildParams.cloudRunnerBranch} ${
CloudRunnerState.unityBuilderRepoUrl
} "${CloudRunnerState.builderPathFull.replace(/\\/g, `/`)}"
${Input.cloudRunnerTests ? '' : '#'} tree ${CloudRunnerState.builderPathFull.replace(/\\/g, `/`)}
${
CloudRunnerState.buildParams.cloudRunnerIntegrationTests ? '' : '#'
} tree ${CloudRunnerState.builderPathFull.replace(/\\/g, `/`)}
chmod +x ${path.join(CloudRunnerState.builderPathFull, 'dist', `index.js`).replace(/\\/g, `/`)}
node ${path.join(CloudRunnerState.builderPathFull, 'dist', `index.js`).replace(/\\/g, `/`)} -m remote-cli
${hooks.filter((x) => x.hook.includes(`after`)).map((x) => x.commands) || ' '}

View File

@ -3,7 +3,6 @@ import { TaskParameterSerializer } from '../services/task-parameter-serializer';
import { CloudRunnerState } from '../state/cloud-runner-state';
import { CloudRunnerStepState } from '../state/cloud-runner-step-state';
import { BuildStep } from '../steps/build-step';
import { SetupStep } from '../steps/setup-step';
import { CustomWorkflow } from './custom-workflow';
import { WorkflowInterface } from './workflow-interface';
import * as core from '@actions/core';
@ -21,26 +20,27 @@ export class BuildAutomationWorkflow implements WorkflowInterface {
try {
CloudRunnerLogger.log(`Cloud Runner is running standard build automation`);
core.startGroup('pre build steps');
if (!CloudRunnerState.buildParams.cliMode) core.startGroup('pre build steps');
let output = '';
if (CloudRunnerState.buildParams.preBuildSteps !== '') {
output += await CustomWorkflow.runCustomJob(CloudRunnerState.buildParams.preBuildSteps);
}
core.endGroup();
if (!CloudRunnerState.buildParams.cliMode) core.endGroup();
CloudRunnerLogger.logWithTime('Configurable pre build step(s) time');
core.startGroup('setup');
output += await new SetupStep().run(
new CloudRunnerStepState(
'alpine/git',
TaskParameterSerializer.readBuildEnvironmentVariables(),
CloudRunnerState.defaultSecrets,
),
);
core.endGroup();
CloudRunnerLogger.logWithTime('Download repository step time');
// core.startGroup('setup');
// output += await new SetupStep().run(
// new CloudRunnerStepState(
// 'alpine/git',
// TaskParameterSerializer.readBuildEnvironmentVariables(),
// CloudRunnerState.defaultSecrets,
// ),
// );
// core.endGroup();
// CloudRunnerLogger.logWithTime('Download repository step time');
core.startGroup('build');
if (!CloudRunnerState.buildParams.cliMode) core.startGroup('build');
CloudRunnerLogger.log(baseImage.toString());
output += await new BuildStep().run(
new CloudRunnerStepState(
baseImage,
@ -48,14 +48,14 @@ export class BuildAutomationWorkflow implements WorkflowInterface {
CloudRunnerState.defaultSecrets,
),
);
core.endGroup();
if (!CloudRunnerState.buildParams.cliMode) core.endGroup();
CloudRunnerLogger.logWithTime('Build time');
core.startGroup('post build steps');
if (!CloudRunnerState.buildParams.cliMode) core.startGroup('post build steps');
if (CloudRunnerState.buildParams.postBuildSteps !== '') {
output += await CustomWorkflow.runCustomJob(CloudRunnerState.buildParams.postBuildSteps);
}
core.endGroup();
if (!CloudRunnerState.buildParams.cliMode) core.endGroup();
CloudRunnerLogger.logWithTime('Configurable post build step(s) time');
CloudRunnerLogger.log(`Cloud Runner finished running standard build automation`);

View File

@ -9,7 +9,7 @@ export class CustomWorkflow {
public static async runCustomJob(buildSteps) {
try {
CloudRunnerLogger.log(`Cloud Runner is running in custom job mode`);
if (Input.cloudRunnerTests) {
if (CloudRunnerState.buildParams.cloudRunnerIntegrationTests) {
CloudRunnerLogger.log(`Parsing build steps: ${buildSteps}`);
}
try {

View File

@ -4,11 +4,8 @@ import fs from 'fs';
import { CloudRunnerSystem } from '../cli/remote-client/remote-client-services/cloud-runner-system';
export class GitRepoReader {
static GetSha() {
return '';
}
public static async GetRemote() {
return (await CloudRunnerSystem.Run(`git remote -v`))
return (await CloudRunnerSystem.Run(`git remote -v`, false, true))
.split(' ')[1]
.split('https://github.com/')[1]
.split('.git')[0];

View File

@ -4,11 +4,11 @@ import * as core from '@actions/core';
export class GithubCliReader {
static async GetGitHubAuthToken() {
try {
const authStatus = await CloudRunnerSystem.Run(`gh auth status`, true);
const authStatus = await CloudRunnerSystem.Run(`gh auth status`, false, true);
if (authStatus.includes('You are not logged') || authStatus === '') {
return '';
}
return (await CloudRunnerSystem.Run(`gh auth status -t`))
return (await CloudRunnerSystem.Run(`gh auth status -t`, false, true))
.split(`Token: `)[1]
.replace(/ /g, '')
.replace(/\n/g, '');

View File

@ -1,8 +1,6 @@
import fs from 'fs';
import path from 'path';
import { GenericInputReader } from './input-readers/generic-input-reader';
import { GitRepoReader } from './input-readers/git-repo';
import { GithubCliReader } from './input-readers/github-cli';
import Platform from './platform';
const formatFunction = (value, arguments_) => {
@ -41,6 +39,9 @@ class Input {
}
}
}
static get cliMode() {
return Input.cliOptions !== undefined && Input.cliOptions.mode !== undefined && Input.cliOptions.mode !== '';
}
private static async queryOverride(query) {
if (!this.shouldUseOverride(query)) {
@ -66,7 +67,7 @@ class Input {
return coreInput;
}
if (Input.cliOptions !== undefined && Input.cliOptions[query] !== undefined) {
if (Input.cliMode && Input.cliOptions[query] !== undefined) {
return Input.cliOptions[query];
}
@ -94,23 +95,16 @@ class Input {
return Input.getInput('region') || 'eu-west-2';
}
static async githubRepo() {
return (
Input.getInput('GITHUB_REPOSITORY') ||
Input.getInput('GITHUB_REPO') ||
(await GitRepoReader.GetRemote()) ||
'game-ci/unity-builder'
);
static get githubRepo() {
return Input.getInput('GITHUB_REPOSITORY') || Input.getInput('GITHUB_REPO') || false;
}
static async branch() {
if (await GitRepoReader.GetBranch()) {
return await GitRepoReader.GetBranch();
} else if (Input.getInput(`GITHUB_REF`)) {
static get branch() {
if (Input.getInput(`GITHUB_REF`)) {
return Input.getInput(`GITHUB_REF`).replace('refs/', '').replace(`head/`, '');
} else if (Input.getInput('branch')) {
return Input.getInput('branch');
} else {
return 'main';
return '';
}
}
@ -119,8 +113,6 @@ class Input {
return Input.getInput(`GITHUB_SHA`);
} else if (Input.getInput(`GitSHA`)) {
return Input.getInput(`GitSHA`);
} else if (GitRepoReader.GetSha()) {
return GitRepoReader.GetSha();
}
}
static get runNumber() {
@ -212,8 +204,8 @@ class Input {
return Input.getInput('sshAgent') || '';
}
static async gitPrivateToken() {
return core.getInput('gitPrivateToken') || (await GithubCliReader.GetGitHubAuthToken()) || '';
static get gitPrivateToken() {
return core.getInput('gitPrivateToken') || false;
}
static get customJob() {
@ -240,6 +232,10 @@ class Input {
return Input.getInput('readInputOverrideCommand') || '';
}
static get cloudRunnerBranch() {
return Input.getInput('cloudRunnerBranch') || 'cloud-runner-develop';
}
static get chownFilesTo() {
return Input.getInput('chownFilesTo') || '';
}