Compare commits
22 Commits
9282018910
...
00b2b44140
Author | SHA1 | Date |
---|---|---|
|
00b2b44140 | |
|
2c8bcdab54 | |
|
1051acaba6 | |
|
e8cd182ec7 | |
|
8c5c87276d | |
|
90fa7ac870 | |
|
7ebadadf6b | |
|
ee3eb2f3a4 | |
|
c65d441f38 | |
|
da183f8ca3 | |
|
f7a6c723e1 | |
|
8424fa0070 | |
|
c52693d481 | |
|
5efa6e34fd | |
|
774224adf6 | |
|
5d221e8956 | |
|
68163b97ca | |
|
ae7d6893e8 | |
|
ac3a803dd3 | |
|
80d22c042f | |
|
66d7daabf8 | |
|
bc3c5abd64 |
File diff suppressed because one or more lines are too long
12
.yarnrc.yml
12
.yarnrc.yml
|
@ -1,3 +1,9 @@
|
|||
# https://yarnpkg.com/configuration/yarnrc
|
||||
|
||||
compressionLevel: mixed
|
||||
enableGlobalCache: false
|
||||
enableHardenedMode: true
|
||||
|
||||
logFilters:
|
||||
- code: YN0013
|
||||
level: discard
|
||||
|
@ -5,9 +11,7 @@ logFilters:
|
|||
level: discard
|
||||
- code: YN0076
|
||||
level: discard
|
||||
- code: YN0086
|
||||
level: discard
|
||||
|
||||
nodeLinker: node-modules
|
||||
|
||||
plugins:
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
|
||||
spec: "@yarnpkg/plugin-interactive-tools"
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
26
package.json
26
package.json
|
@ -23,27 +23,27 @@
|
|||
],
|
||||
"author": "Docker Inc.",
|
||||
"license": "Apache-2.0",
|
||||
"packageManager": "yarn@3.6.3",
|
||||
"packageManager": "yarn@4.9.2",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.11.1",
|
||||
"@docker/actions-toolkit": "^0.62.1",
|
||||
"@docker/actions-toolkit": "^0.63.0",
|
||||
"js-yaml": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"@types/node": "^20.12.12",
|
||||
"@types/node": "^20.19.9",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^7.9.0",
|
||||
"@typescript-eslint/parser": "^7.9.0",
|
||||
"@vercel/ncc": "^0.38.1",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-jest": "^28.5.0",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
||||
"@typescript-eslint/parser": "^7.18.0",
|
||||
"@vercel/ncc": "^0.38.3",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-prettier": "^9.1.2",
|
||||
"eslint-plugin-jest": "^28.14.0",
|
||||
"eslint-plugin-prettier": "^5.5.4",
|
||||
"jest": "^29.7.0",
|
||||
"prettier": "^3.2.5",
|
||||
"ts-jest": "^29.1.2",
|
||||
"prettier": "^3.6.2",
|
||||
"ts-jest": "^29.4.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.4.5"
|
||||
"typescript": "^5.9.2"
|
||||
}
|
||||
}
|
||||
|
|
72
src/main.ts
72
src/main.ts
|
@ -17,6 +17,37 @@ import {ContextInfo} from '@docker/actions-toolkit/lib/types/docker/docker';
|
|||
import * as context from './context';
|
||||
import * as stateHelper from './state-helper';
|
||||
|
||||
/**
|
||||
* Retry a function with exponential backoff
|
||||
*/
|
||||
async function retryWithBackoff<T>(
|
||||
operation: () => Promise<T>,
|
||||
maxRetries: number = 3,
|
||||
initialDelay: number = 1000,
|
||||
maxDelay: number = 10000,
|
||||
shouldRetry: (error: Error) => boolean = () => true
|
||||
): Promise<T> {
|
||||
let retries = 0;
|
||||
let delay = initialDelay;
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
return await operation();
|
||||
} catch (error) {
|
||||
if (retries >= maxRetries || !shouldRetry(error)) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
retries++;
|
||||
core.info(`Retry ${retries}/${maxRetries} after ${delay}ms due to: ${error.message}`);
|
||||
await new Promise(resolve => setTimeout(resolve, delay));
|
||||
|
||||
// Exponential backoff with jitter
|
||||
delay = Math.min(delay * 2, maxDelay) * (0.8 + Math.random() * 0.4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
actionsToolkit.run(
|
||||
// main
|
||||
async () => {
|
||||
|
@ -175,13 +206,40 @@ actionsToolkit.run(
|
|||
|
||||
await core.group(`Booting builder`, async () => {
|
||||
const inspectCmd = await toolkit.buildx.getCommand(await context.getInspectArgs(inputs, toolkit));
|
||||
await Exec.getExecOutput(inspectCmd.command, inspectCmd.args, {
|
||||
ignoreReturnCode: true
|
||||
}).then(res => {
|
||||
if (res.stderr.length > 0 && res.exitCode != 0) {
|
||||
throw new Error(res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error');
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
await retryWithBackoff(
|
||||
async () => {
|
||||
// Create a promise that will timeout after 15 seconds
|
||||
const timeoutPromise = new Promise<never>((_, reject) => {
|
||||
setTimeout(() => {
|
||||
reject(new Error('Timeout exceeded while waiting for buildkit to initialize'));
|
||||
}, 15000); // 15 second timeout
|
||||
});
|
||||
|
||||
// Create the actual command execution promise
|
||||
const execPromise = Exec.getExecOutput(inspectCmd.command, inspectCmd.args, {
|
||||
ignoreReturnCode: true
|
||||
}).then(res => {
|
||||
if (res.stderr.length > 0 && res.exitCode != 0) {
|
||||
throw new Error(res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error');
|
||||
}
|
||||
return res;
|
||||
});
|
||||
|
||||
// Race the timeout against the actual command
|
||||
// If the command takes too long, we'll get the timeout error instead
|
||||
return Promise.race([execPromise, timeoutPromise]);
|
||||
},
|
||||
3, // maxRetries - retry up to 3 times for buildkit initialization
|
||||
1000, // initialDelay - start with 1 second
|
||||
15000 // maxDelay - cap at 15 seconds
|
||||
);
|
||||
} catch (error) {
|
||||
// Log the warning but continue - this matches current behavior where builds still succeed
|
||||
core.warning(`Failed to bootstrap builder after multiple retries: ${error.message}`);
|
||||
core.warning('Continuing execution as buildkit daemon may initialize later');
|
||||
}
|
||||
});
|
||||
|
||||
if (inputs.install) {
|
||||
|
|
Loading…
Reference in New Issue