Skip to content

Commit 7745c4a

Browse files
committed
* Upgrade to AWS SDK3
* Add options to skip waiting for task to finish * Change max wait time variables
1 parent 4d993c2 commit 7745c4a

File tree

5 files changed

+103
-34
lines changed

5 files changed

+103
-34
lines changed

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<!-- action-docs-description -->
44
## Description
55

6-
Run an AWS ECS Fargate task and execute a custom command. See the log output of the command that is executed.
6+
Run an AWS ECS Fargate task and execute a custom commands. See the log output of the commands.
77
<!-- action-docs-description -->
88

99
### Details
@@ -42,6 +42,10 @@ This action is great for executing migrations or other pre/post deployment steps
4242
override-container-environment: |
4343
AWS_REGION=us-east-1
4444
FOO=baz
45+
46+
task-wait-until-stopped: true
47+
task-start-max-wait-time: 120
48+
task-stopped-max-wait-time: 300
4549
```
4650
4751
#### Minimal example
@@ -97,7 +101,9 @@ Will pass the following command to the container on the AWS ECS Fargate task:
97101
| override-container-command | The command to run on the container if `override-container` is passed. | `false` | |
98102
| override-container-environment | Add or override existing environment variables if `override-container` is passed. Provide one per line in key=value format. | `false` | |
99103
| tail-logs | If set to true, will try to extract the logConfiguration for the first container in the task definition. If `override-container` is passed, it will extract the logConfiguration from that container. Tailing logs is only possible if the provided container uses the `awslogs` logDriver. | `false` | true |
100-
| task-stopped-wait-for-max-attempts | How many times to check if the task is stopped before failing the action. The delay between each check is 6 seconds. | `false` | 100 |
104+
| task-wait-until-stopped | Whether to wait for the task to stop before finishing the action. If set to false, the action will finish immediately after the task reaches the `RUNNING` state (fire and forget). | `false` | true |
105+
| task-start-max-wait-time | How long to wait for the task to start (i.e. reach the `RUNNING` state) in seconds. If the task does not start within this time, the pipeline will fail. | `false` | 120 |
106+
| task-stopped-max-wait-time | How long to wait for the task to stop (i.e. reach the `STOPPED` state) in seconds. The task will not be canceled after this time, the pipeline will just be marked as failed. | `false` | 300 |
101107
<!-- action-docs-inputs -->
102108

103109
<!-- action-docs-outputs -->
@@ -107,7 +113,7 @@ Will pass the following command to the container on the AWS ECS Fargate task:
107113
| --- | --- |
108114
| task-arn | The full ARN for the task that was ran. |
109115
| task-id | The ID for the task that was ran. |
110-
| log-output | The log output of the task that was ran, if `tail-logs` was set to true. |
116+
| log-output | The log output of the task that was ran, if `tail-logs` and `task-wait-until-stopped` are set to true. |
111117
<!-- action-docs-outputs -->
112118

113119
<!-- action-docs-runs -->

action.yml

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,34 @@ inputs:
6060
required: false
6161
default: 'true'
6262

63-
task-stopped-wait-for-max-attempts:
63+
task-wait-until-stopped:
6464
description: >-
65-
How many times to check if the task is stopped before failing the action. The delay between each check is 6 seconds.
65+
Whether to wait for the task to stop before finishing the action. If set to false, the action will finish
66+
immediately after the task reaches the `RUNNING` state (fire and forget).
6667
required: false
67-
default: 100
68+
default: 'true'
69+
70+
task-start-max-wait-time:
71+
description: >-
72+
How long to wait for the task to start (i.e. reach the `RUNNING` state) in seconds. If the task does not start
73+
within this time, the pipeline will fail.
74+
required: false
75+
default: 120
76+
77+
task-stopped-max-wait-time:
78+
description: >-
79+
How long to wait for the task to stop (i.e. reach the `STOPPED` state) in seconds. The task will not be canceled
80+
after this time, the pipeline will just be marked as failed.
81+
required: false
82+
default: 300
6883

6984
outputs:
7085
task-arn:
7186
description: 'The full ARN for the task that was ran.'
7287
task-id:
7388
description: 'The ID for the task that was ran.'
7489
log-output:
75-
description: 'The log output of the task that was ran, if `tail-logs` was set to true.'
90+
description: 'The log output of the task that was ran, if `tail-logs` and `task-wait-until-stopped` are set to true.'
7691

7792
runs:
7893
using: 'node20'

dist/index.js

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43562,6 +43562,14 @@ exports["default"] = _default;
4356243562
}).call(this);
4356343563

4356443564

43565+
/***/ }),
43566+
43567+
/***/ 78072:
43568+
/***/ ((module) => {
43569+
43570+
module.exports = eval("require")("@aws-sdk/client-ecs");
43571+
43572+
4356543573
/***/ }),
4356643574

4356743575
/***/ 39491:
@@ -50295,13 +50303,16 @@ var __webpack_exports__ = {};
5029550303
(() => {
5029650304
const core = __nccwpck_require__(42186);
5029750305
const aws = __nccwpck_require__(71786);
50306+
50307+
const {ECS, waitUntilTasksRunning, waitUntilTasksStopped} = __nccwpck_require__(78072);
50308+
5029850309
const smoketail = __nccwpck_require__(45601)
5029950310

5030050311
const main = async () => {
5030150312
try {
5030250313
// Setup AWS clients
50303-
const ecs = new aws.ECS({
50304-
customUserAgent: 'github-action-aws-ecs-run-task'
50314+
const ecs = new ECS({
50315+
customUserAgent: 'github-action-aws-ecs-run-task',
5030550316
});
5030650317

5030750318
// Inputs: Required
@@ -50316,7 +50327,11 @@ const main = async () => {
5031650327
const overrideContainer = core.getInput('override-container', {required: false});
5031750328
const overrideContainerCommand = core.getMultilineInput('override-container-command', {required: false});
5031850329
const overrideContainerEnvironment = core.getMultilineInput('override-container-environment', {required: false});
50319-
const taskStoppedWaitForMaxAttempts = parseInt(core.getInput('task-stopped-wait-for-max-attempts', {required: false}));
50330+
50331+
// Inputs: Waiters
50332+
const taskWaitUntilStopped = core.getBooleanInput('task-wait-until-stopped', {required: false});
50333+
const taskStartMaxWaitTime = parseInt(core.getInput('task-start-max-wait-time', {required: false}));
50334+
const taskStoppedMaxWaitTime = parseInt(core.getInput('task-stopped-max-wait-time', {required: false}));
5032050335

5032150336
// Build Task parameters
5032250337
const taskRequestParams = {
@@ -50384,7 +50399,7 @@ const main = async () => {
5038450399
// Start task
5038550400
core.debug(JSON.stringify(taskRequestParams))
5038650401
core.debug(`Starting task.`)
50387-
let task = await ecs.runTask(taskRequestParams).promise();
50402+
let task = await ecs.runTask(taskRequestParams);
5038850403

5038950404
// Get taskArn and taskId
5039050405
const taskArn = task.tasks[0].taskArn;
@@ -50395,15 +50410,26 @@ const main = async () => {
5039550410

5039650411
// Wait for task to be in running state
5039750412
core.debug(`Waiting for task to be in running state.`)
50398-
await ecs.waitFor('tasksRunning', {cluster, tasks: [taskArn]}).promise();
50413+
await waitUntilTasksRunning({
50414+
client: ecs,
50415+
maxWaitTime: taskStartMaxWaitTime,
50416+
}, {cluster, tasks: [taskArn]});
50417+
50418+
// If taskWaitUntilStopped is false, we can bail out here because we can not tail logs or have any
50419+
// information on the exitCodes or status of the task
50420+
if (!taskWaitUntilStopped) {
50421+
core.info(`Task is running. Exiting without waiting for task to stop.`);
50422+
return;
50423+
}
5039950424

5040050425
// Get logging configuration
5040150426
let logFilterStream = null;
5040250427
let logOutput = '';
5040350428

50429+
// Only create logFilterStream if tailLogs is enabled, and we wait for the task to stop in the pipeline
5040450430
if (tailLogs) {
5040550431
core.debug(`Logging enabled. Getting logConfiguration from TaskDefinition.`)
50406-
let taskDef = await ecs.describeTaskDefinition({taskDefinition: taskDefinition}).promise();
50432+
let taskDef = await ecs.describeTaskDefinition({taskDefinition: taskDefinition});
5040750433
taskDef = taskDef.taskDefinition
5040850434

5040950435
// Iterate all containers in TaskDef and search for given container with awslogs driver
@@ -50451,11 +50477,13 @@ const main = async () => {
5045150477

5045250478
// Wait for Task to finish
5045350479
core.debug(`Waiting for task to finish.`);
50454-
await ecs.waitFor('tasksStopped', {
50480+
await waitUntilTasksStopped({
50481+
client: ecs,
50482+
maxWaitTime: taskStoppedMaxWaitTime,
50483+
}, {
5045550484
cluster,
5045650485
tasks: [taskArn],
50457-
$waiter: {delay: 6, maxAttempts: taskStoppedWaitForMaxAttempts}}
50458-
).promise();
50486+
});
5045950487

5046050488
// Close LogStream and store output
5046150489
if (logFilterStream !== null) {
@@ -50468,7 +50496,7 @@ const main = async () => {
5046850496

5046950497
// Describe Task to get Exit Code and Exceptions
5047050498
core.debug(`Process exit code and exception.`);
50471-
task = await ecs.describeTasks({cluster, tasks: [taskArn]}).promise();
50499+
task = await ecs.describeTasks({cluster, tasks: [taskArn]});
5047250500

5047350501
// Get exitCode
5047450502
if (task.tasks[0].containers[0].exitCode !== 0) {

index.js

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
const core = require('@actions/core');
22
const aws = require('aws-sdk');
3+
4+
const {ECS, waitUntilTasksRunning, waitUntilTasksStopped} = require('@aws-sdk/client-ecs');
5+
36
const smoketail = require('smoketail')
47

58
const main = async () => {
69
try {
710
// Setup AWS clients
8-
const ecs = new aws.ECS({
9-
customUserAgent: 'github-action-aws-ecs-run-task'
11+
const ecs = new ECS({
12+
customUserAgent: 'github-action-aws-ecs-run-task',
1013
});
1114

1215
// Inputs: Required
@@ -21,7 +24,11 @@ const main = async () => {
2124
const overrideContainer = core.getInput('override-container', {required: false});
2225
const overrideContainerCommand = core.getMultilineInput('override-container-command', {required: false});
2326
const overrideContainerEnvironment = core.getMultilineInput('override-container-environment', {required: false});
24-
const taskStoppedWaitForMaxAttempts = parseInt(core.getInput('task-stopped-wait-for-max-attempts', {required: false}));
27+
28+
// Inputs: Waiters
29+
const taskWaitUntilStopped = core.getBooleanInput('task-wait-until-stopped', {required: false});
30+
const taskStartMaxWaitTime = parseInt(core.getInput('task-start-max-wait-time', {required: false}));
31+
const taskStoppedMaxWaitTime = parseInt(core.getInput('task-stopped-max-wait-time', {required: false}));
2532

2633
// Build Task parameters
2734
const taskRequestParams = {
@@ -89,7 +96,7 @@ const main = async () => {
8996
// Start task
9097
core.debug(JSON.stringify(taskRequestParams))
9198
core.debug(`Starting task.`)
92-
let task = await ecs.runTask(taskRequestParams).promise();
99+
let task = await ecs.runTask(taskRequestParams);
93100

94101
// Get taskArn and taskId
95102
const taskArn = task.tasks[0].taskArn;
@@ -100,15 +107,26 @@ const main = async () => {
100107

101108
// Wait for task to be in running state
102109
core.debug(`Waiting for task to be in running state.`)
103-
await ecs.waitFor('tasksRunning', {cluster, tasks: [taskArn]}).promise();
110+
await waitUntilTasksRunning({
111+
client: ecs,
112+
maxWaitTime: taskStartMaxWaitTime,
113+
}, {cluster, tasks: [taskArn]});
114+
115+
// If taskWaitUntilStopped is false, we can bail out here because we can not tail logs or have any
116+
// information on the exitCodes or status of the task
117+
if (!taskWaitUntilStopped) {
118+
core.info(`Task is running. Exiting without waiting for task to stop.`);
119+
return;
120+
}
104121

105122
// Get logging configuration
106123
let logFilterStream = null;
107124
let logOutput = '';
108125

126+
// Only create logFilterStream if tailLogs is enabled, and we wait for the task to stop in the pipeline
109127
if (tailLogs) {
110128
core.debug(`Logging enabled. Getting logConfiguration from TaskDefinition.`)
111-
let taskDef = await ecs.describeTaskDefinition({taskDefinition: taskDefinition}).promise();
129+
let taskDef = await ecs.describeTaskDefinition({taskDefinition: taskDefinition});
112130
taskDef = taskDef.taskDefinition
113131

114132
// Iterate all containers in TaskDef and search for given container with awslogs driver
@@ -156,11 +174,13 @@ const main = async () => {
156174

157175
// Wait for Task to finish
158176
core.debug(`Waiting for task to finish.`);
159-
await ecs.waitFor('tasksStopped', {
177+
await waitUntilTasksStopped({
178+
client: ecs,
179+
maxWaitTime: taskStoppedMaxWaitTime,
180+
}, {
160181
cluster,
161182
tasks: [taskArn],
162-
$waiter: {delay: 6, maxAttempts: taskStoppedWaitForMaxAttempts}}
163-
).promise();
183+
});
164184

165185
// Close LogStream and store output
166186
if (logFilterStream !== null) {
@@ -173,7 +193,7 @@ const main = async () => {
173193

174194
// Describe Task to get Exit Code and Exceptions
175195
core.debug(`Process exit code and exception.`);
176-
task = await ecs.describeTasks({cluster, tasks: [taskArn]}).promise();
196+
task = await ecs.describeTasks({cluster, tasks: [taskArn]});
177197

178198
// Get exitCode
179199
if (task.tasks[0].containers[0].exitCode !== 0) {

package-lock.json

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)