unity-builder/src/model/aws.js

165 lines
4.9 KiB
JavaScript
Raw Normal View History

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
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) {
2021-01-31 22:11:13 +00:00
await this.run(
buildParameters.awsStackName,
'alpine/git',
[
'/bin/sh',
'-c',
`apk update;
apk add git-lfs;
ls ./;
export GITHUB_TOKEN=$(cat /credentials/GITHUB_TOKEN);
cd /data;
git clone https://github.com/${process.env.GITHUB_REPOSITORY}.git repo;
git clone https://github.com/webbertakken/unity-builder.git builder;
cd repo;
git checkout $GITHUB_SHA;
ls`,
],
[
{
name: 'GITHUB_SHA',
value: process.env.GITHUB_SHA,
},
],
);
await this.run(
buildParameters.awsStackName,
baseImage.toString(),
['bin/bash', '-c', 'echo "test"'],
[
{
name: '',
value: '',
},
],
);
2021-01-31 19:22:28 +00:00
}
2021-01-31 22:11:13 +00:00
static async run(stackName, image, commands, environment) {
2021-01-31 19:22:28 +00:00
const ECS = new SDK.ECS();
const CF = new SDK.CloudFormation();
const EC2 = new SDK.EC2();
2021-01-31 19:22:28 +00:00
2021-01-31 22:11:13 +00:00
const alphanumericImageName = image.toString().replace(/[^\da-z]/gi, '');
2021-01-31 20:30:46 +00:00
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");
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 22:11:13 +00:00
command: commands,
environment,
2021-01-31 19:22:28 +00:00
},
],
},
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();
core.info(`Build job is running, `);
2021-01-31 19:22:28 +00:00
// watching logs
const taskDescriptions = await ECS.describeTasks({
tasks: [task.tasks[0].taskArn],
cluster: clusterName,
}).promise();
const networkInterfaces = await EC2.describeNetworkInterfaces({
NetworkInterfaceIds: [
taskDescriptions.tasks[0].attachments
.find((x) => x.type === 'ElasticNetworkInterface')
.details.find((x) => x.name === 'networkInterfaceId').value,
],
}).promise();
core.info(JSON.stringify(networkInterfaces.NetworkInterfaces[0].Association.PublicIp));
2021-01-31 22:11:13 +00:00
const client = new WebSocketClient(
`ws://${networkInterfaces.NetworkInterfaces[0].Association.PublicIp}:80`,
);
client.on('connect', (con) => {
con.on('message', (message) => {
core.info(message);
});
});
// 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;