pull/289/head
Frostebite 2021-08-02 00:38:30 +01:00
parent fd8599c0ac
commit 2a1d36b928
3 changed files with 492 additions and 423 deletions

369
dist/index.js vendored
View File

@ -2093,67 +2093,35 @@ const cacheFolder = 'cache';
const cacheFolderFull = `/${buildVolumeFolder}/${cacheFolder}`; const cacheFolderFull = `/${buildVolumeFolder}/${cacheFolder}`;
class RemoteBuilder { class RemoteBuilder {
static build(buildParameters, baseImage) { static build(buildParameters, baseImage) {
var _a;
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const runNumber = process.env.GITHUB_RUN_NUMBER; RemoteBuilder.buildId = remote_builder_namespace_1.default.generateBuildName(RemoteBuilder.readRunNumber(), buildParameters.platform);
if (!runNumber || runNumber === '') {
throw new Error('no run number found, exiting');
}
RemoteBuilder.buildParams = buildParameters; RemoteBuilder.buildParams = buildParameters;
RemoteBuilder.buildId = remote_builder_namespace_1.default.generateBuildName(runNumber, buildParameters.platform); RemoteBuilder.readBranchNameSetting();
const defaultBranchName = ((_a = process.env.GITHUB_REF) === null || _a === void 0 ? void 0 : _a.split('/').filter((x) => { RemoteBuilder.setupDefaultSecrets();
x = x[0].toUpperCase() + x.slice(1);
return x;
}).join('')) || '';
const branchName = process.env.REMOTE_BUILDER_CACHE !== undefined ? process.env.REMOTE_BUILDER_CACHE : defaultBranchName;
this.SteamDeploy = process.env.STEAM_DEPLOY !== undefined || false;
const token = this.buildParams.githubToken;
RemoteBuilder.newMethod(token);
try { try {
switch (this.buildParams.remoteBuildCluster) { RemoteBuilder.setupBuildPlatform();
case 'aws': yield this.RemoteBuilderProviderPlatform.setupSharedBuildResources(this.buildId, this.buildParams, this.branchName, this.defaultSecrets);
core.info('Building with AWS');
this.RemoteBuilderProviderPlatform = new aws_build_platform_1.default(this.buildParams);
break;
default:
case 'k8s':
core.info('Building with Kubernetes');
this.RemoteBuilderProviderPlatform = new kubernetes_build_platform_1.default(this.buildParams);
break;
}
yield this.RemoteBuilderProviderPlatform.setupSharedBuildResources(this.buildId, this.buildParams, branchName, this.defaultSecrets);
this.buildPathFull = `/${buildVolumeFolder}/${this.buildId}`; this.buildPathFull = `/${buildVolumeFolder}/${this.buildId}`;
this.builderPathFull = `${this.buildPathFull}/builder`; this.builderPathFull = `${this.buildPathFull}/builder`;
this.steamPathFull = `${this.buildPathFull}/steam`; this.steamPathFull = `${this.buildPathFull}/steam`;
this.repoPathFull = `${this.buildPathFull}/${repositoryFolder}`; this.repoPathFull = `${this.buildPathFull}/${repositoryFolder}`;
this.projectPathFull = `${this.repoPathFull}/${this.buildParams.projectPath}`; this.projectPathFull = `${this.repoPathFull}/${this.buildParams.projectPath}`;
this.libraryFolderFull = `${this.projectPathFull}/Library`; this.libraryFolderFull = `${this.projectPathFull}/Library`;
yield RemoteBuilder.SetupStep(branchName); yield RemoteBuilder.SetupStep(this.branchName);
yield RemoteBuilder.BuildStep(baseImage); yield RemoteBuilder.BuildStep(baseImage);
yield RemoteBuilder.CompressionStep(); yield RemoteBuilder.CompressionStep();
yield RemoteBuilder.UploadArtifacts(branchName); yield RemoteBuilder.UploadArtifacts(this.branchName);
if (this.SteamDeploy) { if (this.SteamDeploy) {
yield RemoteBuilder.DeployToSteam(); yield RemoteBuilder.DeployToSteam();
} }
yield this.RemoteBuilderProviderPlatform.cleanupSharedBuildResources(this.buildId, this.buildParams, branchName, this.defaultSecrets); yield this.RemoteBuilderProviderPlatform.cleanupSharedBuildResources(this.buildId, this.buildParams, this.branchName, this.defaultSecrets);
} }
catch (error) { catch (error) {
core.error(JSON.stringify(error, undefined, 4)); yield RemoteBuilder.handleException(error);
core.setFailed('Remote Builder failed');
yield this.RemoteBuilderProviderPlatform.cleanupSharedBuildResources(this.buildId, this.buildParams, branchName, this.defaultSecrets);
throw error; throw error;
} }
}); });
} }
static newMethod(token) {
this.defaultSecrets = [
{
ParameterKey: 'GithubToken',
EnvironmentVariable: 'GITHUB_TOKEN',
ParameterValue: token,
},
];
}
static SetupStep(branchName) { static SetupStep(branchName) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
core.info('Starting step 1/4 clone and restore cache)'); core.info('Starting step 1/4 clone and restore cache)');
@ -2206,17 +2174,125 @@ class RemoteBuilder {
echo ' ' echo ' '
# #
`, `,
], `/${buildVolumeFolder}`, `/${buildVolumeFolder}/`, [ ], `/${buildVolumeFolder}`, `/${buildVolumeFolder}/`, RemoteBuilder.defaultGitShaEnvironmentVariable, this.defaultSecrets);
{
name: 'GITHUB_SHA',
value: process.env.GITHUB_SHA || '',
},
], this.defaultSecrets);
}); });
} }
static BuildStep(baseImage) { static BuildStep(baseImage) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const buildSecrets = new Array(); const buildSecrets = new Array();
RemoteBuilder.setupBuildSecrets(buildSecrets);
core.info('Starting part 2/4 (build unity project)');
yield this.RemoteBuilderProviderPlatform.runBuildTask(this.buildId, baseImage.toString(), [
`
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
`,
], `/${buildVolumeFolder}`, `/${this.repoPathFull}`, RemoteBuilder.readBuildEnvironmentVariables(), buildSecrets);
});
}
static CompressionStep() {
return __awaiter(this, void 0, void 0, function* () {
core.info('Starting step 3/4 build compression');
// Cleanup
yield this.RemoteBuilderProviderPlatform.runBuildTask(this.buildId, 'alpine', [
`
apk update -q
apk add zip -q
cd "${this.libraryFolderFull}"
zip -r "lib-${this.buildId}.zip" "${this.libraryFolderFull}"
mv "lib-${this.buildId}.zip" "${cacheFolderFull}/lib/lib-${this.buildId}.zip"
cd "${this.projectPathFull}"
ls -lh "${RemoteBuilder.buildParams.buildPath}"
zip -r "build-${this.buildId}.zip" "${RemoteBuilder.buildParams.buildPath}"
mv "build-${this.buildId}.zip" "/${buildVolumeFolder}/${this.buildId}/build-${this.buildId}.zip"
`,
], `/${buildVolumeFolder}`, `/${buildVolumeFolder}`, [
{
name: 'GITHUB_SHA',
value: process.env.GITHUB_SHA || '',
},
], this.defaultSecrets);
core.info('compression step complete');
});
}
static UploadArtifacts(branchName) {
return __awaiter(this, void 0, void 0, function* () {
core.info('Starting step 4/4 upload build to s3');
yield this.RemoteBuilderProviderPlatform.runBuildTask(this.buildId, 'amazon/aws-cli', [
`
aws s3 cp ${this.buildId}/build-${this.buildId}.zip s3://game-ci-storage/
# no need to upload Library cache for now
# aws s3 cp /${buildVolumeFolder}/${cacheFolder}/${branchName}/lib-${this.buildId}.zip s3://game-ci-storage/
${this.SteamDeploy ? '#' : ''} rm -r ${this.buildId}
`,
], `/${buildVolumeFolder}`, `/${buildVolumeFolder}/`, RemoteBuilder.readUploadArtifactEnvironmentVariables(), RemoteBuilder.readUploadArtifactsSecrets());
});
}
static DeployToSteam() {
return __awaiter(this, void 0, void 0, function* () {
core.info('Starting steam deployment');
yield this.RemoteBuilderProviderPlatform.runBuildTask(this.buildId, 'cm2network/steamcmd:root', [
`
ls
ls /
cp -r /${buildVolumeFolder}/${this.buildId}/steam/action/entrypoint.sh /entrypoint.sh;
cp -r /${buildVolumeFolder}/${this.buildId}/steam/action/steps/ /steps;
chmod -R +x /entrypoint.sh;
chmod -R +x /steps;
/entrypoint.sh;
rm -r /${buildVolumeFolder}/${this.buildId}
`,
], `/${buildVolumeFolder}`, `/${buildVolumeFolder}/${this.buildId}/steam/action/`, [
{
name: 'GITHUB_SHA',
value: process.env.GITHUB_SHA || '',
},
], RemoteBuilder.readDeployToSteamSecrets());
});
}
static setupBuildPlatform() {
switch (this.buildParams.remoteBuildCluster) {
case 'aws':
core.info('Building with AWS');
this.RemoteBuilderProviderPlatform = new aws_build_platform_1.default(this.buildParams);
break;
default:
case 'k8s':
core.info('Building with Kubernetes');
this.RemoteBuilderProviderPlatform = 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 readBranchNameSetting() {
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,
},
];
}
static setupBuildSecrets(buildSecrets) {
buildSecrets.push(...this.defaultSecrets); buildSecrets.push(...this.defaultSecrets);
if (process.env.UNITY_LICENSE) if (process.env.UNITY_LICENSE)
buildSecrets.push({ buildSecrets.push({
@ -2260,17 +2336,71 @@ class RemoteBuilder {
EnvironmentVariable: 'AWS_ACCESS_KEY_ALIAS_PASS', EnvironmentVariable: 'AWS_ACCESS_KEY_ALIAS_PASS',
ParameterValue: this.buildParams.androidKeyaliasPass, ParameterValue: this.buildParams.androidKeyaliasPass,
}); });
core.info('Starting part 2/4 (build unity project)'); }
yield this.RemoteBuilderProviderPlatform.runBuildTask(this.buildId, baseImage.toString(), [ static readUploadArtifactsSecrets() {
` return [
cp -r "${this.builderPathFull}/dist/default-build-script/" "/UnityBuilderAction" {
cp -r "${this.builderPathFull}/dist/entrypoint.sh" "/entrypoint.sh" ParameterKey: 'AWSAccessKeyID',
cp -r "${this.builderPathFull}/dist/steps/" "/steps" EnvironmentVariable: 'AWS_ACCESS_KEY_ID',
chmod -R +x "/entrypoint.sh" ParameterValue: process.env.AWS_ACCESS_KEY_ID || '',
chmod -R +x "/steps" },
/entrypoint.sh {
`, ParameterKey: 'AWSSecretAccessKey',
], `/${buildVolumeFolder}`, `/${this.repoPathFull}`, [ EnvironmentVariable: 'AWS_SECRET_ACCESS_KEY',
ParameterValue: process.env.AWS_SECRET_ACCESS_KEY || '',
},
...this.defaultSecrets,
];
}
static readDeployToSteamSecrets() {
return [
{
EnvironmentVariable: 'INPUT_APPID',
ParameterKey: 'appId',
ParameterValue: process.env.APP_ID || '',
},
{
EnvironmentVariable: 'INPUT_BUILDDESCRIPTION',
ParameterKey: 'buildDescription',
ParameterValue: process.env.BUILD_DESCRIPTION || '',
},
{
EnvironmentVariable: 'INPUT_ROOTPATH',
ParameterKey: 'rootPath',
ParameterValue: RemoteBuilder.buildParams.buildPath,
},
{
EnvironmentVariable: 'INPUT_RELEASEBRANCH',
ParameterKey: 'releaseBranch',
ParameterValue: process.env.RELEASE_BRANCH || '',
},
{
EnvironmentVariable: 'INPUT_LOCALCONTENTSERVER',
ParameterKey: 'localContentServer',
ParameterValue: process.env.LOCAL_CONTENT_SERVER || '',
},
{
EnvironmentVariable: 'INPUT_PREVIEWENABLED',
ParameterKey: 'previewEnabled',
ParameterValue: process.env.PREVIEW_ENABLED || '',
},
...this.defaultSecrets,
];
}
static readUploadArtifactEnvironmentVariables() {
return [
{
name: 'GITHUB_SHA',
value: process.env.GITHUB_SHA || '',
},
{
name: 'AWS_DEFAULT_REGION',
value: process.env.AWS_DEFAULT_REGION || '',
},
];
}
static readBuildEnvironmentVariables() {
return [
{ {
name: 'ContainerMemory', name: 'ContainerMemory',
value: this.buildParams.remoteBuildMemory, value: this.buildParams.remoteBuildMemory,
@ -2323,124 +2453,23 @@ class RemoteBuilder {
name: 'ANDROID_KEYALIAS_NAME', name: 'ANDROID_KEYALIAS_NAME',
value: this.buildParams.androidKeyaliasName, value: this.buildParams.androidKeyaliasName,
}, },
], buildSecrets); ];
}
static handleException(error) {
return __awaiter(this, void 0, void 0, function* () {
core.error(JSON.stringify(error, undefined, 4));
core.setFailed('Remote Builder failed');
yield this.RemoteBuilderProviderPlatform.cleanupSharedBuildResources(this.buildId, this.buildParams, this.branchName, this.defaultSecrets);
}); });
} }
static CompressionStep() { }
return __awaiter(this, void 0, void 0, function* () { RemoteBuilder.SteamDeploy = process.env.STEAM_DEPLOY !== undefined || false;
core.info('Starting step 3/4 build compression'); RemoteBuilder.defaultGitShaEnvironmentVariable = [
// Cleanup
yield this.RemoteBuilderProviderPlatform.runBuildTask(this.buildId, 'alpine', [
`
apk update -q
apk add zip -q
cd "${this.libraryFolderFull}"
zip -r "lib-${this.buildId}.zip" "${this.libraryFolderFull}"
mv "lib-${this.buildId}.zip" "${cacheFolderFull}/lib/lib-${this.buildId}.zip"
cd "${this.projectPathFull}"
ls -lh "${RemoteBuilder.buildParams.buildPath}"
zip -r "build-${this.buildId}.zip" "${RemoteBuilder.buildParams.buildPath}"
mv "build-${this.buildId}.zip" "/${buildVolumeFolder}/${this.buildId}/build-${this.buildId}.zip"
`,
], `/${buildVolumeFolder}`, `/${buildVolumeFolder}`, [
{ {
name: 'GITHUB_SHA', name: 'GITHUB_SHA',
value: process.env.GITHUB_SHA || '', value: process.env.GITHUB_SHA || '',
}, },
], this.defaultSecrets); ];
core.info('compression step complete');
});
}
static UploadArtifacts(branchName) {
return __awaiter(this, void 0, void 0, function* () {
core.info('Starting step 4/4 upload build to s3');
yield this.RemoteBuilderProviderPlatform.runBuildTask(this.buildId, 'amazon/aws-cli', [
`
aws s3 cp ${this.buildId}/build-${this.buildId}.zip s3://game-ci-storage/
# no need to upload Library cache for now
# aws s3 cp /${buildVolumeFolder}/${cacheFolder}/${branchName}/lib-${this.buildId}.zip s3://game-ci-storage/
${this.SteamDeploy ? '#' : ''} rm -r ${this.buildId}
`,
], `/${buildVolumeFolder}`, `/${buildVolumeFolder}/`, [
{
name: 'GITHUB_SHA',
value: process.env.GITHUB_SHA || '',
},
{
name: 'AWS_DEFAULT_REGION',
value: process.env.AWS_DEFAULT_REGION || '',
},
], [
{
ParameterKey: 'AWSAccessKeyID',
EnvironmentVariable: 'AWS_ACCESS_KEY_ID',
ParameterValue: process.env.AWS_ACCESS_KEY_ID || '',
},
{
ParameterKey: 'AWSSecretAccessKey',
EnvironmentVariable: 'AWS_SECRET_ACCESS_KEY',
ParameterValue: process.env.AWS_SECRET_ACCESS_KEY || '',
},
...this.defaultSecrets,
]);
});
}
static DeployToSteam() {
return __awaiter(this, void 0, void 0, function* () {
core.info('Starting steam deployment');
yield this.RemoteBuilderProviderPlatform.runBuildTask(this.buildId, 'cm2network/steamcmd:root', [
`
ls
ls /
cp -r /${buildVolumeFolder}/${this.buildId}/steam/action/entrypoint.sh /entrypoint.sh;
cp -r /${buildVolumeFolder}/${this.buildId}/steam/action/steps/ /steps;
chmod -R +x /entrypoint.sh;
chmod -R +x /steps;
/entrypoint.sh;
rm -r /${buildVolumeFolder}/${this.buildId}
`,
], `/${buildVolumeFolder}`, `/${buildVolumeFolder}/${this.buildId}/steam/action/`, [
{
name: 'GITHUB_SHA',
value: process.env.GITHUB_SHA || '',
},
], [
{
EnvironmentVariable: 'INPUT_APPID',
ParameterKey: 'appId',
ParameterValue: process.env.APP_ID || '',
},
{
EnvironmentVariable: 'INPUT_BUILDDESCRIPTION',
ParameterKey: 'buildDescription',
ParameterValue: process.env.BUILD_DESCRIPTION || '',
},
{
EnvironmentVariable: 'INPUT_ROOTPATH',
ParameterKey: 'rootPath',
ParameterValue: RemoteBuilder.buildParams.buildPath,
},
{
EnvironmentVariable: 'INPUT_RELEASEBRANCH',
ParameterKey: 'releaseBranch',
ParameterValue: process.env.RELEASE_BRANCH || '',
},
{
EnvironmentVariable: 'INPUT_LOCALCONTENTSERVER',
ParameterKey: 'localContentServer',
ParameterValue: process.env.LOCAL_CONTENT_SERVER || '',
},
{
EnvironmentVariable: 'INPUT_PREVIEWENABLED',
ParameterKey: 'previewEnabled',
ParameterValue: process.env.PREVIEW_ENABLED || '',
},
...this.defaultSecrets,
]);
});
}
}
RemoteBuilder.SteamDeploy = false;
exports.default = RemoteBuilder; exports.default = RemoteBuilder;

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -5,59 +5,47 @@ import RemoteBuilderNamespace from './remote-builder-namespace';
import RemoteBuilderSecret from './remote-builder-secret'; import RemoteBuilderSecret from './remote-builder-secret';
import { RemoteBuilderProviderInterface } from './remote-builder-provider-interface'; import { RemoteBuilderProviderInterface } from './remote-builder-provider-interface';
import Kubernetes from './kubernetes-build-platform'; import Kubernetes from './kubernetes-build-platform';
import RemoteBuilderEnvironmentVariable from './remote-builder-environment-variable';
const repositoryFolder = 'repo'; const repositoryFolder = 'repo';
const buildVolumeFolder = 'data'; const buildVolumeFolder = 'data';
const cacheFolder = 'cache'; const cacheFolder = 'cache';
const cacheFolderFull = `/${buildVolumeFolder}/${cacheFolder}`; const cacheFolderFull = `/${buildVolumeFolder}/${cacheFolder}`;
class RemoteBuilder { class RemoteBuilder {
static SteamDeploy: boolean = false; private static buildId: string;
private static branchName: string;
private static buildParams: BuildParameters;
static RemoteBuilderProviderPlatform: RemoteBuilderProviderInterface;
private static defaultSecrets: RemoteBuilderSecret[];
static SteamDeploy: boolean = process.env.STEAM_DEPLOY !== undefined || false;
private static buildPathFull: string; private static buildPathFull: string;
private static builderPathFull: string; private static builderPathFull: string;
private static steamPathFull: string; private static steamPathFull: string;
private static repoPathFull: string; private static repoPathFull: string;
private static projectPathFull: string; private static projectPathFull: string;
private static libraryFolderFull: string; private static libraryFolderFull: string;
private static buildId: string; private static readonly defaultGitShaEnvironmentVariable = [
private static buildParams: BuildParameters; {
private static defaultSecrets: RemoteBuilderSecret[]; name: 'GITHUB_SHA',
static RemoteBuilderProviderPlatform: RemoteBuilderProviderInterface; value: process.env.GITHUB_SHA || '',
},
];
static async build(buildParameters: BuildParameters, baseImage) { static async build(buildParameters: BuildParameters, baseImage) {
const runNumber = process.env.GITHUB_RUN_NUMBER; RemoteBuilder.buildId = RemoteBuilderNamespace.generateBuildName(
if (!runNumber || runNumber === '') { RemoteBuilder.readRunNumber(),
throw new Error('no run number found, exiting'); buildParameters.platform,
} );
RemoteBuilder.buildParams = buildParameters; RemoteBuilder.buildParams = buildParameters;
RemoteBuilder.buildId = RemoteBuilderNamespace.generateBuildName(runNumber, buildParameters.platform); RemoteBuilder.readBranchNameSetting();
const defaultBranchName = RemoteBuilder.setupDefaultSecrets();
process.env.GITHUB_REF?.split('/')
.filter((x) => {
x = x[0].toUpperCase() + x.slice(1);
return x;
})
.join('') || '';
const branchName =
process.env.REMOTE_BUILDER_CACHE !== undefined ? process.env.REMOTE_BUILDER_CACHE : defaultBranchName;
this.SteamDeploy = process.env.STEAM_DEPLOY !== undefined || false;
const token: string = this.buildParams.githubToken;
RemoteBuilder.newMethod(token);
try { try {
switch (this.buildParams.remoteBuildCluster) { RemoteBuilder.setupBuildPlatform();
case 'aws':
core.info('Building with AWS');
this.RemoteBuilderProviderPlatform = new AWSBuildPlatform(this.buildParams);
break;
default:
case 'k8s':
core.info('Building with Kubernetes');
this.RemoteBuilderProviderPlatform = new Kubernetes(this.buildParams);
break;
}
await this.RemoteBuilderProviderPlatform.setupSharedBuildResources( await this.RemoteBuilderProviderPlatform.setupSharedBuildResources(
this.buildId, this.buildId,
this.buildParams, this.buildParams,
branchName, this.branchName,
this.defaultSecrets, this.defaultSecrets,
); );
@ -68,42 +56,25 @@ class RemoteBuilder {
this.projectPathFull = `${this.repoPathFull}/${this.buildParams.projectPath}`; this.projectPathFull = `${this.repoPathFull}/${this.buildParams.projectPath}`;
this.libraryFolderFull = `${this.projectPathFull}/Library`; this.libraryFolderFull = `${this.projectPathFull}/Library`;
await RemoteBuilder.SetupStep(branchName); await RemoteBuilder.SetupStep(this.branchName);
await RemoteBuilder.BuildStep(baseImage); await RemoteBuilder.BuildStep(baseImage);
await RemoteBuilder.CompressionStep(); await RemoteBuilder.CompressionStep();
await RemoteBuilder.UploadArtifacts(branchName); await RemoteBuilder.UploadArtifacts(this.branchName);
if (this.SteamDeploy) { if (this.SteamDeploy) {
await RemoteBuilder.DeployToSteam(); await RemoteBuilder.DeployToSteam();
} }
await this.RemoteBuilderProviderPlatform.cleanupSharedBuildResources( await this.RemoteBuilderProviderPlatform.cleanupSharedBuildResources(
this.buildId, this.buildId,
this.buildParams, this.buildParams,
branchName, this.branchName,
this.defaultSecrets, this.defaultSecrets,
); );
} catch (error) { } catch (error) {
core.error(JSON.stringify(error, undefined, 4)); await RemoteBuilder.handleException(error);
core.setFailed('Remote Builder failed');
await this.RemoteBuilderProviderPlatform.cleanupSharedBuildResources(
this.buildId,
this.buildParams,
branchName,
this.defaultSecrets,
);
throw error; throw error;
} }
} }
private static newMethod(token: string) {
this.defaultSecrets = [
{
ParameterKey: 'GithubToken',
EnvironmentVariable: 'GITHUB_TOKEN',
ParameterValue: token,
},
];
}
private static async SetupStep(branchName: string | undefined) { private static async SetupStep(branchName: string | undefined) {
core.info('Starting step 1/4 clone and restore cache)'); core.info('Starting step 1/4 clone and restore cache)');
@ -164,6 +135,56 @@ class RemoteBuilder {
], ],
`/${buildVolumeFolder}`, `/${buildVolumeFolder}`,
`/${buildVolumeFolder}/`, `/${buildVolumeFolder}/`,
RemoteBuilder.defaultGitShaEnvironmentVariable,
this.defaultSecrets,
);
}
private static async BuildStep(baseImage: any) {
const buildSecrets = new Array();
RemoteBuilder.setupBuildSecrets(buildSecrets);
core.info('Starting part 2/4 (build unity project)');
await this.RemoteBuilderProviderPlatform.runBuildTask(
this.buildId,
baseImage.toString(),
[
`
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
`,
],
`/${buildVolumeFolder}`,
`/${this.repoPathFull}`,
RemoteBuilder.readBuildEnvironmentVariables(),
buildSecrets,
);
}
private static async CompressionStep() {
core.info('Starting step 3/4 build compression');
// Cleanup
await this.RemoteBuilderProviderPlatform.runBuildTask(
this.buildId,
'alpine',
[
`
apk update -q
apk add zip -q
cd "${this.libraryFolderFull}"
zip -r "lib-${this.buildId}.zip" "${this.libraryFolderFull}"
mv "lib-${this.buildId}.zip" "${cacheFolderFull}/lib/lib-${this.buildId}.zip"
cd "${this.projectPathFull}"
ls -lh "${RemoteBuilder.buildParams.buildPath}"
zip -r "build-${this.buildId}.zip" "${RemoteBuilder.buildParams.buildPath}"
mv "build-${this.buildId}.zip" "/${buildVolumeFolder}/${this.buildId}/build-${this.buildId}.zip"
`,
],
`/${buildVolumeFolder}`,
`/${buildVolumeFolder}`,
[ [
{ {
name: 'GITHUB_SHA', name: 'GITHUB_SHA',
@ -172,11 +193,103 @@ class RemoteBuilder {
], ],
this.defaultSecrets, this.defaultSecrets,
); );
core.info('compression step complete');
} }
private static async BuildStep(baseImage: any) { private static async UploadArtifacts(branchName: string | undefined) {
const buildSecrets = new Array(); core.info('Starting step 4/4 upload build to s3');
await this.RemoteBuilderProviderPlatform.runBuildTask(
this.buildId,
'amazon/aws-cli',
[
`
aws s3 cp ${this.buildId}/build-${this.buildId}.zip s3://game-ci-storage/
# no need to upload Library cache for now
# aws s3 cp /${buildVolumeFolder}/${cacheFolder}/${branchName}/lib-${this.buildId}.zip s3://game-ci-storage/
${this.SteamDeploy ? '#' : ''} rm -r ${this.buildId}
`,
],
`/${buildVolumeFolder}`,
`/${buildVolumeFolder}/`,
RemoteBuilder.readUploadArtifactEnvironmentVariables(),
RemoteBuilder.readUploadArtifactsSecrets(),
);
}
private static async DeployToSteam() {
core.info('Starting steam deployment');
await this.RemoteBuilderProviderPlatform.runBuildTask(
this.buildId,
'cm2network/steamcmd:root',
[
`
ls
ls /
cp -r /${buildVolumeFolder}/${this.buildId}/steam/action/entrypoint.sh /entrypoint.sh;
cp -r /${buildVolumeFolder}/${this.buildId}/steam/action/steps/ /steps;
chmod -R +x /entrypoint.sh;
chmod -R +x /steps;
/entrypoint.sh;
rm -r /${buildVolumeFolder}/${this.buildId}
`,
],
`/${buildVolumeFolder}`,
`/${buildVolumeFolder}/${this.buildId}/steam/action/`,
[
{
name: 'GITHUB_SHA',
value: process.env.GITHUB_SHA || '',
},
],
RemoteBuilder.readDeployToSteamSecrets(),
);
}
private static setupBuildPlatform() {
switch (this.buildParams.remoteBuildCluster) {
case 'aws':
core.info('Building with AWS');
this.RemoteBuilderProviderPlatform = new AWSBuildPlatform(this.buildParams);
break;
default:
case 'k8s':
core.info('Building with Kubernetes');
this.RemoteBuilderProviderPlatform = 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 readBranchNameSetting() {
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,
},
];
}
private static setupBuildSecrets(buildSecrets: any[]) {
buildSecrets.push(...this.defaultSecrets); buildSecrets.push(...this.defaultSecrets);
if (process.env.UNITY_LICENSE) if (process.env.UNITY_LICENSE)
@ -227,23 +340,75 @@ class RemoteBuilder {
EnvironmentVariable: 'AWS_ACCESS_KEY_ALIAS_PASS', EnvironmentVariable: 'AWS_ACCESS_KEY_ALIAS_PASS',
ParameterValue: this.buildParams.androidKeyaliasPass, ParameterValue: this.buildParams.androidKeyaliasPass,
}); });
core.info('Starting part 2/4 (build unity project)'); }
await this.RemoteBuilderProviderPlatform.runBuildTask(
this.buildId, private static readUploadArtifactsSecrets() {
baseImage.toString(), return [
[ {
` ParameterKey: 'AWSAccessKeyID',
cp -r "${this.builderPathFull}/dist/default-build-script/" "/UnityBuilderAction" EnvironmentVariable: 'AWS_ACCESS_KEY_ID',
cp -r "${this.builderPathFull}/dist/entrypoint.sh" "/entrypoint.sh" ParameterValue: process.env.AWS_ACCESS_KEY_ID || '',
cp -r "${this.builderPathFull}/dist/steps/" "/steps" },
chmod -R +x "/entrypoint.sh" {
chmod -R +x "/steps" ParameterKey: 'AWSSecretAccessKey',
/entrypoint.sh EnvironmentVariable: 'AWS_SECRET_ACCESS_KEY',
`, ParameterValue: process.env.AWS_SECRET_ACCESS_KEY || '',
], },
`/${buildVolumeFolder}`, ...this.defaultSecrets,
`/${this.repoPathFull}`, ];
[ }
private static readDeployToSteamSecrets(): RemoteBuilderSecret[] {
return [
{
EnvironmentVariable: 'INPUT_APPID',
ParameterKey: 'appId',
ParameterValue: process.env.APP_ID || '',
},
{
EnvironmentVariable: 'INPUT_BUILDDESCRIPTION',
ParameterKey: 'buildDescription',
ParameterValue: process.env.BUILD_DESCRIPTION || '',
},
{
EnvironmentVariable: 'INPUT_ROOTPATH',
ParameterKey: 'rootPath',
ParameterValue: RemoteBuilder.buildParams.buildPath,
},
{
EnvironmentVariable: 'INPUT_RELEASEBRANCH',
ParameterKey: 'releaseBranch',
ParameterValue: process.env.RELEASE_BRANCH || '',
},
{
EnvironmentVariable: 'INPUT_LOCALCONTENTSERVER',
ParameterKey: 'localContentServer',
ParameterValue: process.env.LOCAL_CONTENT_SERVER || '',
},
{
EnvironmentVariable: 'INPUT_PREVIEWENABLED',
ParameterKey: 'previewEnabled',
ParameterValue: process.env.PREVIEW_ENABLED || '',
},
...this.defaultSecrets,
];
}
private static readUploadArtifactEnvironmentVariables() {
return [
{
name: 'GITHUB_SHA',
value: process.env.GITHUB_SHA || '',
},
{
name: 'AWS_DEFAULT_REGION',
value: process.env.AWS_DEFAULT_REGION || '',
},
];
}
private static readBuildEnvironmentVariables(): RemoteBuilderEnvironmentVariable[] {
return [
{ {
name: 'ContainerMemory', name: 'ContainerMemory',
value: this.buildParams.remoteBuildMemory, value: this.buildParams.remoteBuildMemory,
@ -296,143 +461,18 @@ class RemoteBuilder {
name: 'ANDROID_KEYALIAS_NAME', name: 'ANDROID_KEYALIAS_NAME',
value: this.buildParams.androidKeyaliasName, value: this.buildParams.androidKeyaliasName,
}, },
], ];
buildSecrets,
);
} }
private static async CompressionStep() { private static async handleException(error: unknown) {
core.info('Starting step 3/4 build compression'); core.error(JSON.stringify(error, undefined, 4));
// Cleanup core.setFailed('Remote Builder failed');
await this.RemoteBuilderProviderPlatform.runBuildTask( await this.RemoteBuilderProviderPlatform.cleanupSharedBuildResources(
this.buildId, this.buildId,
'alpine', this.buildParams,
[ this.branchName,
`
apk update -q
apk add zip -q
cd "${this.libraryFolderFull}"
zip -r "lib-${this.buildId}.zip" "${this.libraryFolderFull}"
mv "lib-${this.buildId}.zip" "${cacheFolderFull}/lib/lib-${this.buildId}.zip"
cd "${this.projectPathFull}"
ls -lh "${RemoteBuilder.buildParams.buildPath}"
zip -r "build-${this.buildId}.zip" "${RemoteBuilder.buildParams.buildPath}"
mv "build-${this.buildId}.zip" "/${buildVolumeFolder}/${this.buildId}/build-${this.buildId}.zip"
`,
],
`/${buildVolumeFolder}`,
`/${buildVolumeFolder}`,
[
{
name: 'GITHUB_SHA',
value: process.env.GITHUB_SHA || '',
},
],
this.defaultSecrets, this.defaultSecrets,
); );
core.info('compression step complete');
}
private static async UploadArtifacts(branchName: string | undefined) {
core.info('Starting step 4/4 upload build to s3');
await this.RemoteBuilderProviderPlatform.runBuildTask(
this.buildId,
'amazon/aws-cli',
[
`
aws s3 cp ${this.buildId}/build-${this.buildId}.zip s3://game-ci-storage/
# no need to upload Library cache for now
# aws s3 cp /${buildVolumeFolder}/${cacheFolder}/${branchName}/lib-${this.buildId}.zip s3://game-ci-storage/
${this.SteamDeploy ? '#' : ''} rm -r ${this.buildId}
`,
],
`/${buildVolumeFolder}`,
`/${buildVolumeFolder}/`,
[
{
name: 'GITHUB_SHA',
value: process.env.GITHUB_SHA || '',
},
{
name: 'AWS_DEFAULT_REGION',
value: process.env.AWS_DEFAULT_REGION || '',
},
],
[
{
ParameterKey: 'AWSAccessKeyID',
EnvironmentVariable: 'AWS_ACCESS_KEY_ID',
ParameterValue: process.env.AWS_ACCESS_KEY_ID || '',
},
{
ParameterKey: 'AWSSecretAccessKey',
EnvironmentVariable: 'AWS_SECRET_ACCESS_KEY',
ParameterValue: process.env.AWS_SECRET_ACCESS_KEY || '',
},
...this.defaultSecrets,
],
);
}
private static async DeployToSteam() {
core.info('Starting steam deployment');
await this.RemoteBuilderProviderPlatform.runBuildTask(
this.buildId,
'cm2network/steamcmd:root',
[
`
ls
ls /
cp -r /${buildVolumeFolder}/${this.buildId}/steam/action/entrypoint.sh /entrypoint.sh;
cp -r /${buildVolumeFolder}/${this.buildId}/steam/action/steps/ /steps;
chmod -R +x /entrypoint.sh;
chmod -R +x /steps;
/entrypoint.sh;
rm -r /${buildVolumeFolder}/${this.buildId}
`,
],
`/${buildVolumeFolder}`,
`/${buildVolumeFolder}/${this.buildId}/steam/action/`,
[
{
name: 'GITHUB_SHA',
value: process.env.GITHUB_SHA || '',
},
],
[
{
EnvironmentVariable: 'INPUT_APPID',
ParameterKey: 'appId',
ParameterValue: process.env.APP_ID || '',
},
{
EnvironmentVariable: 'INPUT_BUILDDESCRIPTION',
ParameterKey: 'buildDescription',
ParameterValue: process.env.BUILD_DESCRIPTION || '',
},
{
EnvironmentVariable: 'INPUT_ROOTPATH',
ParameterKey: 'rootPath',
ParameterValue: RemoteBuilder.buildParams.buildPath,
},
{
EnvironmentVariable: 'INPUT_RELEASEBRANCH',
ParameterKey: 'releaseBranch',
ParameterValue: process.env.RELEASE_BRANCH || '',
},
{
EnvironmentVariable: 'INPUT_LOCALCONTENTSERVER',
ParameterKey: 'localContentServer',
ParameterValue: process.env.LOCAL_CONTENT_SERVER || '',
},
{
EnvironmentVariable: 'INPUT_PREVIEWENABLED',
ParameterKey: 'previewEnabled',
ParameterValue: process.env.PREVIEW_ENABLED || '',
},
...this.defaultSecrets,
],
);
} }
} }
export default RemoteBuilder; export default RemoteBuilder;