mirror of
https://github.com/docker/setup-buildx-action.git
synced 2025-08-23 07:27:48 +03:00
Compare commits
7 commits
720c4e53d1
...
9282018910
Author | SHA1 | Date | |
---|---|---|---|
|
9282018910 | ||
|
e468171a9d | ||
|
a3e7502fd0 | ||
|
b145473295 | ||
|
80d22c042f | ||
|
66d7daabf8 | ||
|
bc3c5abd64 |
5 changed files with 71 additions and 12 deletions
1
.github/workflows/ci.yml
vendored
1
.github/workflows/ci.yml
vendored
|
@ -621,6 +621,7 @@ jobs:
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
name: foo
|
name: foo
|
||||||
|
keep-state: true
|
||||||
|
|
||||||
keep-state-error:
|
keep-state-error:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
2
dist/index.js
generated
vendored
2
dist/index.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/index.js.map
generated
vendored
2
dist/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
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 context from './context';
|
||||||
import * as stateHelper from './state-helper';
|
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(
|
actionsToolkit.run(
|
||||||
// main
|
// main
|
||||||
async () => {
|
async () => {
|
||||||
|
@ -175,13 +206,40 @@ actionsToolkit.run(
|
||||||
|
|
||||||
await core.group(`Booting builder`, async () => {
|
await core.group(`Booting builder`, async () => {
|
||||||
const inspectCmd = await toolkit.buildx.getCommand(await context.getInspectArgs(inputs, toolkit));
|
const inspectCmd = await toolkit.buildx.getCommand(await context.getInspectArgs(inputs, toolkit));
|
||||||
await Exec.getExecOutput(inspectCmd.command, inspectCmd.args, {
|
|
||||||
ignoreReturnCode: true
|
try {
|
||||||
}).then(res => {
|
await retryWithBackoff(
|
||||||
if (res.stderr.length > 0 && res.exitCode != 0) {
|
async () => {
|
||||||
throw new Error(res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error');
|
// 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) {
|
if (inputs.install) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ export const certsDir = process.env['STATE_certsDir'] || '';
|
||||||
export const tmpDockerContext = process.env['STATE_tmpDockerContext'] || '';
|
export const tmpDockerContext = process.env['STATE_tmpDockerContext'] || '';
|
||||||
export const cleanup = /true/i.test(process.env['STATE_cleanup'] || '');
|
export const cleanup = /true/i.test(process.env['STATE_cleanup'] || '');
|
||||||
export const buildxIsDefaultBuilder = /true/i.test(process.env['STATE_buildxIsDefaultBuilder'] || '');
|
export const buildxIsDefaultBuilder = /true/i.test(process.env['STATE_buildxIsDefaultBuilder'] || '');
|
||||||
export const keepState = !!process.env['STATE_keepState'];
|
export const keepState = /true/i.test(process.env['STATE_keepState'] || '');
|
||||||
|
|
||||||
export function setDebug(debug: string) {
|
export function setDebug(debug: string) {
|
||||||
core.saveState('isDebug', debug);
|
core.saveState('isDebug', debug);
|
||||||
|
@ -47,6 +47,6 @@ export function setBuildxIsDefaultBuilder(buildxIsDefaultBuilder: boolean) {
|
||||||
core.saveState('buildxIsDefaultBuilder', buildxIsDefaultBuilder);
|
core.saveState('buildxIsDefaultBuilder', buildxIsDefaultBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setKeepState(retain: boolean) {
|
export function setKeepState(keepState: boolean) {
|
||||||
core.saveState('keepState', retain);
|
core.saveState('keepState', keepState);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue