catch stack creation errors

pull/263/head
Frostebite 2021-05-22 00:48:47 +01:00
parent 7b98b2c992
commit 4e4e9e0b11
5 changed files with 158 additions and 144 deletions

145
dist/index.js vendored
View File

@ -54,7 +54,7 @@ function run() {
break;
case 'aws':
core.info('Building with AWS');
yield model_1.AWS.runBuildJob(buildParameters, baseImage);
yield model_1.AWS.build(buildParameters, baseImage);
break;
// default and local case
default:
@ -1231,6 +1231,8 @@ class AWSBuildEnvironment {
`;
const taskDefStackName = `${stackName}-${buildUid}`;
let taskDefCloudFormation = this.readTaskCloudFormationTemplate();
const cleanupTaskDefStackName = `${taskDefStackName}-cleanup`;
const cleanupCloudFormation = fs.readFileSync(`${__dirname}/cloud-formations/cloudformation-stack-ttl.yml`, 'utf8');
// Debug secrets
// core.info(JSON.stringify(secrets, undefined, 4));
for (const secret of secrets) {
@ -1274,78 +1276,71 @@ class AWSBuildEnvironment {
const mappedSecrets = secrets.map((x) => {
return { ParameterKey: x.ParameterKey.replace(/[^\dA-Za-z]/g, ''), ParameterValue: x.ParameterValue };
});
yield CF.createStack({
StackName: taskDefStackName,
TemplateBody: taskDefCloudFormation,
Parameters: [
{
ParameterKey: 'ImageUrl',
ParameterValue: image,
},
{
ParameterKey: 'ServiceName',
ParameterValue: taskDefStackName,
},
{
ParameterKey: 'Command',
ParameterValue: commands.join(','),
},
{
ParameterKey: 'EntryPoint',
ParameterValue: entrypoint.join(','),
},
{
ParameterKey: 'WorkingDirectory',
ParameterValue: workingdir,
},
{
ParameterKey: 'EFSMountDirectory',
ParameterValue: mountdir,
},
{
ParameterKey: 'BUILDID',
ParameterValue: buildUid,
},
...mappedSecrets,
],
}).promise();
core.info('Creating worker cluster...');
const cleanupTaskDefStackName = `${taskDefStackName}-cleanup`;
const cleanupCloudFormation = fs.readFileSync(`${__dirname}/cloud-formations/cloudformation-stack-ttl.yml`, 'utf8');
yield CF.createStack({
StackName: cleanupTaskDefStackName,
TemplateBody: cleanupCloudFormation,
Capabilities: ['CAPABILITY_IAM'],
Parameters: [
{
ParameterKey: 'StackName',
ParameterValue: taskDefStackName,
},
{
ParameterKey: 'DeleteStackName',
ParameterValue: cleanupTaskDefStackName,
},
{
ParameterKey: 'TTL',
ParameterValue: '100',
},
{
ParameterKey: 'BUILDID',
ParameterValue: buildUid,
},
],
}).promise();
core.info('Creating cleanup cluster...');
try {
yield CF.createStack({
StackName: taskDefStackName,
TemplateBody: taskDefCloudFormation,
Parameters: [
{
ParameterKey: 'ImageUrl',
ParameterValue: image,
},
{
ParameterKey: 'ServiceName',
ParameterValue: taskDefStackName,
},
{
ParameterKey: 'Command',
ParameterValue: commands.join(','),
},
{
ParameterKey: 'EntryPoint',
ParameterValue: entrypoint.join(','),
},
{
ParameterKey: 'WorkingDirectory',
ParameterValue: workingdir,
},
{
ParameterKey: 'EFSMountDirectory',
ParameterValue: mountdir,
},
{
ParameterKey: 'BUILDID',
ParameterValue: buildUid,
},
...mappedSecrets,
],
}).promise();
core.info('Creating worker cluster...');
yield CF.createStack({
StackName: cleanupTaskDefStackName,
TemplateBody: cleanupCloudFormation,
Capabilities: ['CAPABILITY_IAM'],
Parameters: [
{
ParameterKey: 'StackName',
ParameterValue: taskDefStackName,
},
{
ParameterKey: 'DeleteStackName',
ParameterValue: cleanupTaskDefStackName,
},
{
ParameterKey: 'TTL',
ParameterValue: '100',
},
{
ParameterKey: 'BUILDID',
ParameterValue: buildUid,
},
],
}).promise();
core.info('Creating cleanup cluster...');
yield CF.waitFor('stackCreateComplete', { StackName: taskDefStackName }).promise();
}
catch (error) {
core.error(error);
const events = (yield CF.describeStackEvents({ StackName: taskDefStackName }).promise()).StackEvents;
const resources = (yield CF.describeStackResources({ StackName: taskDefStackName }).promise()).StackResources;
core.info(taskDefCloudFormation);
core.info(JSON.stringify(events, undefined, 4));
core.info(JSON.stringify(resources, undefined, 4));
yield AWSBuildEnvironment.handleStackCreationFailure(error, CF, taskDefStackName, taskDefCloudFormation);
throw error;
}
const taskDefResources = (yield CF.describeStackResources({
@ -1365,6 +1360,16 @@ class AWSBuildEnvironment {
};
});
}
static handleStackCreationFailure(error, CF, taskDefStackName, taskDefCloudFormation) {
return __awaiter(this, void 0, void 0, function* () {
core.error(error);
const events = (yield CF.describeStackEvents({ StackName: taskDefStackName }).promise()).StackEvents;
const resources = (yield CF.describeStackResources({ StackName: taskDefStackName }).promise()).StackResources;
core.info(taskDefCloudFormation);
core.info(JSON.stringify(events, undefined, 4));
core.info(JSON.stringify(resources, undefined, 4));
});
}
static readTaskCloudFormationTemplate() {
return fs.readFileSync(`${__dirname}/cloud-formations/task-def-formation.yml`, 'utf8');
}
@ -1625,7 +1630,7 @@ const repositoryDirectoryName = 'repo';
const efsDirectoryName = 'data';
const cacheDirectoryName = 'cache';
class RemoteBuilder {
static runBuildJob(buildParameters, baseImage) {
static build(buildParameters, baseImage) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
try {

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -20,7 +20,7 @@ async function run() {
case 'aws':
core.info('Building with AWS');
await AWS.runBuildJob(buildParameters, baseImage);
await AWS.build(buildParameters, baseImage);
break;
// default and local case

View File

@ -58,6 +58,8 @@ class AWSBuildEnvironment {
`;
const taskDefStackName = `${stackName}-${buildUid}`;
let taskDefCloudFormation = this.readTaskCloudFormationTemplate();
const cleanupTaskDefStackName = `${taskDefStackName}-cleanup`;
const cleanupCloudFormation = fs.readFileSync(`${__dirname}/cloud-formations/cloudformation-stack-ttl.yml`, 'utf8');
// Debug secrets
// core.info(JSON.stringify(secrets, undefined, 4));
@ -106,81 +108,72 @@ class AWSBuildEnvironment {
const mappedSecrets = secrets.map((x) => {
return { ParameterKey: x.ParameterKey.replace(/[^\dA-Za-z]/g, ''), ParameterValue: x.ParameterValue };
});
await CF.createStack({
StackName: taskDefStackName,
TemplateBody: taskDefCloudFormation,
Parameters: [
{
ParameterKey: 'ImageUrl',
ParameterValue: image,
},
{
ParameterKey: 'ServiceName',
ParameterValue: taskDefStackName,
},
{
ParameterKey: 'Command',
ParameterValue: commands.join(','),
},
{
ParameterKey: 'EntryPoint',
ParameterValue: entrypoint.join(','),
},
{
ParameterKey: 'WorkingDirectory',
ParameterValue: workingdir,
},
{
ParameterKey: 'EFSMountDirectory',
ParameterValue: mountdir,
},
{
ParameterKey: 'BUILDID',
ParameterValue: buildUid,
},
...mappedSecrets,
],
}).promise();
core.info('Creating worker cluster...');
const cleanupTaskDefStackName = `${taskDefStackName}-cleanup`;
const cleanupCloudFormation = fs.readFileSync(`${__dirname}/cloud-formations/cloudformation-stack-ttl.yml`, 'utf8');
await CF.createStack({
StackName: cleanupTaskDefStackName,
TemplateBody: cleanupCloudFormation,
Capabilities: ['CAPABILITY_IAM'],
Parameters: [
{
ParameterKey: 'StackName',
ParameterValue: taskDefStackName,
},
{
ParameterKey: 'DeleteStackName',
ParameterValue: cleanupTaskDefStackName,
},
{
ParameterKey: 'TTL',
ParameterValue: '100',
},
{
ParameterKey: 'BUILDID',
ParameterValue: buildUid,
},
],
}).promise();
core.info('Creating cleanup cluster...');
try {
await CF.createStack({
StackName: taskDefStackName,
TemplateBody: taskDefCloudFormation,
Parameters: [
{
ParameterKey: 'ImageUrl',
ParameterValue: image,
},
{
ParameterKey: 'ServiceName',
ParameterValue: taskDefStackName,
},
{
ParameterKey: 'Command',
ParameterValue: commands.join(','),
},
{
ParameterKey: 'EntryPoint',
ParameterValue: entrypoint.join(','),
},
{
ParameterKey: 'WorkingDirectory',
ParameterValue: workingdir,
},
{
ParameterKey: 'EFSMountDirectory',
ParameterValue: mountdir,
},
{
ParameterKey: 'BUILDID',
ParameterValue: buildUid,
},
...mappedSecrets,
],
}).promise();
core.info('Creating worker cluster...');
await CF.createStack({
StackName: cleanupTaskDefStackName,
TemplateBody: cleanupCloudFormation,
Capabilities: ['CAPABILITY_IAM'],
Parameters: [
{
ParameterKey: 'StackName',
ParameterValue: taskDefStackName,
},
{
ParameterKey: 'DeleteStackName',
ParameterValue: cleanupTaskDefStackName,
},
{
ParameterKey: 'TTL',
ParameterValue: '100',
},
{
ParameterKey: 'BUILDID',
ParameterValue: buildUid,
},
],
}).promise();
core.info('Creating cleanup cluster...');
await CF.waitFor('stackCreateComplete', { StackName: taskDefStackName }).promise();
} catch (error) {
core.error(error);
const events = (await CF.describeStackEvents({ StackName: taskDefStackName }).promise()).StackEvents;
const resources = (await CF.describeStackResources({ StackName: taskDefStackName }).promise()).StackResources;
core.info(taskDefCloudFormation);
core.info(JSON.stringify(events, undefined, 4));
core.info(JSON.stringify(resources, undefined, 4));
await AWSBuildEnvironment.handleStackCreationFailure(error, CF, taskDefStackName, taskDefCloudFormation);
throw error;
}
@ -207,6 +200,22 @@ class AWSBuildEnvironment {
};
}
private static async handleStackCreationFailure(
error: any,
CF: SDK.CloudFormation,
taskDefStackName: string,
taskDefCloudFormation: string,
) {
core.error(error);
const events = (await CF.describeStackEvents({ StackName: taskDefStackName }).promise()).StackEvents;
const resources = (await CF.describeStackResources({ StackName: taskDefStackName }).promise()).StackResources;
core.info(taskDefCloudFormation);
core.info(JSON.stringify(events, undefined, 4));
core.info(JSON.stringify(resources, undefined, 4));
}
static readTaskCloudFormationTemplate(): string {
return fs.readFileSync(`${__dirname}/cloud-formations/task-def-formation.yml`, 'utf8');
}

View File

@ -8,7 +8,7 @@ const efsDirectoryName = 'data';
const cacheDirectoryName = 'cache';
class RemoteBuilder {
static async runBuildJob(buildParameters: BuildParameters, baseImage) {
static async build(buildParameters: BuildParameters, baseImage) {
try {
const nanoid = customAlphabet(RemoteBuilderAlphabet.alphabet, 4);
const buildUid = `${process.env.GITHUB_RUN_NUMBER}-${buildParameters.platform