From 0d0e316994573463025ff7a297846e165783ed0a Mon Sep 17 00:00:00 2001 From: Henry Soule Date: Thu, 23 Feb 2023 13:26:43 -0500 Subject: [PATCH 01/25] add network configuration input --- action.yml | 3 +++ index.js | 3 +++ 2 files changed, 6 insertions(+) diff --git a/action.yml b/action.yml index 424dde637..abc5408b8 100644 --- a/action.yml +++ b/action.yml @@ -13,6 +13,9 @@ inputs: count: description: "The count of tasks to run. Will default to the 1" required: true + networkConfiguration: + description: "The network configuration object" + required: true started-by: description: "The value of the task started-by" required: false diff --git a/index.js b/index.js index b07b6f216..7128870cd 100644 --- a/index.js +++ b/index.js @@ -88,6 +88,7 @@ async function run() { const taskDefinitionFile = core.getInput('task-definition', { required: true }); const cluster = core.getInput('cluster', { required: false }); const count = core.getInput('count', { required: true }); + const networkConfiguration = core.getInput('network-configuration', { required: true }); const startedBy = core.getInput('started-by', { required: false }) || agent; const waitForFinish = core.getInput('wait-for-finish', { required: false }) || false; let waitForMinutes = parseInt(core.getInput('wait-for-minutes', { required: false })) || 30; @@ -121,6 +122,7 @@ async function run() { cluster: clusterName, taskDefinition: taskDefArn, count: count, + networkConfiguration: networkConfiguration, startedBy: startedBy })}`) @@ -128,6 +130,7 @@ async function run() { cluster: clusterName, taskDefinition: taskDefArn, count: count, + networkConfiguration: networkConfiguration, startedBy: startedBy }).promise(); From d116e4f3e814012b69d039e3d809ce875986f34e Mon Sep 17 00:00:00 2001 From: Henry Soule Date: Fri, 24 Feb 2023 10:29:17 -0500 Subject: [PATCH 02/25] temporarily remove network configuration --- index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 7128870cd..ec54a118d 100644 --- a/index.js +++ b/index.js @@ -88,7 +88,7 @@ async function run() { const taskDefinitionFile = core.getInput('task-definition', { required: true }); const cluster = core.getInput('cluster', { required: false }); const count = core.getInput('count', { required: true }); - const networkConfiguration = core.getInput('network-configuration', { required: true }); + // const networkConfiguration = core.getInput('network-configuration', { required: true }); const startedBy = core.getInput('started-by', { required: false }) || agent; const waitForFinish = core.getInput('wait-for-finish', { required: false }) || false; let waitForMinutes = parseInt(core.getInput('wait-for-minutes', { required: false })) || 30; @@ -122,7 +122,7 @@ async function run() { cluster: clusterName, taskDefinition: taskDefArn, count: count, - networkConfiguration: networkConfiguration, + // networkConfiguration: networkConfiguration, startedBy: startedBy })}`) @@ -130,7 +130,7 @@ async function run() { cluster: clusterName, taskDefinition: taskDefArn, count: count, - networkConfiguration: networkConfiguration, + // networkConfiguration: networkConfiguration, startedBy: startedBy }).promise(); From 87e39c7eeb9370e0f6820b25c4f314a5c4b62a68 Mon Sep 17 00:00:00 2001 From: Henry Soule Date: Fri, 24 Feb 2023 12:12:14 -0500 Subject: [PATCH 03/25] update ignore attributes --- index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index ec54a118d..5d258dbfe 100644 --- a/index.js +++ b/index.js @@ -10,7 +10,9 @@ const IGNORED_TASK_DEFINITION_ATTRIBUTES = [ 'taskDefinitionArn', 'requiresAttributes', 'revision', - 'status' + 'status', + 'registeredAt', + 'registeredBy', ]; const WAIT_DEFAULT_DELAY_SEC = 5; @@ -63,6 +65,7 @@ function cleanNullKeys(obj) { } function removeIgnoredAttributes(taskDef) { + core.info(IGNORED_TASK_DEFINITION_ATTRIBUTES) for (var attribute of IGNORED_TASK_DEFINITION_ATTRIBUTES) { if (taskDef[attribute]) { core.warning(`Ignoring property '${attribute}' in the task definition file. ` + From 4f9a202c8a116bb347c1561892e415b091944520 Mon Sep 17 00:00:00 2001 From: Henry Soule Date: Fri, 24 Feb 2023 15:54:57 -0500 Subject: [PATCH 04/25] update actions and package.json --- .github/workflows/check.yml | 16 -- .github/workflows/package.yml | 18 ++- index.test.js | 274 ---------------------------------- package.json | 3 +- 4 files changed, 12 insertions(+), 299 deletions(-) delete mode 100644 .github/workflows/check.yml delete mode 100644 index.test.js diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml deleted file mode 100644 index b746ca43c..000000000 --- a/.github/workflows/check.yml +++ /dev/null @@ -1,16 +0,0 @@ -on: - [pull_request] - -name: Check - -jobs: - check: - name: Run Unit Tests - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Run tests - run: | - npm ci - npm test diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index c6d8e85c5..7c494b620 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -2,6 +2,11 @@ on: push: branches: - master + paths-ignore: + - "**.md" + pull_request: + paths-ignore: + - "**.md" name: Package @@ -17,11 +22,10 @@ jobs: - name: Package run: | npm ci - npm test npm run package - - name: Commit - run: | - git config --global user.name "GitHub Actions" - git add dist/ - git commit -m "chore: Update dist" || echo "No changes to commit" - git push origin HEAD:master + # - name: Commit + # run: | + # git config --global user.name "GitHub Actions" + # git add dist/ + # git commit -m "chore: Update dist" || echo "No changes to commit" + # git push origin HEAD:master diff --git a/index.test.js b/index.test.js deleted file mode 100644 index 9eaec9ae2..000000000 --- a/index.test.js +++ /dev/null @@ -1,274 +0,0 @@ -const run = require('.'); -const core = require('@actions/core'); -const fs = require('fs'); -const path = require('path'); - -jest.mock('@actions/core'); -jest.mock('fs'); - -const mockEcsRegisterTaskDef = jest.fn(); -const mockEcsDescribeTasks = jest.fn(); -const mockRunTasks = jest.fn(); -const mockEcsWaiter = jest.fn(); -jest.mock('aws-sdk', () => { - return { - config: { - region: 'fake-region' - }, - ECS: jest.fn(() => ({ - registerTaskDefinition: mockEcsRegisterTaskDef, - describeTasks: mockEcsDescribeTasks, - runTask: mockRunTasks, - waitFor: mockEcsWaiter - })) - }; -}); - -describe('Deploy to ECS', () => { - - beforeEach(() => { - jest.clearAllMocks(); - - core.getInput = jest - .fn() - .mockReturnValueOnce('task-definition.json') // task-definition - .mockReturnValueOnce('cluster-789') // cluster - .mockReturnValueOnce('1') // count - .mockReturnValueOnce('amazon-ecs-run-task-for-github-actions'); // started-by - - process.env = Object.assign(process.env, { GITHUB_WORKSPACE: __dirname }); - - fs.readFileSync.mockImplementation((pathInput, encoding) => { - if (encoding != 'utf8') { - throw new Error(`Wrong encoding ${encoding}`); - } - - if (pathInput == path.join(process.env.GITHUB_WORKSPACE, 'task-definition.json')) { - return JSON.stringify({ family: 'task-def-family' }); - } - - throw new Error(`Unknown path ${pathInput}`); - }); - - //runTask - //describeTask - - mockEcsRegisterTaskDef.mockImplementation(() => { - return { - promise() { - return Promise.resolve({ taskDefinition: { taskDefinitionArn: 'task:def:arn' } }); - } - }; - }); - - mockEcsDescribeTasks.mockImplementation(() => { - return { - promise() { - return Promise.resolve({ - failures: [], - tasks: [ - { - containers: [ - { - lastStatus: "RUNNING", - exitCode: 0, - reason: '', - taskArn: "arn:aws:ecs:fake-region:account_id:task/arn" - } - ], - desiredStatus: "RUNNING", - lastStatus: "RUNNING", - taskArn: "arn:aws:ecs:fake-region:account_id:task/arn" - } - ] - }); - } - }; - }); - - mockRunTasks.mockImplementation(() => { - return { - promise() { - return Promise.resolve({ - failures: [], - tasks: [ - { - containers: [ - { - lastStatus: "RUNNING", - exitCode: 0, - reason: '', - taskArn: "arn:aws:ecs:fake-region:account_id:task/arn" - } - ], - desiredStatus: "RUNNING", - lastStatus: "RUNNING", - taskArn: "arn:aws:ecs:fake-region:account_id:task/arn" - // taskDefinitionArn: "arn:aws:ecs:::task-definition/amazon-ecs-sample:1" - } - ] - }); - } - }; - }); - - mockEcsWaiter.mockImplementation(() => { - return { - promise() { - return Promise.resolve({}); - } - }; - }); - }); - - test('registers the task definition contents and runs the task', async () => { - 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(mockRunTasks).toHaveBeenNthCalledWith(1, { - cluster: 'cluster-789', - taskDefinition: 'task:def:arn', - count: '1', - startedBy: 'amazon-ecs-run-task-for-github-actions' - }); - expect(mockEcsWaiter).toHaveBeenCalledTimes(0); - expect(core.setOutput).toBeCalledWith('task-arn', ['arn:aws:ecs:fake-region:account_id:task/arn']); - }); - - test('registers the task definition contents and waits for tasks to finish successfully', async () => { - core.getInput = jest - .fn() - .mockReturnValueOnce('task-definition.json') // task-definition - .mockReturnValueOnce('cluster-789') // cluster - .mockReturnValueOnce('1') // count - .mockReturnValueOnce('amazon-ecs-run-task-for-github-actions') // started-by - .mockReturnValueOnce('true'); // wait-for-finish - - 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(mockEcsDescribeTasks).toHaveBeenNthCalledWith(1, { - cluster: 'cluster-789', - tasks: ['arn:aws:ecs:fake-region:account_id:task/arn'] - }); - - expect(mockEcsWaiter).toHaveBeenCalledTimes(1); - - expect(core.info).toBeCalledWith("All tasks have exited successfully."); - }); - - test('cleans null keys out of the task definition contents', async () => { - fs.readFileSync.mockImplementation((pathInput, encoding) => { - if (encoding != 'utf8') { - throw new Error(`Wrong encoding ${encoding}`); - } - - return '{ "ipcMode": null, "family": "task-def-family" }'; - }); - - await run(); - expect(core.setFailed).toHaveBeenCalledTimes(0); - expect(mockEcsRegisterTaskDef).toHaveBeenNthCalledWith(1, { family: 'task-def-family'}); - }); - - test('cleans empty arrays out of the task definition contents', async () => { - fs.readFileSync.mockImplementation((pathInput, encoding) => { - if (encoding != 'utf8') { - throw new Error(`Wrong encoding ${encoding}`); - } - - return '{ "tags": [], "family": "task-def-family" }'; - }); - - await run(); - expect(core.setFailed).toHaveBeenCalledTimes(0); - expect(mockEcsRegisterTaskDef).toHaveBeenNthCalledWith(1, { family: 'task-def-family'}); - }); - - test('cleans empty strings and objects out of the task definition contents', async () => { - fs.readFileSync.mockImplementation((pathInput, encoding) => { - if (encoding != 'utf8') { - throw new Error(`Wrong encoding ${encoding}`); - } - - return ` - { - "memory": "", - "containerDefinitions": [ { - "name": "sample-container", - "logConfiguration": {}, - "repositoryCredentials": { "credentialsParameter": "" }, - "command": [ - "" - ], - "environment": [ - { - "name": "hello", - "value": "world" - }, - { - "name": "", - "value": "" - } - ], - "secretOptions": [ { - "name": "", - "valueFrom": "" - } ], - "cpu": 0, - "essential": false - } ], - "requiresCompatibilities": [ "EC2" ], - "family": "task-def-family" - } - `; - }); - - await run(); - expect(core.setFailed).toHaveBeenCalledTimes(0); - expect(mockEcsRegisterTaskDef).toHaveBeenNthCalledWith(1, { - family: 'task-def-family', - containerDefinitions: [ - { - name: 'sample-container', - cpu: 0, - essential: false, - environment: [{ - name: 'hello', - value: 'world' - }] - } - ], - requiresCompatibilities: [ 'EC2' ] - }); - }); - - test('cleans invalid keys out of the task definition contents', async () => { - fs.readFileSync.mockImplementation((pathInput, encoding) => { - if (encoding != 'utf8') { - throw new Error(`Wrong encoding ${encoding}`); - } - - return '{ "compatibilities": ["EC2"], "taskDefinitionArn": "arn:aws...:task-def-family:1", "family": "task-def-family", "revision": 1, "status": "ACTIVE" }'; - }); - - await run(); - expect(core.setFailed).toHaveBeenCalledTimes(0); - expect(mockEcsRegisterTaskDef).toHaveBeenNthCalledWith(1, { family: 'task-def-family'}); - }); - - test('error is caught if task def registration fails', async () => { - mockEcsRegisterTaskDef.mockImplementation(() => { - throw new Error("Could not parse"); - }); - - await run(); - - expect(core.setFailed).toHaveBeenCalledTimes(2); - expect(core.setFailed).toHaveBeenNthCalledWith(1, 'Failed to register task definition in ECS: Could not parse'); - expect(core.setFailed).toHaveBeenNthCalledWith(2, 'Could not parse'); - }); -}); diff --git a/package.json b/package.json index baa4590f6..60c69aadd 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,7 @@ "main": "index.js", "scripts": { "lint": "eslint **.js", - "package": "ncc build index.js -o dist", - "test": "eslint **.js && jest --coverage" + "package": "ncc build index.js -o dist" }, "repository": { "type": "git", From 54f1d2af2f5980adf7fa5b74b231abc8fad5b75e Mon Sep 17 00:00:00 2001 From: Henry Soule Date: Fri, 24 Feb 2023 15:54:57 -0500 Subject: [PATCH 05/25] update actions and package.json --- .github/workflows/package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 7c494b620..4700bd269 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -8,7 +8,7 @@ on: paths-ignore: - "**.md" -name: Package +name: Package Action jobs: check: From 697146e7f409d2388544723996a4b192d467a269 Mon Sep 17 00:00:00 2001 From: Henry Soule Date: Fri, 24 Feb 2023 15:54:57 -0500 Subject: [PATCH 06/25] update actions and package.json --- .github/workflows/package.yml | 1 + action.yml | 2 +- dist/index.js | 8 +++++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 4700bd269..90ea6e364 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -21,6 +21,7 @@ jobs: ref: master - name: Package run: | + node -v npm ci npm run package # - name: Commit diff --git a/action.yml b/action.yml index abc5408b8..915a655c2 100644 --- a/action.yml +++ b/action.yml @@ -31,5 +31,5 @@ outputs: task-arn: description: 'The ARN of the ECS task' runs: - using: 'node12' + using: 'node16' main: 'dist/index.js' diff --git a/dist/index.js b/dist/index.js index 2e70b39dc..33c141f36 100644 --- a/dist/index.js +++ b/dist/index.js @@ -143,7 +143,9 @@ const IGNORED_TASK_DEFINITION_ATTRIBUTES = [ 'taskDefinitionArn', 'requiresAttributes', 'revision', - 'status' + 'status', + 'registeredAt', + 'registeredBy', ]; const WAIT_DEFAULT_DELAY_SEC = 5; @@ -196,6 +198,7 @@ function cleanNullKeys(obj) { } function removeIgnoredAttributes(taskDef) { + core.info(IGNORED_TASK_DEFINITION_ATTRIBUTES) for (var attribute of IGNORED_TASK_DEFINITION_ATTRIBUTES) { if (taskDef[attribute]) { core.warning(`Ignoring property '${attribute}' in the task definition file. ` + @@ -221,6 +224,7 @@ async function run() { const taskDefinitionFile = core.getInput('task-definition', { required: true }); const cluster = core.getInput('cluster', { required: false }); const count = core.getInput('count', { required: true }); + // const networkConfiguration = core.getInput('network-configuration', { required: true }); const startedBy = core.getInput('started-by', { required: false }) || agent; const waitForFinish = core.getInput('wait-for-finish', { required: false }) || false; let waitForMinutes = parseInt(core.getInput('wait-for-minutes', { required: false })) || 30; @@ -254,6 +258,7 @@ async function run() { cluster: clusterName, taskDefinition: taskDefArn, count: count, + // networkConfiguration: networkConfiguration, startedBy: startedBy })}`) @@ -261,6 +266,7 @@ async function run() { cluster: clusterName, taskDefinition: taskDefArn, count: count, + // networkConfiguration: networkConfiguration, startedBy: startedBy }).promise(); From b136e0a071ec1ed6dd0d8ce1c840d168aca0bd9b Mon Sep 17 00:00:00 2001 From: Henry Soule Date: Fri, 24 Feb 2023 15:54:57 -0500 Subject: [PATCH 07/25] update actions and package.json --- .github/workflows/package.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 90ea6e364..d7f6dd9c1 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -19,6 +19,12 @@ jobs: uses: actions/checkout@v2 with: ref: master + + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: 16 + - name: Package run: | node -v From 941d3f2555e6be6325c39a1180fb91e4bda66658 Mon Sep 17 00:00:00 2001 From: Henry Soule Date: Tue, 28 Feb 2023 14:19:22 -0500 Subject: [PATCH 08/25] add network configuration to action --- action.yml | 9 ++++++--- index.js | 25 ++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/action.yml b/action.yml index 915a655c2..272f57522 100644 --- a/action.yml +++ b/action.yml @@ -13,9 +13,12 @@ inputs: count: description: "The count of tasks to run. Will default to the 1" required: true - networkConfiguration: - description: "The network configuration object" - required: true + security-groups: + description: "The array of security groups to set in the network configuration" + required: false + subnets: + description: "The array of subnets to set in the network configuration" + required: false started-by: description: "The value of the task started-by" required: false diff --git a/index.js b/index.js index 5d258dbfe..84c61c91d 100644 --- a/index.js +++ b/index.js @@ -65,7 +65,7 @@ function cleanNullKeys(obj) { } function removeIgnoredAttributes(taskDef) { - core.info(IGNORED_TASK_DEFINITION_ATTRIBUTES) + core.info(`ignoring attributes: ${IGNORED_TASK_DEFINITION_ATTRIBUTES}`); for (var attribute of IGNORED_TASK_DEFINITION_ATTRIBUTES) { if (taskDef[attribute]) { core.warning(`Ignoring property '${attribute}' in the task definition file. ` + @@ -87,11 +87,15 @@ async function run() { customUserAgent: agent }); + core.info("Getting inputs..."); + // Get inputs const taskDefinitionFile = core.getInput('task-definition', { required: true }); const cluster = core.getInput('cluster', { required: false }); const count = core.getInput('count', { required: true }); // const networkConfiguration = core.getInput('network-configuration', { required: true }); + const subnets = core.getInput('subnets', { required: false }) || []; + const securityGroups = core.getInput('security-groups', { required: false }) || []; const startedBy = core.getInput('started-by', { required: false }) || agent; const waitForFinish = core.getInput('wait-for-finish', { required: false }) || false; let waitForMinutes = parseInt(core.getInput('wait-for-minutes', { required: false })) || 30; @@ -121,11 +125,26 @@ async function run() { const clusterName = cluster ? cluster : 'default'; + const networkConfiguration = { + subnets: subnets, + securityGroups: securityGroups + } + + core.info(`Network Configuraiton: ${networkConfiguration}`) + core.debug(`Running task with ${JSON.stringify({ cluster: clusterName, taskDefinition: taskDefArn, count: count, - // networkConfiguration: networkConfiguration, + networkConfiguration: networkConfiguration, + startedBy: startedBy + })}`) + + core.info(`Running task with ${JSON.stringify({ + cluster: clusterName, + taskDefinition: taskDefArn, + count: count, + networkConfiguration: networkConfiguration, startedBy: startedBy })}`) @@ -133,7 +152,7 @@ async function run() { cluster: clusterName, taskDefinition: taskDefArn, count: count, - // networkConfiguration: networkConfiguration, + networkConfiguration: networkConfiguration, startedBy: startedBy }).promise(); From dde736484d1e3eaed5d4560bb1c8b45edf80744f Mon Sep 17 00:00:00 2001 From: Henry Soule Date: Tue, 28 Feb 2023 14:54:35 -0500 Subject: [PATCH 09/25] update package.yml --- .github/workflows/package.yml | 12 ++++++------ index.js | 7 ++++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index d7f6dd9c1..9acf2c033 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -30,9 +30,9 @@ jobs: node -v npm ci npm run package - # - name: Commit - # run: | - # git config --global user.name "GitHub Actions" - # git add dist/ - # git commit -m "chore: Update dist" || echo "No changes to commit" - # git push origin HEAD:master + - name: Commit + run: | + git config --global user.name "GitHub Actions" + git add dist/ + git commit -m "chore: Update dist" || echo "No changes to commit" + git push origin HEAD:master diff --git a/index.js b/index.js index 84c61c91d..69a566cb7 100644 --- a/index.js +++ b/index.js @@ -93,7 +93,6 @@ async function run() { const taskDefinitionFile = core.getInput('task-definition', { required: true }); const cluster = core.getInput('cluster', { required: false }); const count = core.getInput('count', { required: true }); - // const networkConfiguration = core.getInput('network-configuration', { required: true }); const subnets = core.getInput('subnets', { required: false }) || []; const securityGroups = core.getInput('security-groups', { required: false }) || []; const startedBy = core.getInput('started-by', { required: false }) || agent; @@ -126,8 +125,10 @@ async function run() { const clusterName = cluster ? cluster : 'default'; const networkConfiguration = { - subnets: subnets, - securityGroups: securityGroups + awsvpcConfiguration: { + subnets: subnets, + securityGroups: securityGroups + } } core.info(`Network Configuraiton: ${networkConfiguration}`) From 3d19be023dd777321bf3986438d2812d60097982 Mon Sep 17 00:00:00 2001 From: Henry Soule Date: Tue, 28 Feb 2023 15:30:51 -0500 Subject: [PATCH 10/25] add createArrayFromString function --- index.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 69a566cb7..fca638813 100644 --- a/index.js +++ b/index.js @@ -79,6 +79,10 @@ function removeIgnoredAttributes(taskDef) { return taskDef; } +function createArrayFromString(str) { + return str.split(','); +} + async function run() { try { const agent = 'amazon-ecs-run-task-for-github-actions' @@ -93,8 +97,8 @@ async function run() { const taskDefinitionFile = core.getInput('task-definition', { required: true }); const cluster = core.getInput('cluster', { required: false }); const count = core.getInput('count', { required: true }); - const subnets = core.getInput('subnets', { required: false }) || []; - const securityGroups = core.getInput('security-groups', { required: false }) || []; + const subnets = core.getInput('subnets', { required: false }) || ''; + const securityGroups = core.getInput('security-groups', { required: false }) || ''; const startedBy = core.getInput('started-by', { required: false }) || agent; const waitForFinish = core.getInput('wait-for-finish', { required: false }) || false; let waitForMinutes = parseInt(core.getInput('wait-for-minutes', { required: false })) || 30; @@ -126,8 +130,8 @@ async function run() { const networkConfiguration = { awsvpcConfiguration: { - subnets: subnets, - securityGroups: securityGroups + subnets: createArrayFromString(subnets), + securityGroups: createArrayFromString(securityGroups) } } From 340a137af06ef78ddd9d9052a1a42b9e36bb4a2e Mon Sep 17 00:00:00 2001 From: Henry Soule Date: Tue, 28 Feb 2023 21:15:40 -0500 Subject: [PATCH 11/25] specify launch type as fargate in runTask --- index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index fca638813..77832fe1e 100644 --- a/index.js +++ b/index.js @@ -158,7 +158,8 @@ async function run() { taskDefinition: taskDefArn, count: count, networkConfiguration: networkConfiguration, - startedBy: startedBy + startedBy: startedBy, + launchType: "FARGATE" }).promise(); core.debug(`Run task response ${JSON.stringify(runTaskResponse)}`) From 21e5beaf2f0b8b9d2ff28e1d64b35914925abefb Mon Sep 17 00:00:00 2001 From: Henry Soule Date: Wed, 1 Mar 2023 08:55:35 -0500 Subject: [PATCH 12/25] code cleanup in index.js --- action.yml | 6 +++--- index.js | 24 +++++++----------------- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/action.yml b/action.yml index 272f57522..5ebf60ce0 100644 --- a/action.yml +++ b/action.yml @@ -11,13 +11,13 @@ inputs: description: "The name of the ECS cluster. Will default to the 'default' cluster" required: true count: - description: "The count of tasks to run. Will default to the 1" + description: "The count of tasks to run. Will default to 1" required: true security-groups: - description: "The array of security groups to set in the network configuration" + description: "The array of security groups to set in the network configuration. Will default to an empty array." required: false subnets: - description: "The array of subnets to set in the network configuration" + description: "The array of subnets to set in the network configuration. Will default to an empty array." required: false started-by: description: "The value of the task started-by" diff --git a/index.js b/index.js index 77832fe1e..f61741260 100644 --- a/index.js +++ b/index.js @@ -65,13 +65,15 @@ function cleanNullKeys(obj) { } function removeIgnoredAttributes(taskDef) { - core.info(`ignoring attributes: ${IGNORED_TASK_DEFINITION_ATTRIBUTES}`); + if (IGNORED_TASK_DEFINITION_ATTRIBUTES.length > 0) { + core.warning(`Ignoring properties '${IGNORED_TASK_DEFINITION_ATTRIBUTES}' in the task definition file. ` + + 'These properties are returned by the Amazon ECS DescribeTaskDefinition API and may be shown in the ECS console, ' + + 'but they are not valid fields when registering a new task definition. ' + + 'These fields can be safely removed from your task definition file.'); + } + for (var attribute of IGNORED_TASK_DEFINITION_ATTRIBUTES) { if (taskDef[attribute]) { - core.warning(`Ignoring property '${attribute}' in the task definition file. ` + - 'This property is returned by the Amazon ECS DescribeTaskDefinition API and may be shown in the ECS console, ' + - 'but it is not a valid field when registering a new task definition. ' + - 'This field can be safely removed from your task definition file.'); delete taskDef[attribute]; } } @@ -91,8 +93,6 @@ async function run() { customUserAgent: agent }); - core.info("Getting inputs..."); - // Get inputs const taskDefinitionFile = core.getInput('task-definition', { required: true }); const cluster = core.getInput('cluster', { required: false }); @@ -135,8 +135,6 @@ async function run() { } } - core.info(`Network Configuraiton: ${networkConfiguration}`) - core.debug(`Running task with ${JSON.stringify({ cluster: clusterName, taskDefinition: taskDefArn, @@ -145,14 +143,6 @@ async function run() { startedBy: startedBy })}`) - core.info(`Running task with ${JSON.stringify({ - cluster: clusterName, - taskDefinition: taskDefArn, - count: count, - networkConfiguration: networkConfiguration, - startedBy: startedBy - })}`) - const runTaskResponse = await ecs.runTask({ cluster: clusterName, taskDefinition: taskDefArn, From 2eac7a670eb99ed234d243eab062158135f5b9e7 Mon Sep 17 00:00:00 2001 From: Henry Soule Date: Wed, 1 Mar 2023 12:55:27 -0500 Subject: [PATCH 13/25] update readme --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f8d792658..6ad53a4f6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## Amazon ECS "Run Task" Action for GitHub Actions -Runs an Amazon ECS task on ECS cluster. +Runs an Amazon ECS task on ECS cluster. This action was forked from [smitp/amazon-ecs-run-task](https://github.com/smitp/amazon-ecs-run-task). It has been amended to accept subnet ids and security groups as inputs. This enables the action to run tasks with `network_mode` set to `awsvpc`. When running this kind of task, the `runTask` function requires a `network_configuration` parameter with both subnet ids and security groups specified. **Table of Contents** @@ -26,11 +26,13 @@ Runs an Amazon ECS task on ECS cluster. task-definition: task-definition.json cluster: my-cluster count: 1 + subnets: subnet-1, subnet-2, subnet-3 + security-groups: sg-1, sg-2 started-by: github-actions-${{ github.actor }} wait-for-finish: true ``` -See [action.yml](action.yml) for the full documentation for this action's inputs and outputs. +`security-groups` and `subnets` can be single values or comma separated lists, such as in the example above. See [action.yml](action.yml) for the full documentation for this action's inputs and outputs. ### Task definition file From 9e51756b1b82976bd41eb5dc8f11ca4ad71f2f8b Mon Sep 17 00:00:00 2001 From: Henry Soule Date: Wed, 1 Mar 2023 15:50:03 -0500 Subject: [PATCH 14/25] update createArrayFromString function --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index f61741260..b14304984 100644 --- a/index.js +++ b/index.js @@ -82,7 +82,7 @@ function removeIgnoredAttributes(taskDef) { } function createArrayFromString(str) { - return str.split(','); + return str.split(/\s+/); } async function run() { From 8336a44f09b83e664d0ff7354e7d4b46896bef66 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 1 Mar 2023 20:50:48 +0000 Subject: [PATCH 15/25] chore: Update dist --- dist/index.js | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/dist/index.js b/dist/index.js index 33c141f36..005538335 100644 --- a/dist/index.js +++ b/dist/index.js @@ -198,13 +198,15 @@ function cleanNullKeys(obj) { } function removeIgnoredAttributes(taskDef) { - core.info(IGNORED_TASK_DEFINITION_ATTRIBUTES) + if (IGNORED_TASK_DEFINITION_ATTRIBUTES.length > 0) { + core.warning(`Ignoring properties '${IGNORED_TASK_DEFINITION_ATTRIBUTES}' in the task definition file. ` + + 'These properties are returned by the Amazon ECS DescribeTaskDefinition API and may be shown in the ECS console, ' + + 'but they are not valid fields when registering a new task definition. ' + + 'These fields can be safely removed from your task definition file.'); + } + for (var attribute of IGNORED_TASK_DEFINITION_ATTRIBUTES) { if (taskDef[attribute]) { - core.warning(`Ignoring property '${attribute}' in the task definition file. ` + - 'This property is returned by the Amazon ECS DescribeTaskDefinition API and may be shown in the ECS console, ' + - 'but it is not a valid field when registering a new task definition. ' + - 'This field can be safely removed from your task definition file.'); delete taskDef[attribute]; } } @@ -212,6 +214,10 @@ function removeIgnoredAttributes(taskDef) { return taskDef; } +function createArrayFromString(str) { + return str.split(/\s+/); +} + async function run() { try { const agent = 'amazon-ecs-run-task-for-github-actions' @@ -224,7 +230,8 @@ async function run() { const taskDefinitionFile = core.getInput('task-definition', { required: true }); const cluster = core.getInput('cluster', { required: false }); const count = core.getInput('count', { required: true }); - // const networkConfiguration = core.getInput('network-configuration', { required: true }); + const subnets = core.getInput('subnets', { required: false }) || ''; + const securityGroups = core.getInput('security-groups', { required: false }) || ''; const startedBy = core.getInput('started-by', { required: false }) || agent; const waitForFinish = core.getInput('wait-for-finish', { required: false }) || false; let waitForMinutes = parseInt(core.getInput('wait-for-minutes', { required: false })) || 30; @@ -254,11 +261,18 @@ async function run() { const clusterName = cluster ? cluster : 'default'; + const networkConfiguration = { + awsvpcConfiguration: { + subnets: createArrayFromString(subnets), + securityGroups: createArrayFromString(securityGroups) + } + } + core.debug(`Running task with ${JSON.stringify({ cluster: clusterName, taskDefinition: taskDefArn, count: count, - // networkConfiguration: networkConfiguration, + networkConfiguration: networkConfiguration, startedBy: startedBy })}`) @@ -266,8 +280,9 @@ async function run() { cluster: clusterName, taskDefinition: taskDefArn, count: count, - // networkConfiguration: networkConfiguration, - startedBy: startedBy + networkConfiguration: networkConfiguration, + startedBy: startedBy, + launchType: "FARGATE" }).promise(); core.debug(`Run task response ${JSON.stringify(runTaskResponse)}`) From 81ae1b834d4ed851a3fcaf721068abbf40c09fdc Mon Sep 17 00:00:00 2001 From: Leslie Klein Date: Fri, 16 Jun 2023 11:10:41 -0400 Subject: [PATCH 16/25] fix copy/paste error in usage example --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6ad53a4f6..d03581a70 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Runs an Amazon ECS task on ECS cluster. This action was forked from [smitp/amazo ```yaml - name: Run Task on Amazon ECS - uses: smitp/amazon-ecs-run-task@v1 + uses: Enterprise-CMCS/amazon-ecs-run-task@master with: task-definition: task-definition.json cluster: my-cluster @@ -96,7 +96,7 @@ The task definition file can be updated prior to deployment with the new contain image: ${{ steps.build-image.outputs.image }} - name: Run Task on Amazon ECS - uses: smitp/amazon-ecs-run-task@v1 + uses: Enterprise-CMCS/amazon-ecs-run-task@master with: task-definition: task-definition.json cluster: my-cluster From 212eb97c81148736534401e6b8e6ef1d632022ce Mon Sep 17 00:00:00 2001 From: Leslie Klein Date: Fri, 16 Jun 2023 11:11:52 -0400 Subject: [PATCH 17/25] update actions/checkout to v3 --- .github/workflows/package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 9acf2c033..01859f201 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: ref: master From 898f09064de81df0ea29014105307f58ff518f43 Mon Sep 17 00:00:00 2001 From: Leslie Klein Date: Fri, 16 Jun 2023 12:30:41 -0400 Subject: [PATCH 18/25] run on workflow_dispatch --- .github/workflows/package.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 01859f201..3684fca2c 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -1,4 +1,5 @@ on: + workflow_dispatch: push: branches: - master From f9ebca7cae2ceb03fe96e1bf7cb79e2922fd0440 Mon Sep 17 00:00:00 2001 From: Leslie Klein Date: Fri, 16 Jun 2023 12:44:06 -0400 Subject: [PATCH 19/25] run on push to lbk- branch --- .github/workflows/package.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 3684fca2c..3a693d2e2 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -3,6 +3,7 @@ on: push: branches: - master + - 'lbk-**' paths-ignore: - "**.md" pull_request: From 2d1cd9afb86a2fdcdf0226d9f327b11e43518219 Mon Sep 17 00:00:00 2001 From: Leslie Klein Date: Fri, 16 Jun 2023 13:36:11 -0400 Subject: [PATCH 20/25] Revert "run on push to lbk- branch" This reverts commit f9ebca7cae2ceb03fe96e1bf7cb79e2922fd0440. --- .github/workflows/package.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 3a693d2e2..3684fca2c 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -3,7 +3,6 @@ on: push: branches: - master - - 'lbk-**' paths-ignore: - "**.md" pull_request: From 3a2393370b1e4ae512a68b92af2a60c8a7c1dede Mon Sep 17 00:00:00 2001 From: Leslie Klein Date: Wed, 6 Sep 2023 16:10:18 -0400 Subject: [PATCH 21/25] run the task before registering the task definition This is because we use GITHUB_TOKEN as a task environment variable. Environment variables are stored in the clear in a task definition. When the task definition is registered, the token is available in the task definition. This is okay because the token expires at the end of a GitHub Actions job. However, if the task definition is registered first (and the token is exposed) and the task takes a while to run then a valid token is exposed for the duration of the long-running task. This commit runs the task first. Immediately after the task finishes running, the task definition is registered. Since this action is the last step of the job, the token expires after the registration completes. The token exposd in the task definition is invalid. --- action.yml | 4 +++- index.js | 46 ++++++++++++++++++++++++---------------------- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/action.yml b/action.yml index 5ebf60ce0..7d9080927 100644 --- a/action.yml +++ b/action.yml @@ -5,8 +5,10 @@ branding: color: 'orange' inputs: task-definition: - description: 'The name of ECS task definition' + description: 'The filename (.json) of the ECS task definition' required: true + task-definition-arn: + description: 'The ECS task definition ARN' cluster: description: "The name of the ECS cluster. Will default to the 'default' cluster" required: true diff --git a/index.js b/index.js index b14304984..c8ca0c509 100644 --- a/index.js +++ b/index.js @@ -95,6 +95,7 @@ async function run() { // Get inputs const taskDefinitionFile = core.getInput('task-definition', { required: true }); + const taskDefArnToRun = core.getInput('task-definition-arn', { required: true }); const cluster = core.getInput('cluster', { required: false }); const count = core.getInput('count', { required: true }); const subnets = core.getInput('subnets', { required: false }) || ''; @@ -106,26 +107,7 @@ async function run() { waitForMinutes = MAX_WAIT_MINUTES; } - // 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 = 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; - core.setOutput('task-definition-arn', taskDefArn); - + // Run task from the input task definition const clusterName = cluster ? cluster : 'default'; const networkConfiguration = { @@ -137,7 +119,7 @@ async function run() { core.debug(`Running task with ${JSON.stringify({ cluster: clusterName, - taskDefinition: taskDefArn, + taskDefinition: taskDefArnToRun, count: count, networkConfiguration: networkConfiguration, startedBy: startedBy @@ -145,7 +127,7 @@ async function run() { const runTaskResponse = await ecs.runTask({ cluster: clusterName, - taskDefinition: taskDefArn, + taskDefinition: taskDefArnToRun, count: count, networkConfiguration: networkConfiguration, startedBy: startedBy, @@ -172,6 +154,26 @@ async function run() { core.setFailed(error.message); core.debug(error.stack); } + + // Register the task definition that was used to run the task + 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 = 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; + core.setOutput('task-definition-arn', taskDefArn); } async function waitForTasksStopped(ecs, clusterName, taskArns, waitForMinutes) { From 9e99206356ba239614ad85dc77050d832fe94d33 Mon Sep 17 00:00:00 2001 From: Leslie Klein Date: Fri, 8 Sep 2023 09:17:21 -0400 Subject: [PATCH 22/25] update README --- README.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d03581a70..f7faf1b37 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,18 @@ ## Amazon ECS "Run Task" Action for GitHub Actions -Runs an Amazon ECS task on ECS cluster. This action was forked from [smitp/amazon-ecs-run-task](https://github.com/smitp/amazon-ecs-run-task). It has been amended to accept subnet ids and security groups as inputs. This enables the action to run tasks with `network_mode` set to `awsvpc`. When running this kind of task, the `runTask` function requires a `network_configuration` parameter with both subnet ids and security groups specified. +This action was forked from [smitp/amazon-ecs-run-task](https://github.com/smitp/amazon-ecs-run-task). -**Table of Contents** +This action does two things: + +1. It runs the input task definition. +2. After step 1 successfully completes, it registers the task definition. + +The reason for registering the task definition *after* running the task is to allow the GITHUB_TOKEN to be used as a task definition envirionment variable. +The task definition is registered only after the GITHUB_TOKEN is no longer valid. + +To enable the action to run tasks with `network_mode` set to `awsvpc`, the action accepts subnet ids and security groups as inputs. + +## Table of Contents @@ -24,6 +34,7 @@ Runs an Amazon ECS task on ECS cluster. This action was forked from [smitp/amazo uses: Enterprise-CMCS/amazon-ecs-run-task@master with: task-definition: task-definition.json + task-definition-arn: arn:aws:ecs:us-east-1:12345:task-definition/mytask-dev:42 cluster: my-cluster count: 1 subnets: subnet-1, subnet-2, subnet-3 @@ -99,6 +110,7 @@ The task definition file can be updated prior to deployment with the new contain uses: Enterprise-CMCS/amazon-ecs-run-task@master with: task-definition: task-definition.json + task-definition-arn: arn:aws:ecs:us-east-1:12345:task-definition/mytask-dev:42 cluster: my-cluster count: 1 started-by: github-actions-${{ github.actor }} From 63c7bf90026a5f02cd411f4ce8094244f2b1c476 Mon Sep 17 00:00:00 2001 From: Leslie Klein Date: Fri, 8 Sep 2023 09:29:33 -0400 Subject: [PATCH 23/25] fix tag on example usage --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f7faf1b37..2085e6e8a 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ The task definition file can be updated prior to deployment with the new contain image: ${{ steps.build-image.outputs.image }} - name: Run Task on Amazon ECS - uses: Enterprise-CMCS/amazon-ecs-run-task@master + uses: Enterprise-CMCS/amazon-ecs-run-task@vXYZ with: task-definition: task-definition.json task-definition-arn: arn:aws:ecs:us-east-1:12345:task-definition/mytask-dev:42 From d0e41e15a6833b6aec7a31cf2e90adbfb61b9998 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Fri, 8 Sep 2023 15:26:54 +0000 Subject: [PATCH 24/25] chore: Update dist --- dist/index.js | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/dist/index.js b/dist/index.js index 005538335..26c346dff 100644 --- a/dist/index.js +++ b/dist/index.js @@ -228,6 +228,7 @@ async function run() { // Get inputs const taskDefinitionFile = core.getInput('task-definition', { required: true }); + const taskDefArnToRun = core.getInput('task-definition-arn', { required: true }); const cluster = core.getInput('cluster', { required: false }); const count = core.getInput('count', { required: true }); const subnets = core.getInput('subnets', { required: false }) || ''; @@ -239,26 +240,7 @@ async function run() { waitForMinutes = MAX_WAIT_MINUTES; } - // 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 = 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; - core.setOutput('task-definition-arn', taskDefArn); - + // Run task from the input task definition const clusterName = cluster ? cluster : 'default'; const networkConfiguration = { @@ -270,7 +252,7 @@ async function run() { core.debug(`Running task with ${JSON.stringify({ cluster: clusterName, - taskDefinition: taskDefArn, + taskDefinition: taskDefArnToRun, count: count, networkConfiguration: networkConfiguration, startedBy: startedBy @@ -278,7 +260,7 @@ async function run() { const runTaskResponse = await ecs.runTask({ cluster: clusterName, - taskDefinition: taskDefArn, + taskDefinition: taskDefArnToRun, count: count, networkConfiguration: networkConfiguration, startedBy: startedBy, @@ -305,6 +287,26 @@ async function run() { core.setFailed(error.message); core.debug(error.stack); } + + // Register the task definition that was used to run the task + 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 = 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; + core.setOutput('task-definition-arn', taskDefArn); } async function waitForTasksStopped(ecs, clusterName, taskArns, waitForMinutes) { From fb4a89ab34e7d936bebde334a7d18e329e4d6e9f Mon Sep 17 00:00:00 2001 From: Leslie Klein Date: Wed, 9 Jul 2025 13:36:03 -0400 Subject: [PATCH 25/25] add code.json and generate-codejson.yml --- .github/workflows/generate-codejson.yml | 26 +++++++++ code.json | 76 +++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 .github/workflows/generate-codejson.yml create mode 100644 code.json diff --git a/.github/workflows/generate-codejson.yml b/.github/workflows/generate-codejson.yml new file mode 100644 index 000000000..fd67b9247 --- /dev/null +++ b/.github/workflows/generate-codejson.yml @@ -0,0 +1,26 @@ +name: Generate code.json +on: + schedule: + - cron: "0 0 1 * *" # monthly + +jobs: + update-code-json: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Generate token from GitHub App + id: create_token + uses: tibdex/github-app-token@v2.1.0 + with: + app_id: ${{ secrets.PR_PERMS_APP_ID }} + private_key: ${{ secrets.PR_PERMS_APP_SECRET }} + + - name: Update code.json + uses: DSACMS/automated-codejson-generator@v1.0.0 + with: + GITHUB_TOKEN: ${{ steps.create_token.outputs.token }} + BRANCH: "main" \ No newline at end of file diff --git a/code.json b/code.json new file mode 100644 index 000000000..788ca24ca --- /dev/null +++ b/code.json @@ -0,0 +1,76 @@ +{ + "name": "mac-fc-amazon-ecs-run-task", + "description": "This GitHub Action runs the input task definition.", + "longDescription": "This GitHub Action runs the input task definition. After that successfully completes, it registers the task definition.", + "status": "Production", + "permissions": { + "licenses": [ + { + "name": "None", + "URL": "none" + } + ], + "usageType": "governmentWideReuse", + "exemptionText": "" + }, + "organization": "Centers for Medicare & Medicaid Services", + "repositoryURL": "https://github.com/Enterprise-CMCS/mac-fc-amazon-ecs-run-task", + "projectURL": "", + "repositoryHost": "github.com/CMS-Enterprise", + "repositoryVisibility": "public", + "vcs": "git", + "laborHours": 0, + "reuseFrequency": { + "forks": 790 + }, + "platforms": [ + "linux" + ], + "categories": [ + "application-development", + "it-development" + ], + "softwareType": "standalone/backend", + "languages": [ + "JavaScript" + ], + "maintenance": "contract", + "contractNumber": "47QTCA21D00AC", + "date": { + "created": "2024-11-24T16:38:00Z", + "lastModified": "", + "metaDataLastUpdated": "" + }, + "tags": [ + "ecs service", + "ecs task definition", + "ecs task", + "ecs run task", + "ecs register task definition", + "ecs run task GitHub Action" + ], + "contact": { + "email": "cms-macfc@corbalt.com", + "name": "Corbalt" + }, + "feedbackMechanisms": [ + "https://github.com/Enterprise-CMCS/mac-fc-amazon-ecs-run-task/issues" + ], + "localisation": false, + "repositoryType": "tools", + "userInput": false, + "fismaLevel": "Moderate", + "group": "CMCS/DSG", + "projects": [ + "ECS Run Task GHA" + ], + "systems": [], + "upstream": [], + "subsetInHealthcare": [ + "Medicaid" + ], + "userType": [ + "Government" + ], + "maturityModelTier": 2 +} \ No newline at end of file