2021-01-31 19:22:28 +00:00
|
|
|
/* eslint-disable no-plusplus */
|
|
|
|
|
/* eslint-disable no-await-in-loop */
|
|
|
|
|
import * as SDK from 'aws-sdk';
|
2021-01-31 20:03:11 +00:00
|
|
|
|
2021-01-31 21:10:50 +00:00
|
|
|
const WebSocketClient = require('websocket').client;
|
2021-01-31 19:22:28 +00:00
|
|
|
const fs = require('fs');
|
|
|
|
|
const core = require('@actions/core');
|
|
|
|
|
|
|
|
|
|
class AWS {
|
|
|
|
|
static async runBuildJob(buildParameters, baseImage) {
|
|
|
|
|
await this.run(buildParameters.awsStackName, baseImage.toString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static async run(stackName, image) {
|
|
|
|
|
const ECS = new SDK.ECS();
|
|
|
|
|
const CF = new SDK.CloudFormation();
|
2021-01-31 21:53:23 +00:00
|
|
|
const EC2 = new SDK.EC2();
|
2021-01-31 19:22:28 +00:00
|
|
|
|
2021-01-31 20:30:46 +00:00
|
|
|
const alphanumericImageName = image.toString().replace(/[^0-9a-z]/gi, '');
|
|
|
|
|
const taskDefStackName = `${stackName}-taskDef-${alphanumericImageName}`;
|
2021-01-31 19:22:28 +00:00
|
|
|
const stackExists =
|
|
|
|
|
(await CF.listStacks().promise()).StackSummaries.find(
|
|
|
|
|
(x) => x.StackName === taskDefStackName,
|
|
|
|
|
) !== undefined;
|
|
|
|
|
|
|
|
|
|
if (!stackExists) {
|
|
|
|
|
core.info("Task Definition doesn't exist, creating a task definition stack");
|
2021-01-31 20:22:36 +00:00
|
|
|
const taskDefCloudFormation = fs.readFileSync(`${__dirname}/task-def-formation.yml`, 'utf8');
|
2021-01-31 19:22:28 +00:00
|
|
|
await CF.createStack({
|
|
|
|
|
StackName: taskDefStackName,
|
|
|
|
|
TemplateBody: taskDefCloudFormation,
|
|
|
|
|
Parameters: [
|
|
|
|
|
{
|
|
|
|
|
ParameterKey: 'ImageUrl',
|
|
|
|
|
ParameterValue: image,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
}).promise();
|
|
|
|
|
await CF.waitFor('stackCreateComplete', { StackName: taskDefStackName }).promise();
|
|
|
|
|
} else {
|
|
|
|
|
core.info('Task definition stack exists already');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const taskDefResources = await CF.describeStackResources({
|
|
|
|
|
StackName: taskDefStackName,
|
|
|
|
|
}).promise();
|
|
|
|
|
|
|
|
|
|
const baseResources = await CF.describeStackResources({ StackName: stackName }).promise();
|
|
|
|
|
|
|
|
|
|
const clusterName = baseResources.StackResources.find(
|
|
|
|
|
(x) => x.LogicalResourceId === 'ECSCluster',
|
|
|
|
|
).PhysicalResourceId;
|
|
|
|
|
const task = await ECS.runTask({
|
|
|
|
|
cluster: clusterName,
|
|
|
|
|
taskDefinition: taskDefResources.StackResources.find(
|
|
|
|
|
(x) => x.LogicalResourceId === 'TaskDefinition',
|
|
|
|
|
).PhysicalResourceId,
|
|
|
|
|
platformVersion: '1.4.0',
|
|
|
|
|
launchType: 'FARGATE',
|
|
|
|
|
overrides: {
|
|
|
|
|
containerOverrides: [
|
|
|
|
|
{
|
|
|
|
|
name: 'example',
|
2021-01-31 21:30:57 +00:00
|
|
|
command: ['bin/bash', '-c', 'echo "test"'],
|
2021-01-31 19:22:28 +00:00
|
|
|
// environment: []
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
networkConfiguration: {
|
|
|
|
|
awsvpcConfiguration: {
|
|
|
|
|
subnets: [
|
|
|
|
|
baseResources.StackResources.find((x) => x.LogicalResourceId === 'PublicSubnetOne')
|
|
|
|
|
.PhysicalResourceId,
|
|
|
|
|
baseResources.StackResources.find((x) => x.LogicalResourceId === 'PublicSubnetTwo')
|
|
|
|
|
.PhysicalResourceId,
|
|
|
|
|
],
|
|
|
|
|
assignPublicIp: 'ENABLED',
|
|
|
|
|
securityGroups: [
|
|
|
|
|
baseResources.StackResources.find(
|
|
|
|
|
(x) => x.LogicalResourceId === 'ContainerSecurityGroup',
|
|
|
|
|
).PhysicalResourceId,
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}).promise();
|
|
|
|
|
|
|
|
|
|
await ECS.waitFor('tasksRunning', {
|
|
|
|
|
cluster: clusterName,
|
2021-01-31 20:43:20 +00:00
|
|
|
tasks: [task.tasks[0].taskArn],
|
2021-01-31 19:22:28 +00:00
|
|
|
}).promise();
|
|
|
|
|
|
2021-01-31 21:10:50 +00:00
|
|
|
core.info(`Build job is running, `);
|
2021-01-31 19:22:28 +00:00
|
|
|
|
|
|
|
|
// watching logs
|
2021-01-31 21:19:08 +00:00
|
|
|
const taskDescriptions = await ECS.describeTasks({
|
|
|
|
|
tasks: [task.tasks[0].taskArn],
|
|
|
|
|
cluster: clusterName,
|
|
|
|
|
}).promise();
|
2021-01-31 21:53:23 +00:00
|
|
|
const networkInterfaces = await EC2.describeNetworkInterfaces({
|
|
|
|
|
NetworkInterfaceIds: [
|
|
|
|
|
taskDescriptions.tasks[0].attachments
|
|
|
|
|
.find((x) => x.type === 'ElasticNetworkInterface')
|
|
|
|
|
.details.find((x) => x.name === 'networkInterfaceId').value,
|
|
|
|
|
],
|
|
|
|
|
}).promise();
|
2021-01-31 21:54:12 +00:00
|
|
|
core.info(JSON.stringify(networkInterfaces.NetworkInterfaces[0].Association.PublicIp));
|
2021-01-31 21:10:50 +00:00
|
|
|
// const client = new WebSocketClient('ws://');
|
|
|
|
|
// client.on('connect', (con) => {
|
|
|
|
|
// con.on('message', (message) => {
|
|
|
|
|
// core.info(message);
|
|
|
|
|
// });
|
|
|
|
|
// });
|
|
|
|
|
|
2021-01-31 21:13:43 +00:00
|
|
|
// await this.watch(async () => {
|
|
|
|
|
// return (
|
|
|
|
|
// await ECS.describeTasks({ tasks: [task.tasks[0].taskArn], cluster: clusterName }).promise()
|
|
|
|
|
// ).tasks[0].lastStatus;
|
|
|
|
|
// }, 'example');
|
2021-01-31 19:22:28 +00:00
|
|
|
|
|
|
|
|
await ECS.waitFor('tasksStopped', {
|
|
|
|
|
cluster: clusterName,
|
2021-01-31 20:43:20 +00:00
|
|
|
tasks: [task.tasks[0].taskArn],
|
2021-01-31 19:22:28 +00:00
|
|
|
}).promise();
|
|
|
|
|
|
|
|
|
|
core.info('Build job has ended');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
export default AWS;
|