Refactor state and steps out of cloud-runner main class
parent
1ce7383d4a
commit
11fd1dccbf
|
|
@ -535,7 +535,7 @@ class AWSBuildEnvironment {
|
||||||
StackName: taskDefStackName,
|
StackName: taskDefStackName,
|
||||||
}).promise()).StackResources;
|
}).promise()).StackResources;
|
||||||
const baseResources = (yield CF.describeStackResources({ StackName: this.baseStackName }).promise()).StackResources;
|
const baseResources = (yield CF.describeStackResources({ StackName: this.baseStackName }).promise()).StackResources;
|
||||||
// TODO: offer a parameter to decide if you want the guarenteed shutdown or fastest startup time possible
|
// TODO: offer a parameter to decide if you want the guaranteed shutdown or fastest startup time possible
|
||||||
return {
|
return {
|
||||||
taskDefStackName,
|
taskDefStackName,
|
||||||
taskDefCloudFormation,
|
taskDefCloudFormation,
|
||||||
|
|
@ -963,6 +963,461 @@ class CloudRunnerNamespace {
|
||||||
exports.default = CloudRunnerNamespace;
|
exports.default = CloudRunnerNamespace;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 32877:
|
||||||
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.CloudRunnerState = void 0;
|
||||||
|
const image_environment_factory_1 = __importDefault(__webpack_require__(25145));
|
||||||
|
class CloudRunnerState {
|
||||||
|
static readBuildEnvironmentVariables() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: 'ContainerMemory',
|
||||||
|
value: CloudRunnerState.buildParams.cloudRunnerMemory,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ContainerCpu',
|
||||||
|
value: CloudRunnerState.buildParams.cloudRunnerCpu,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'GITHUB_WORKSPACE',
|
||||||
|
value: `/${CloudRunnerState.buildVolumeFolder}/${CloudRunnerState.buildGuid}/${CloudRunnerState.repositoryFolder}/`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PROJECT_PATH',
|
||||||
|
value: CloudRunnerState.buildParams.projectPath,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BUILD_PATH',
|
||||||
|
value: CloudRunnerState.buildParams.buildPath,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BUILD_FILE',
|
||||||
|
value: CloudRunnerState.buildParams.buildFile,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BUILD_NAME',
|
||||||
|
value: CloudRunnerState.buildParams.buildName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BUILD_METHOD',
|
||||||
|
value: CloudRunnerState.buildParams.buildMethod,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CUSTOM_PARAMETERS',
|
||||||
|
value: CloudRunnerState.buildParams.customParameters,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BUILD_TARGET',
|
||||||
|
value: CloudRunnerState.buildParams.platform,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ANDROID_VERSION_CODE',
|
||||||
|
value: CloudRunnerState.buildParams.androidVersionCode.toString(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ANDROID_KEYSTORE_NAME',
|
||||||
|
value: CloudRunnerState.buildParams.androidKeystoreName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ANDROID_KEYALIAS_NAME',
|
||||||
|
value: CloudRunnerState.buildParams.androidKeyaliasName,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
static getHandleCachingCommand() {
|
||||||
|
return `${CloudRunnerState.builderPathFull}/dist/cloud-runner/handleCaching.sh "${CloudRunnerState.cacheFolderFull}" "${CloudRunnerState.libraryFolderFull}" "${CloudRunnerState.lfsDirectory}" "${CloudRunnerState.purgeRemoteCaching}"`;
|
||||||
|
}
|
||||||
|
static getCloneNoLFSCommand() {
|
||||||
|
return `${CloudRunnerState.builderPathFull}/dist/cloud-runner/cloneNoLFS.sh "${CloudRunnerState.repoPathFull}" "${CloudRunnerState.targetBuildRepoUrl}"`;
|
||||||
|
}
|
||||||
|
static getCloneBuilder() {
|
||||||
|
return `git clone -q ${CloudRunnerState.CloudRunnerBranch} ${CloudRunnerState.unityBuilderRepoUrl} ${CloudRunnerState.builderPathFull}`;
|
||||||
|
}
|
||||||
|
static readRunNumber() {
|
||||||
|
const runNumber = process.env.GITHUB_RUN_NUMBER;
|
||||||
|
if (!runNumber || runNumber === '') {
|
||||||
|
throw new Error('no run number found, exiting');
|
||||||
|
}
|
||||||
|
return runNumber;
|
||||||
|
}
|
||||||
|
static setupFolderVariables() {
|
||||||
|
CloudRunnerState.buildPathFull = `/${CloudRunnerState.buildVolumeFolder}/${CloudRunnerState.buildGuid}`;
|
||||||
|
CloudRunnerState.builderPathFull = `${CloudRunnerState.buildPathFull}/builder`;
|
||||||
|
CloudRunnerState.steamPathFull = `${CloudRunnerState.buildPathFull}/steam`;
|
||||||
|
CloudRunnerState.repoPathFull = `${CloudRunnerState.buildPathFull}/${CloudRunnerState.repositoryFolder}`;
|
||||||
|
CloudRunnerState.projectPathFull = `${CloudRunnerState.repoPathFull}/${CloudRunnerState.buildParams.projectPath}`;
|
||||||
|
CloudRunnerState.libraryFolderFull = `${CloudRunnerState.projectPathFull}/Library`;
|
||||||
|
CloudRunnerState.cacheFolderFull = `/${CloudRunnerState.buildVolumeFolder}/${CloudRunnerState.cacheFolder}/${CloudRunnerState.branchName}`;
|
||||||
|
CloudRunnerState.lfsDirectory = `${CloudRunnerState.repoPathFull}/.git/lfs`;
|
||||||
|
CloudRunnerState.purgeRemoteCaching = process.env.PURGE_REMOTE_BUILDER_CACHE !== undefined;
|
||||||
|
CloudRunnerState.CloudRunnerBranch = process.env.CloudRunnerBranch
|
||||||
|
? `--branch "${process.env.CloudRunnerBranch}"`
|
||||||
|
: '';
|
||||||
|
CloudRunnerState.unityBuilderRepoUrl = `https://${CloudRunnerState.buildParams.githubToken}@github.com/game-ci/unity-builder.git`;
|
||||||
|
CloudRunnerState.targetBuildRepoUrl = `https://${CloudRunnerState.buildParams.githubToken}@github.com/${process.env.GITHUB_REPOSITORY}.git`;
|
||||||
|
}
|
||||||
|
static setupBranchName() {
|
||||||
|
var _a;
|
||||||
|
const defaultBranchName = ((_a = process.env.GITHUB_REF) === null || _a === void 0 ? void 0 : _a.split('/').filter((x) => {
|
||||||
|
x = x[0].toUpperCase() + x.slice(1);
|
||||||
|
return x;
|
||||||
|
}).join('')) || '';
|
||||||
|
CloudRunnerState.branchName =
|
||||||
|
process.env.REMOTE_BUILDER_CACHE !== undefined ? process.env.REMOTE_BUILDER_CACHE : defaultBranchName;
|
||||||
|
}
|
||||||
|
static setupDefaultSecrets() {
|
||||||
|
CloudRunnerState.defaultSecrets = [
|
||||||
|
{
|
||||||
|
ParameterKey: 'GithubToken',
|
||||||
|
EnvironmentVariable: 'GITHUB_TOKEN',
|
||||||
|
ParameterValue: CloudRunnerState.buildParams.githubToken,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ParameterKey: 'branch',
|
||||||
|
EnvironmentVariable: 'branch',
|
||||||
|
ParameterValue: CloudRunnerState.branchName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ParameterKey: 'buildPathFull',
|
||||||
|
EnvironmentVariable: 'buildPathFull',
|
||||||
|
ParameterValue: CloudRunnerState.buildPathFull,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ParameterKey: 'projectPathFull',
|
||||||
|
EnvironmentVariable: 'projectPathFull',
|
||||||
|
ParameterValue: CloudRunnerState.projectPathFull,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ParameterKey: 'libraryFolderFull',
|
||||||
|
EnvironmentVariable: 'libraryFolderFull',
|
||||||
|
ParameterValue: CloudRunnerState.libraryFolderFull,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ParameterKey: 'builderPathFull',
|
||||||
|
EnvironmentVariable: 'builderPathFull',
|
||||||
|
ParameterValue: CloudRunnerState.builderPathFull,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ParameterKey: 'repoPathFull',
|
||||||
|
EnvironmentVariable: 'repoPathFull',
|
||||||
|
ParameterValue: CloudRunnerState.repoPathFull,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ParameterKey: 'steamPathFull',
|
||||||
|
EnvironmentVariable: 'steamPathFull',
|
||||||
|
ParameterValue: CloudRunnerState.steamPathFull,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
CloudRunnerState.defaultSecrets.push(...image_environment_factory_1.default.getEnvironmentVariables(CloudRunnerState.buildParams).map((x) => {
|
||||||
|
return {
|
||||||
|
ParameterKey: x.name,
|
||||||
|
EnvironmentVariable: x.name,
|
||||||
|
ParameterValue: x.value,
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.CloudRunnerState = CloudRunnerState;
|
||||||
|
CloudRunnerState.defaultGitShaEnvironmentVariable = [
|
||||||
|
{
|
||||||
|
name: 'GITHUB_SHA',
|
||||||
|
value: process.env.GITHUB_SHA || '',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
CloudRunnerState.repositoryFolder = 'repo';
|
||||||
|
CloudRunnerState.buildVolumeFolder = 'data';
|
||||||
|
CloudRunnerState.cacheFolder = 'cache';
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 81355:
|
||||||
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.CloudRunnerStepState = void 0;
|
||||||
|
class CloudRunnerStepState {
|
||||||
|
constructor(image, environmentVariables, secrets) {
|
||||||
|
this.image = image;
|
||||||
|
this.environment = environmentVariables;
|
||||||
|
this.secrets = secrets;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.CloudRunnerStepState = CloudRunnerStepState;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 48396:
|
||||||
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.BuildStep = void 0;
|
||||||
|
const cloud_runner_logger_1 = __importDefault(__webpack_require__(17375));
|
||||||
|
const cloud_runner_state_1 = __webpack_require__(32877);
|
||||||
|
class BuildStep {
|
||||||
|
run(cloudRunnerStepState) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
yield BuildStep.BuildStep(cloudRunnerStepState.image, cloudRunnerStepState.environment, cloudRunnerStepState.secrets);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
static BuildStep(image, environmentVariables, secrets) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
cloud_runner_logger_1.default.log('Starting part 2/4 (build unity project)');
|
||||||
|
yield cloud_runner_state_1.CloudRunnerState.CloudRunnerProviderPlatform.runBuildTask(cloud_runner_state_1.CloudRunnerState.buildGuid, image, [
|
||||||
|
`
|
||||||
|
printenv
|
||||||
|
export GITHUB_WORKSPACE="${cloud_runner_state_1.CloudRunnerState.repoPathFull}"
|
||||||
|
cp -r "${cloud_runner_state_1.CloudRunnerState.builderPathFull}/dist/default-build-script/" "/UnityBuilderAction"
|
||||||
|
cp -r "${cloud_runner_state_1.CloudRunnerState.builderPathFull}/dist/entrypoint.sh" "/entrypoint.sh"
|
||||||
|
cp -r "${cloud_runner_state_1.CloudRunnerState.builderPathFull}/dist/steps/" "/steps"
|
||||||
|
chmod -R +x "/entrypoint.sh"
|
||||||
|
chmod -R +x "/steps"
|
||||||
|
/entrypoint.sh
|
||||||
|
${process.env.DEBUG ? '' : '#'}tree -L 4 "${cloud_runner_state_1.CloudRunnerState.buildPathFull}"
|
||||||
|
${process.env.DEBUG ? '' : '#'}ls -lh "/${cloud_runner_state_1.CloudRunnerState.buildVolumeFolder}"
|
||||||
|
`,
|
||||||
|
], `/${cloud_runner_state_1.CloudRunnerState.buildVolumeFolder}`, `/${cloud_runner_state_1.CloudRunnerState.projectPathFull}`, environmentVariables, secrets);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.BuildStep = BuildStep;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 30851:
|
||||||
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.CompressionStep = void 0;
|
||||||
|
const cloud_runner_logger_1 = __importDefault(__webpack_require__(17375));
|
||||||
|
const cloud_runner_state_1 = __webpack_require__(32877);
|
||||||
|
class CompressionStep {
|
||||||
|
run(cloudRunnerStepState) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
yield CompressionStep.CompressionStep(cloudRunnerStepState.environment, cloudRunnerStepState.secrets);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
static CompressionStep(environmentVariables, secrets) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
cloud_runner_logger_1.default.log('Starting step 3/4 build compression');
|
||||||
|
// Cleanup
|
||||||
|
yield cloud_runner_state_1.CloudRunnerState.CloudRunnerProviderPlatform.runBuildTask(cloud_runner_state_1.CloudRunnerState.buildGuid, 'alpine', [
|
||||||
|
`
|
||||||
|
printenv
|
||||||
|
apk update -q
|
||||||
|
apk add zip tree -q
|
||||||
|
${process.env.DEBUG ? '' : '#'}tree -L 4 "$repoPathFull"
|
||||||
|
${process.env.DEBUG ? '' : '#'}ls -lh "$repoPathFull"
|
||||||
|
cd "$libraryFolderFull/.."
|
||||||
|
zip -r "lib-$BUILDID.zip" "./Library"
|
||||||
|
mv "lib-$BUILDID.zip" "/$cacheFolderFull/lib"
|
||||||
|
cd "$repoPathFull"
|
||||||
|
ls -lh "$repoPathFull"
|
||||||
|
zip -r "build-$BUILDID.zip" "./${cloud_runner_state_1.CloudRunnerState.buildParams.buildPath}"
|
||||||
|
mv "build-$BUILDID.zip" "/$cacheFolderFull/build-$BUILDID.zip"
|
||||||
|
${process.env.DEBUG ? '' : '#'}tree -L 4 "/$cacheFolderFull"
|
||||||
|
${process.env.DEBUG ? '' : '#'}tree -L 4 "/$cacheFolderFull/.."
|
||||||
|
${process.env.DEBUG ? '' : '#'}tree -L 4 "$repoPathFull"
|
||||||
|
${process.env.DEBUG ? '' : '#'}ls -lh "$repoPathFull"
|
||||||
|
`,
|
||||||
|
], `/${cloud_runner_state_1.CloudRunnerState.buildVolumeFolder}`, `/${cloud_runner_state_1.CloudRunnerState.buildVolumeFolder}`, [
|
||||||
|
...environmentVariables,
|
||||||
|
...[
|
||||||
|
{
|
||||||
|
name: 'cacheFolderFull',
|
||||||
|
value: cloud_runner_state_1.CloudRunnerState.cacheFolderFull,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
], secrets);
|
||||||
|
cloud_runner_logger_1.default.log('compression step complete');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.CompressionStep = CompressionStep;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 47493:
|
||||||
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.CustomStep = void 0;
|
||||||
|
const cloud_runner_logger_1 = __importDefault(__webpack_require__(17375));
|
||||||
|
const cloud_runner_state_1 = __webpack_require__(32877);
|
||||||
|
const yaml_1 = __importDefault(__webpack_require__(13552));
|
||||||
|
class CustomStep {
|
||||||
|
static runCustomJob(buildSteps) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
cloud_runner_logger_1.default.log(`Cloud Runner is running in custom job mode`);
|
||||||
|
buildSteps = yaml_1.default.parse(buildSteps);
|
||||||
|
for (const step of buildSteps) {
|
||||||
|
const stepSecrets = step.secrets.map((x) => {
|
||||||
|
const secret = {
|
||||||
|
ParameterKey: x.name,
|
||||||
|
EnvironmentVariable: x.name,
|
||||||
|
ParameterValue: x.value,
|
||||||
|
};
|
||||||
|
return secret;
|
||||||
|
});
|
||||||
|
yield cloud_runner_state_1.CloudRunnerState.CloudRunnerProviderPlatform.runBuildTask(cloud_runner_state_1.CloudRunnerState.buildGuid, step['image'], step['commands'], `/${cloud_runner_state_1.CloudRunnerState.buildVolumeFolder}`, `/${cloud_runner_state_1.CloudRunnerState.buildVolumeFolder}`, cloud_runner_state_1.CloudRunnerState.defaultGitShaEnvironmentVariable, [...cloud_runner_state_1.CloudRunnerState.defaultSecrets, ...stepSecrets]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.CustomStep = CustomStep;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 36798:
|
||||||
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.DownloadRepositoryStep = void 0;
|
||||||
|
const cloud_runner_logger_1 = __importDefault(__webpack_require__(17375));
|
||||||
|
const cloud_runner_state_1 = __webpack_require__(32877);
|
||||||
|
class DownloadRepositoryStep {
|
||||||
|
run(cloudRunnerStepState) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
yield DownloadRepositoryStep.downloadRepositoryStep(cloudRunnerStepState.image, cloudRunnerStepState.environment, cloudRunnerStepState.secrets);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
static downloadRepositoryStep(image, environmentVariables, secrets) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
cloud_runner_logger_1.default.log('Starting step 1/4 clone and restore cache');
|
||||||
|
yield cloud_runner_state_1.CloudRunnerState.CloudRunnerProviderPlatform.runBuildTask(cloud_runner_state_1.CloudRunnerState.buildGuid, image, [
|
||||||
|
` printenv
|
||||||
|
apk update -q
|
||||||
|
apk add unzip zip git-lfs jq tree -q
|
||||||
|
mkdir -p ${cloud_runner_state_1.CloudRunnerState.buildPathFull}
|
||||||
|
mkdir -p ${cloud_runner_state_1.CloudRunnerState.builderPathFull}
|
||||||
|
mkdir -p ${cloud_runner_state_1.CloudRunnerState.repoPathFull}
|
||||||
|
${cloud_runner_state_1.CloudRunnerState.getCloneBuilder()}
|
||||||
|
echo ' '
|
||||||
|
echo 'Initializing source repository for cloning with caching of LFS files'
|
||||||
|
${cloud_runner_state_1.CloudRunnerState.getCloneNoLFSCommand()}
|
||||||
|
echo 'Source repository initialized'
|
||||||
|
echo ' '
|
||||||
|
echo 'Starting checks of cache for the Unity project Library and git LFS files'
|
||||||
|
${cloud_runner_state_1.CloudRunnerState.getHandleCachingCommand()}
|
||||||
|
`,
|
||||||
|
], `/${cloud_runner_state_1.CloudRunnerState.buildVolumeFolder}`, `/${cloud_runner_state_1.CloudRunnerState.buildVolumeFolder}/`, environmentVariables, secrets);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.DownloadRepositoryStep = DownloadRepositoryStep;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 15732:
|
||||||
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.EphemeralGitHubRunnerStep = void 0;
|
||||||
|
const cloud_runner_logger_1 = __importDefault(__webpack_require__(17375));
|
||||||
|
const cloud_runner_state_1 = __webpack_require__(32877);
|
||||||
|
class EphemeralGitHubRunnerStep {
|
||||||
|
run(cloudRunnerStepState) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
yield EphemeralGitHubRunnerStep.runJobAsEphemeralGitHubRunner(cloudRunnerStepState.image, cloudRunnerStepState.environment, cloudRunnerStepState.secrets);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
static runJobAsEphemeralGitHubRunner(image, environmentVariables, secrets) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
cloud_runner_logger_1.default.log(`Cloud Runner is running in ephemeral GitHub runner mode`);
|
||||||
|
const installAndStartRunner = 'mkdir actions-runner && cd actions-runner && curl -O -L https://github.com/actions/runner/releases/download/v2.283.1/actions-runner-linux-x64-2.283.1.tar.gz && tar xzf ./actions-runner-linux-x64-2.283.1.tar.gz';
|
||||||
|
yield cloud_runner_state_1.CloudRunnerState.CloudRunnerProviderPlatform.runBuildTask(cloud_runner_state_1.CloudRunnerState.buildGuid, image, [installAndStartRunner], `/${cloud_runner_state_1.CloudRunnerState.buildVolumeFolder}`, `/${cloud_runner_state_1.CloudRunnerState.buildVolumeFolder}`, environmentVariables, secrets);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.EphemeralGitHubRunnerStep = EphemeralGitHubRunnerStep;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 79144:
|
/***/ 79144:
|
||||||
|
|
@ -1005,54 +1460,45 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
const aws_build_platform_1 = __importDefault(__webpack_require__(81683));
|
const aws_build_platform_1 = __importDefault(__webpack_require__(81683));
|
||||||
const core = __importStar(__webpack_require__(42186));
|
const core = __importStar(__webpack_require__(42186));
|
||||||
const cloud_runner_namespace_1 = __importDefault(__webpack_require__(58738));
|
const cloud_runner_namespace_1 = __importDefault(__webpack_require__(58738));
|
||||||
|
const cloud_runner_state_1 = __webpack_require__(32877);
|
||||||
const kubernetes_build_platform_1 = __importDefault(__webpack_require__(10471));
|
const kubernetes_build_platform_1 = __importDefault(__webpack_require__(10471));
|
||||||
const image_environment_factory_1 = __importDefault(__webpack_require__(25145));
|
|
||||||
const yaml_1 = __importDefault(__webpack_require__(13552));
|
|
||||||
const cloud_runner_logger_1 = __importDefault(__webpack_require__(17375));
|
const cloud_runner_logger_1 = __importDefault(__webpack_require__(17375));
|
||||||
const repositoryFolder = 'repo';
|
const build_step_1 = __webpack_require__(48396);
|
||||||
const buildVolumeFolder = 'data';
|
const compression_step_1 = __webpack_require__(30851);
|
||||||
const cacheFolder = 'cache';
|
const download_repository_step_1 = __webpack_require__(36798);
|
||||||
|
const custom_step_1 = __webpack_require__(47493);
|
||||||
|
const ephemeral_github_runner_step_1 = __webpack_require__(15732);
|
||||||
|
const cloud_runner_step_state_1 = __webpack_require__(81355);
|
||||||
class CloudRunner {
|
class CloudRunner {
|
||||||
static setup(buildParameters) {
|
static setup(buildParameters) {
|
||||||
cloud_runner_logger_1.default.setup();
|
cloud_runner_logger_1.default.setup();
|
||||||
CloudRunner.buildGuid = cloud_runner_namespace_1.default.generateBuildName(CloudRunner.readRunNumber(), buildParameters.platform);
|
cloud_runner_state_1.CloudRunnerState.buildGuid = cloud_runner_namespace_1.default.generateBuildName(cloud_runner_state_1.CloudRunnerState.readRunNumber(), buildParameters.platform);
|
||||||
CloudRunner.buildParams = buildParameters;
|
cloud_runner_state_1.CloudRunnerState.buildParams = buildParameters;
|
||||||
CloudRunner.setupBranchName();
|
cloud_runner_state_1.CloudRunnerState.setupBranchName();
|
||||||
CloudRunner.setupFolderVariables();
|
cloud_runner_state_1.CloudRunnerState.setupFolderVariables();
|
||||||
CloudRunner.setupDefaultSecrets();
|
cloud_runner_state_1.CloudRunnerState.setupDefaultSecrets();
|
||||||
CloudRunner.setupBuildPlatform();
|
CloudRunner.setupBuildPlatform();
|
||||||
}
|
}
|
||||||
static setupFolderVariables() {
|
static setupBuildPlatform() {
|
||||||
this.buildPathFull = `/${buildVolumeFolder}/${this.buildGuid}`;
|
switch (cloud_runner_state_1.CloudRunnerState.buildParams.cloudRunnerCluster) {
|
||||||
this.builderPathFull = `${this.buildPathFull}/builder`;
|
case 'aws':
|
||||||
this.steamPathFull = `${this.buildPathFull}/steam`;
|
cloud_runner_logger_1.default.log('Building with AWS');
|
||||||
this.repoPathFull = `${this.buildPathFull}/${repositoryFolder}`;
|
cloud_runner_state_1.CloudRunnerState.CloudRunnerProviderPlatform = new aws_build_platform_1.default(cloud_runner_state_1.CloudRunnerState.buildParams);
|
||||||
this.projectPathFull = `${this.repoPathFull}/${this.buildParams.projectPath}`;
|
break;
|
||||||
this.libraryFolderFull = `${this.projectPathFull}/Library`;
|
default:
|
||||||
this.cacheFolderFull = `/${buildVolumeFolder}/${cacheFolder}/${this.branchName}`;
|
case 'k8s':
|
||||||
this.lfsDirectory = `${this.repoPathFull}/.git/lfs`;
|
cloud_runner_logger_1.default.log('Building with Kubernetes');
|
||||||
this.purgeRemoteCaching = process.env.PURGE_REMOTE_BUILDER_CACHE !== undefined;
|
cloud_runner_state_1.CloudRunnerState.CloudRunnerProviderPlatform = new kubernetes_build_platform_1.default(cloud_runner_state_1.CloudRunnerState.buildParams);
|
||||||
this.CloudRunnerBranch = process.env.CloudRunnerBranch ? `--branch "${process.env.CloudRunnerBranch}"` : '';
|
break;
|
||||||
this.unityBuilderRepoUrl = `https://${this.buildParams.githubToken}@github.com/game-ci/unity-builder.git`;
|
}
|
||||||
this.targetBuildRepoUrl = `https://${this.buildParams.githubToken}@github.com/${process.env.GITHUB_REPOSITORY}.git`;
|
|
||||||
}
|
|
||||||
static getHandleCachingCommand() {
|
|
||||||
return `${this.builderPathFull}/dist/cloud-runner/handleCaching.sh "${this.cacheFolderFull}" "${this.libraryFolderFull}" "${this.lfsDirectory}" "${this.purgeRemoteCaching}"`;
|
|
||||||
}
|
|
||||||
static getCloneNoLFSCommand() {
|
|
||||||
return `${this.builderPathFull}/dist/cloud-runner/cloneNoLFS.sh "${this.repoPathFull}" "${this.targetBuildRepoUrl}"`;
|
|
||||||
}
|
|
||||||
static getCloneBuilder() {
|
|
||||||
return `git clone -q ${this.CloudRunnerBranch} ${this.unityBuilderRepoUrl} ${this.builderPathFull}`;
|
|
||||||
}
|
}
|
||||||
static run(buildParameters, baseImage) {
|
static run(buildParameters, baseImage) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
CloudRunner.setup(buildParameters);
|
CloudRunner.setup(buildParameters);
|
||||||
try {
|
try {
|
||||||
yield CloudRunner.setupSharedBuildResources();
|
yield cloud_runner_state_1.CloudRunnerState.CloudRunnerProviderPlatform.setupSharedBuildResources(cloud_runner_state_1.CloudRunnerState.buildGuid, cloud_runner_state_1.CloudRunnerState.buildParams, cloud_runner_state_1.CloudRunnerState.branchName, cloud_runner_state_1.CloudRunnerState.defaultSecrets);
|
||||||
yield CloudRunner.setupStep();
|
yield CloudRunner.runJob(baseImage);
|
||||||
yield CloudRunner.runMainJob(baseImage);
|
yield cloud_runner_state_1.CloudRunnerState.CloudRunnerProviderPlatform.cleanupSharedBuildResources(cloud_runner_state_1.CloudRunnerState.buildGuid, cloud_runner_state_1.CloudRunnerState.buildParams, cloud_runner_state_1.CloudRunnerState.branchName, cloud_runner_state_1.CloudRunnerState.defaultSecrets);
|
||||||
yield CloudRunner.cleanupSharedBuildResources();
|
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
yield CloudRunner.handleException(error);
|
yield CloudRunner.handleException(error);
|
||||||
|
|
@ -1060,293 +1506,47 @@ class CloudRunner {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static setupSharedBuildResources() {
|
static runJob(baseImage) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
yield this.CloudRunnerProviderPlatform.setupSharedBuildResources(this.buildGuid, this.buildParams, this.branchName, this.defaultSecrets);
|
core.info(`Custom build steps: ${cloud_runner_state_1.CloudRunnerState.buildParams.customBuildSteps}`);
|
||||||
});
|
if (cloud_runner_state_1.CloudRunnerState.buildParams.customBuildSteps === '') {
|
||||||
}
|
|
||||||
static setupBuildPlatform() {
|
|
||||||
switch (this.buildParams.cloudRunnerCluster) {
|
|
||||||
case 'aws':
|
|
||||||
cloud_runner_logger_1.default.log('Building with AWS');
|
|
||||||
this.CloudRunnerProviderPlatform = new aws_build_platform_1.default(this.buildParams);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
case 'k8s':
|
|
||||||
cloud_runner_logger_1.default.log('Building with Kubernetes');
|
|
||||||
this.CloudRunnerProviderPlatform = new kubernetes_build_platform_1.default(this.buildParams);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static readRunNumber() {
|
|
||||||
const runNumber = process.env.GITHUB_RUN_NUMBER;
|
|
||||||
if (!runNumber || runNumber === '') {
|
|
||||||
throw new Error('no run number found, exiting');
|
|
||||||
}
|
|
||||||
return runNumber;
|
|
||||||
}
|
|
||||||
static setupBranchName() {
|
|
||||||
var _a;
|
|
||||||
const defaultBranchName = ((_a = process.env.GITHUB_REF) === null || _a === void 0 ? void 0 : _a.split('/').filter((x) => {
|
|
||||||
x = x[0].toUpperCase() + x.slice(1);
|
|
||||||
return x;
|
|
||||||
}).join('')) || '';
|
|
||||||
this.branchName =
|
|
||||||
process.env.REMOTE_BUILDER_CACHE !== undefined ? process.env.REMOTE_BUILDER_CACHE : defaultBranchName;
|
|
||||||
}
|
|
||||||
static setupDefaultSecrets() {
|
|
||||||
this.defaultSecrets = [
|
|
||||||
{
|
|
||||||
ParameterKey: 'GithubToken',
|
|
||||||
EnvironmentVariable: 'GITHUB_TOKEN',
|
|
||||||
ParameterValue: this.buildParams.githubToken,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ParameterKey: 'branch',
|
|
||||||
EnvironmentVariable: 'branch',
|
|
||||||
ParameterValue: this.branchName,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ParameterKey: 'buildPathFull',
|
|
||||||
EnvironmentVariable: 'buildPathFull',
|
|
||||||
ParameterValue: this.buildPathFull,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ParameterKey: 'projectPathFull',
|
|
||||||
EnvironmentVariable: 'projectPathFull',
|
|
||||||
ParameterValue: this.projectPathFull,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ParameterKey: 'libraryFolderFull',
|
|
||||||
EnvironmentVariable: 'libraryFolderFull',
|
|
||||||
ParameterValue: this.libraryFolderFull,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ParameterKey: 'builderPathFull',
|
|
||||||
EnvironmentVariable: 'builderPathFull',
|
|
||||||
ParameterValue: this.builderPathFull,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ParameterKey: 'repoPathFull',
|
|
||||||
EnvironmentVariable: 'repoPathFull',
|
|
||||||
ParameterValue: this.repoPathFull,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ParameterKey: 'steamPathFull',
|
|
||||||
EnvironmentVariable: 'steamPathFull',
|
|
||||||
ParameterValue: this.steamPathFull,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
this.defaultSecrets.push(...image_environment_factory_1.default.getEnvironmentVariables(this.buildParams).map((x) => {
|
|
||||||
return {
|
|
||||||
ParameterKey: x.name,
|
|
||||||
EnvironmentVariable: x.name,
|
|
||||||
ParameterValue: x.value,
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
static readBuildEnvironmentVariables() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
name: 'ContainerMemory',
|
|
||||||
value: this.buildParams.cloudRunnerMemory,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'ContainerCpu',
|
|
||||||
value: this.buildParams.cloudRunnerCpu,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'GITHUB_WORKSPACE',
|
|
||||||
value: `/${buildVolumeFolder}/${this.buildGuid}/${repositoryFolder}/`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'PROJECT_PATH',
|
|
||||||
value: this.buildParams.projectPath,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'BUILD_PATH',
|
|
||||||
value: this.buildParams.buildPath,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'BUILD_FILE',
|
|
||||||
value: this.buildParams.buildFile,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'BUILD_NAME',
|
|
||||||
value: this.buildParams.buildName,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'BUILD_METHOD',
|
|
||||||
value: this.buildParams.buildMethod,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'CUSTOM_PARAMETERS',
|
|
||||||
value: this.buildParams.customParameters,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'BUILD_TARGET',
|
|
||||||
value: this.buildParams.platform,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'ANDROID_VERSION_CODE',
|
|
||||||
value: this.buildParams.androidVersionCode.toString(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'ANDROID_KEYSTORE_NAME',
|
|
||||||
value: this.buildParams.androidKeystoreName,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'ANDROID_KEYALIAS_NAME',
|
|
||||||
value: this.buildParams.androidKeyaliasName,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
static runMainJob(baseImage) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (this.buildParams.customBuildSteps === '') {
|
|
||||||
yield CloudRunner.standardBuildAutomation(baseImage);
|
yield CloudRunner.standardBuildAutomation(baseImage);
|
||||||
}
|
}
|
||||||
else if (this.buildParams.customBuildSteps === 'ephemeral') {
|
else if (cloud_runner_state_1.CloudRunnerState.buildParams.customBuildSteps === 'ephemeral') {
|
||||||
yield CloudRunner.runJobAsEphemeralGitHubRunner(baseImage);
|
yield new ephemeral_github_runner_step_1.EphemeralGitHubRunnerStep().run(new cloud_runner_step_state_1.CloudRunnerStepState(baseImage, cloud_runner_state_1.CloudRunnerState.readBuildEnvironmentVariables(), cloud_runner_state_1.CloudRunnerState.defaultSecrets));
|
||||||
|
}
|
||||||
|
else if (cloud_runner_state_1.CloudRunnerState.buildParams.customBuildSteps === 'download') {
|
||||||
|
yield new download_repository_step_1.DownloadRepositoryStep().run(new cloud_runner_step_state_1.CloudRunnerStepState('alpine/git', cloud_runner_state_1.CloudRunnerState.readBuildEnvironmentVariables(), cloud_runner_state_1.CloudRunnerState.defaultSecrets));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
yield CloudRunner.runCustomJob(this.buildParams.customBuildSteps);
|
yield custom_step_1.CustomStep.runCustomJob(cloud_runner_state_1.CloudRunnerState.buildParams.customBuildSteps);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static standardBuildAutomation(baseImage) {
|
static standardBuildAutomation(baseImage) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
cloud_runner_logger_1.default.log(`Cloud Runner is running in standard build automation mode`);
|
cloud_runner_logger_1.default.log(`Cloud Runner is running standard build automation`);
|
||||||
cloud_runner_logger_1.default.logWithTime('Pre build steps time');
|
yield new download_repository_step_1.DownloadRepositoryStep().run(new cloud_runner_step_state_1.CloudRunnerStepState('alpine/git', cloud_runner_state_1.CloudRunnerState.readBuildEnvironmentVariables(), cloud_runner_state_1.CloudRunnerState.defaultSecrets));
|
||||||
yield this.runCustomJob(this.buildParams.preBuildSteps);
|
cloud_runner_logger_1.default.logWithTime('Download repository step time');
|
||||||
cloud_runner_logger_1.default.logWithTime('Setup time');
|
yield custom_step_1.CustomStep.runCustomJob(cloud_runner_state_1.CloudRunnerState.buildParams.preBuildSteps);
|
||||||
yield CloudRunner.BuildStep(baseImage);
|
cloud_runner_logger_1.default.logWithTime('Pre build step(s) time');
|
||||||
|
new build_step_1.BuildStep().run(new cloud_runner_step_state_1.CloudRunnerStepState(baseImage, cloud_runner_state_1.CloudRunnerState.readBuildEnvironmentVariables(), cloud_runner_state_1.CloudRunnerState.defaultSecrets));
|
||||||
cloud_runner_logger_1.default.logWithTime('Build time');
|
cloud_runner_logger_1.default.logWithTime('Build time');
|
||||||
yield CloudRunner.CompressionStep();
|
yield new compression_step_1.CompressionStep().run(new cloud_runner_step_state_1.CloudRunnerStepState('alpine', cloud_runner_state_1.CloudRunnerState.readBuildEnvironmentVariables(), cloud_runner_state_1.CloudRunnerState.defaultSecrets));
|
||||||
cloud_runner_logger_1.default.logWithTime('Compression time');
|
cloud_runner_logger_1.default.logWithTime('Compression time');
|
||||||
yield this.runCustomJob(this.buildParams.postBuildSteps);
|
yield custom_step_1.CustomStep.runCustomJob(cloud_runner_state_1.CloudRunnerState.buildParams.postBuildSteps);
|
||||||
cloud_runner_logger_1.default.logWithTime('Post build steps time');
|
cloud_runner_logger_1.default.logWithTime('Post build step(s) time');
|
||||||
});
|
cloud_runner_logger_1.default.log(`Cloud Runner finished running standard build automation`);
|
||||||
}
|
|
||||||
static runJobAsEphemeralGitHubRunner(baseImage) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
cloud_runner_logger_1.default.log(`Cloud Runner is running in ephemeral GitHub runner mode`);
|
|
||||||
const installAndStartRunner = 'mkdir actions-runner && cd actions-runner && curl -O -L https://github.com/actions/runner/releases/download/v2.283.1/actions-runner-linux-x64-2.283.1.tar.gz && tar xzf ./actions-runner-linux-x64-2.283.1.tar.gz';
|
|
||||||
yield this.CloudRunnerProviderPlatform.runBuildTask(this.buildGuid, baseImage, [installAndStartRunner], `/${buildVolumeFolder}`, `/${buildVolumeFolder}`, this.defaultGitShaEnvironmentVariable, [...this.defaultSecrets]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
static runCustomJob(buildSteps) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
cloud_runner_logger_1.default.log(`Cloud Runner is running in custom job mode`);
|
|
||||||
buildSteps = yaml_1.default.parse(buildSteps);
|
|
||||||
for (const step of buildSteps) {
|
|
||||||
const stepSecrets = step.secrets.map((x) => {
|
|
||||||
const secret = {
|
|
||||||
ParameterKey: x.name,
|
|
||||||
EnvironmentVariable: x.name,
|
|
||||||
ParameterValue: x.value,
|
|
||||||
};
|
|
||||||
return secret;
|
|
||||||
});
|
|
||||||
yield this.CloudRunnerProviderPlatform.runBuildTask(this.buildGuid, step['image'], step['commands'], `/${buildVolumeFolder}`, `/${buildVolumeFolder}`, this.defaultGitShaEnvironmentVariable, [...this.defaultSecrets, ...stepSecrets]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
static setupStep() {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
cloud_runner_logger_1.default.log('Starting step 1/4 clone and restore cache)');
|
|
||||||
yield this.CloudRunnerProviderPlatform.runBuildTask(this.buildGuid, 'alpine/git', [
|
|
||||||
` printenv
|
|
||||||
apk update -q
|
|
||||||
apk add unzip zip git-lfs jq tree -q
|
|
||||||
mkdir -p ${this.buildPathFull}
|
|
||||||
mkdir -p ${this.builderPathFull}
|
|
||||||
mkdir -p ${this.repoPathFull}
|
|
||||||
${this.getCloneBuilder()}
|
|
||||||
echo ' '
|
|
||||||
echo 'Initializing source repository for cloning with caching of LFS files'
|
|
||||||
${this.getCloneNoLFSCommand()}
|
|
||||||
echo 'Source repository initialized'
|
|
||||||
echo ' '
|
|
||||||
echo 'Starting checks of cache for the Unity project Library and git LFS files'
|
|
||||||
${this.getHandleCachingCommand()}
|
|
||||||
`,
|
|
||||||
], `/${buildVolumeFolder}`, `/${buildVolumeFolder}/`, CloudRunner.defaultGitShaEnvironmentVariable, this.defaultSecrets);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
static BuildStep(baseImage) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
cloud_runner_logger_1.default.log('Starting part 2/4 (build unity project)');
|
|
||||||
yield this.CloudRunnerProviderPlatform.runBuildTask(this.buildGuid, baseImage.toString(), [
|
|
||||||
`
|
|
||||||
printenv
|
|
||||||
export GITHUB_WORKSPACE="${this.repoPathFull}"
|
|
||||||
cp -r "${this.builderPathFull}/dist/default-build-script/" "/UnityBuilderAction"
|
|
||||||
cp -r "${this.builderPathFull}/dist/entrypoint.sh" "/entrypoint.sh"
|
|
||||||
cp -r "${this.builderPathFull}/dist/steps/" "/steps"
|
|
||||||
chmod -R +x "/entrypoint.sh"
|
|
||||||
chmod -R +x "/steps"
|
|
||||||
/entrypoint.sh
|
|
||||||
${process.env.DEBUG ? '' : '#'}tree -L 4 "${this.buildPathFull}"
|
|
||||||
${process.env.DEBUG ? '' : '#'}ls -lh "/${buildVolumeFolder}"
|
|
||||||
`,
|
|
||||||
], `/${buildVolumeFolder}`, `/${this.projectPathFull}`, CloudRunner.readBuildEnvironmentVariables(), this.defaultSecrets);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
static CompressionStep() {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
cloud_runner_logger_1.default.log('Starting step 3/4 build compression');
|
|
||||||
// Cleanup
|
|
||||||
yield this.CloudRunnerProviderPlatform.runBuildTask(this.buildGuid, 'alpine', [
|
|
||||||
`
|
|
||||||
printenv
|
|
||||||
apk update -q
|
|
||||||
apk add zip tree -q
|
|
||||||
${process.env.DEBUG ? '' : '#'}tree -L 4 "$repoPathFull"
|
|
||||||
${process.env.DEBUG ? '' : '#'}ls -lh "$repoPathFull"
|
|
||||||
cd "$libraryFolderFull/.."
|
|
||||||
zip -r "lib-$BUILDID.zip" "./Library"
|
|
||||||
mv "lib-$BUILDID.zip" "/$cacheFolderFull/lib"
|
|
||||||
cd "$repoPathFull"
|
|
||||||
ls -lh "$repoPathFull"
|
|
||||||
zip -r "build-$BUILDID.zip" "./${CloudRunner.buildParams.buildPath}"
|
|
||||||
mv "build-$BUILDID.zip" "/$cacheFolderFull/build-$BUILDID.zip"
|
|
||||||
${process.env.DEBUG ? '' : '#'}tree -L 4 "/$cacheFolderFull"
|
|
||||||
${process.env.DEBUG ? '' : '#'}tree -L 4 "/$cacheFolderFull/.."
|
|
||||||
${process.env.DEBUG ? '' : '#'}tree -L 4 "$repoPathFull"
|
|
||||||
${process.env.DEBUG ? '' : '#'}ls -lh "$repoPathFull"
|
|
||||||
`,
|
|
||||||
], `/${buildVolumeFolder}`, `/${buildVolumeFolder}`, [
|
|
||||||
...CloudRunner.defaultGitShaEnvironmentVariable,
|
|
||||||
...[
|
|
||||||
{
|
|
||||||
name: 'cacheFolderFull',
|
|
||||||
value: this.cacheFolderFull,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
], this.defaultSecrets);
|
|
||||||
cloud_runner_logger_1.default.log('compression step complete');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
static cleanupSharedBuildResources() {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
yield this.CloudRunnerProviderPlatform.cleanupSharedBuildResources(this.buildGuid, this.buildParams, this.branchName, this.defaultSecrets);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static handleException(error) {
|
static handleException(error) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
cloud_runner_logger_1.default.error(JSON.stringify(error, undefined, 4));
|
cloud_runner_logger_1.default.error(JSON.stringify(error, undefined, 4));
|
||||||
core.setFailed('Remote Builder failed');
|
core.setFailed('Remote Builder failed');
|
||||||
yield this.CloudRunnerProviderPlatform.cleanupSharedBuildResources(this.buildGuid, this.buildParams, this.branchName, this.defaultSecrets);
|
yield cloud_runner_state_1.CloudRunnerState.CloudRunnerProviderPlatform.cleanupSharedBuildResources(cloud_runner_state_1.CloudRunnerState.buildGuid, cloud_runner_state_1.CloudRunnerState.buildParams, cloud_runner_state_1.CloudRunnerState.branchName, cloud_runner_state_1.CloudRunnerState.defaultSecrets);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CloudRunner.defaultGitShaEnvironmentVariable = [
|
|
||||||
{
|
|
||||||
name: 'GITHUB_SHA',
|
|
||||||
value: process.env.GITHUB_SHA || '',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
exports.default = CloudRunner;
|
exports.default = CloudRunner;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -242,7 +242,7 @@ class AWSBuildEnvironment implements CloudRunnerProviderInterface {
|
||||||
|
|
||||||
const baseResources = (await CF.describeStackResources({ StackName: this.baseStackName }).promise()).StackResources;
|
const baseResources = (await CF.describeStackResources({ StackName: this.baseStackName }).promise()).StackResources;
|
||||||
|
|
||||||
// TODO: offer a parameter to decide if you want the guarenteed shutdown or fastest startup time possible
|
// TODO: offer a parameter to decide if you want the guaranteed shutdown or fastest startup time possible
|
||||||
|
|
||||||
return {
|
return {
|
||||||
taskDefStackName,
|
taskDefStackName,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,194 @@
|
||||||
|
import { BuildParameters } from '../..';
|
||||||
|
import { CloudRunnerProviderInterface } from '../cloud-runner-services/cloud-runner-provider-interface';
|
||||||
|
import CloudRunnerSecret from '../cloud-runner-services/cloud-runner-secret';
|
||||||
|
import CloudRunnerEnvironmentVariable from '../cloud-runner-services/cloud-runner-environment-variable';
|
||||||
|
import ImageEnvironmentFactory from '../../image-environment-factory';
|
||||||
|
|
||||||
|
export class CloudRunnerState {
|
||||||
|
public static CloudRunnerProviderPlatform: CloudRunnerProviderInterface;
|
||||||
|
public static buildParams: BuildParameters;
|
||||||
|
public static defaultSecrets: CloudRunnerSecret[];
|
||||||
|
public static buildGuid: string;
|
||||||
|
public static branchName: string;
|
||||||
|
public static buildPathFull: string;
|
||||||
|
public static builderPathFull: string;
|
||||||
|
public static steamPathFull: string;
|
||||||
|
public static repoPathFull: string;
|
||||||
|
public static projectPathFull: string;
|
||||||
|
public static libraryFolderFull: string;
|
||||||
|
public static cacheFolderFull: string;
|
||||||
|
public static lfsDirectory: string;
|
||||||
|
public static purgeRemoteCaching: boolean;
|
||||||
|
public static CloudRunnerBranch: string;
|
||||||
|
public static unityBuilderRepoUrl: string;
|
||||||
|
public static targetBuildRepoUrl: string;
|
||||||
|
public static readonly defaultGitShaEnvironmentVariable = [
|
||||||
|
{
|
||||||
|
name: 'GITHUB_SHA',
|
||||||
|
value: process.env.GITHUB_SHA || '',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
public static readonly repositoryFolder = 'repo';
|
||||||
|
public static readonly buildVolumeFolder = 'data';
|
||||||
|
public static readonly cacheFolder = 'cache';
|
||||||
|
|
||||||
|
public static readBuildEnvironmentVariables(): CloudRunnerEnvironmentVariable[] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: 'ContainerMemory',
|
||||||
|
value: CloudRunnerState.buildParams.cloudRunnerMemory,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ContainerCpu',
|
||||||
|
value: CloudRunnerState.buildParams.cloudRunnerCpu,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'GITHUB_WORKSPACE',
|
||||||
|
value: `/${CloudRunnerState.buildVolumeFolder}/${CloudRunnerState.buildGuid}/${CloudRunnerState.repositoryFolder}/`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PROJECT_PATH',
|
||||||
|
value: CloudRunnerState.buildParams.projectPath,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BUILD_PATH',
|
||||||
|
value: CloudRunnerState.buildParams.buildPath,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BUILD_FILE',
|
||||||
|
value: CloudRunnerState.buildParams.buildFile,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BUILD_NAME',
|
||||||
|
value: CloudRunnerState.buildParams.buildName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BUILD_METHOD',
|
||||||
|
value: CloudRunnerState.buildParams.buildMethod,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CUSTOM_PARAMETERS',
|
||||||
|
value: CloudRunnerState.buildParams.customParameters,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BUILD_TARGET',
|
||||||
|
value: CloudRunnerState.buildParams.platform,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ANDROID_VERSION_CODE',
|
||||||
|
value: CloudRunnerState.buildParams.androidVersionCode.toString(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ANDROID_KEYSTORE_NAME',
|
||||||
|
value: CloudRunnerState.buildParams.androidKeystoreName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ANDROID_KEYALIAS_NAME',
|
||||||
|
value: CloudRunnerState.buildParams.androidKeyaliasName,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getHandleCachingCommand() {
|
||||||
|
return `${CloudRunnerState.builderPathFull}/dist/cloud-runner/handleCaching.sh "${CloudRunnerState.cacheFolderFull}" "${CloudRunnerState.libraryFolderFull}" "${CloudRunnerState.lfsDirectory}" "${CloudRunnerState.purgeRemoteCaching}"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getCloneNoLFSCommand() {
|
||||||
|
return `${CloudRunnerState.builderPathFull}/dist/cloud-runner/cloneNoLFS.sh "${CloudRunnerState.repoPathFull}" "${CloudRunnerState.targetBuildRepoUrl}"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getCloneBuilder() {
|
||||||
|
return `git clone -q ${CloudRunnerState.CloudRunnerBranch} ${CloudRunnerState.unityBuilderRepoUrl} ${CloudRunnerState.builderPathFull}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readRunNumber() {
|
||||||
|
const runNumber = process.env.GITHUB_RUN_NUMBER;
|
||||||
|
if (!runNumber || runNumber === '') {
|
||||||
|
throw new Error('no run number found, exiting');
|
||||||
|
}
|
||||||
|
return runNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static setupFolderVariables() {
|
||||||
|
CloudRunnerState.buildPathFull = `/${CloudRunnerState.buildVolumeFolder}/${CloudRunnerState.buildGuid}`;
|
||||||
|
CloudRunnerState.builderPathFull = `${CloudRunnerState.buildPathFull}/builder`;
|
||||||
|
CloudRunnerState.steamPathFull = `${CloudRunnerState.buildPathFull}/steam`;
|
||||||
|
CloudRunnerState.repoPathFull = `${CloudRunnerState.buildPathFull}/${CloudRunnerState.repositoryFolder}`;
|
||||||
|
CloudRunnerState.projectPathFull = `${CloudRunnerState.repoPathFull}/${CloudRunnerState.buildParams.projectPath}`;
|
||||||
|
CloudRunnerState.libraryFolderFull = `${CloudRunnerState.projectPathFull}/Library`;
|
||||||
|
CloudRunnerState.cacheFolderFull = `/${CloudRunnerState.buildVolumeFolder}/${CloudRunnerState.cacheFolder}/${CloudRunnerState.branchName}`;
|
||||||
|
CloudRunnerState.lfsDirectory = `${CloudRunnerState.repoPathFull}/.git/lfs`;
|
||||||
|
CloudRunnerState.purgeRemoteCaching = process.env.PURGE_REMOTE_BUILDER_CACHE !== undefined;
|
||||||
|
CloudRunnerState.CloudRunnerBranch = process.env.CloudRunnerBranch
|
||||||
|
? `--branch "${process.env.CloudRunnerBranch}"`
|
||||||
|
: '';
|
||||||
|
CloudRunnerState.unityBuilderRepoUrl = `https://${CloudRunnerState.buildParams.githubToken}@github.com/game-ci/unity-builder.git`;
|
||||||
|
CloudRunnerState.targetBuildRepoUrl = `https://${CloudRunnerState.buildParams.githubToken}@github.com/${process.env.GITHUB_REPOSITORY}.git`;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static setupBranchName() {
|
||||||
|
const defaultBranchName =
|
||||||
|
process.env.GITHUB_REF?.split('/')
|
||||||
|
.filter((x) => {
|
||||||
|
x = x[0].toUpperCase() + x.slice(1);
|
||||||
|
return x;
|
||||||
|
})
|
||||||
|
.join('') || '';
|
||||||
|
CloudRunnerState.branchName =
|
||||||
|
process.env.REMOTE_BUILDER_CACHE !== undefined ? process.env.REMOTE_BUILDER_CACHE : defaultBranchName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static setupDefaultSecrets() {
|
||||||
|
CloudRunnerState.defaultSecrets = [
|
||||||
|
{
|
||||||
|
ParameterKey: 'GithubToken',
|
||||||
|
EnvironmentVariable: 'GITHUB_TOKEN',
|
||||||
|
ParameterValue: CloudRunnerState.buildParams.githubToken,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ParameterKey: 'branch',
|
||||||
|
EnvironmentVariable: 'branch',
|
||||||
|
ParameterValue: CloudRunnerState.branchName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ParameterKey: 'buildPathFull',
|
||||||
|
EnvironmentVariable: 'buildPathFull',
|
||||||
|
ParameterValue: CloudRunnerState.buildPathFull,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ParameterKey: 'projectPathFull',
|
||||||
|
EnvironmentVariable: 'projectPathFull',
|
||||||
|
ParameterValue: CloudRunnerState.projectPathFull,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ParameterKey: 'libraryFolderFull',
|
||||||
|
EnvironmentVariable: 'libraryFolderFull',
|
||||||
|
ParameterValue: CloudRunnerState.libraryFolderFull,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ParameterKey: 'builderPathFull',
|
||||||
|
EnvironmentVariable: 'builderPathFull',
|
||||||
|
ParameterValue: CloudRunnerState.builderPathFull,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ParameterKey: 'repoPathFull',
|
||||||
|
EnvironmentVariable: 'repoPathFull',
|
||||||
|
ParameterValue: CloudRunnerState.repoPathFull,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ParameterKey: 'steamPathFull',
|
||||||
|
EnvironmentVariable: 'steamPathFull',
|
||||||
|
ParameterValue: CloudRunnerState.steamPathFull,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
CloudRunnerState.defaultSecrets.push(
|
||||||
|
...ImageEnvironmentFactory.getEnvironmentVariables(CloudRunnerState.buildParams).map((x) => {
|
||||||
|
return {
|
||||||
|
ParameterKey: x.name,
|
||||||
|
EnvironmentVariable: x.name,
|
||||||
|
ParameterValue: x.value,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
import CloudRunnerEnvironmentVariable from '../cloud-runner-services/cloud-runner-environment-variable';
|
||||||
|
import CloudRunnerSecret from '../cloud-runner-services/cloud-runner-secret';
|
||||||
|
|
||||||
|
export class CloudRunnerStepState {
|
||||||
|
public image: string;
|
||||||
|
public environment: CloudRunnerEnvironmentVariable[];
|
||||||
|
public secrets: CloudRunnerSecret[];
|
||||||
|
constructor(image: string, environmentVariables: CloudRunnerEnvironmentVariable[], secrets: CloudRunnerSecret[]) {
|
||||||
|
this.image = image;
|
||||||
|
this.environment = environmentVariables;
|
||||||
|
this.secrets = secrets;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
import CloudRunnerEnvironmentVariable from '../cloud-runner-services/cloud-runner-environment-variable';
|
||||||
|
import CloudRunnerLogger from '../cloud-runner-services/cloud-runner-logger';
|
||||||
|
import CloudRunnerSecret from '../cloud-runner-services/cloud-runner-secret';
|
||||||
|
import { CloudRunnerState } from '../cloud-runner-state/cloud-runner-state';
|
||||||
|
import { CloudRunnerStepState } from '../cloud-runner-state/cloud-runner-step-state';
|
||||||
|
import { StandardStepInterface } from './standard-step-interface';
|
||||||
|
|
||||||
|
export class BuildStep implements StandardStepInterface {
|
||||||
|
async run(cloudRunnerStepState: CloudRunnerStepState) {
|
||||||
|
await BuildStep.BuildStep(
|
||||||
|
cloudRunnerStepState.image,
|
||||||
|
cloudRunnerStepState.environment,
|
||||||
|
cloudRunnerStepState.secrets,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async BuildStep(
|
||||||
|
image: string,
|
||||||
|
environmentVariables: CloudRunnerEnvironmentVariable[],
|
||||||
|
secrets: CloudRunnerSecret[],
|
||||||
|
) {
|
||||||
|
CloudRunnerLogger.log('Starting part 2/4 (build unity project)');
|
||||||
|
await CloudRunnerState.CloudRunnerProviderPlatform.runBuildTask(
|
||||||
|
CloudRunnerState.buildGuid,
|
||||||
|
image,
|
||||||
|
[
|
||||||
|
`
|
||||||
|
printenv
|
||||||
|
export GITHUB_WORKSPACE="${CloudRunnerState.repoPathFull}"
|
||||||
|
cp -r "${CloudRunnerState.builderPathFull}/dist/default-build-script/" "/UnityBuilderAction"
|
||||||
|
cp -r "${CloudRunnerState.builderPathFull}/dist/entrypoint.sh" "/entrypoint.sh"
|
||||||
|
cp -r "${CloudRunnerState.builderPathFull}/dist/steps/" "/steps"
|
||||||
|
chmod -R +x "/entrypoint.sh"
|
||||||
|
chmod -R +x "/steps"
|
||||||
|
/entrypoint.sh
|
||||||
|
${process.env.DEBUG ? '' : '#'}tree -L 4 "${CloudRunnerState.buildPathFull}"
|
||||||
|
${process.env.DEBUG ? '' : '#'}ls -lh "/${CloudRunnerState.buildVolumeFolder}"
|
||||||
|
`,
|
||||||
|
],
|
||||||
|
`/${CloudRunnerState.buildVolumeFolder}`,
|
||||||
|
`/${CloudRunnerState.projectPathFull}`,
|
||||||
|
environmentVariables,
|
||||||
|
secrets,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
import CloudRunnerEnvironmentVariable from '../cloud-runner-services/cloud-runner-environment-variable';
|
||||||
|
import CloudRunnerLogger from '../cloud-runner-services/cloud-runner-logger';
|
||||||
|
import CloudRunnerSecret from '../cloud-runner-services/cloud-runner-secret';
|
||||||
|
import { CloudRunnerState } from '../cloud-runner-state/cloud-runner-state';
|
||||||
|
import { CloudRunnerStepState } from '../cloud-runner-state/cloud-runner-step-state';
|
||||||
|
import { StandardStepInterface } from './standard-step-interface';
|
||||||
|
|
||||||
|
export class CompressionStep implements StandardStepInterface {
|
||||||
|
async run(cloudRunnerStepState: CloudRunnerStepState) {
|
||||||
|
await CompressionStep.CompressionStep(cloudRunnerStepState.environment, cloudRunnerStepState.secrets);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async CompressionStep(
|
||||||
|
environmentVariables: CloudRunnerEnvironmentVariable[],
|
||||||
|
secrets: CloudRunnerSecret[],
|
||||||
|
) {
|
||||||
|
CloudRunnerLogger.log('Starting step 3/4 build compression');
|
||||||
|
// Cleanup
|
||||||
|
await CloudRunnerState.CloudRunnerProviderPlatform.runBuildTask(
|
||||||
|
CloudRunnerState.buildGuid,
|
||||||
|
'alpine',
|
||||||
|
[
|
||||||
|
`
|
||||||
|
printenv
|
||||||
|
apk update -q
|
||||||
|
apk add zip tree -q
|
||||||
|
${process.env.DEBUG ? '' : '#'}tree -L 4 "$repoPathFull"
|
||||||
|
${process.env.DEBUG ? '' : '#'}ls -lh "$repoPathFull"
|
||||||
|
cd "$libraryFolderFull/.."
|
||||||
|
zip -r "lib-$BUILDID.zip" "./Library"
|
||||||
|
mv "lib-$BUILDID.zip" "/$cacheFolderFull/lib"
|
||||||
|
cd "$repoPathFull"
|
||||||
|
ls -lh "$repoPathFull"
|
||||||
|
zip -r "build-$BUILDID.zip" "./${CloudRunnerState.buildParams.buildPath}"
|
||||||
|
mv "build-$BUILDID.zip" "/$cacheFolderFull/build-$BUILDID.zip"
|
||||||
|
${process.env.DEBUG ? '' : '#'}tree -L 4 "/$cacheFolderFull"
|
||||||
|
${process.env.DEBUG ? '' : '#'}tree -L 4 "/$cacheFolderFull/.."
|
||||||
|
${process.env.DEBUG ? '' : '#'}tree -L 4 "$repoPathFull"
|
||||||
|
${process.env.DEBUG ? '' : '#'}ls -lh "$repoPathFull"
|
||||||
|
`,
|
||||||
|
],
|
||||||
|
`/${CloudRunnerState.buildVolumeFolder}`,
|
||||||
|
`/${CloudRunnerState.buildVolumeFolder}`,
|
||||||
|
[
|
||||||
|
...environmentVariables,
|
||||||
|
...[
|
||||||
|
{
|
||||||
|
name: 'cacheFolderFull',
|
||||||
|
value: CloudRunnerState.cacheFolderFull,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
secrets,
|
||||||
|
);
|
||||||
|
CloudRunnerLogger.log('compression step complete');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
import CloudRunnerLogger from '../cloud-runner-services/cloud-runner-logger';
|
||||||
|
import CloudRunnerSecret from '../cloud-runner-services/cloud-runner-secret';
|
||||||
|
import { CloudRunnerState } from '../cloud-runner-state/cloud-runner-state';
|
||||||
|
import YAML from 'yaml';
|
||||||
|
|
||||||
|
export class CustomStep {
|
||||||
|
public static async runCustomJob(buildSteps) {
|
||||||
|
CloudRunnerLogger.log(`Cloud Runner is running in custom job mode`);
|
||||||
|
buildSteps = YAML.parse(buildSteps);
|
||||||
|
for (const step of buildSteps) {
|
||||||
|
const stepSecrets: CloudRunnerSecret[] = step.secrets.map((x) => {
|
||||||
|
const secret: CloudRunnerSecret = {
|
||||||
|
ParameterKey: x.name,
|
||||||
|
EnvironmentVariable: x.name,
|
||||||
|
ParameterValue: x.value,
|
||||||
|
};
|
||||||
|
return secret;
|
||||||
|
});
|
||||||
|
await CloudRunnerState.CloudRunnerProviderPlatform.runBuildTask(
|
||||||
|
CloudRunnerState.buildGuid,
|
||||||
|
step['image'],
|
||||||
|
step['commands'],
|
||||||
|
`/${CloudRunnerState.buildVolumeFolder}`,
|
||||||
|
`/${CloudRunnerState.buildVolumeFolder}`,
|
||||||
|
CloudRunnerState.defaultGitShaEnvironmentVariable,
|
||||||
|
[...CloudRunnerState.defaultSecrets, ...stepSecrets],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
import CloudRunnerEnvironmentVariable from '../cloud-runner-services/cloud-runner-environment-variable';
|
||||||
|
import CloudRunnerLogger from '../cloud-runner-services/cloud-runner-logger';
|
||||||
|
import CloudRunnerSecret from '../cloud-runner-services/cloud-runner-secret';
|
||||||
|
import { CloudRunnerState } from '../cloud-runner-state/cloud-runner-state';
|
||||||
|
import { CloudRunnerStepState } from '../cloud-runner-state/cloud-runner-step-state';
|
||||||
|
import { StandardStepInterface } from './standard-step-interface';
|
||||||
|
|
||||||
|
export class DownloadRepositoryStep implements StandardStepInterface {
|
||||||
|
async run(cloudRunnerStepState: CloudRunnerStepState) {
|
||||||
|
await DownloadRepositoryStep.downloadRepositoryStep(
|
||||||
|
cloudRunnerStepState.image,
|
||||||
|
cloudRunnerStepState.environment,
|
||||||
|
cloudRunnerStepState.secrets,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async downloadRepositoryStep(
|
||||||
|
image: string,
|
||||||
|
environmentVariables: CloudRunnerEnvironmentVariable[],
|
||||||
|
secrets: CloudRunnerSecret[],
|
||||||
|
) {
|
||||||
|
CloudRunnerLogger.log('Starting step 1/4 clone and restore cache');
|
||||||
|
await CloudRunnerState.CloudRunnerProviderPlatform.runBuildTask(
|
||||||
|
CloudRunnerState.buildGuid,
|
||||||
|
image,
|
||||||
|
[
|
||||||
|
` printenv
|
||||||
|
apk update -q
|
||||||
|
apk add unzip zip git-lfs jq tree -q
|
||||||
|
mkdir -p ${CloudRunnerState.buildPathFull}
|
||||||
|
mkdir -p ${CloudRunnerState.builderPathFull}
|
||||||
|
mkdir -p ${CloudRunnerState.repoPathFull}
|
||||||
|
${CloudRunnerState.getCloneBuilder()}
|
||||||
|
echo ' '
|
||||||
|
echo 'Initializing source repository for cloning with caching of LFS files'
|
||||||
|
${CloudRunnerState.getCloneNoLFSCommand()}
|
||||||
|
echo 'Source repository initialized'
|
||||||
|
echo ' '
|
||||||
|
echo 'Starting checks of cache for the Unity project Library and git LFS files'
|
||||||
|
${CloudRunnerState.getHandleCachingCommand()}
|
||||||
|
`,
|
||||||
|
],
|
||||||
|
`/${CloudRunnerState.buildVolumeFolder}`,
|
||||||
|
`/${CloudRunnerState.buildVolumeFolder}/`,
|
||||||
|
environmentVariables,
|
||||||
|
secrets,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
import CloudRunnerEnvironmentVariable from '../cloud-runner-services/cloud-runner-environment-variable';
|
||||||
|
import CloudRunnerLogger from '../cloud-runner-services/cloud-runner-logger';
|
||||||
|
import CloudRunnerSecret from '../cloud-runner-services/cloud-runner-secret';
|
||||||
|
import { CloudRunnerState } from '../cloud-runner-state/cloud-runner-state';
|
||||||
|
import { CloudRunnerStepState } from '../cloud-runner-state/cloud-runner-step-state';
|
||||||
|
import { StandardStepInterface } from './standard-step-interface';
|
||||||
|
|
||||||
|
export class EphemeralGitHubRunnerStep implements StandardStepInterface {
|
||||||
|
async run(cloudRunnerStepState: CloudRunnerStepState) {
|
||||||
|
await EphemeralGitHubRunnerStep.runJobAsEphemeralGitHubRunner(
|
||||||
|
cloudRunnerStepState.image,
|
||||||
|
cloudRunnerStepState.environment,
|
||||||
|
cloudRunnerStepState.secrets,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async runJobAsEphemeralGitHubRunner(
|
||||||
|
image: string,
|
||||||
|
environmentVariables: CloudRunnerEnvironmentVariable[],
|
||||||
|
secrets: CloudRunnerSecret[],
|
||||||
|
) {
|
||||||
|
CloudRunnerLogger.log(`Cloud Runner is running in ephemeral GitHub runner mode`);
|
||||||
|
const installAndStartRunner =
|
||||||
|
'mkdir actions-runner && cd actions-runner && curl -O -L https://github.com/actions/runner/releases/download/v2.283.1/actions-runner-linux-x64-2.283.1.tar.gz && tar xzf ./actions-runner-linux-x64-2.283.1.tar.gz';
|
||||||
|
await CloudRunnerState.CloudRunnerProviderPlatform.runBuildTask(
|
||||||
|
CloudRunnerState.buildGuid,
|
||||||
|
image,
|
||||||
|
[installAndStartRunner],
|
||||||
|
`/${CloudRunnerState.buildVolumeFolder}`,
|
||||||
|
`/${CloudRunnerState.buildVolumeFolder}`,
|
||||||
|
environmentVariables,
|
||||||
|
secrets,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { CloudRunnerStepState } from '../cloud-runner-state/cloud-runner-step-state';
|
||||||
|
|
||||||
|
export interface StandardStepInterface {
|
||||||
|
run(
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
cloudRunnerStepState: CloudRunnerStepState,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -2,425 +2,138 @@ import AWSBuildPlatform from './aws/aws-build-platform';
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import { BuildParameters } from '..';
|
import { BuildParameters } from '..';
|
||||||
import CloudRunnerNamespace from './cloud-runner-services/cloud-runner-namespace';
|
import CloudRunnerNamespace from './cloud-runner-services/cloud-runner-namespace';
|
||||||
import CloudRunnerSecret from './cloud-runner-services/cloud-runner-secret';
|
import { CloudRunnerState } from './cloud-runner-state/cloud-runner-state';
|
||||||
import { CloudRunnerProviderInterface } from './cloud-runner-services/cloud-runner-provider-interface';
|
|
||||||
import Kubernetes from './k8s/kubernetes-build-platform';
|
import Kubernetes from './k8s/kubernetes-build-platform';
|
||||||
import CloudRunnerEnvironmentVariable from './cloud-runner-services/cloud-runner-environment-variable';
|
|
||||||
import ImageEnvironmentFactory from '../image-environment-factory';
|
|
||||||
import YAML from 'yaml';
|
|
||||||
import CloudRunnerLogger from './cloud-runner-services/cloud-runner-logger';
|
import CloudRunnerLogger from './cloud-runner-services/cloud-runner-logger';
|
||||||
const repositoryFolder = 'repo';
|
import { BuildStep } from './cloud-runner-steps/build-step';
|
||||||
const buildVolumeFolder = 'data';
|
import { CompressionStep } from './cloud-runner-steps/compression-step';
|
||||||
const cacheFolder = 'cache';
|
import { DownloadRepositoryStep } from './cloud-runner-steps/download-repository-step';
|
||||||
|
import { CustomStep } from './cloud-runner-steps/custom-step';
|
||||||
|
import { EphemeralGitHubRunnerStep } from './cloud-runner-steps/ephemeral-github-runner-step';
|
||||||
|
import { CloudRunnerStepState } from './cloud-runner-state/cloud-runner-step-state';
|
||||||
|
|
||||||
class CloudRunner {
|
class CloudRunner {
|
||||||
static CloudRunnerProviderPlatform: CloudRunnerProviderInterface;
|
|
||||||
private static buildParams: BuildParameters;
|
|
||||||
private static defaultSecrets: CloudRunnerSecret[];
|
|
||||||
private static buildGuid: string;
|
|
||||||
private static branchName: string;
|
|
||||||
private static buildPathFull: string;
|
|
||||||
private static builderPathFull: string;
|
|
||||||
private static steamPathFull: string;
|
|
||||||
private static repoPathFull: string;
|
|
||||||
private static projectPathFull: string;
|
|
||||||
private static libraryFolderFull: string;
|
|
||||||
private static cacheFolderFull: string;
|
|
||||||
private static lfsDirectory: string;
|
|
||||||
private static purgeRemoteCaching: boolean;
|
|
||||||
private static CloudRunnerBranch: string;
|
|
||||||
private static unityBuilderRepoUrl: string;
|
|
||||||
private static targetBuildRepoUrl: string;
|
|
||||||
private static readonly defaultGitShaEnvironmentVariable = [
|
|
||||||
{
|
|
||||||
name: 'GITHUB_SHA',
|
|
||||||
value: process.env.GITHUB_SHA || '',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
private static setup(buildParameters: BuildParameters) {
|
private static setup(buildParameters: BuildParameters) {
|
||||||
CloudRunnerLogger.setup();
|
CloudRunnerLogger.setup();
|
||||||
CloudRunner.buildGuid = CloudRunnerNamespace.generateBuildName(
|
CloudRunnerState.buildGuid = CloudRunnerNamespace.generateBuildName(
|
||||||
CloudRunner.readRunNumber(),
|
CloudRunnerState.readRunNumber(),
|
||||||
buildParameters.platform,
|
buildParameters.platform,
|
||||||
);
|
);
|
||||||
CloudRunner.buildParams = buildParameters;
|
CloudRunnerState.buildParams = buildParameters;
|
||||||
CloudRunner.setupBranchName();
|
CloudRunnerState.setupBranchName();
|
||||||
CloudRunner.setupFolderVariables();
|
CloudRunnerState.setupFolderVariables();
|
||||||
CloudRunner.setupDefaultSecrets();
|
CloudRunnerState.setupDefaultSecrets();
|
||||||
CloudRunner.setupBuildPlatform();
|
CloudRunner.setupBuildPlatform();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static setupFolderVariables() {
|
public static setupBuildPlatform() {
|
||||||
this.buildPathFull = `/${buildVolumeFolder}/${this.buildGuid}`;
|
switch (CloudRunnerState.buildParams.cloudRunnerCluster) {
|
||||||
this.builderPathFull = `${this.buildPathFull}/builder`;
|
case 'aws':
|
||||||
this.steamPathFull = `${this.buildPathFull}/steam`;
|
CloudRunnerLogger.log('Building with AWS');
|
||||||
this.repoPathFull = `${this.buildPathFull}/${repositoryFolder}`;
|
CloudRunnerState.CloudRunnerProviderPlatform = new AWSBuildPlatform(CloudRunnerState.buildParams);
|
||||||
this.projectPathFull = `${this.repoPathFull}/${this.buildParams.projectPath}`;
|
break;
|
||||||
this.libraryFolderFull = `${this.projectPathFull}/Library`;
|
default:
|
||||||
this.cacheFolderFull = `/${buildVolumeFolder}/${cacheFolder}/${this.branchName}`;
|
case 'k8s':
|
||||||
this.lfsDirectory = `${this.repoPathFull}/.git/lfs`;
|
CloudRunnerLogger.log('Building with Kubernetes');
|
||||||
this.purgeRemoteCaching = process.env.PURGE_REMOTE_BUILDER_CACHE !== undefined;
|
CloudRunnerState.CloudRunnerProviderPlatform = new Kubernetes(CloudRunnerState.buildParams);
|
||||||
this.CloudRunnerBranch = process.env.CloudRunnerBranch ? `--branch "${process.env.CloudRunnerBranch}"` : '';
|
break;
|
||||||
this.unityBuilderRepoUrl = `https://${this.buildParams.githubToken}@github.com/game-ci/unity-builder.git`;
|
}
|
||||||
this.targetBuildRepoUrl = `https://${this.buildParams.githubToken}@github.com/${process.env.GITHUB_REPOSITORY}.git`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static getHandleCachingCommand() {
|
|
||||||
return `${this.builderPathFull}/dist/cloud-runner/handleCaching.sh "${this.cacheFolderFull}" "${this.libraryFolderFull}" "${this.lfsDirectory}" "${this.purgeRemoteCaching}"`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static getCloneNoLFSCommand() {
|
|
||||||
return `${this.builderPathFull}/dist/cloud-runner/cloneNoLFS.sh "${this.repoPathFull}" "${this.targetBuildRepoUrl}"`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static getCloneBuilder() {
|
|
||||||
return `git clone -q ${this.CloudRunnerBranch} ${this.unityBuilderRepoUrl} ${this.builderPathFull}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async run(buildParameters: BuildParameters, baseImage) {
|
static async run(buildParameters: BuildParameters, baseImage) {
|
||||||
CloudRunner.setup(buildParameters);
|
CloudRunner.setup(buildParameters);
|
||||||
try {
|
try {
|
||||||
await CloudRunner.setupSharedBuildResources();
|
await CloudRunnerState.CloudRunnerProviderPlatform.setupSharedBuildResources(
|
||||||
await CloudRunner.setupStep();
|
CloudRunnerState.buildGuid,
|
||||||
await CloudRunner.runMainJob(baseImage);
|
CloudRunnerState.buildParams,
|
||||||
await CloudRunner.cleanupSharedBuildResources();
|
CloudRunnerState.branchName,
|
||||||
|
CloudRunnerState.defaultSecrets,
|
||||||
|
);
|
||||||
|
await CloudRunner.runJob(baseImage);
|
||||||
|
await CloudRunnerState.CloudRunnerProviderPlatform.cleanupSharedBuildResources(
|
||||||
|
CloudRunnerState.buildGuid,
|
||||||
|
CloudRunnerState.buildParams,
|
||||||
|
CloudRunnerState.branchName,
|
||||||
|
CloudRunnerState.defaultSecrets,
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await CloudRunner.handleException(error);
|
await CloudRunner.handleException(error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async setupSharedBuildResources() {
|
private static async runJob(baseImage: any) {
|
||||||
await this.CloudRunnerProviderPlatform.setupSharedBuildResources(
|
core.info(`Custom build steps: ${CloudRunnerState.buildParams.customBuildSteps}`);
|
||||||
this.buildGuid,
|
if (CloudRunnerState.buildParams.customBuildSteps === '') {
|
||||||
this.buildParams,
|
|
||||||
this.branchName,
|
|
||||||
this.defaultSecrets,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static setupBuildPlatform() {
|
|
||||||
switch (this.buildParams.cloudRunnerCluster) {
|
|
||||||
case 'aws':
|
|
||||||
CloudRunnerLogger.log('Building with AWS');
|
|
||||||
this.CloudRunnerProviderPlatform = new AWSBuildPlatform(this.buildParams);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
case 'k8s':
|
|
||||||
CloudRunnerLogger.log('Building with Kubernetes');
|
|
||||||
this.CloudRunnerProviderPlatform = new Kubernetes(this.buildParams);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readRunNumber() {
|
|
||||||
const runNumber = process.env.GITHUB_RUN_NUMBER;
|
|
||||||
if (!runNumber || runNumber === '') {
|
|
||||||
throw new Error('no run number found, exiting');
|
|
||||||
}
|
|
||||||
return runNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static setupBranchName() {
|
|
||||||
const defaultBranchName =
|
|
||||||
process.env.GITHUB_REF?.split('/')
|
|
||||||
.filter((x) => {
|
|
||||||
x = x[0].toUpperCase() + x.slice(1);
|
|
||||||
return x;
|
|
||||||
})
|
|
||||||
.join('') || '';
|
|
||||||
this.branchName =
|
|
||||||
process.env.REMOTE_BUILDER_CACHE !== undefined ? process.env.REMOTE_BUILDER_CACHE : defaultBranchName;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static setupDefaultSecrets() {
|
|
||||||
this.defaultSecrets = [
|
|
||||||
{
|
|
||||||
ParameterKey: 'GithubToken',
|
|
||||||
EnvironmentVariable: 'GITHUB_TOKEN',
|
|
||||||
ParameterValue: this.buildParams.githubToken,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ParameterKey: 'branch',
|
|
||||||
EnvironmentVariable: 'branch',
|
|
||||||
ParameterValue: this.branchName,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ParameterKey: 'buildPathFull',
|
|
||||||
EnvironmentVariable: 'buildPathFull',
|
|
||||||
ParameterValue: this.buildPathFull,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ParameterKey: 'projectPathFull',
|
|
||||||
EnvironmentVariable: 'projectPathFull',
|
|
||||||
ParameterValue: this.projectPathFull,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ParameterKey: 'libraryFolderFull',
|
|
||||||
EnvironmentVariable: 'libraryFolderFull',
|
|
||||||
ParameterValue: this.libraryFolderFull,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ParameterKey: 'builderPathFull',
|
|
||||||
EnvironmentVariable: 'builderPathFull',
|
|
||||||
ParameterValue: this.builderPathFull,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ParameterKey: 'repoPathFull',
|
|
||||||
EnvironmentVariable: 'repoPathFull',
|
|
||||||
ParameterValue: this.repoPathFull,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ParameterKey: 'steamPathFull',
|
|
||||||
EnvironmentVariable: 'steamPathFull',
|
|
||||||
ParameterValue: this.steamPathFull,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
this.defaultSecrets.push(
|
|
||||||
...ImageEnvironmentFactory.getEnvironmentVariables(this.buildParams).map((x) => {
|
|
||||||
return {
|
|
||||||
ParameterKey: x.name,
|
|
||||||
EnvironmentVariable: x.name,
|
|
||||||
ParameterValue: x.value,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readBuildEnvironmentVariables(): CloudRunnerEnvironmentVariable[] {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
name: 'ContainerMemory',
|
|
||||||
value: this.buildParams.cloudRunnerMemory,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'ContainerCpu',
|
|
||||||
value: this.buildParams.cloudRunnerCpu,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'GITHUB_WORKSPACE',
|
|
||||||
value: `/${buildVolumeFolder}/${this.buildGuid}/${repositoryFolder}/`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'PROJECT_PATH',
|
|
||||||
value: this.buildParams.projectPath,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'BUILD_PATH',
|
|
||||||
value: this.buildParams.buildPath,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'BUILD_FILE',
|
|
||||||
value: this.buildParams.buildFile,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'BUILD_NAME',
|
|
||||||
value: this.buildParams.buildName,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'BUILD_METHOD',
|
|
||||||
value: this.buildParams.buildMethod,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'CUSTOM_PARAMETERS',
|
|
||||||
value: this.buildParams.customParameters,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'BUILD_TARGET',
|
|
||||||
value: this.buildParams.platform,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'ANDROID_VERSION_CODE',
|
|
||||||
value: this.buildParams.androidVersionCode.toString(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'ANDROID_KEYSTORE_NAME',
|
|
||||||
value: this.buildParams.androidKeystoreName,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'ANDROID_KEYALIAS_NAME',
|
|
||||||
value: this.buildParams.androidKeyaliasName,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async runMainJob(baseImage: any) {
|
|
||||||
if (this.buildParams.customBuildSteps === '') {
|
|
||||||
await CloudRunner.standardBuildAutomation(baseImage);
|
await CloudRunner.standardBuildAutomation(baseImage);
|
||||||
} else if (this.buildParams.customBuildSteps === 'ephemeral') {
|
} else if (CloudRunnerState.buildParams.customBuildSteps === 'ephemeral') {
|
||||||
await CloudRunner.runJobAsEphemeralGitHubRunner(baseImage);
|
await new EphemeralGitHubRunnerStep().run(
|
||||||
|
new CloudRunnerStepState(
|
||||||
|
baseImage,
|
||||||
|
CloudRunnerState.readBuildEnvironmentVariables(),
|
||||||
|
CloudRunnerState.defaultSecrets,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else if (CloudRunnerState.buildParams.customBuildSteps === 'download') {
|
||||||
|
await new DownloadRepositoryStep().run(
|
||||||
|
new CloudRunnerStepState(
|
||||||
|
'alpine/git',
|
||||||
|
CloudRunnerState.readBuildEnvironmentVariables(),
|
||||||
|
CloudRunnerState.defaultSecrets,
|
||||||
|
),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
await CloudRunner.runCustomJob(this.buildParams.customBuildSteps);
|
await CustomStep.runCustomJob(CloudRunnerState.buildParams.customBuildSteps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async standardBuildAutomation(baseImage: any) {
|
private static async standardBuildAutomation(baseImage: any) {
|
||||||
CloudRunnerLogger.log(`Cloud Runner is running in standard build automation mode`);
|
CloudRunnerLogger.log(`Cloud Runner is running standard build automation`);
|
||||||
CloudRunnerLogger.logWithTime('Pre build steps time');
|
|
||||||
await this.runCustomJob(this.buildParams.preBuildSteps);
|
await new DownloadRepositoryStep().run(
|
||||||
CloudRunnerLogger.logWithTime('Setup time');
|
new CloudRunnerStepState(
|
||||||
await CloudRunner.BuildStep(baseImage);
|
'alpine/git',
|
||||||
|
CloudRunnerState.readBuildEnvironmentVariables(),
|
||||||
|
CloudRunnerState.defaultSecrets,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
CloudRunnerLogger.logWithTime('Download repository step time');
|
||||||
|
|
||||||
|
await CustomStep.runCustomJob(CloudRunnerState.buildParams.preBuildSteps);
|
||||||
|
CloudRunnerLogger.logWithTime('Pre build step(s) time');
|
||||||
|
|
||||||
|
new BuildStep().run(
|
||||||
|
new CloudRunnerStepState(
|
||||||
|
baseImage,
|
||||||
|
CloudRunnerState.readBuildEnvironmentVariables(),
|
||||||
|
CloudRunnerState.defaultSecrets,
|
||||||
|
),
|
||||||
|
);
|
||||||
CloudRunnerLogger.logWithTime('Build time');
|
CloudRunnerLogger.logWithTime('Build time');
|
||||||
await CloudRunner.CompressionStep();
|
|
||||||
|
await new CompressionStep().run(
|
||||||
|
new CloudRunnerStepState(
|
||||||
|
'alpine',
|
||||||
|
CloudRunnerState.readBuildEnvironmentVariables(),
|
||||||
|
CloudRunnerState.defaultSecrets,
|
||||||
|
),
|
||||||
|
);
|
||||||
CloudRunnerLogger.logWithTime('Compression time');
|
CloudRunnerLogger.logWithTime('Compression time');
|
||||||
await this.runCustomJob(this.buildParams.postBuildSteps);
|
|
||||||
CloudRunnerLogger.logWithTime('Post build steps time');
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async runJobAsEphemeralGitHubRunner(baseImage: any) {
|
await CustomStep.runCustomJob(CloudRunnerState.buildParams.postBuildSteps);
|
||||||
CloudRunnerLogger.log(`Cloud Runner is running in ephemeral GitHub runner mode`);
|
CloudRunnerLogger.logWithTime('Post build step(s) time');
|
||||||
const installAndStartRunner =
|
|
||||||
'mkdir actions-runner && cd actions-runner && curl -O -L https://github.com/actions/runner/releases/download/v2.283.1/actions-runner-linux-x64-2.283.1.tar.gz && tar xzf ./actions-runner-linux-x64-2.283.1.tar.gz';
|
|
||||||
await this.CloudRunnerProviderPlatform.runBuildTask(
|
|
||||||
this.buildGuid,
|
|
||||||
baseImage,
|
|
||||||
[installAndStartRunner],
|
|
||||||
`/${buildVolumeFolder}`,
|
|
||||||
`/${buildVolumeFolder}`,
|
|
||||||
this.defaultGitShaEnvironmentVariable,
|
|
||||||
[...this.defaultSecrets],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async runCustomJob(buildSteps) {
|
CloudRunnerLogger.log(`Cloud Runner finished running standard build automation`);
|
||||||
CloudRunnerLogger.log(`Cloud Runner is running in custom job mode`);
|
|
||||||
buildSteps = YAML.parse(buildSteps);
|
|
||||||
for (const step of buildSteps) {
|
|
||||||
const stepSecrets: CloudRunnerSecret[] = step.secrets.map((x) => {
|
|
||||||
const secret: CloudRunnerSecret = {
|
|
||||||
ParameterKey: x.name,
|
|
||||||
EnvironmentVariable: x.name,
|
|
||||||
ParameterValue: x.value,
|
|
||||||
};
|
|
||||||
return secret;
|
|
||||||
});
|
|
||||||
await this.CloudRunnerProviderPlatform.runBuildTask(
|
|
||||||
this.buildGuid,
|
|
||||||
step['image'],
|
|
||||||
step['commands'],
|
|
||||||
`/${buildVolumeFolder}`,
|
|
||||||
`/${buildVolumeFolder}`,
|
|
||||||
this.defaultGitShaEnvironmentVariable,
|
|
||||||
[...this.defaultSecrets, ...stepSecrets],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async setupStep() {
|
|
||||||
CloudRunnerLogger.log('Starting step 1/4 clone and restore cache)');
|
|
||||||
await this.CloudRunnerProviderPlatform.runBuildTask(
|
|
||||||
this.buildGuid,
|
|
||||||
'alpine/git',
|
|
||||||
[
|
|
||||||
` printenv
|
|
||||||
apk update -q
|
|
||||||
apk add unzip zip git-lfs jq tree -q
|
|
||||||
mkdir -p ${this.buildPathFull}
|
|
||||||
mkdir -p ${this.builderPathFull}
|
|
||||||
mkdir -p ${this.repoPathFull}
|
|
||||||
${this.getCloneBuilder()}
|
|
||||||
echo ' '
|
|
||||||
echo 'Initializing source repository for cloning with caching of LFS files'
|
|
||||||
${this.getCloneNoLFSCommand()}
|
|
||||||
echo 'Source repository initialized'
|
|
||||||
echo ' '
|
|
||||||
echo 'Starting checks of cache for the Unity project Library and git LFS files'
|
|
||||||
${this.getHandleCachingCommand()}
|
|
||||||
`,
|
|
||||||
],
|
|
||||||
`/${buildVolumeFolder}`,
|
|
||||||
`/${buildVolumeFolder}/`,
|
|
||||||
CloudRunner.defaultGitShaEnvironmentVariable,
|
|
||||||
this.defaultSecrets,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async BuildStep(baseImage: any) {
|
|
||||||
CloudRunnerLogger.log('Starting part 2/4 (build unity project)');
|
|
||||||
await this.CloudRunnerProviderPlatform.runBuildTask(
|
|
||||||
this.buildGuid,
|
|
||||||
baseImage.toString(),
|
|
||||||
[
|
|
||||||
`
|
|
||||||
printenv
|
|
||||||
export GITHUB_WORKSPACE="${this.repoPathFull}"
|
|
||||||
cp -r "${this.builderPathFull}/dist/default-build-script/" "/UnityBuilderAction"
|
|
||||||
cp -r "${this.builderPathFull}/dist/entrypoint.sh" "/entrypoint.sh"
|
|
||||||
cp -r "${this.builderPathFull}/dist/steps/" "/steps"
|
|
||||||
chmod -R +x "/entrypoint.sh"
|
|
||||||
chmod -R +x "/steps"
|
|
||||||
/entrypoint.sh
|
|
||||||
${process.env.DEBUG ? '' : '#'}tree -L 4 "${this.buildPathFull}"
|
|
||||||
${process.env.DEBUG ? '' : '#'}ls -lh "/${buildVolumeFolder}"
|
|
||||||
`,
|
|
||||||
],
|
|
||||||
`/${buildVolumeFolder}`,
|
|
||||||
`/${this.projectPathFull}`,
|
|
||||||
CloudRunner.readBuildEnvironmentVariables(),
|
|
||||||
this.defaultSecrets,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async CompressionStep() {
|
|
||||||
CloudRunnerLogger.log('Starting step 3/4 build compression');
|
|
||||||
// Cleanup
|
|
||||||
await this.CloudRunnerProviderPlatform.runBuildTask(
|
|
||||||
this.buildGuid,
|
|
||||||
'alpine',
|
|
||||||
[
|
|
||||||
`
|
|
||||||
printenv
|
|
||||||
apk update -q
|
|
||||||
apk add zip tree -q
|
|
||||||
${process.env.DEBUG ? '' : '#'}tree -L 4 "$repoPathFull"
|
|
||||||
${process.env.DEBUG ? '' : '#'}ls -lh "$repoPathFull"
|
|
||||||
cd "$libraryFolderFull/.."
|
|
||||||
zip -r "lib-$BUILDID.zip" "./Library"
|
|
||||||
mv "lib-$BUILDID.zip" "/$cacheFolderFull/lib"
|
|
||||||
cd "$repoPathFull"
|
|
||||||
ls -lh "$repoPathFull"
|
|
||||||
zip -r "build-$BUILDID.zip" "./${CloudRunner.buildParams.buildPath}"
|
|
||||||
mv "build-$BUILDID.zip" "/$cacheFolderFull/build-$BUILDID.zip"
|
|
||||||
${process.env.DEBUG ? '' : '#'}tree -L 4 "/$cacheFolderFull"
|
|
||||||
${process.env.DEBUG ? '' : '#'}tree -L 4 "/$cacheFolderFull/.."
|
|
||||||
${process.env.DEBUG ? '' : '#'}tree -L 4 "$repoPathFull"
|
|
||||||
${process.env.DEBUG ? '' : '#'}ls -lh "$repoPathFull"
|
|
||||||
`,
|
|
||||||
],
|
|
||||||
`/${buildVolumeFolder}`,
|
|
||||||
`/${buildVolumeFolder}`,
|
|
||||||
[
|
|
||||||
...CloudRunner.defaultGitShaEnvironmentVariable,
|
|
||||||
...[
|
|
||||||
{
|
|
||||||
name: 'cacheFolderFull',
|
|
||||||
value: this.cacheFolderFull,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
this.defaultSecrets,
|
|
||||||
);
|
|
||||||
CloudRunnerLogger.log('compression step complete');
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async cleanupSharedBuildResources() {
|
|
||||||
await this.CloudRunnerProviderPlatform.cleanupSharedBuildResources(
|
|
||||||
this.buildGuid,
|
|
||||||
this.buildParams,
|
|
||||||
this.branchName,
|
|
||||||
this.defaultSecrets,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async handleException(error: unknown) {
|
private static async handleException(error: unknown) {
|
||||||
CloudRunnerLogger.error(JSON.stringify(error, undefined, 4));
|
CloudRunnerLogger.error(JSON.stringify(error, undefined, 4));
|
||||||
core.setFailed('Remote Builder failed');
|
core.setFailed('Remote Builder failed');
|
||||||
await this.CloudRunnerProviderPlatform.cleanupSharedBuildResources(
|
await CloudRunnerState.CloudRunnerProviderPlatform.cleanupSharedBuildResources(
|
||||||
this.buildGuid,
|
CloudRunnerState.buildGuid,
|
||||||
this.buildParams,
|
CloudRunnerState.buildParams,
|
||||||
this.branchName,
|
CloudRunnerState.branchName,
|
||||||
this.defaultSecrets,
|
CloudRunnerState.defaultSecrets,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue