Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for capacity provider strategy attribute #76

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Runs an Amazon ECS task on ECS cluster.
count: 1
started-by: github-actions-${{ github.actor }}
wait-for-finish: true
capacity-provider-strategy: '[{"capacityProvider": "provider", "base": 1, "weight": 1}]' # optional
```

See [action.yml](action.yml) for the full documentation for this action's inputs and outputs.
Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ inputs:
wait-for-minutes:
description: 'How long to wait for the task reach stopped state, in minutes (default: 30 minutes, max: 6 hours).'
required: false
capacity-provider-strategy:
description: "JSON representation of the capacity provider strategy to use for the task."
required: false
outputs:
task-definition-arn:
description: 'The ARN of the registered ECS task definition'
Expand Down
21 changes: 18 additions & 3 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,26 @@ async function run() {
const taskDefinitionFile = core.getInput('task-definition', { required: true });
const cluster = core.getInput('cluster', { required: false });
const count = core.getInput('count', { required: true });
const capacityProviderStrategyString = core.getInput('capacity-provider-strategy', { required: true });
const startedBy = core.getInput('started-by', { required: false }) || agent;
const waitForFinish = core.getInput('wait-for-finish', { required: false }) || false;
let waitForMinutes = parseInt(core.getInput('wait-for-minutes', { required: false })) || 30;
if (waitForMinutes > MAX_WAIT_MINUTES) {
waitForMinutes = MAX_WAIT_MINUTES;
}

let capacityProviderStrategy;
if (capacityProviderStrategyString != "") {
try {
capacityProviderStrategy = JSON.parse(capacityProviderStrategyString);
} catch (error) {
core.setFailed("Failed to parse capacity provider strategy definition: " + error.message);
core.debug("Parameter value:");
core.debug(capacityProviderStrategyString);
throw(error);
}
}

// Register the task definition
core.debug('Registering the task definition');
const taskDefPath = path.isAbsolute(taskDefinitionFile) ?
Expand All @@ -254,13 +267,15 @@ async function run() {
cluster: clusterName,
taskDefinition: taskDefArn,
count: count,
capacityProviderStrategy: capacityProviderStrategy,
startedBy: startedBy
})}`)

const runTaskResponse = await ecs.runTask({
cluster: clusterName,
taskDefinition: taskDefArn,
count: count,
capacityProviderStrategy: capacityProviderStrategy,
startedBy: startedBy
}).promise();

