mirror of
https://github.com/docker/build-push-action.git
synced 2025-06-28 07:16:42 +02:00
Merge pull request #4 from WarpBuilds/feat/teardown_post_hook
This commit is contained in:
commit
0288f15378
8 changed files with 4820 additions and 7312 deletions
7
.github/workflows/debug.yaml
vendored
7
.github/workflows/debug.yaml
vendored
|
@ -3,7 +3,8 @@ name: Debug WarpBuild Docker Configure Action
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- fix-error-messages
|
- feat/teardown_post_hook
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
WARPBUILD_API_DOMAIN: "https://api.dev.warpbuild.dev"
|
WARPBUILD_API_DOMAIN: "https://api.dev.warpbuild.dev"
|
||||||
|
@ -14,7 +15,7 @@ jobs:
|
||||||
runs-on: warpdev-ubuntu-latest-x64-2x
|
runs-on: warpdev-ubuntu-latest-x64-2x
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
run_number: [1,2]
|
run_number: [1]
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
|
@ -29,6 +30,6 @@ jobs:
|
||||||
push: false
|
push: false
|
||||||
# platforms: linux/amd64,linux/arm64
|
# platforms: linux/amd64,linux/arm64
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64
|
||||||
profile-name: test-dev
|
profile-name: dev-eph
|
||||||
|
|
||||||
|
|
||||||
|
|
48
dist/index.js
generated
vendored
48
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
985
dist/licenses.txt
generated
vendored
985
dist/licenses.txt
generated
vendored
File diff suppressed because it is too large
Load diff
2
dist/sourcemap-register.js
generated
vendored
2
dist/sourcemap-register.js
generated
vendored
File diff suppressed because one or more lines are too long
18
src/main.ts
18
src/main.ts
|
@ -17,7 +17,7 @@ import {BuilderInfo} from '@docker/actions-toolkit/lib/types/buildx/builder';
|
||||||
import {ConfigFile} from '@docker/actions-toolkit/lib/types/docker/docker';
|
import {ConfigFile} from '@docker/actions-toolkit/lib/types/docker/docker';
|
||||||
import {UploadArtifactResponse} from '@docker/actions-toolkit/lib/types/github';
|
import {UploadArtifactResponse} from '@docker/actions-toolkit/lib/types/github';
|
||||||
|
|
||||||
import {WarpBuildRemoteBuilders, performCleanup} from './warpbuild';
|
import {WarpBuildRemoteBuilders} from './warpbuild';
|
||||||
|
|
||||||
import * as context from './context';
|
import * as context from './context';
|
||||||
|
|
||||||
|
@ -205,7 +205,7 @@ actionsToolkit.run(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remoteBuilders) {
|
if (remoteBuilders) {
|
||||||
remoteBuilders.saveCleanupState();
|
remoteBuilders.saveState();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// post
|
// post
|
||||||
|
@ -250,7 +250,19 @@ actionsToolkit.run(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await performCleanup();
|
const inputs: context.Inputs = await context.getInputs();
|
||||||
|
const parsedTimeout = parseInt(inputs.timeout);
|
||||||
|
|
||||||
|
remoteBuilders = new WarpBuildRemoteBuilders({
|
||||||
|
apiKey: inputs.apiKey,
|
||||||
|
profileName: inputs.profileName,
|
||||||
|
timeout: parsedTimeout
|
||||||
|
});
|
||||||
|
|
||||||
|
remoteBuilders.loadState();
|
||||||
|
await remoteBuilders.removeBuilderInstances();
|
||||||
|
await remoteBuilders.removeBuilderConfiguration();
|
||||||
|
await remoteBuilders.removeCertDirs();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ interface BuilderDetailsResponse extends BuilderInstance {}
|
||||||
|
|
||||||
interface CleanupState {
|
interface CleanupState {
|
||||||
builderName: string;
|
builderName: string;
|
||||||
|
builderInstances: BuilderInstance[];
|
||||||
certDirs: string[];
|
certDirs: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ export class WarpBuildRemoteBuilders {
|
||||||
private readonly isWarpBuildRunner: boolean;
|
private readonly isWarpBuildRunner: boolean;
|
||||||
private readonly scriptStartTime: number;
|
private readonly scriptStartTime: number;
|
||||||
private readonly apiDomain: string;
|
private readonly apiDomain: string;
|
||||||
private readonly builderName: string;
|
private builderName: string;
|
||||||
private builderInstances: BuilderInstance[] = [];
|
private builderInstances: BuilderInstance[] = [];
|
||||||
private certDirs: string[] = [];
|
private certDirs: string[] = [];
|
||||||
private assignmentPromise: Promise<void> | null = null;
|
private assignmentPromise: Promise<void> | null = null;
|
||||||
|
@ -82,16 +83,30 @@ export class WarpBuildRemoteBuilders {
|
||||||
/**
|
/**
|
||||||
* Save cleanup state to GitHub Actions state
|
* Save cleanup state to GitHub Actions state
|
||||||
*/
|
*/
|
||||||
public saveCleanupState(): void {
|
public saveState(): void {
|
||||||
const state: CleanupState = {
|
const state: CleanupState = {
|
||||||
builderName: this.builderName,
|
builderName: this.builderName,
|
||||||
|
builderInstances: this.builderInstances,
|
||||||
certDirs: this.certDirs
|
certDirs: this.certDirs
|
||||||
};
|
};
|
||||||
|
|
||||||
core.saveState('warpbuild-cleanup-state', JSON.stringify(state));
|
core.saveState('warpbuild-state', JSON.stringify(state));
|
||||||
core.debug(`Saved cleanup state: ${JSON.stringify(state)}`);
|
core.debug(`Saved cleanup state: ${JSON.stringify(state)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public loadState(): void {
|
||||||
|
const stateStr = core.getState('warpbuild-state');
|
||||||
|
if (stateStr) {
|
||||||
|
const state = JSON.parse(stateStr) as CleanupState;
|
||||||
|
this.builderName = state.builderName;
|
||||||
|
this.builderInstances = state.builderInstances;
|
||||||
|
this.certDirs = state.certDirs;
|
||||||
|
core.debug(`Loaded cleanup state: ${JSON.stringify(state)}`);
|
||||||
|
} else {
|
||||||
|
core.debug('No cleanup state found');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if required tools are available
|
* Check if required tools are available
|
||||||
*/
|
*/
|
||||||
|
@ -175,6 +190,7 @@ export class WarpBuildRemoteBuilders {
|
||||||
|
|
||||||
core.info(`✓ Successfully assigned ${data.builder_instances.length} builder(s) after ${retryCount} attempts`);
|
core.info(`✓ Successfully assigned ${data.builder_instances.length} builder(s) after ${retryCount} attempts`);
|
||||||
this.builderInstances = data.builder_instances;
|
this.builderInstances = data.builder_instances;
|
||||||
|
this.saveState();
|
||||||
return;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof Error && error.message.startsWith('API Error:')) {
|
if (error instanceof Error && error.message.startsWith('API Error:')) {
|
||||||
|
@ -452,42 +468,46 @@ export class WarpBuildRemoteBuilders {
|
||||||
private determineRunnerType(): boolean {
|
private determineRunnerType(): boolean {
|
||||||
return Boolean(process.env.WARPBUILD_RUNNER_VERIFICATION_TOKEN);
|
return Boolean(process.env.WARPBUILD_RUNNER_VERIFICATION_TOKEN);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
public async removeBuilderConfiguration(): Promise<void> {
|
||||||
* Static cleanup function that can be called from post step
|
await execAsync(`docker buildx rm ${this.builderName} --force`).catch(error => {
|
||||||
* without needing the class instance
|
core.warning(`Failed to remove Docker buildx builder: ${error.message}`);
|
||||||
*/
|
});
|
||||||
export async function performCleanup(): Promise<void> {
|
|
||||||
const stateJson = core.getState('warpbuild-cleanup-state');
|
|
||||||
if (!stateJson) {
|
|
||||||
core.info('No cleanup state found');
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
public async removeBuilderInstances(): Promise<void> {
|
||||||
const state: CleanupState = JSON.parse(stateJson);
|
for (const builderInstance of this.builderInstances) {
|
||||||
|
try {
|
||||||
|
const removeBuilderEndpoint = `${this.apiDomain}/api/v1/builders/${builderInstance.id}/teardown`;
|
||||||
|
const authHeader = this.isWarpBuildRunner ? `Bearer ${process.env.WARPBUILD_RUNNER_VERIFICATION_TOKEN}` : `Bearer ${this.apiKey}`;
|
||||||
|
|
||||||
await core.group(`Cleaning up WarpBuild resources from state`, async () => {
|
const response = await fetch(removeBuilderEndpoint, {
|
||||||
// Remove Docker buildx builder
|
method: 'DELETE',
|
||||||
if (state.builderName) {
|
headers: {Authorization: authHeader}
|
||||||
core.info(`Removing Docker buildx builder: ${state.builderName}`);
|
|
||||||
await execAsync(`docker buildx rm ${state.builderName} --force`).catch(error => {
|
|
||||||
core.warning(`Failed to remove Docker buildx builder: ${error.message}`);
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
// Remove certificate directories
|
if (!response.ok) {
|
||||||
for (const certDir of state.certDirs) {
|
const errorData = await response.json().catch(() => ({message: 'Unknown error'}));
|
||||||
|
throw new Error(`Failed to remove builder instance: ${errorData.description || errorData.message || 'Unknown error'}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
core.info(`Builder instance ${builderInstance.id} removed successfully`);
|
||||||
|
} catch (error) {
|
||||||
|
core.warning(`Failed to remove builder instance: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async removeCertDirs(): Promise<void> {
|
||||||
|
for (const certDir of this.certDirs) {
|
||||||
|
try {
|
||||||
if (fs.existsSync(certDir)) {
|
if (fs.existsSync(certDir)) {
|
||||||
core.info(`Removing certificate directory: ${certDir}`);
|
core.info(`Removing certificate directory: ${certDir}`);
|
||||||
fs.rmSync(certDir, {recursive: true, force: true});
|
fs.rmSync(certDir, {recursive: true, force: true});
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
core.warning(`Failed to remove certificate directory: ${error.message}`);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
core.info('Cleanup completed successfully');
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
core.warning(`Error during cleanup from state: ${error.message}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue