From ab77eedd599fe08913eade0616f9400b42376fc3 Mon Sep 17 00:00:00 2001 From: Shaun Martin Date: Wed, 15 Jun 2022 16:08:27 -0500 Subject: [PATCH] fix: truncate overly long code deploy descriptions --- action.yml | 2 +- index.js | 10 +++--- index.test.js | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 90 insertions(+), 8 deletions(-) diff --git a/action.yml b/action.yml index 6ba61a93b..a18b581ad 100644 --- a/action.yml +++ b/action.yml @@ -29,7 +29,7 @@ inputs: description: "The name of the AWS CodeDeploy deployment group, if the ECS service uses the CODE_DEPLOY deployment controller. Will default to 'DgpECS-{cluster}-{service}'." required: false codedeploy-deployment-description: - description: "A description of the deployment, if the ECS service uses the CODE_DEPLOY deployment controller." + description: "A description of the deployment, if the ECS service uses the CODE_DEPLOY deployment controller. NOTE: This will be truncated to 512 characters if necessary." required: false force-new-deployment: description: 'Whether to force a new deployment of the service. Valid value is "true". Will default to not force a new deployment.' diff --git a/index.js b/index.js index 09efe440a..b3dee9f4a 100644 --- a/index.js +++ b/index.js @@ -55,11 +55,7 @@ async function runTask(ecs, clusterName, taskDefArn, waitForMinutes) { const taskArns = runTaskResponse.tasks.map(task => task.taskArn); core.setOutput('run-task-arn', taskArns); - - taskArns.map(taskArn => { - let taskId = taskArn.split('/').pop(); - core.info(`Task running: https://console.aws.amazon.com/ecs/home?region=${aws.config.region}#/clusters/${clusterName}/tasks`) - }); + core.info(`Task running: https://console.aws.amazon.com/ecs/home?region=${aws.config.region}#/clusters/${clusterName}/tasks`); if (runTaskResponse.failures && runTaskResponse.failures.length > 0) { const failure = runTaskResponse.failures[0]; @@ -313,9 +309,11 @@ async function createCodeDeployDeployment(codedeploy, clusterName, service, task } } }; + // If it hasn't been set then we don't even want to pass it to the api call to maintain previous behaviour. if (codeDeployDescription) { - deploymentParams.description = codeDeployDescription + // CodeDeploy Deployment Descriptions have a max length of 512 characters, so truncate if necessary + deploymentParams.description = (codeDeployDescription.length <= 512) ? codeDeployDescription : `${codeDeployDescription.substring(0,511)}…`; } const createDeployResponse = await codedeploy.createDeployment(deploymentParams).promise(); core.setOutput('codedeploy-deployment-id', createDeployResponse.deploymentId); diff --git a/index.test.js b/index.test.js index 8e7ab28df..c5db8b52a 100644 --- a/index.test.js +++ b/index.test.js @@ -893,6 +893,90 @@ 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 and creates a CodeDeploy deployment with custom application, deployment group and long description', async () => { + core.getInput = jest + .fn(input => { + return { + 'task-definition': 'task-definition.json', + 'service': 'service-456', + 'cluster': 'cluster-789', + 'wait-for-service-stability': 'TRUE', + 'codedeploy-application': 'Custom-Application', + 'codedeploy-deployment-group': 'Custom-Deployment-Group', + 'codedeploy-deployment-description': 'Custom-Deployment'.repeat(31) + }[input]; + }); + + mockEcsDescribeServices.mockImplementation(() => { + return { + promise() { + return Promise.resolve({ + failures: [], + services: [{ + status: 'ACTIVE', + deploymentController: { + type: 'CODE_DEPLOY' + } + }] + }); + } + }; + }); + + await run(); + expect(core.setFailed).toHaveBeenCalledTimes(0); + + expect(mockEcsRegisterTaskDef).toHaveBeenNthCalledWith(1, { family: 'task-def-family'}); + expect(core.setOutput).toHaveBeenNthCalledWith(1, 'task-definition-arn', 'task:def:arn'); + expect(mockEcsDescribeServices).toHaveBeenNthCalledWith(1, { + cluster: 'cluster-789', + services: ['service-456'] + }); + + expect(mockCodeDeployCreateDeployment).toHaveBeenNthCalledWith(1, { + applicationName: 'Custom-Application', + deploymentGroupName: 'Custom-Deployment-Group', + description: 'Custom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentCustom-DeploymentC…', + revision: { + revisionType: 'AppSpecContent', + appSpecContent: { + content: JSON.stringify({ + Resources: [{ + TargetService: { + Type: 'AWS::ECS::Service', + Properties: { + TaskDefinition: 'task:def:arn', + LoadBalancerInfo: { + ContainerName: "web", + ContainerPort: 80 + } + } + } + }] + }), + sha256: '0911d1e99f48b492e238d1284d8ddb805382d33e1d1fc74ffadf37d8b7e6d096' + } + } + }); + + expect(mockCodeDeployWaiter).toHaveBeenNthCalledWith(1, 'deploymentSuccessful', { + deploymentId: 'deployment-1', + $waiter: { + delay: 15, + maxAttempts: ( + EXPECTED_DEFAULT_WAIT_TIME + + EXPECTED_CODE_DEPLOY_TERMINATION_WAIT_TIME + + EXPECTED_CODE_DEPLOY_DEPLOYMENT_READY_WAIT_TIME + ) * 4 + } + }); + + expect(mockEcsUpdateService).toHaveBeenCalledTimes(0); + expect(mockEcsWaiter).toHaveBeenCalledTimes(0); + + 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 () => { core.getInput = jest.fn().mockReturnValueOnce('/hello/task-definition.json'); fs.readFileSync.mockImplementation((pathInput, encoding) => { @@ -1127,7 +1211,7 @@ describe('Deploy to ECS', () => { launchType: "EC2", taskDefinition: 'task:def:arn', overrides: { containerOverrides: [{ name: 'someapp', command: 'somecmd' }] }, - networkConfiguration: { awsVpcNetworkConfiguration: { subnets: ['a', 'b'], securityGroups: ['c', 'd'] } } + networkConfiguration: { awsvpcConfiguration: { subnets: ['a', 'b'], securityGroups: ['c', 'd'] } } }); expect(core.setOutput).toHaveBeenNthCalledWith(2, 'run-task-arn', ["arn:aws:ecs:fake-region:account_id:task/arn"]); });