Expand Down Expand Up @@ -294,7 +309,7 @@ async function waitForTasksStopped(ecs, clusterName, taskArns, waitForMinutes) {
const maxAttempts = (waitForMinutes * 60) / WAIT_DEFAULT_DELAY_SEC;

core.debug('Waiting for tasks to stop');

const waitTaskResponse = await ecs.waitFor('tasksStopped', {
cluster: clusterName,
tasks: taskArns,
Expand All @@ -305,7 +320,7 @@ async function waitForTasksStopped(ecs, clusterName, taskArns, waitForMinutes) {
}).promise();

core.debug(`Run task response ${JSON.stringify(waitTaskResponse)}`)

core.info(`All tasks have stopped. Watch progress in the Amazon ECS console: https://console.aws.amazon.com/ecs/home?region=${aws.config.region}#/clusters/${clusterName}/tasks`);
}

Expand All @@ -320,7 +335,7 @@ async function tasksExitCode(ecs, clusterName, taskArns) {
const reasons = containers.map(container => container.reason)

const failuresIdx = [];

exitCodes.filter((exitCode, index) => {
if (exitCode !== 0) {
failuresIdx.push(index)
Expand Down
21 changes: 18 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,26 @@ async function run() {
const taskDefinitionFile = core.getInput('task-definition', { required: true });
const cluster = core.getInput('cluster', { required: false });
const count = core.getInput('count', { required: true });
const capacityProviderStrategyString = core.getInput('capacity-provider-strategy', { required: true });
const startedBy = core.getInput('started-by', { required: false }) || agent;
const waitForFinish = core.getInput('wait-for-finish', { required: false }) || false;
let waitForMinutes = parseInt(core.getInput('wait-for-minutes', { required: false })) || 30;
if (waitForMinutes > MAX_WAIT_MINUTES) {
waitForMinutes = MAX_WAIT_MINUTES;
}

let capacityProviderStrategy;
if (capacityProviderStrategyString != "") {
try {
capacityProviderStrategy = JSON.parse(capacityProviderStrategyString);
} catch (error) {
core.setFailed("Failed to parse capacity provider strategy definition: " + error.message);
core.debug("Parameter value:");
core.debug(capacityProviderStrategyString);
throw(error);
}
}

// Register the task definition
core.debug('Registering the task definition');
const taskDefPath = path.isAbsolute(taskDefinitionFile) ?
Expand All @@ -121,13 +134,15 @@ async function run() {
cluster: clusterName,
taskDefinition: taskDefArn,
count: count,
capacityProviderStrategy: capacityProviderStrategy,
startedBy: startedBy
})}`)

const runTaskResponse = await ecs.runTask({
cluster: clusterName,
taskDefinition: taskDefArn,
count: count,
capacityProviderStrategy: capacityProviderStrategy,
startedBy: startedBy
}).promise();

Expand Down Expand Up @@ -161,7 +176,7 @@ async function waitForTasksStopped(ecs, clusterName, taskArns, waitForMinutes) {
const maxAttempts = (waitForMinutes * 60) / WAIT_DEFAULT_DELAY_SEC;

core.debug('Waiting for tasks to stop');

const waitTaskResponse = await ecs.waitFor('tasksStopped', {
cluster: clusterName,
tasks: taskArns,
Expand All @@ -172,7 +187,7 @@ async function waitForTasksStopped(ecs, clusterName, taskArns, waitForMinutes) {
}).promise();

core.debug(`Run task response ${JSON.stringify(waitTaskResponse)}`)

core.info(`All tasks have stopped. Watch progress in the Amazon ECS console: https://console.aws.amazon.com/ecs/home?region=${aws.config.region}#/clusters/${clusterName}/tasks`);
}

Expand All @@ -187,7 +202,7 @@ async function tasksExitCode(ecs, clusterName, taskArns) {
const reasons = containers.map(container => container.reason)

const failuresIdx = [];

exitCodes.filter((exitCode, index) => {
if (exitCode !== 0) {
failuresIdx.push(index)
Expand Down
21 changes: 20 additions & 1 deletion index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ describe('Deploy to ECS', () => {
.mockReturnValueOnce('task-definition.json') // task-definition
.mockReturnValueOnce('cluster-789') // cluster
.mockReturnValueOnce('1') // count
.mockReturnValueOnce('') // capacity-provider-strategy
.mockReturnValueOnce('amazon-ecs-run-task-for-github-actions'); // started-by

process.env = Object.assign(process.env, { GITHUB_WORKSPACE: __dirname });
Expand Down Expand Up @@ -142,6 +143,7 @@ describe('Deploy to ECS', () => {
.mockReturnValueOnce('task-definition.json') // task-definition
.mockReturnValueOnce('cluster-789') // cluster
.mockReturnValueOnce('1') // count
.mockReturnValueOnce('') // capacity-provider-strategy
.mockReturnValueOnce('amazon-ecs-run-task-for-github-actions') // started-by
.mockReturnValueOnce('true'); // wait-for-finish

Expand Down Expand Up @@ -260,7 +262,7 @@ describe('Deploy to ECS', () => {
expect(mockEcsRegisterTaskDef).toHaveBeenNthCalledWith(1, { family: 'task-def-family'});
});

test('error is caught if task def registration fails', async () => {
test('error is caught if capacity provider strategy param parsing fails', async () => {
mockEcsRegisterTaskDef.mockImplementation(() => {
throw new Error("Could not parse");
});
Expand All @@ -271,4 +273,21 @@ describe('Deploy to ECS', () => {
expect(core.setFailed).toHaveBeenNthCalledWith(1, 'Failed to register task definition in ECS: Could not parse');
expect(core.setFailed).toHaveBeenNthCalledWith(2, 'Could not parse');
});

test('error is caught if task def registration fails', async () => {
core.getInput = jest
.fn()
.mockReturnValueOnce('task-definition.json') // task-definition
.mockReturnValueOnce('cluster-789') // cluster
.mockReturnValueOnce('1') // count
.mockReturnValueOnce('not-a-json') // capacity-provider-strategy
.mockReturnValueOnce('amazon-ecs-run-task-for-github-actions') // started-by
.mockReturnValueOnce('true'); // wait-for-finish

await run();

expect(core.setFailed).toHaveBeenCalledTimes(2);
expect(core.setFailed).toHaveBeenNthCalledWith(1, 'Failed to parse capacity provider strategy definition: Unexpected token o in JSON at position 1');
expect(core.setFailed).toHaveBeenNthCalledWith(2, 'Unexpected token o in JSON at position 1');
});
});