mirror of
https://github.com/game-ci/unity-builder.git
synced 2026-02-04 16:19:09 +08:00
Cloud Runner v2 (#310)
This commit is contained in:
106
src/model/cloud-runner/aws/aws-base-stack.ts
Normal file
106
src/model/cloud-runner/aws/aws-base-stack.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import CloudRunnerLogger from '../services/cloud-runner-logger';
|
||||
import * as core from '@actions/core';
|
||||
import * as SDK from 'aws-sdk';
|
||||
import * as fs from 'fs';
|
||||
import path from 'path';
|
||||
const crypto = require('crypto');
|
||||
|
||||
export class AWSBaseStack {
|
||||
constructor(baseStackName: string) {
|
||||
this.baseStackName = baseStackName;
|
||||
}
|
||||
private baseStackName: string;
|
||||
|
||||
async setupBaseStack(CF: SDK.CloudFormation) {
|
||||
const baseStackName = this.baseStackName;
|
||||
|
||||
const baseStack = fs.readFileSync(path.join(__dirname, 'cloud-formations', 'base-setup.yml'), 'utf8');
|
||||
|
||||
// Cloud Formation Input
|
||||
const describeStackInput: SDK.CloudFormation.DescribeStacksInput = {
|
||||
StackName: baseStackName,
|
||||
};
|
||||
const parametersWithoutHash: SDK.CloudFormation.Parameter[] = [
|
||||
{ ParameterKey: 'EnvironmentName', ParameterValue: baseStackName },
|
||||
];
|
||||
const parametersHash = crypto
|
||||
.createHash('md5')
|
||||
.update(baseStack + JSON.stringify(parametersWithoutHash))
|
||||
.digest('hex');
|
||||
const parameters: SDK.CloudFormation.Parameter[] = [
|
||||
...parametersWithoutHash,
|
||||
...[{ ParameterKey: 'Version', ParameterValue: parametersHash }],
|
||||
];
|
||||
const updateInput: SDK.CloudFormation.UpdateStackInput = {
|
||||
StackName: baseStackName,
|
||||
TemplateBody: baseStack,
|
||||
Parameters: parameters,
|
||||
Capabilities: ['CAPABILITY_IAM'],
|
||||
};
|
||||
const createStackInput: SDK.CloudFormation.CreateStackInput = {
|
||||
StackName: baseStackName,
|
||||
TemplateBody: baseStack,
|
||||
Parameters: parameters,
|
||||
Capabilities: ['CAPABILITY_IAM'],
|
||||
};
|
||||
|
||||
const stacks = await CF.listStacks({
|
||||
StackStatusFilter: ['UPDATE_COMPLETE', 'CREATE_COMPLETE', 'ROLLBACK_COMPLETE'],
|
||||
}).promise();
|
||||
const stackNames = stacks.StackSummaries?.map((x) => x.StackName) || [];
|
||||
const stackExists: Boolean = stackNames.includes(baseStackName) || false;
|
||||
const describeStack = async () => {
|
||||
return await CF.describeStacks(describeStackInput).promise();
|
||||
};
|
||||
try {
|
||||
if (!stackExists) {
|
||||
CloudRunnerLogger.log(`${baseStackName} stack does not exist (${JSON.stringify(stackNames)})`);
|
||||
await CF.createStack(createStackInput).promise();
|
||||
CloudRunnerLogger.log(`created stack (version: ${parametersHash})`);
|
||||
}
|
||||
const CFState = await describeStack();
|
||||
let stack = CFState.Stacks?.[0];
|
||||
if (!stack) {
|
||||
throw new Error(`Base stack doesn't exist, even after creation, stackExists check: ${stackExists}`);
|
||||
}
|
||||
const stackVersion = stack.Parameters?.find((x) => x.ParameterKey === 'Version')?.ParameterValue;
|
||||
|
||||
if (stack.StackStatus === 'CREATE_IN_PROGRESS') {
|
||||
await CF.waitFor('stackCreateComplete', describeStackInput).promise();
|
||||
}
|
||||
|
||||
if (stackExists) {
|
||||
CloudRunnerLogger.log(`Base stack exists (version: ${stackVersion}, local version: ${parametersHash})`);
|
||||
if (parametersHash !== stackVersion) {
|
||||
CloudRunnerLogger.log(`Attempting update of base stack`);
|
||||
try {
|
||||
await CF.updateStack(updateInput).promise();
|
||||
} catch (error: any) {
|
||||
if (error['message'].includes('No updates are to be performed')) {
|
||||
CloudRunnerLogger.log(`No updates are to be performed`);
|
||||
} else {
|
||||
CloudRunnerLogger.log(`Update Failed (Stack name: ${baseStackName})`);
|
||||
CloudRunnerLogger.log(error['message']);
|
||||
}
|
||||
CloudRunnerLogger.log(`Continuing...`);
|
||||
}
|
||||
} else {
|
||||
CloudRunnerLogger.log(`No update required`);
|
||||
}
|
||||
stack = (await describeStack()).Stacks?.[0];
|
||||
if (!stack) {
|
||||
throw new Error(
|
||||
`Base stack doesn't exist, even after updating and creation, stackExists check: ${stackExists}`,
|
||||
);
|
||||
}
|
||||
if (stack.StackStatus === 'UPDATE_IN_PROGRESS') {
|
||||
await CF.waitFor('stackUpdateComplete', describeStackInput).promise();
|
||||
}
|
||||
}
|
||||
CloudRunnerLogger.log('base stack is now ready');
|
||||
} catch (error) {
|
||||
core.error(JSON.stringify(await describeStack(), undefined, 4));
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user