From 43672e26a2d56d16ba875d41e631999f02750b71 Mon Sep 17 00:00:00 2001 From: Guillaume Delacour Date: Mon, 26 Aug 2024 13:14:47 +0200 Subject: [PATCH 1/3] feat: Get tags from services and set ad-hoc run-task --- README.md | 34 +++++++++++++++++++ action.yml | 6 ++++ dist/index.js | 18 ++++++---- index.js | 18 ++++++---- index.test.js | 86 ++++++++++++++++++++++++++++++++++++++++------- package-lock.json | 35 ++++++++++++------- package.json | 4 +-- 7 files changed, 159 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 5d57d586e..3d9f2fd40 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,19 @@ To turn on [Amazon ECS-managed tags](https://docs.aws.amazon.com/AmazonECS/lates enable-ecs-managed-tags: true ``` +You can propagate your custom tags from your existing service using `propagate-tags`: + +```yaml + - name: Deploy Amazon ECS task definition + 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 + propagate-tags: SERVICE +``` + ## Credentials and Region This action relies on the [default behavior of the AWS SDK for Javascript](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-credentials-node.html) to determine AWS credentials and region. @@ -288,6 +301,27 @@ In the following example, the service would not be updated until the ad-hoc task Overrides and VPC networking options are available as well. See [action.yml](action.yml) for more details. The `FARGATE` launch type requires `awsvpc` network mode in your task definition and you must specify a network configuration. +### Tags + +To tag your tasks: + +* to turn on Amazon ECS-managed tags (`aws:ecs:clusterName`), use `enable-ecs-managed-tags` +* for custom tags, use `run-task-tags` + +```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 + run-task: true + enable-ecs-managed-tags: true + run-task-tags: '[{"key": "project", "value": "myproject"}]' + wait-for-task-stopped: true +``` + ## Troubleshooting This action emits debug logs to help troubleshoot deployment failures. To see the debug logs, create a secret named `ACTIONS_STEP_DEBUG` with value `true` in your repository. diff --git a/action.yml b/action.yml index 9e9444ef3..c3bc7b271 100644 --- a/action.yml +++ b/action.yml @@ -61,12 +61,18 @@ inputs: run-task-started-by: description: "A name to use for the startedBy tag when running a task outside of a service. Will default to 'GitHub-Actions'." required: false + run-task-tags: + description: 'A JSON array of tags' + required: false wait-for-task-stopped: description: 'Whether to wait for the task to stop when running it outside of a service. Will default to not wait.' required: false enable-ecs-managed-tags: description: "Determines whether to turn on Amazon ECS managed tags 'aws:ecs:serviceName' and 'aws:ecs:clusterName' for the tasks in the service." required: false + propagate-tags: + description: "Determines to propagate the tags from the 'SERVICE' to the task. Will default to 'NONE'" + required: false outputs: task-definition-arn: description: 'The ARN of the registered ECS task definition' diff --git a/dist/index.js b/dist/index.js index c0bdd2be4..a16872f0b 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, runTaskTags) { core.info('Running task') const waitForTask = core.getInput('wait-for-task-stopped', { required: false }) || 'false'; @@ -61,7 +61,8 @@ async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSMa }, launchType: launchType, networkConfiguration: Object.keys(awsvpcConfiguration).length === 0 ? null : { awsvpcConfiguration: awsvpcConfiguration }, - enableECSManagedTags: enableECSManagedTags + enableECSManagedTags: enableECSManagedTags, + tags: runTaskTags }); core.debug(`Run task response ${JSON.stringify(runTaskResponse)}`) @@ -135,7 +136,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) { +async function updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags, propagateTags) { core.debug('Updating the service'); let params = { @@ -143,7 +144,8 @@ async function updateEcsService(ecs, clusterName, service, taskDefArn, waitForSe service: service, taskDefinition: taskDefArn, forceNewDeployment: forceNewDeployment, - enableECSManagedTags: enableECSManagedTags + enableECSManagedTags: enableECSManagedTags, + propagateTags: propagateTags }; // Add the desiredCount property only if it is defined and a number. @@ -401,7 +403,9 @@ async function run() { const desiredCount = parseInt((core.getInput('desired-count', {required: false}))); const enableECSManagedTagsInput = core.getInput('enable-ecs-managed-tags', { required: false }) || 'false'; const enableECSManagedTags = enableECSManagedTagsInput.toLowerCase() === 'true'; - + const propagateTags = core.getInput('propagate-tags', { required: false }) || 'NONE'; + const runTaskTags = JSON.parse(core.getInput('run-task-tags', { required: false }) || '[]'); + // Register the task definition core.debug('Registering the task definition'); const taskDefPath = path.isAbsolute(taskDefinitionFile) ? @@ -428,7 +432,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, runTaskTags); } // Update the service with the new task definition @@ -452,7 +456,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 core.debug('Updating service...'); - await updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags); + await updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags, propagateTags); } else if (serviceResponse.deploymentController.type === 'CODE_DEPLOY') { // Service uses CodeDeploy, so we should start a CodeDeploy deployment diff --git a/index.js b/index.js index 6168cc706..9fc82e8af 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, runTaskTags) { core.info('Running task') const waitForTask = core.getInput('wait-for-task-stopped', { required: false }) || 'false'; @@ -55,7 +55,8 @@ async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSMa }, launchType: launchType, networkConfiguration: Object.keys(awsvpcConfiguration).length === 0 ? null : { awsvpcConfiguration: awsvpcConfiguration }, - enableECSManagedTags: enableECSManagedTags + enableECSManagedTags: enableECSManagedTags, + tags: runTaskTags }); core.debug(`Run task response ${JSON.stringify(runTaskResponse)}`) @@ -129,7 +130,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) { +async function updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags, propagateTags) { core.debug('Updating the service'); let params = { @@ -137,7 +138,8 @@ async function updateEcsService(ecs, clusterName, service, taskDefArn, waitForSe service: service, taskDefinition: taskDefArn, forceNewDeployment: forceNewDeployment, - enableECSManagedTags: enableECSManagedTags + enableECSManagedTags: enableECSManagedTags, + propagateTags: propagateTags }; // Add the desiredCount property only if it is defined and a number. @@ -395,7 +397,9 @@ async function run() { const desiredCount = parseInt((core.getInput('desired-count', {required: false}))); const enableECSManagedTagsInput = core.getInput('enable-ecs-managed-tags', { required: false }) || 'false'; const enableECSManagedTags = enableECSManagedTagsInput.toLowerCase() === 'true'; - + const propagateTags = core.getInput('propagate-tags', { required: false }) || 'NONE'; + const runTaskTags = JSON.parse(core.getInput('run-task-tags', { required: false }) || '[]'); + // Register the task definition core.debug('Registering the task definition'); const taskDefPath = path.isAbsolute(taskDefinitionFile) ? @@ -422,7 +426,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, runTaskTags); } // Update the service with the new task definition @@ -446,7 +450,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 core.debug('Updating service...'); - await updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags); + await updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags, propagateTags); } else if (serviceResponse.deploymentController.type === 'CODE_DEPLOY') { // Service uses CodeDeploy, so we should start a CodeDeploy deployment diff --git a/index.test.js b/index.test.js index 2b610cd74..a5e620d7a 100644 --- a/index.test.js +++ b/index.test.js @@ -183,7 +183,8 @@ describe('Deploy to ECS', () => { service: 'service-456', taskDefinition: 'task:def:arn', forceNewDeployment: false, - enableECSManagedTags: false + enableECSManagedTags: false, + propagateTags: 'NONE' }); expect(waitUntilServicesStable).toHaveBeenCalledTimes(0); expect(core.info).toBeCalledWith("Deployment started. Watch this deployment's progress in the Amazon ECS console: https://fake-region.console.aws.amazon.com/ecs/v2/clusters/cluster-789/services/service-456/events?region=fake-region"); @@ -215,7 +216,8 @@ describe('Deploy to ECS', () => { service: 'service-456', taskDefinition: 'task:def:arn', forceNewDeployment: false, - enableECSManagedTags: false + enableECSManagedTags: false, + propagateTags: 'NONE' }); expect(waitUntilServicesStable).toHaveBeenCalledTimes(0); expect(core.info).toBeCalledWith("Deployment started. Watch this deployment's progress in the Amazon ECS console: https://fake-region.console.aws.amazon.com/ecs/v2/clusters/cluster-789/services/service-456/events?region=fake-region"); @@ -711,6 +713,8 @@ describe('Deploy to ECS', () => { .mockReturnValueOnce('') // run-task .mockReturnValueOnce('') // desired count .mockReturnValueOnce('') // enable-ecs-managed-tags + .mockReturnValueOnce('') // propagate-task + .mockReturnValueOnce('') // run-task-tags .mockReturnValueOnce('/hello/appspec.json') // codedeploy-appspec .mockReturnValueOnce('MyApplication') // codedeploy-application .mockReturnValueOnce('MyDeploymentGroup'); // codedeploy-deployment-group @@ -948,7 +952,8 @@ describe('Deploy to ECS', () => { service: 'service-456', taskDefinition: 'task:def:arn', forceNewDeployment: false, - enableECSManagedTags: false + enableECSManagedTags: false, + propagateTags: 'NONE' }); expect(waitUntilServicesStable).toHaveBeenNthCalledWith( 1, @@ -988,7 +993,8 @@ describe('Deploy to ECS', () => { service: 'service-456', taskDefinition: 'task:def:arn', forceNewDeployment: false, - enableECSManagedTags: false + enableECSManagedTags: false, + propagateTags: 'NONE' }); expect(waitUntilServicesStable).toHaveBeenNthCalledWith( 1, @@ -1028,7 +1034,8 @@ describe('Deploy to ECS', () => { service: 'service-456', taskDefinition: 'task:def:arn', forceNewDeployment: false, - enableECSManagedTags: false + enableECSManagedTags: false, + propagateTags: 'NONE' }); expect(waitUntilServicesStable).toHaveBeenNthCalledWith( 1, @@ -1070,7 +1077,8 @@ describe('Deploy to ECS', () => { service: 'service-456', taskDefinition: 'task:def:arn', forceNewDeployment: true, - enableECSManagedTags: false + enableECSManagedTags: false, + propagateTags: 'NONE' }); }); @@ -1095,7 +1103,8 @@ describe('Deploy to ECS', () => { service: 'service-456', taskDefinition: 'task:def:arn', forceNewDeployment: false, - enableECSManagedTags: false + enableECSManagedTags: false, + propagateTags: 'NONE' }); }); @@ -1122,6 +1131,8 @@ describe('Deploy to ECS', () => { .mockReturnValueOnce('') // wait-for-service-stability .mockReturnValueOnce('') // wait-for-minutes .mockReturnValueOnce('') // enable-ecs-managed-tags + .mockReturnValueOnce('') // propagate-tags + .mockReturnValueOnce('') // run-task-tags .mockReturnValueOnce('') // force-new-deployment .mockReturnValueOnce('') // desired-count .mockReturnValueOnce('true'); // run-task @@ -1139,7 +1150,8 @@ describe('Deploy to ECS', () => { taskDefinition: 'task:def:arn', overrides: {"containerOverrides": []}, networkConfiguration: null, - enableECSManagedTags: false + enableECSManagedTags: false, + tags: [] }); expect(core.setOutput).toHaveBeenNthCalledWith(2, 'run-task-arn', ["arn:aws:ecs:fake-region:account_id:task/arn"]); @@ -1155,7 +1167,9 @@ describe('Deploy to ECS', () => { .mockReturnValueOnce('') // wait-for-minutes .mockReturnValueOnce('') // force-new-deployment .mockReturnValueOnce('') // desired-count - .mockReturnValueOnce('true') // enable-ecs-managed-tags + .mockReturnValueOnce('false') // enable-ecs-managed-tags + .mockReturnValueOnce('') // propagate-tags + .mockReturnValueOnce('') // run-task-tags .mockReturnValueOnce('true') // run-task .mockReturnValueOnce('false') // wait-for-task-stopped .mockReturnValueOnce('someJoe') // run-task-started-by @@ -1176,7 +1190,8 @@ describe('Deploy to ECS', () => { taskDefinition: 'task:def:arn', overrides: { containerOverrides: [{ name: 'someapp', command: 'somecmd' }] }, networkConfiguration: { awsvpcConfiguration: { subnets: ['a', 'b'], securityGroups: ['c', 'd'], assignPublicIp: "DISABLED" } }, - enableECSManagedTags: true + enableECSManagedTags: false, + tags: [] }); expect(core.setOutput).toHaveBeenNthCalledWith(2, 'run-task-arn', ["arn:aws:ecs:fake-region:account_id:task/arn"]); }); @@ -1192,6 +1207,8 @@ describe('Deploy to ECS', () => { .mockReturnValueOnce('') // force-new-deployment .mockReturnValueOnce('') // desired-count .mockReturnValueOnce('') // enable-ecs-managed-tags + .mockReturnValueOnce('') // propagate-tags + .mockReturnValueOnce('') // run-task-tags .mockReturnValueOnce('true') // run-task .mockReturnValueOnce('false') // wait-for-task-stopped .mockReturnValueOnce('someJoe') // run-task-started-by @@ -1214,7 +1231,8 @@ describe('Deploy to ECS', () => { service: 'service-456', taskDefinition: 'task:def:arn', forceNewDeployment: false, - enableECSManagedTags: false + enableECSManagedTags: false, + propagateTags: 'NONE', }); expect(mockRunTask).toHaveBeenCalledWith({ startedBy: 'someJoe', @@ -1223,7 +1241,8 @@ describe('Deploy to ECS', () => { launchType: 'EC2', overrides: { containerOverrides: [{ name: 'someapp', command: 'somecmd' }] }, networkConfiguration: { awsvpcConfiguration: { subnets: ['a', 'b'], securityGroups: ['c', 'd'], assignPublicIp: "DISABLED" } }, - enableECSManagedTags: false + enableECSManagedTags: false, + tags: [] }); expect(core.setOutput).toHaveBeenNthCalledWith(2, 'run-task-arn', ["arn:aws:ecs:fake-region:account_id:task/arn"]); }); @@ -1239,6 +1258,8 @@ describe('Deploy to ECS', () => { .mockReturnValueOnce('') // force-new-deployment .mockReturnValueOnce('') // desired-count .mockReturnValueOnce('') // enable-ecs-managed-tags + .mockReturnValueOnce('') // propagate-tags + .mockReturnValueOnce('') // run-task-tags .mockReturnValueOnce('true') // run-task .mockReturnValueOnce('true'); // wait-for-task-stopped @@ -1263,6 +1284,8 @@ describe('Deploy to ECS', () => { .mockReturnValueOnce('') // enable-ecs-managed-tags .mockReturnValueOnce('') // force-new-deployment .mockReturnValueOnce('') // desired-count + .mockReturnValueOnce('') // propagate-tags + .mockReturnValueOnce('') // run-task-tags .mockReturnValueOnce('true') // run-task .mockReturnValueOnce('true') // wait-for-task-stopped .mockReturnValueOnce('someJoe') // run-task-started-by @@ -1280,7 +1303,8 @@ describe('Deploy to ECS', () => { launchType: 'EC2', overrides: { containerOverrides: [] }, networkConfiguration: null, - enableECSManagedTags: false + enableECSManagedTags: false, + tags: [] }); }); @@ -1294,6 +1318,8 @@ describe('Deploy to ECS', () => { .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 @@ -1336,6 +1362,8 @@ describe('Deploy to ECS', () => { .mockReturnValueOnce('') // force-new-deployment .mockReturnValueOnce('') // desired-count .mockReturnValueOnce('') // enable-ecs-managed-tags + .mockReturnValueOnce('') // propagate-tags + .mockReturnValueOnce('') // run-task-tags .mockReturnValueOnce('true') // run-task .mockReturnValueOnce('false'); // wait-for-task-stopped @@ -1446,4 +1474,36 @@ 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('propagate service tags from service and enable ecs managed tags', async () => { + 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('') // desired-count + .mockReturnValueOnce('true') // enable-ecs-managed-tags + .mockReturnValueOnce('SERVICE'); // propagate-tags + + 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(mockEcsUpdateService).toHaveBeenNthCalledWith(1, { + cluster: 'cluster-789', + service: 'service-456', + taskDefinition: 'task:def:arn', + forceNewDeployment: false, + enableECSManagedTags: true, + propagateTags: 'SERVICE' + }); + }); }); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b43481891..7a50c47d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,9 +15,9 @@ "yaml": "^2.5.0" }, "devDependencies": { - "@eslint/js": "^9.9.0", + "@eslint/js": "^9.9.1", "@vercel/ncc": "^0.38.1", - "eslint": "^9.9.0", + "eslint": "^9.9.1", "globals": "^15.9.0", "jest": "^29.7.0" } @@ -1391,9 +1391,9 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", - "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", "dev": true, "dependencies": { "@eslint/object-schema": "^2.1.4", @@ -1458,9 +1458,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.0.tgz", - "integrity": "sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==", + "version": "9.9.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.1.tgz", + "integrity": "sha512-xIDQRsfg5hNBqHz04H1R3scSVwmI+KUbqjsQKHKQ1DAUSaUjYPReZZmS/5PNiKu1fUvzDd6H7DEDKACSEhu+TQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3186,16 +3186,16 @@ } }, "node_modules/eslint": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.9.0.tgz", - "integrity": "sha512-JfiKJrbx0506OEerjK2Y1QlldtBxkAlLxT5OEcRF8uaQ86noDe2k31Vw9rnSWv+MXZHj7OOUV/dA0AhdLFcyvA==", + "version": "9.9.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.9.1.tgz", + "integrity": "sha512-dHvhrbfr4xFQ9/dq+jcVneZMyRYLjggWjk6RVsIiHsP8Rz6yZ8LvZ//iU4TrZF+SXWG+JkNF2OyiZRvzgRDqMg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.11.0", - "@eslint/config-array": "^0.17.1", + "@eslint/config-array": "^0.18.0", "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.9.0", + "@eslint/js": "9.9.1", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.3.0", "@nodelib/fs.walk": "^1.2.8", @@ -3272,6 +3272,15 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/@eslint/js": { + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.0.tgz", + "integrity": "sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", diff --git a/package.json b/package.json index e4eeec037..c1d04b19b 100644 --- a/package.json +++ b/package.json @@ -31,9 +31,9 @@ "yaml": "^2.5.0" }, "devDependencies": { - "@eslint/js": "^9.9.0", + "@eslint/js": "^9.9.1", "@vercel/ncc": "^0.38.1", - "eslint": "^9.9.0", + "eslint": "^9.9.1", "globals": "^15.9.0", "jest": "^29.7.0" } From d49b663ef5ba4672742d25522c27f1e954935d5e Mon Sep 17 00:00:00 2001 From: Guillaume Delacour Date: Fri, 30 Aug 2024 18:07:03 +0200 Subject: [PATCH 2/3] tags input get in runTask --- dist/index.js | 8 ++++---- index.js | 8 ++++---- index.test.js | 7 ------- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/dist/index.js b/dist/index.js index a16872f0b..5d045ce50 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, runTaskTags) { +async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags) { core.info('Running task') const waitForTask = core.getInput('wait-for-task-stopped', { required: false }) || 'false'; @@ -37,6 +37,7 @@ async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSMa const securityGroupIds = core.getInput('run-task-security-groups', { required: false }) || ''; const containerOverrides = JSON.parse(core.getInput('run-task-container-overrides', { required: false }) || '[]'); const assignPublicIP = core.getInput('run-task-assign-public-IP', { required: false }) || 'DISABLED'; + const tags = JSON.parse(core.getInput('run-task-tags', { required: false }) || '[]'); let awsvpcConfiguration = {} @@ -62,7 +63,7 @@ async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSMa launchType: launchType, networkConfiguration: Object.keys(awsvpcConfiguration).length === 0 ? null : { awsvpcConfiguration: awsvpcConfiguration }, enableECSManagedTags: enableECSManagedTags, - tags: runTaskTags + tags: tags }); core.debug(`Run task response ${JSON.stringify(runTaskResponse)}`) @@ -404,7 +405,6 @@ async function run() { const enableECSManagedTagsInput = core.getInput('enable-ecs-managed-tags', { required: false }) || 'false'; const enableECSManagedTags = enableECSManagedTagsInput.toLowerCase() === 'true'; const propagateTags = core.getInput('propagate-tags', { required: false }) || 'NONE'; - const runTaskTags = JSON.parse(core.getInput('run-task-tags', { required: false }) || '[]'); // Register the task definition core.debug('Registering the task definition'); @@ -432,7 +432,7 @@ async function run() { core.debug(`shouldRunTask: ${shouldRunTask}`); if (shouldRunTask) { core.debug("Running ad-hoc task..."); - await runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags, runTaskTags); + await runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags); } // Update the service with the new task definition diff --git a/index.js b/index.js index 9fc82e8af..8e9f90d9b 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, runTaskTags) { +async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags) { core.info('Running task') const waitForTask = core.getInput('wait-for-task-stopped', { required: false }) || 'false'; @@ -31,6 +31,7 @@ async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSMa const securityGroupIds = core.getInput('run-task-security-groups', { required: false }) || ''; const containerOverrides = JSON.parse(core.getInput('run-task-container-overrides', { required: false }) || '[]'); const assignPublicIP = core.getInput('run-task-assign-public-IP', { required: false }) || 'DISABLED'; + const tags = JSON.parse(core.getInput('run-task-tags', { required: false }) || '[]'); let awsvpcConfiguration = {} @@ -56,7 +57,7 @@ async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSMa launchType: launchType, networkConfiguration: Object.keys(awsvpcConfiguration).length === 0 ? null : { awsvpcConfiguration: awsvpcConfiguration }, enableECSManagedTags: enableECSManagedTags, - tags: runTaskTags + tags: tags }); core.debug(`Run task response ${JSON.stringify(runTaskResponse)}`) @@ -398,7 +399,6 @@ async function run() { const enableECSManagedTagsInput = core.getInput('enable-ecs-managed-tags', { required: false }) || 'false'; const enableECSManagedTags = enableECSManagedTagsInput.toLowerCase() === 'true'; const propagateTags = core.getInput('propagate-tags', { required: false }) || 'NONE'; - const runTaskTags = JSON.parse(core.getInput('run-task-tags', { required: false }) || '[]'); // Register the task definition core.debug('Registering the task definition'); @@ -426,7 +426,7 @@ async function run() { core.debug(`shouldRunTask: ${shouldRunTask}`); if (shouldRunTask) { core.debug("Running ad-hoc task..."); - await runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags, runTaskTags); + await runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags); } // Update the service with the new task definition diff --git a/index.test.js b/index.test.js index a5e620d7a..852a6f588 100644 --- a/index.test.js +++ b/index.test.js @@ -714,7 +714,6 @@ describe('Deploy to ECS', () => { .mockReturnValueOnce('') // desired count .mockReturnValueOnce('') // enable-ecs-managed-tags .mockReturnValueOnce('') // propagate-task - .mockReturnValueOnce('') // run-task-tags .mockReturnValueOnce('/hello/appspec.json') // codedeploy-appspec .mockReturnValueOnce('MyApplication') // codedeploy-application .mockReturnValueOnce('MyDeploymentGroup'); // codedeploy-deployment-group @@ -1132,7 +1131,6 @@ describe('Deploy to ECS', () => { .mockReturnValueOnce('') // wait-for-minutes .mockReturnValueOnce('') // enable-ecs-managed-tags .mockReturnValueOnce('') // propagate-tags - .mockReturnValueOnce('') // run-task-tags .mockReturnValueOnce('') // force-new-deployment .mockReturnValueOnce('') // desired-count .mockReturnValueOnce('true'); // run-task @@ -1169,7 +1167,6 @@ describe('Deploy to ECS', () => { .mockReturnValueOnce('') // desired-count .mockReturnValueOnce('false') // enable-ecs-managed-tags .mockReturnValueOnce('') // propagate-tags - .mockReturnValueOnce('') // run-task-tags .mockReturnValueOnce('true') // run-task .mockReturnValueOnce('false') // wait-for-task-stopped .mockReturnValueOnce('someJoe') // run-task-started-by @@ -1208,7 +1205,6 @@ describe('Deploy to ECS', () => { .mockReturnValueOnce('') // desired-count .mockReturnValueOnce('') // enable-ecs-managed-tags .mockReturnValueOnce('') // propagate-tags - .mockReturnValueOnce('') // run-task-tags .mockReturnValueOnce('true') // run-task .mockReturnValueOnce('false') // wait-for-task-stopped .mockReturnValueOnce('someJoe') // run-task-started-by @@ -1259,7 +1255,6 @@ describe('Deploy to ECS', () => { .mockReturnValueOnce('') // desired-count .mockReturnValueOnce('') // enable-ecs-managed-tags .mockReturnValueOnce('') // propagate-tags - .mockReturnValueOnce('') // run-task-tags .mockReturnValueOnce('true') // run-task .mockReturnValueOnce('true'); // wait-for-task-stopped @@ -1285,7 +1280,6 @@ describe('Deploy to ECS', () => { .mockReturnValueOnce('') // force-new-deployment .mockReturnValueOnce('') // desired-count .mockReturnValueOnce('') // propagate-tags - .mockReturnValueOnce('') // run-task-tags .mockReturnValueOnce('true') // run-task .mockReturnValueOnce('true') // wait-for-task-stopped .mockReturnValueOnce('someJoe') // run-task-started-by @@ -1363,7 +1357,6 @@ describe('Deploy to ECS', () => { .mockReturnValueOnce('') // desired-count .mockReturnValueOnce('') // enable-ecs-managed-tags .mockReturnValueOnce('') // propagate-tags - .mockReturnValueOnce('') // run-task-tags .mockReturnValueOnce('true') // run-task .mockReturnValueOnce('false'); // wait-for-task-stopped From e8c61f2740a6f445e712bc8b7397ff966e1c50af Mon Sep 17 00:00:00 2001 From: Guillaume Delacour Date: Tue, 3 Sep 2024 16:53:34 +0200 Subject: [PATCH 3/3] Add run-task-tags option in existing test --- index.test.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/index.test.js b/index.test.js index 852a6f588..2cae5c1b9 100644 --- a/index.test.js +++ b/index.test.js @@ -1173,7 +1173,9 @@ describe('Deploy to ECS', () => { .mockReturnValueOnce('EC2') // run-task-launch-type .mockReturnValueOnce('a,b') // run-task-subnet-ids .mockReturnValueOnce('c,d') // run-task-security-group-ids - .mockReturnValueOnce(JSON.stringify([{ name: 'someapp', command: 'somecmd' }])); // run-task-container-overrides + .mockReturnValueOnce(JSON.stringify([{ name: 'someapp', command: 'somecmd' }])) // run-task-container-overrides + .mockReturnValueOnce('') // run-task-assign-public-IP + .mockReturnValueOnce('[{"key": "project", "value": "myproject"}]'); // run-task-tags await run(); expect(core.setFailed).toHaveBeenCalledTimes(0); @@ -1188,7 +1190,7 @@ describe('Deploy to ECS', () => { overrides: { containerOverrides: [{ name: 'someapp', command: 'somecmd' }] }, networkConfiguration: { awsvpcConfiguration: { subnets: ['a', 'b'], securityGroups: ['c', 'd'], assignPublicIp: "DISABLED" } }, enableECSManagedTags: false, - tags: [] + tags: [{"key": "project", "value": "myproject"}] }); expect(core.setOutput).toHaveBeenNthCalledWith(2, 'run-task-arn', ["arn:aws:ecs:fake-region:account_id:task/arn"]); });