Skip to content

Commit 741e127

Browse files
authored
Merge branch 'main' into github-workflow-release-proposal
2 parents 89abae7 + 149d3e4 commit 741e127

File tree

7 files changed

+66037
-288563
lines changed

7 files changed

+66037
-288563
lines changed

.github/workflows/package.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
on:
2+
push:
3+
branches:
4+
- main
5+
6+
name: Package
7+
8+
jobs:
9+
check:
10+
name: Package distribution file
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Checkout
14+
uses: actions/checkout@v3
15+
with:
16+
ref: main
17+
- name: Package
18+
run: |
19+
npm ci
20+
npm run lint
21+
npm test
22+
npm run package
23+
- name: Commit
24+
run: |
25+
git config --global user.name "GitHub Actions"
26+
git add dist/
27+
git commit -m "chore: Update dist" || echo "No changes to commit"
28+
git push origin HEAD:main

README.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,31 @@ The only required input is `project-name`.
4646
the one defined here replaces the one in the CodeBuild project.
4747
For a list of CodeBuild environment variables, see
4848

49+
1. **update-interval** (optional) :
50+
Update interval as seconds for how often the API is called to check on the status.
51+
52+
A higher value mitigates the chance of hitting API rate-limiting especially when
53+
running many instances of this action in parallel, but also introduces a larger
54+
potential time overhead (ranging from 0 to update interval) for the action to
55+
fetch the build result and finish.
56+
57+
Lower value limits the potential time overhead worst case but it may hit the API
58+
rate-limit more often, depending on the use-case.
59+
60+
The default value is 30.
61+
62+
1. **update-back-off** (optional) :
63+
Base back-off time in seconds for the update interval.
64+
65+
When API rate-limiting is hit the back-off time, augmented with jitter, will be
66+
added to the next update interval.
67+
E.g. with update interval of 30 and back-off time of 15, upon hitting the rate-limit
68+
the next interval for the update call will be 30 + random_between(0, 15 _ 2 \*\* 0))
69+
seconds and if the rate-limit is hit again the next interval will be
70+
30 + random_between(0, 15 _ 2 \*\* 1) and so on.
71+
72+
The default value is 15.
73+
4974
### Outputs
5075

5176
1. **aws-build-id** : The CodeBuild build ID of the build that the action ran.
@@ -220,7 +245,7 @@ Otherwise, it fails.
220245
221246
In the call to StartBuild, we pass in all
222247
`GITHUB_` [environment variables][github environment variables] in the GitHub Actions environment,
223-
plus any environment variables that you specified in the `evn-passthrough` input value.
248+
plus any environment variables that you specified in the `env-passthrough` input value.
224249
225250
Regardless of the project configuration in CodeBuild or GitHub Actions,
226251
we always pass the following parameters and values to CodeBuild in the StartBuild API call.

action.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ inputs:
2222
env-vars-for-codebuild:
2323
description: 'Comma separated list of environment variables to send to CodeBuild'
2424
required: false
25+
update-interval:
26+
description: 'How often the action calls the API for updates'
27+
required: false
28+
update-back-off:
29+
description: 'Base back-off time for the update calls for API if rate-limiting is encountered'
30+
required: false
31+
2532
outputs:
2633
aws-build-id:
2734
description: 'The AWS CodeBuild Build ID for this build.'

code-build.js

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,34 +20,37 @@ function runBuild() {
2020
// get a codeBuild instance from the SDK
2121
const sdk = buildSdk();
2222

23+
const inputs = githubInputs();
24+
25+
const config = (({ updateInterval, updateBackOff }) => ({
26+
updateInterval,
27+
updateBackOff,
28+
}))(inputs);
29+
2330
// Get input options for startBuild
24-
const params = inputs2Parameters(githubInputs());
31+
const params = inputs2Parameters(inputs);
2532

26-
return build(sdk, params);
33+
return build(sdk, params, config);
2734
}
2835

29-
async function build(sdk, params) {
36+
async function build(sdk, params, config) {
3037
// Start the build
3138
const start = await sdk.codeBuild.startBuild(params).promise();
3239

3340
// Wait for the build to "complete"
34-
return waitForBuildEndTime(sdk, start.build);
41+
return waitForBuildEndTime(sdk, start.build, config);
3542
}
3643

3744
async function waitForBuildEndTime(
3845
sdk,
3946
{ id, logs },
47+
{ updateInterval, updateBackOff },
4048
seqEmptyLogs,
4149
totalEvents,
4250
throttleCount,
4351
nextToken
4452
) {
45-
const {
46-
codeBuild,
47-
cloudWatchLogs,
48-
wait = 1000 * 30,
49-
backOff = 1000 * 15,
50-
} = sdk;
53+
const { codeBuild, cloudWatchLogs } = sdk;
5154

5255
totalEvents = totalEvents || 0;
5356
seqEmptyLogs = seqEmptyLogs || 0;
@@ -86,17 +89,21 @@ async function waitForBuildEndTime(
8689
if (errObject) {
8790
//We caught an error in trying to make the AWS api call, and are now checking to see if it was just a rate limiting error
8891
if (errObject.message && errObject.message.search("Rate exceeded") !== -1) {
89-
//We were rate-limited, so add `backOff` seconds to the wait time
90-
let newWait = wait + backOff;
92+
// We were rate-limited, so add backoff with Full Jitter, ref: https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/
93+
let jitteredBackOff = Math.floor(
94+
Math.random() * (updateBackOff * 2 ** throttleCount)
95+
);
96+
let newWait = updateInterval + jitteredBackOff;
9197
throttleCount++;
9298

9399
//Sleep before trying again
94100
await new Promise((resolve) => setTimeout(resolve, newWait));
95101

96102
// Try again from the same token position
97103
return waitForBuildEndTime(
98-
{ ...sdk, wait: newWait },
104+
{ ...sdk },
99105
{ id, logs },
106+
{ updateInterval: newWait, updateBackOff },
100107
seqEmptyLogs,
101108
totalEvents,
102109
throttleCount,
@@ -136,13 +143,19 @@ async function waitForBuildEndTime(
136143
// More to do: Sleep for a few seconds to avoid rate limiting
137144
// If never throttled and build is complete, halve CWL polling delay to minimize latency
138145
await new Promise((resolve) =>
139-
setTimeout(resolve, current.endTime && throttleCount == 0 ? wait / 2 : wait)
146+
setTimeout(
147+
resolve,
148+
current.endTime && throttleCount == 0
149+
? updateInterval / 2
150+
: updateInterval
151+
)
140152
);
141153

142154
// Try again
143155
return waitForBuildEndTime(
144156
sdk,
145157
current,
158+
{ updateInterval, updateBackOff },
146159
seqEmptyLogs,
147160
totalEvents,
148161
throttleCount,
@@ -184,6 +197,17 @@ function githubInputs() {
184197
.map((i) => i.trim())
185198
.filter((i) => i !== "");
186199

200+
const updateInterval =
201+
parseInt(
202+
core.getInput("update-interval", { required: false }) || "30",
203+
10
204+
) * 1000;
205+
const updateBackOff =
206+
parseInt(
207+
core.getInput("update-back-off", { required: false }) || "15",
208+
10
209+
) * 1000;
210+
187211
return {
188212
projectName,
189213
owner,
@@ -194,6 +218,8 @@ function githubInputs() {
194218
environmentTypeOverride,
195219
imageOverride,
196220
envPassthrough,
221+
updateInterval,
222+
updateBackOff,
197223
};
198224
}
199225

0 commit comments

Comments
 (0)