mirror of
https://github.com/docker/build-push-action.git
synced 2025-08-11 02:52:11 +00:00
refactor: remove tmpDir management and buildx installation
Since setup-docker-builder handles all infrastructure setup, build-push-action no longer needs to: - Install buildx (just assert it's available) - Manage temporary directories (handled by actions toolkit) Changes: - Replace buildx installation with simple availability assertion - Remove tmpDir state management entirely - Remove buildx-version input parameter - Clean up unused imports and functions The action now assumes buildx is already configured by setup-docker-builder or another setup action, making it simpler and more focused. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
4108c3efae
commit
fece9d42f3
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
@ -58,7 +58,6 @@ export interface Inputs {
|
|||||||
ulimit: string[];
|
ulimit: string[];
|
||||||
'github-token': string;
|
'github-token': string;
|
||||||
nofallback: boolean;
|
nofallback: boolean;
|
||||||
'buildx-version': string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getInputs(): Promise<Inputs> {
|
export async function getInputs(): Promise<Inputs> {
|
||||||
@ -96,8 +95,7 @@ export async function getInputs(): Promise<Inputs> {
|
|||||||
target: core.getInput('target'),
|
target: core.getInput('target'),
|
||||||
ulimit: Util.getInputList('ulimit', {ignoreComma: true}),
|
ulimit: Util.getInputList('ulimit', {ignoreComma: true}),
|
||||||
'github-token': core.getInput('github-token'),
|
'github-token': core.getInput('github-token'),
|
||||||
nofallback: core.getBooleanInput('nofallback'),
|
nofallback: core.getBooleanInput('nofallback')
|
||||||
'buildx-version': core.getInput('buildx-version')
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
96
src/main.ts
96
src/main.ts
@ -1,4 +1,3 @@
|
|||||||
import * as fs from 'fs';
|
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as stateHelper from './state-helper';
|
import * as stateHelper from './state-helper';
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
@ -20,47 +19,10 @@ import * as context from './context';
|
|||||||
import * as reporter from './reporter';
|
import * as reporter from './reporter';
|
||||||
import {Metric_MetricType} from '@buf/blacksmith_vm-agent.bufbuild_es/stickydisk/v1/stickydisk_pb';
|
import {Metric_MetricType} from '@buf/blacksmith_vm-agent.bufbuild_es/stickydisk/v1/stickydisk_pb';
|
||||||
|
|
||||||
const DEFAULT_BUILDX_VERSION = 'v0.23.0';
|
async function assertBuildxAvailable(toolkit: Toolkit): Promise<void> {
|
||||||
|
if (!(await toolkit.buildx.isAvailable())) {
|
||||||
async function retryWithBackoff<T>(operation: () => Promise<T>, maxRetries: number = 5, initialBackoffMs: number = 200): Promise<T> {
|
core.setFailed(`Docker buildx is required. Please use setup-docker-builder action or setup-buildx-action to configure buildx.`);
|
||||||
let lastError: Error = new Error('No error occurred');
|
throw new Error('Docker buildx is not available');
|
||||||
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
||||||
try {
|
|
||||||
return await operation();
|
|
||||||
} catch (error) {
|
|
||||||
lastError = error;
|
|
||||||
if (error.message?.includes('429') || error.status === 429) {
|
|
||||||
if (attempt < maxRetries - 1) {
|
|
||||||
const backoffMs = initialBackoffMs * Math.pow(2, attempt);
|
|
||||||
core.info(`Rate limited (429). Retrying in ${backoffMs}ms...`);
|
|
||||||
await new Promise(resolve => setTimeout(resolve, backoffMs));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw lastError;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function setupBuildx(version: string, toolkit: Toolkit): Promise<void> {
|
|
||||||
let toolPath;
|
|
||||||
const standalone = await toolkit.buildx.isStandalone();
|
|
||||||
|
|
||||||
if (!(await toolkit.buildx.isAvailable()) || version) {
|
|
||||||
await core.group(`Download buildx from GitHub Releases`, async () => {
|
|
||||||
toolPath = await retryWithBackoff(() => toolkit.buildxInstall.download(version || 'latest', true));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (toolPath) {
|
|
||||||
await core.group(`Install buildx`, async () => {
|
|
||||||
if (standalone) {
|
|
||||||
await toolkit.buildxInstall.installStandalone(toolPath);
|
|
||||||
} else {
|
|
||||||
await toolkit.buildxInstall.installPlugin(toolPath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await core.group(`Buildx version`, async () => {
|
await core.group(`Buildx version`, async () => {
|
||||||
@ -68,12 +30,6 @@ async function setupBuildx(version: string, toolkit: Toolkit): Promise<void> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validates the version string to ensure it matches a basic expected pattern.
|
|
||||||
// Accepts versions of the form `v<MAJOR>.<MINOR>.<PATCH>` (e.g., v0.20.0) or the literal string `latest`.
|
|
||||||
function isValidBuildxVersion(version: string): boolean {
|
|
||||||
return version === 'latest' || /^v\d+\.\d+\.\d+$/.test(version);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reports the build start to the backend and gets a build ID for tracking.
|
* Reports the build start to the backend and gets a build ID for tracking.
|
||||||
*
|
*
|
||||||
@ -130,24 +86,9 @@ actionsToolkit.run(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Determine which Buildx version to install. If the user provided an input, validate it;
|
// Assert that buildx is available (should be installed by setup-docker-builder)
|
||||||
// otherwise, fall back to the default.
|
await core.group(`Check buildx availability`, async () => {
|
||||||
let buildxVersion = DEFAULT_BUILDX_VERSION;
|
await assertBuildxAvailable(toolkit);
|
||||||
if (inputs['buildx-version'] && inputs['buildx-version'].trim() !== '') {
|
|
||||||
if (isValidBuildxVersion(inputs['buildx-version'])) {
|
|
||||||
buildxVersion = inputs['buildx-version'];
|
|
||||||
} else {
|
|
||||||
core.warning(`Invalid buildx-version '${inputs['buildx-version']}'. ` + `Expected 'latest' or a version in the form v<MAJOR>.<MINOR>.<PATCH>. ` + `Falling back to default ${DEFAULT_BUILDX_VERSION}.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await core.group(`Setup buildx`, async () => {
|
|
||||||
await setupBuildx(buildxVersion, toolkit);
|
|
||||||
|
|
||||||
if (!(await toolkit.buildx.isAvailable())) {
|
|
||||||
core.setFailed(`Docker buildx is required. See https://github.com/docker/setup-buildx-action to set up buildx.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let buildId: string | null = null;
|
let buildId: string | null = null;
|
||||||
@ -173,15 +114,12 @@ actionsToolkit.run(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// The sentinel file should already exist from setup-docker-builder
|
|
||||||
|
|
||||||
let builder: BuilderInfo;
|
let builder: BuilderInfo;
|
||||||
await core.group(`Builder info`, async () => {
|
await core.group(`Builder info`, async () => {
|
||||||
builder = await toolkit.builder.inspect();
|
builder = await toolkit.builder.inspect();
|
||||||
core.info(JSON.stringify(builder, null, 2));
|
core.info(JSON.stringify(builder, null, 2));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
await core.group(`Proxy configuration`, async () => {
|
await core.group(`Proxy configuration`, async () => {
|
||||||
let dockerConfig: ConfigFile | undefined;
|
let dockerConfig: ConfigFile | undefined;
|
||||||
let dockerConfigMalformed = false;
|
let dockerConfigMalformed = false;
|
||||||
@ -207,7 +145,6 @@ actionsToolkit.run(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
stateHelper.setTmpDir(Context.tmpDir());
|
|
||||||
|
|
||||||
const args: string[] = await context.getArgs(inputs, toolkit);
|
const args: string[] = await context.getArgs(inputs, toolkit);
|
||||||
args.push('--debug');
|
args.push('--debug');
|
||||||
@ -302,7 +239,7 @@ actionsToolkit.run(
|
|||||||
buildError = error as Error;
|
buildError = error as Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
await core.group('Cleaning up Blacksmith builder', async () => {
|
await core.group('Reporting build completion', async () => {
|
||||||
try {
|
try {
|
||||||
let exportRes;
|
let exportRes;
|
||||||
if (!buildError) {
|
if (!buildError) {
|
||||||
@ -312,10 +249,6 @@ actionsToolkit.run(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buildkitd is now managed by setup-docker-builder, not here
|
|
||||||
|
|
||||||
// Sticky disk is now managed by setup-docker-builder, not here
|
|
||||||
|
|
||||||
if (buildId) {
|
if (buildId) {
|
||||||
if (!buildError) {
|
if (!buildError) {
|
||||||
await reporter.reportBuildCompleted(exportRes, buildId, ref, buildDurationSeconds);
|
await reporter.reportBuildCompleted(exportRes, buildId, ref, buildDurationSeconds);
|
||||||
@ -326,8 +259,6 @@ actionsToolkit.run(
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.warning(`Error during Blacksmith builder shutdown: ${error.message}`);
|
core.warning(`Error during Blacksmith builder shutdown: ${error.message}`);
|
||||||
await reporter.reportBuildPushActionFailure(error, 'shutting down blacksmith builder');
|
await reporter.reportBuildPushActionFailure(error, 'shutting down blacksmith builder');
|
||||||
} finally {
|
|
||||||
// Buildkitd logs are managed by setup-docker-builder
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -340,15 +271,7 @@ actionsToolkit.run(
|
|||||||
async () => {
|
async () => {
|
||||||
await core.group('Final cleanup', async () => {
|
await core.group('Final cleanup', async () => {
|
||||||
try {
|
try {
|
||||||
|
// No temp directory cleanup needed - handled by actions toolkit
|
||||||
// Buildkitd is now managed by setup-docker-builder, not here
|
|
||||||
// Sticky disk is also managed by setup-docker-builder, not here
|
|
||||||
|
|
||||||
// Clean up temp directory if it exists.
|
|
||||||
if (stateHelper.tmpDir.length > 0) {
|
|
||||||
fs.rmSync(stateHelper.tmpDir, {recursive: true});
|
|
||||||
core.debug(`Removed temp folder ${stateHelper.tmpDir}`);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.warning(`Error during final cleanup: ${error.message}`);
|
core.warning(`Error during final cleanup: ${error.message}`);
|
||||||
await reporter.reportBuildPushActionFailure(error, 'final cleanup');
|
await reporter.reportBuildPushActionFailure(error, 'final cleanup');
|
||||||
@ -392,4 +315,3 @@ function buildSummaryEnabled(): boolean {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ import * as core from '@actions/core';
|
|||||||
|
|
||||||
import {Inputs, sanitizeInputs} from './context';
|
import {Inputs, sanitizeInputs} from './context';
|
||||||
|
|
||||||
export const tmpDir = process.env['STATE_tmpDir'] || '';
|
|
||||||
export const inputs = process.env['STATE_inputs'] ? JSON.parse(process.env['STATE_inputs']) : undefined;
|
export const inputs = process.env['STATE_inputs'] ? JSON.parse(process.env['STATE_inputs']) : undefined;
|
||||||
export const buildRef = process.env['STATE_buildRef'] || '';
|
export const buildRef = process.env['STATE_buildRef'] || '';
|
||||||
export const isSummarySupported = !!process.env['STATE_isSummarySupported'];
|
export const isSummarySupported = !!process.env['STATE_isSummarySupported'];
|
||||||
@ -14,9 +13,6 @@ export const dockerBuildStatus = process.env['STATE_dockerBuildStatus'] || '';
|
|||||||
export const blacksmithBuilderLaunchTime = process.env['STATE_blacksmithBuilderLaunchTime'] || '';
|
export const blacksmithBuilderLaunchTime = process.env['STATE_blacksmithBuilderLaunchTime'] || '';
|
||||||
export const dockerBuildDurationSeconds = process.env['STATE_dockerBuildDurationSeconds'] || '';
|
export const dockerBuildDurationSeconds = process.env['STATE_dockerBuildDurationSeconds'] || '';
|
||||||
|
|
||||||
export function setTmpDir(tmpDir: string) {
|
|
||||||
core.saveState('tmpDir', tmpDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setInputs(inputs: Inputs) {
|
export function setInputs(inputs: Inputs) {
|
||||||
core.saveState('inputs', JSON.stringify(sanitizeInputs(inputs)));
|
core.saveState('inputs', JSON.stringify(sanitizeInputs(inputs)));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user