Skip to content

Commit

Permalink
feat: Add desired tasks (#505)
Browse files Browse the repository at this point in the history
* add desired count

* add desired count

* add desired count

* fix test for desired count

* small change

* update dist/index.js

* address feedback @iamhopaul123

* update dist/index.js

---------

Co-authored-by: Adithya Kolla <kolladit@amazon.com>
  • Loading branch information
romankydybets and KollaAdithya authored Feb 7, 2024
1 parent ee7a5be commit e5f78d3
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 32 deletions.
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ inputs:
task-definition:
description: 'The path to the ECS task definition file to register'
required: true
desired-count:
description: 'The number of instantiations of the task to place and keep running in your service.'
required: false
service:
description: 'The name of the ECS service to deploy to. The action will only register the task definition if no service is given.'
required: false
Expand Down
16 changes: 12 additions & 4 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,19 @@ const IGNORED_TASK_DEFINITION_ATTRIBUTES = [
];

// Deploy to a service that uses the 'ECS' deployment controller
async function updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment) {
async function updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount) {
core.debug('Updating the service');
await ecs.updateService({
let params = {
cluster: clusterName,
service: service,
taskDefinition: taskDefArn,
forceNewDeployment: forceNewDeployment
}).promise();
};
// Add the desiredCount property only if it is defined and a number.
if (!isNaN(desiredCount) && desiredCount !== undefined) {
params.desiredCount = desiredCount;
}
await ecs.updateService(params).promise();

const consoleHostname = aws.config.region.startsWith('cn') ? 'console.amazonaws.cn' : 'console.aws.amazon.com';

Expand Down Expand Up @@ -275,6 +280,9 @@ async function run() {
const forceNewDeployInput = core.getInput('force-new-deployment', { required: false }) || 'false';
const forceNewDeployment = forceNewDeployInput.toLowerCase() === 'true';

const desiredCount = parseInt((core.getInput('desired-count', {required: false})));


// Register the task definition
core.debug('Registering the task definition');
const taskDefPath = path.isAbsolute(taskDefinitionFile) ?
Expand Down Expand Up @@ -316,7 +324,7 @@ async function run() {

if (!serviceResponse.deploymentController || !serviceResponse.deploymentController.type || serviceResponse.deploymentController.type === 'ECS') {
// Service uses the 'ECS' deployment controller, so we can call UpdateService
await updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment);
await updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount);
} else if (serviceResponse.deploymentController.type === 'CODE_DEPLOY') {
// Service uses CodeDeploy, so we should start a CodeDeploy deployment
await createCodeDeployDeployment(codedeploy, clusterName, service, taskDefArn, waitForService, waitForMinutes);
Expand Down
16 changes: 12 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,19 @@ const IGNORED_TASK_DEFINITION_ATTRIBUTES = [
];

// Deploy to a service that uses the 'ECS' deployment controller
async function updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment) {
async function updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount) {
core.debug('Updating the service');
await ecs.updateService({
let params = {
cluster: clusterName,
service: service,
taskDefinition: taskDefArn,
forceNewDeployment: forceNewDeployment
}).promise();
};
// Add the desiredCount property only if it is defined and a number.
if (!isNaN(desiredCount) && desiredCount !== undefined) {
params.desiredCount = desiredCount;
}
await ecs.updateService(params).promise();

const consoleHostname = aws.config.region.startsWith('cn') ? 'console.amazonaws.cn' : 'console.aws.amazon.com';

Expand Down Expand Up @@ -269,6 +274,9 @@ async function run() {
const forceNewDeployInput = core.getInput('force-new-deployment', { required: false }) || 'false';
const forceNewDeployment = forceNewDeployInput.toLowerCase() === 'true';

const desiredCount = parseInt((core.getInput('desired-count', {required: false})));


// Register the task definition
core.debug('Registering the task definition');
const taskDefPath = path.isAbsolute(taskDefinitionFile) ?
Expand Down Expand Up @@ -310,7 +318,7 @@ async function run() {

if (!serviceResponse.deploymentController || !serviceResponse.deploymentController.type || serviceResponse.deploymentController.type === 'ECS') {
// Service uses the 'ECS' deployment controller, so we can call UpdateService
await updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment);
await updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount);
} else if (serviceResponse.deploymentController.type === 'CODE_DEPLOY') {
// Service uses CodeDeploy, so we should start a CodeDeploy deployment
await createCodeDeployDeployment(codedeploy, clusterName, service, taskDefArn, waitForService, waitForMinutes);
Expand Down
55 changes: 31 additions & 24 deletions index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -687,14 +687,15 @@ describe('Deploy to ECS', () => {
core.getInput = jest
.fn()
.mockReturnValueOnce('task-definition.json') // task-definition
.mockReturnValueOnce('service-456') // service
.mockReturnValueOnce('cluster-789') // cluster
.mockReturnValueOnce('false') // wait-for-service-stability
.mockReturnValueOnce('') // wait-for-minutes
.mockReturnValueOnce('') // force-new-deployment
.mockReturnValueOnce('/hello/appspec.json') // codedeploy-appspec
.mockReturnValueOnce('MyApplication') // codedeploy-application
.mockReturnValueOnce('MyDeploymentGroup'); // codedeploy-deployment-group
.mockReturnValueOnce('service-456') // service
.mockReturnValueOnce('cluster-789') // cluster
.mockReturnValueOnce('false') // wait-for-service-stability
.mockReturnValueOnce('') // wait-for-minutes
.mockReturnValueOnce('') // force-new-deployment
.mockReturnValueOnce('') // desired count
.mockReturnValueOnce('/hello/appspec.json') // codedeploy-appspec
.mockReturnValueOnce('MyApplication') // codedeploy-application
.mockReturnValueOnce('MyDeploymentGroup') // codedeploy-deployment-group

fs.readFileSync.mockReturnValue(`
{
Expand Down Expand Up @@ -887,7 +888,7 @@ describe('Deploy to ECS', () => {
expect(core.info).toBeCalledWith("Deployment started. Watch this deployment's progress in the AWS CodeDeploy console: https://console.aws.amazon.com/codesuite/codedeploy/deployments/deployment-1?region=fake-region");
});

test('registers the task definition contents at an absolute path', async () => {
test('registers the task definition contents at an absolute path', async () => {
core.getInput = jest.fn().mockReturnValueOnce('/hello/task-definition.json');
fs.readFileSync.mockImplementation((pathInput, encoding) => {
if (encoding != 'utf8') {
Expand All @@ -908,13 +909,14 @@ describe('Deploy to ECS', () => {
expect(core.setOutput).toHaveBeenNthCalledWith(1, 'task-definition-arn', 'task:def:arn');
});

test('waits for the service to be stable', async () => {
test('waits for the service to be stable', async () => {
core.getInput = jest
.fn()
.mockReturnValueOnce('task-definition.json') // task-definition
.mockReturnValueOnce('service-456') // service
.mockReturnValueOnce('cluster-789') // cluster
.mockReturnValueOnce('TRUE'); // wait-for-service-stability
.mockReturnValueOnce('service-456') // service
.mockReturnValueOnce('cluster-789') // cluster
.mockReturnValueOnce('TRUE') // wait-for-service-stability
.mockReturnValueOnce(''); // desired count

await run();
expect(core.setFailed).toHaveBeenCalledTimes(0);
Expand Down Expand Up @@ -945,10 +947,11 @@ describe('Deploy to ECS', () => {
core.getInput = jest
.fn()
.mockReturnValueOnce('task-definition.json') // task-definition
.mockReturnValueOnce('service-456') // service
.mockReturnValueOnce('cluster-789') // cluster
.mockReturnValueOnce('TRUE') // wait-for-service-stability
.mockReturnValueOnce('60'); // wait-for-minutes
.mockReturnValueOnce('service-456') // service
.mockReturnValueOnce('cluster-789') // cluster
.mockReturnValueOnce('TRUE') // wait-for-service-stability
.mockReturnValueOnce('60') // wait-for-minutes
.mockReturnValueOnce(''); // desired count

await run();
expect(core.setFailed).toHaveBeenCalledTimes(0);
Expand Down Expand Up @@ -979,10 +982,11 @@ describe('Deploy to ECS', () => {
core.getInput = jest
.fn()
.mockReturnValueOnce('task-definition.json') // task-definition
.mockReturnValueOnce('service-456') // service
.mockReturnValueOnce('cluster-789') // cluster
.mockReturnValueOnce('TRUE') // wait-for-service-stability
.mockReturnValueOnce('1000'); // wait-for-minutes
.mockReturnValueOnce('service-456') // service
.mockReturnValueOnce('cluster-789') // cluster
.mockReturnValueOnce('TRUE') // wait-for-service-stability
.mockReturnValueOnce('1000') // wait-for-minutes
.mockReturnValueOnce('abc'); // desired count is NaN

await run();
expect(core.setFailed).toHaveBeenCalledTimes(0);
Expand Down Expand Up @@ -1012,12 +1016,13 @@ describe('Deploy to ECS', () => {
test('force new deployment', async () => {
core.getInput = jest
.fn()
.mockReturnValueOnce('task-definition.json') // task-definition
.mockReturnValueOnce('task-definition.json') // task-definition
.mockReturnValueOnce('service-456') // service
.mockReturnValueOnce('cluster-789') // cluster
.mockReturnValueOnce('false') // wait-for-service-stability
.mockReturnValueOnce('') // wait-for-minutes
.mockReturnValueOnce('true'); // force-new-deployment
.mockReturnValueOnce('true') // force-new-deployment
.mockReturnValueOnce('4'); // desired count is number

await run();
expect(core.setFailed).toHaveBeenCalledTimes(0);
Expand All @@ -1030,6 +1035,7 @@ describe('Deploy to ECS', () => {
});
expect(mockEcsUpdateService).toHaveBeenNthCalledWith(1, {
cluster: 'cluster-789',
desiredCount: 4,
service: 'service-456',
taskDefinition: 'task:def:arn',
forceNewDeployment: true
Expand All @@ -1040,7 +1046,8 @@ describe('Deploy to ECS', () => {
core.getInput = jest
.fn()
.mockReturnValueOnce('task-definition.json') // task-definition
.mockReturnValueOnce('service-456'); // service
.mockReturnValueOnce('service-456') // service
.mockReturnValueOnce(''); // desired count

await run();
expect(core.setFailed).toHaveBeenCalledTimes(0);
Expand Down

0 comments on commit e5f78d3

Please sign in to comment.