From 33506196c479e316f03f0d21fe59c1e4e9126a67 Mon Sep 17 00:00:00 2001 From: Milton Neto Date: Fri, 20 Oct 2023 22:03:05 -0300 Subject: [PATCH 1/2] feat(task-definition-arn): Add support for direct ARN in task definition input parameter. --- index.js | 48 ++++++++++++++++++++++++++++++------------------ index.test.js | 15 +++++++++++++++ 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/index.js b/index.js index 7f759a088..6e445a725 100644 --- a/index.js +++ b/index.js @@ -257,7 +257,7 @@ async function run() { }); // Get inputs - const taskDefinitionFile = core.getInput('task-definition', { required: true }); + const taskDefinitionContent = core.getInput('task-definition', { required: true }); const service = core.getInput('service', { required: false }); const cluster = core.getInput('cluster', { required: false }); const waitForService = core.getInput('wait-for-service-stability', { required: false }); @@ -269,23 +269,35 @@ async function run() { const forceNewDeployInput = core.getInput('force-new-deployment', { required: false }) || 'false'; const forceNewDeployment = forceNewDeployInput.toLowerCase() === 'true'; - // Register the task definition - core.debug('Registering the task definition'); - const taskDefPath = path.isAbsolute(taskDefinitionFile) ? - taskDefinitionFile : - path.join(process.env.GITHUB_WORKSPACE, taskDefinitionFile); - const fileContents = fs.readFileSync(taskDefPath, 'utf8'); - const taskDefContents = maintainValidObjects(removeIgnoredAttributes(cleanNullKeys(yaml.parse(fileContents)))); - let registerResponse; - try { - registerResponse = await ecs.registerTaskDefinition(taskDefContents).promise(); - } catch (error) { - core.setFailed("Failed to register task definition in ECS: " + error.message); - core.debug("Task definition contents:"); - core.debug(JSON.stringify(taskDefContents, undefined, 4)); - throw(error); - } - const taskDefArn = registerResponse.taskDefinition.taskDefinitionArn; + let taskDefArn = null; + + // Of taskDefContent starts with arn: then we assume it is a task definition ARN + if (taskDefinitionContent.startsWith("arn:")) { + taskDefArn = taskDefinitionContent; + + // + // Else we assume it is a task definition file + } else { + const taskDefinitionFile = taskDefinitionContent; + + core.debug('Registering the task definition'); + const taskDefPath = path.isAbsolute(taskDefinitionFile) ? + taskDefinitionFile : + path.join(process.env.GITHUB_WORKSPACE, taskDefinitionFile); + const fileContents = fs.readFileSync(taskDefPath, 'utf8'); + const taskDefContents = maintainValidObjects(removeIgnoredAttributes(cleanNullKeys(yaml.parse(fileContents)))); + let registerResponse; + try { + registerResponse = await ecs.registerTaskDefinition(taskDefContents).promise(); + } catch (error) { + core.setFailed("Failed to register task definition in ECS: " + error.message); + core.debug("Task definition contents:"); + core.debug(JSON.stringify(taskDefContents, undefined, 4)); + throw(error); + } + taskDefArn = registerResponse.taskDefinition.taskDefinitionArn; + } + core.setOutput('task-definition-arn', taskDefArn); // Update the service with the new task definition diff --git a/index.test.js b/index.test.js index a032634b8..6307f4a16 100644 --- a/index.test.js +++ b/index.test.js @@ -16,6 +16,7 @@ const mockEcsWaiter = jest.fn(); const mockCodeDeployCreateDeployment = jest.fn(); const mockCodeDeployGetDeploymentGroup = jest.fn(); const mockCodeDeployWaiter = jest.fn(); + let config = { region: 'fake-region', }; @@ -151,6 +152,20 @@ describe('Deploy to ECS', () => { }); }); + test('uses task definition ARN if taskDefinitionContent starts with arn:', async () => { + core.getInput = jest + .fn() + .mockReturnValueOnce('arn:aws:ecs:region:account-id:task-definition/task-name:task-revision') // task-definition + .mockReturnValueOnce('service-456') // service + .mockReturnValueOnce('cluster-789'); // cluster + + await run(); + + expect(core.setFailed).toHaveBeenCalledTimes(0); + expect(mockEcsRegisterTaskDef).toHaveBeenCalledTimes(0); // Importante, não deve chamar a função de registro + expect(core.setOutput).toHaveBeenNthCalledWith(1, 'task-definition-arn', 'arn:aws:ecs:region:account-id:task-definition/task-name:task-revision'); + }); + test('registers the task definition contents and updates the service', async () => { await run(); expect(core.setFailed).toHaveBeenCalledTimes(0); From 2fbf82a7f75b96e0bacdba7a972607c956582a95 Mon Sep 17 00:00:00 2001 From: Milton Neto Date: Fri, 20 Oct 2023 22:21:23 -0300 Subject: [PATCH 2/2] feat(README.md): Improvements to README.md to explain the option to directly pass the ARN. --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index b05d5060f..15532ecec 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,19 @@ The task definition file can be updated prior to deployment with the new contain wait-for-service-stability: true ``` +If you're using CloudFormation tools such as AWS CDK, Serverless Framework, or others to construct your task definition, you can directly pass the ARN of the task definition. For example: +```yaml + - name: Deploy Amazon ECS task definition + uses: aws-actions/amazon-ecs-deploy-task-definition@v1 + with: + task-definition: arn:aws:ecs:::task-definition/: + service: my-service + cluster: my-cluster + wait-for-service-stability: true + +``` + + ## 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.