diff --git a/README.md b/README.md index d0b20be0f..c6025e176 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ Registers an Amazon ECS task definition and deploys it to an ECS service. - [Credentials and Region](#credentials-and-region) - [Permissions](#permissions) - [AWS CodeDeploy Support](#aws-codedeploy-support) +- [Polling Configuration](#polling-configuration) - [Troubleshooting](#troubleshooting) - [License Summary](#license-summary) - [Security Disclosures](#security-disclosures) @@ -388,6 +389,25 @@ This is particularly useful in cases where ECS or a previous task definition app wait-for-service-stability: true ``` +## Polling Configuration + +By default when waiting for service stability or task completion, the AWS SDK uses exponential backoff which can result in delays up to 120 seconds between polling attempts. This means even after your service becomes stable, you may wait up to 2 minutes before the next poll detects it. + +To use consistent polling intervals instead, set `wait-max-delay-seconds`: + +```yaml + - name: Deploy to Amazon ECS + uses: aws-actions/amazon-ecs-deploy-task-definition@v2 + with: + task-definition: task-definition.json + service: my-service + cluster: my-cluster + wait-for-service-stability: true + wait-max-delay-seconds: 15 +``` + +This configuration polls every 15 seconds instead of using exponential backoff. + ## Retries To automatically retry a failed task definition deployment, use the max-retries input. This controls how many times the action will attempt to register and deploy the task definition before failing. diff --git a/action.yml b/action.yml index 606c4f14e..064fff342 100644 --- a/action.yml +++ b/action.yml @@ -22,6 +22,9 @@ inputs: wait-for-minutes: description: 'How long to wait for the ECS service to reach stable state, in minutes (default: 30 minutes, max: 6 hours). For CodeDeploy deployments, any wait time configured in the CodeDeploy deployment group will be added to this value.' required: false + wait-max-delay-seconds: + description: 'Maximum delay in seconds between polling attempts when waiting for service stability or task completion. If not set, AWS SDK uses exponential backoff up to 120 seconds. Set to 15 for consistent 15-second polling intervals.' + required: false codedeploy-appspec: description: "The path to the AWS CodeDeploy AppSpec file, if the ECS service uses the CODE_DEPLOY deployment controller. Will default to 'appspec.yaml'." required: false diff --git a/dist/index.js b/dist/index.js index 9641f2ccc..a1891e158 100644 --- a/dist/index.js +++ b/dist/index.js @@ -27,7 +27,7 @@ const IGNORED_TASK_DEFINITION_ATTRIBUTES = [ ]; // Method to run a stand-alone task with desired inputs -async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags) { +async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags, waitMaxDelaySeconds) { core.info('Running task') const waitForTask = core.getInput('wait-for-task-stopped', { required: false }) || 'false'; @@ -102,7 +102,7 @@ async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSMa // Wait for task to end if (waitForTask && waitForTask.toLowerCase() === "true") { - await waitForTasksStopped(ecs, clusterName, taskArns, waitForMinutes) + await waitForTasksStopped(ecs, clusterName, taskArns, waitForMinutes, waitMaxDelaySeconds) await tasksExitCode(ecs, clusterName, taskArns) } else { core.debug('Not waiting for the task to stop'); @@ -151,18 +151,24 @@ function convertToManagedEbsVolumeObject(managedEbsVolume) { } // Poll tasks until they enter a stopped state -async function waitForTasksStopped(ecs, clusterName, taskArns, waitForMinutes) { +async function waitForTasksStopped(ecs, clusterName, taskArns, waitForMinutes, waitMaxDelaySeconds) { if (waitForMinutes > MAX_WAIT_MINUTES) { waitForMinutes = MAX_WAIT_MINUTES; } core.info(`Waiting for tasks to stop. Will wait for ${waitForMinutes} minutes`); - const waitTaskResponse = await waitUntilTasksStopped({ + const waiterConfig = { client: ecs, minDelay: WAIT_DEFAULT_DELAY_SEC, maxWaitTime: waitForMinutes * 60, - }, { + }; + + if (waitMaxDelaySeconds) { + waiterConfig.maxDelay = waitMaxDelaySeconds; + } + + const waitTaskResponse = await waitUntilTasksStopped(waiterConfig, { cluster: clusterName, tasks: taskArns, }); @@ -197,7 +203,7 @@ async function tasksExitCode(ecs, clusterName, taskArns) { } // Deploy to a service that uses the 'ECS' deployment controller -async function updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags, propagateTags) { +async function updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags, propagateTags, waitMaxDelaySeconds) { core.debug('Updating the service'); const serviceManagedEBSVolumeName = core.getInput('service-managed-ebs-volume-name', { required: false }) || ''; @@ -242,11 +248,18 @@ async function updateEcsService(ecs, clusterName, service, taskDefArn, waitForSe // Wait for service stability if (waitForService && waitForService.toLowerCase() === 'true') { core.debug(`Waiting for the service to become stable. Will wait for ${waitForMinutes} minutes`); - await waitUntilServicesStable({ + + const waiterConfig = { client: ecs, minDelay: WAIT_DEFAULT_DELAY_SEC, maxWaitTime: waitForMinutes * 60 - }, { + }; + + if (waitMaxDelaySeconds) { + waiterConfig.maxDelay = waitMaxDelaySeconds; + } + + await waitUntilServicesStable(waiterConfig, { services: [service], cluster: clusterName }); @@ -381,7 +394,7 @@ function validateProxyConfigurations(taskDef){ } // Deploy to a service that uses the 'CODE_DEPLOY' deployment controller -async function createCodeDeployDeployment(codedeploy, clusterName, service, taskDefArn, waitForService, waitForMinutes) { +async function createCodeDeployDeployment(codedeploy, clusterName, service, taskDefArn, waitForService, waitForMinutes, waitMaxDelaySeconds) { core.debug('Updating AppSpec file with new task definition ARN'); let codeDeployAppSpecFile = core.getInput('codedeploy-appspec', { required : false }); @@ -460,11 +473,18 @@ async function createCodeDeployDeployment(codedeploy, clusterName, service, task totalWaitMin = MAX_WAIT_MINUTES; } core.debug(`Waiting for the deployment to complete. Will wait for ${totalWaitMin} minutes`); - await waitUntilDeploymentSuccessful({ + + const waiterConfig = { client: codedeploy, minDelay: WAIT_DEFAULT_DELAY_SEC, maxWaitTime: totalWaitMin * 60 - }, { + }; + + if (waitMaxDelaySeconds) { + waiterConfig.maxDelay = waitMaxDelaySeconds; + } + + await waitUntilDeploymentSuccessful(waiterConfig, { deploymentId: createDeployResponse.deploymentId }); } else { @@ -486,6 +506,9 @@ async function run() { waitForMinutes = MAX_WAIT_MINUTES; } + const waitMaxDelaySecondsInput = core.getInput('wait-max-delay-seconds', { required: false }); + const waitMaxDelaySeconds = waitMaxDelaySecondsInput ? parseInt(waitMaxDelaySecondsInput) : null; + const forceNewDeployInput = core.getInput('force-new-deployment', { required: false }) || 'false'; const forceNewDeployment = forceNewDeployInput.toLowerCase() === 'true'; const desiredCount = parseInt((core.getInput('desired-count', {required: false}))); @@ -545,7 +568,7 @@ async function run() { core.debug(`shouldRunTask: ${shouldRunTask}`); if (shouldRunTask) { core.debug("Running ad-hoc task..."); - await runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags); + await runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags, waitMaxDelaySeconds); } // Update the service with the new task definition @@ -569,12 +592,12 @@ async function run() { if (!serviceResponse.deploymentController || !serviceResponse.deploymentController.type || serviceResponse.deploymentController.type === 'ECS') { // Service uses the 'ECS' deployment controller, so we can call UpdateService core.debug('Updating service...'); - await updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags, propagateTags); + await updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags, propagateTags, waitMaxDelaySeconds); } else if (serviceResponse.deploymentController.type === 'CODE_DEPLOY') { // Service uses CodeDeploy, so we should start a CodeDeploy deployment core.debug('Deploying service in the default cluster'); - await createCodeDeployDeployment(codedeploy, clusterName, service, taskDefArn, waitForService, waitForMinutes); + await createCodeDeployDeployment(codedeploy, clusterName, service, taskDefArn, waitForService, waitForMinutes, waitMaxDelaySeconds); } else { throw new Error(`Unsupported deployment controller: ${serviceResponse.deploymentController.type}`); } diff --git a/index.js b/index.js index 2bcf2b415..bc580559c 100644 --- a/index.js +++ b/index.js @@ -21,7 +21,7 @@ const IGNORED_TASK_DEFINITION_ATTRIBUTES = [ ]; // Method to run a stand-alone task with desired inputs -async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags) { +async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags, waitMaxDelaySeconds) { core.info('Running task') const waitForTask = core.getInput('wait-for-task-stopped', { required: false }) || 'false'; @@ -96,7 +96,7 @@ async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSMa // Wait for task to end if (waitForTask && waitForTask.toLowerCase() === "true") { - await waitForTasksStopped(ecs, clusterName, taskArns, waitForMinutes) + await waitForTasksStopped(ecs, clusterName, taskArns, waitForMinutes, waitMaxDelaySeconds) await tasksExitCode(ecs, clusterName, taskArns) } else { core.debug('Not waiting for the task to stop'); @@ -145,18 +145,24 @@ function convertToManagedEbsVolumeObject(managedEbsVolume) { } // Poll tasks until they enter a stopped state -async function waitForTasksStopped(ecs, clusterName, taskArns, waitForMinutes) { +async function waitForTasksStopped(ecs, clusterName, taskArns, waitForMinutes, waitMaxDelaySeconds) { if (waitForMinutes > MAX_WAIT_MINUTES) { waitForMinutes = MAX_WAIT_MINUTES; } core.info(`Waiting for tasks to stop. Will wait for ${waitForMinutes} minutes`); - const waitTaskResponse = await waitUntilTasksStopped({ + const waiterConfig = { client: ecs, minDelay: WAIT_DEFAULT_DELAY_SEC, maxWaitTime: waitForMinutes * 60, - }, { + }; + + if (waitMaxDelaySeconds) { + waiterConfig.maxDelay = waitMaxDelaySeconds; + } + + const waitTaskResponse = await waitUntilTasksStopped(waiterConfig, { cluster: clusterName, tasks: taskArns, }); @@ -191,7 +197,7 @@ async function tasksExitCode(ecs, clusterName, taskArns) { } // Deploy to a service that uses the 'ECS' deployment controller -async function updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags, propagateTags) { +async function updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags, propagateTags, waitMaxDelaySeconds) { core.debug('Updating the service'); const serviceManagedEBSVolumeName = core.getInput('service-managed-ebs-volume-name', { required: false }) || ''; @@ -236,11 +242,18 @@ async function updateEcsService(ecs, clusterName, service, taskDefArn, waitForSe // Wait for service stability if (waitForService && waitForService.toLowerCase() === 'true') { core.debug(`Waiting for the service to become stable. Will wait for ${waitForMinutes} minutes`); - await waitUntilServicesStable({ + + const waiterConfig = { client: ecs, minDelay: WAIT_DEFAULT_DELAY_SEC, maxWaitTime: waitForMinutes * 60 - }, { + }; + + if (waitMaxDelaySeconds) { + waiterConfig.maxDelay = waitMaxDelaySeconds; + } + + await waitUntilServicesStable(waiterConfig, { services: [service], cluster: clusterName }); @@ -375,7 +388,7 @@ function validateProxyConfigurations(taskDef){ } // Deploy to a service that uses the 'CODE_DEPLOY' deployment controller -async function createCodeDeployDeployment(codedeploy, clusterName, service, taskDefArn, waitForService, waitForMinutes) { +async function createCodeDeployDeployment(codedeploy, clusterName, service, taskDefArn, waitForService, waitForMinutes, waitMaxDelaySeconds) { core.debug('Updating AppSpec file with new task definition ARN'); let codeDeployAppSpecFile = core.getInput('codedeploy-appspec', { required : false }); @@ -454,11 +467,18 @@ async function createCodeDeployDeployment(codedeploy, clusterName, service, task totalWaitMin = MAX_WAIT_MINUTES; } core.debug(`Waiting for the deployment to complete. Will wait for ${totalWaitMin} minutes`); - await waitUntilDeploymentSuccessful({ + + const waiterConfig = { client: codedeploy, minDelay: WAIT_DEFAULT_DELAY_SEC, maxWaitTime: totalWaitMin * 60 - }, { + }; + + if (waitMaxDelaySeconds) { + waiterConfig.maxDelay = waitMaxDelaySeconds; + } + + await waitUntilDeploymentSuccessful(waiterConfig, { deploymentId: createDeployResponse.deploymentId }); } else { @@ -480,6 +500,9 @@ async function run() { waitForMinutes = MAX_WAIT_MINUTES; } + const waitMaxDelaySecondsInput = core.getInput('wait-max-delay-seconds', { required: false }); + const waitMaxDelaySeconds = waitMaxDelaySecondsInput ? parseInt(waitMaxDelaySecondsInput) : null; + const forceNewDeployInput = core.getInput('force-new-deployment', { required: false }) || 'false'; const forceNewDeployment = forceNewDeployInput.toLowerCase() === 'true'; const desiredCount = parseInt((core.getInput('desired-count', {required: false}))); @@ -539,7 +562,7 @@ async function run() { core.debug(`shouldRunTask: ${shouldRunTask}`); if (shouldRunTask) { core.debug("Running ad-hoc task..."); - await runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags); + await runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags, waitMaxDelaySeconds); } // Update the service with the new task definition @@ -563,12 +586,12 @@ async function run() { if (!serviceResponse.deploymentController || !serviceResponse.deploymentController.type || serviceResponse.deploymentController.type === 'ECS') { // Service uses the 'ECS' deployment controller, so we can call UpdateService core.debug('Updating service...'); - await updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags, propagateTags); + await updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags, propagateTags, waitMaxDelaySeconds); } else if (serviceResponse.deploymentController.type === 'CODE_DEPLOY') { // Service uses CodeDeploy, so we should start a CodeDeploy deployment core.debug('Deploying service in the default cluster'); - await createCodeDeployDeployment(codedeploy, clusterName, service, taskDefArn, waitForService, waitForMinutes); + await createCodeDeployDeployment(codedeploy, clusterName, service, taskDefArn, waitForService, waitForMinutes, waitMaxDelaySeconds); } else { throw new Error(`Unsupported deployment controller: ${serviceResponse.deploymentController.type}`); } diff --git a/index.test.js b/index.test.js index 5e79c4cd6..690d2f1e5 100644 --- a/index.test.js +++ b/index.test.js @@ -1053,6 +1053,49 @@ 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('creates CodeDeploy deployment with custom max delay', async () => { + core.getInput = jest.fn(input => { + if (input === 'task-definition') return 'task-definition.json'; + if (input === 'service') return 'service-456'; + if (input === 'cluster') return 'cluster-789'; + if (input === 'wait-for-service-stability') return 'TRUE'; + if (input === 'wait-max-delay-seconds') return '15'; + return ''; + }); + + mockEcsDescribeServices.mockImplementation( + () => Promise.resolve({ + failures: [], + services: [{ + status: 'ACTIVE', + deploymentController: { + type: 'CODE_DEPLOY' + } + }] + }) + ); + + await run(); + expect(core.setFailed).toHaveBeenCalledTimes(0); + + expect(waitUntilDeploymentSuccessful).toHaveBeenNthCalledWith( + 1, + { + client: mockCodeDeployClient, + minDelay: 15, + maxDelay: 15, + maxWaitTime: ( + EXPECTED_DEFAULT_WAIT_TIME + + EXPECTED_CODE_DEPLOY_TERMINATION_WAIT_TIME + + EXPECTED_CODE_DEPLOY_DEPLOYMENT_READY_WAIT_TIME + ) * 60, + }, + { + deploymentId: 'deployment-1', + } + ); + }); + 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) => { @@ -1202,17 +1245,43 @@ describe('Deploy to ECS', () => { ); }); + test('waits for the service to be stable with custom max delay', async () => { + core.getInput = jest.fn(input => { + if (input === 'task-definition') return 'task-definition.json'; + if (input === 'service') return 'service-456'; + if (input === 'cluster') return 'cluster-789'; + if (input === 'wait-for-service-stability') return 'TRUE'; + if (input === 'wait-max-delay-seconds') return '15'; + return ''; + }); + + await run(); + expect(core.setFailed).toHaveBeenCalledTimes(0); + + expect(waitUntilServicesStable).toHaveBeenNthCalledWith( + 1, + { + client: mockEcsClient, + minDelay: 15, + maxDelay: 15, + maxWaitTime: EXPECTED_DEFAULT_WAIT_TIME * 60, + }, + { + services: ['service-456'], + cluster: 'cluster-789', + } + ); + }); + test('force new deployment', async () => { - core.getInput = jest - .fn() - .mockReturnValueOnce('task-definition.json') // task-definition - .mockReturnValueOnce('service-456') // service - .mockReturnValueOnce('cluster-789') // cluster - .mockReturnValueOnce('3') // max-retries - .mockReturnValueOnce('false') // wait-for-service-stability - .mockReturnValueOnce('') // wait-for-minutes - .mockReturnValueOnce('true') // force-new-deployment - .mockReturnValueOnce('4'); // desired count is number + core.getInput = jest.fn(input => { + if (input === 'task-definition') return 'task-definition.json'; + if (input === 'service') return 'service-456'; + if (input === 'cluster') return 'cluster-789'; + if (input === 'force-new-deployment') return 'true'; + if (input === 'desired-count') return '4'; + return ''; + }); await run(); expect(core.setFailed).toHaveBeenCalledTimes(0); @@ -1471,6 +1540,41 @@ describe('Deploy to ECS', () => { expect(waitUntilTasksStopped).toHaveBeenCalledTimes(1); }); + test('run task and wait for it to stop with custom max delay', async () => { + core.getInput = jest + .fn(input => { + if (input === 'task-definition') return 'task-definition.json'; + if (input === 'cluster') return 'somecluster'; + if (input === 'run-task') return 'true'; + if (input === 'wait-for-task-stopped') return 'true'; + if (input === 'wait-max-delay-seconds') return '15'; + if (input === 'run-task-launch-type') return 'FARGATE'; + if (input === 'run-task-container-overrides') return '[]'; + if (input === 'run-task-tags') return '[]'; + if (input === 'run-task-capacity-provider-strategy') return '[]'; + if (input === 'run-task-managed-ebs-volume-name') return ''; + if (input === 'run-task-managed-ebs-volume') return '{}'; + return ''; + }); + + await run(); + expect(core.setFailed).toHaveBeenCalledTimes(0); + + expect(waitUntilTasksStopped).toHaveBeenNthCalledWith( + 1, + { + client: mockEcsClient, + minDelay: 15, + maxDelay: 15, + maxWaitTime: EXPECTED_DEFAULT_WAIT_TIME * 60, + }, + { + cluster: 'somecluster', + tasks: ["arn:aws:ecs:fake-region:account_id:task/arn"], + } + ); + }); + test('run task in bridge network mode', async () => { core.getInput = jest .fn(input => { @@ -1568,20 +1672,19 @@ describe('Deploy to ECS', () => { }); test('error is caught if run task fails with (wait-for-task-stopped: true)', async () => { - core.getInput = jest - .fn() - .mockReturnValueOnce('task-definition.json') // task-definition - .mockReturnValueOnce('') // service - .mockReturnValueOnce('somecluster') // cluster - .mockReturnValueOnce('3') // max-retries - .mockReturnValueOnce('') // wait-for-service-stability - .mockReturnValueOnce('') // wait-for-minutes - .mockReturnValueOnce('') // force-new-deployment - .mockReturnValueOnce('') // desired-count - .mockReturnValueOnce('') // enable-ecs-managed-tags - .mockReturnValueOnce('') // propagate-tags - .mockReturnValueOnce('true') // run-task - .mockReturnValueOnce('true'); // wait-for-task-stopped + core.getInput = jest.fn(input => { + if (input === 'task-definition') return 'task-definition.json'; + if (input === 'cluster') return 'somecluster'; + if (input === 'run-task') return 'true'; + if (input === 'wait-for-task-stopped') return 'true'; + if (input === 'run-task-launch-type') return 'FARGATE'; + if (input === 'run-task-container-overrides') return '[]'; + if (input === 'run-task-tags') return '[]'; + if (input === 'run-task-capacity-provider-strategy') return '[]'; + if (input === 'run-task-managed-ebs-volume-name') return ''; + if (input === 'run-task-managed-ebs-volume') return '{}'; + return ''; + }); mockRunTask.mockImplementation( () => Promise.resolve({ @@ -1736,18 +1839,13 @@ describe('Deploy to ECS', () => { }); test('propagate service tags from service', async () => { - core.getInput = jest - .fn() - .mockReturnValueOnce('task-definition.json') // task-definition - .mockReturnValueOnce('service-456') // service - .mockReturnValueOnce('cluster-789') // cluster - .mockReturnValueOnce('3') // max-retries - .mockReturnValueOnce('false') // wait-for-service-stability - .mockReturnValueOnce('') // wait-for-minutes - .mockReturnValueOnce('') // force-new-deployment - .mockReturnValueOnce('') // desired-count - .mockReturnValueOnce('') // enable-ecs-managed-tags - .mockReturnValueOnce('SERVICE'); // propagate-tags + core.getInput = jest.fn(input => { + if (input === 'task-definition') return 'task-definition.json'; + if (input === 'service') return 'service-456'; + if (input === 'cluster') return 'cluster-789'; + if (input === 'propagate-tags') return 'SERVICE'; + return ''; + }); await run(); expect(core.setFailed).toHaveBeenCalledTimes(0); @@ -1770,18 +1868,14 @@ describe('Deploy to ECS', () => { }); test('update service with setting true to enableECSManagedTags', async () => { - core.getInput = jest - .fn() - .mockReturnValueOnce('task-definition.json') // task-definition - .mockReturnValueOnce('service-456') // service - .mockReturnValueOnce('cluster-789') // cluster - .mockReturnValueOnce('3') // max-retries - .mockReturnValueOnce('false') // wait-for-service-stability - .mockReturnValueOnce('') // wait-for-minutes - .mockReturnValueOnce('') // force-new-deployment - .mockReturnValueOnce('') // desired-count - .mockReturnValueOnce('true') // enable-ecs-managed-tags - .mockReturnValueOnce('SERVICE'); // propagate-tags + core.getInput = jest.fn(input => { + if (input === 'task-definition') return 'task-definition.json'; + if (input === 'service') return 'service-456'; + if (input === 'cluster') return 'cluster-789'; + if (input === 'enable-ecs-managed-tags') return 'true'; + if (input === 'propagate-tags') return 'SERVICE'; + return ''; + }); await run(); expect(core.setFailed).toHaveBeenCalledTimes(0); @@ -1804,18 +1898,14 @@ describe('Deploy to ECS', () => { }); test('update service with setting false to enableECSManagedTags', async () => { - core.getInput = jest - .fn() - .mockReturnValueOnce('task-definition.json') // task-definition - .mockReturnValueOnce('service-456') // service - .mockReturnValueOnce('cluster-789') // cluster - .mockReturnValueOnce('3') // max-retries - .mockReturnValueOnce('false') // wait-for-service-stability - .mockReturnValueOnce('') // wait-for-minutes - .mockReturnValueOnce('') // force-new-deployment - .mockReturnValueOnce('') // desired-count - .mockReturnValueOnce('false') // enable-ecs-managed-tags - .mockReturnValueOnce('SERVICE'); // propagate-tags + core.getInput = jest.fn(input => { + if (input === 'task-definition') return 'task-definition.json'; + if (input === 'service') return 'service-456'; + if (input === 'cluster') return 'cluster-789'; + if (input === 'enable-ecs-managed-tags') return 'false'; + if (input === 'propagate-tags') return 'SERVICE'; + return ''; + }); await run(); expect(core.setFailed).toHaveBeenCalledTimes(0); diff --git a/package-lock.json b/package-lock.json index 71a5b6ff1..831c50cb0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "aws-actions-amazon-ecs-deploy-task-definition", - "version": "2.5.1", + "version": "2.6.0", "license": "MIT", "dependencies": { "@actions/core": "^2.0.1",