Merge pull request #99 from useblacksmith/scaffold-multi-platform
src: add scaffolding for support multi-platform builds
This commit is contained in:
commit
1def72df18
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -9,16 +9,10 @@ const config: Config.InitialOptions = {
|
|||
'^.+\\.ts$': 'ts-jest',
|
||||
'^.+\\.js$': 'babel-jest'
|
||||
},
|
||||
transformIgnorePatterns: [
|
||||
'/node_modules/(?!(@buf|@connectrpc)/)'
|
||||
],
|
||||
transformIgnorePatterns: ['/node_modules/(?!(@buf|@connectrpc)/)'],
|
||||
verbose: true,
|
||||
collectCoverage: true,
|
||||
collectCoverageFrom: [
|
||||
'src/**/*.ts',
|
||||
'!src/**/*.d.ts',
|
||||
'!src/**/__tests__/**'
|
||||
]
|
||||
collectCoverageFrom: ['src/**/*.ts', '!src/**/*.d.ts', '!src/**/__tests__/**']
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.1",
|
||||
"@buf/blacksmith_vm-agent.connectrpc_es": "^1.6.1-20250209182455-7d83cfb8ddb1.2",
|
||||
"@buf/blacksmith_vm-agent.connectrpc_es": "^1.6.1-20250211212423-70f4f1344c53.2",
|
||||
"@connectrpc/connect": "^1.6.1",
|
||||
"@connectrpc/connect-node": "^1.6.1",
|
||||
"@docker/actions-toolkit": "0.37.1",
|
||||
|
@ -2304,8 +2304,8 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@buf/blacksmith_vm-agent.bufbuild_es": {
|
||||
"version": "1.10.0-20250209182455-7d83cfb8ddb1.1",
|
||||
"resolved": "https://buf.build/gen/npm/v1/@buf/blacksmith_vm-agent.bufbuild_es/-/blacksmith_vm-agent.bufbuild_es-1.10.0-20250209182455-7d83cfb8ddb1.1.tgz",
|
||||
"version": "1.10.0-20250211212423-70f4f1344c53.1",
|
||||
"resolved": "https://buf.build/gen/npm/v1/@buf/blacksmith_vm-agent.bufbuild_es/-/blacksmith_vm-agent.bufbuild_es-1.10.0-20250211212423-70f4f1344c53.1.tgz",
|
||||
"dependencies": {
|
||||
"@buf/googleapis_googleapis.bufbuild_es": "1.10.0-20250203201857-83c0f6c19b2f.1"
|
||||
},
|
||||
|
@ -2314,10 +2314,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@buf/blacksmith_vm-agent.connectrpc_es": {
|
||||
"version": "1.6.1-20250209182455-7d83cfb8ddb1.2",
|
||||
"resolved": "https://buf.build/gen/npm/v1/@buf/blacksmith_vm-agent.connectrpc_es/-/blacksmith_vm-agent.connectrpc_es-1.6.1-20250209182455-7d83cfb8ddb1.2.tgz",
|
||||
"version": "1.6.1-20250211212423-70f4f1344c53.2",
|
||||
"resolved": "https://buf.build/gen/npm/v1/@buf/blacksmith_vm-agent.connectrpc_es/-/blacksmith_vm-agent.connectrpc_es-1.6.1-20250211212423-70f4f1344c53.2.tgz",
|
||||
"dependencies": {
|
||||
"@buf/blacksmith_vm-agent.bufbuild_es": "1.10.0-20250209182455-7d83cfb8ddb1.1",
|
||||
"@buf/blacksmith_vm-agent.bufbuild_es": "1.10.0-20250211212423-70f4f1344c53.1",
|
||||
"@buf/googleapis_googleapis.connectrpc_es": "1.6.1-20250203201857-83c0f6c19b2f.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
"packageManager": "yarn@3.6.3",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.1",
|
||||
"@buf/blacksmith_vm-agent.connectrpc_es": "^1.6.1-20250209182455-7d83cfb8ddb1.2",
|
||||
"@buf/blacksmith_vm-agent.connectrpc_es": "^1.6.1-20250211212423-70f4f1344c53.2",
|
||||
"@connectrpc/connect": "^1.6.1",
|
||||
"@connectrpc/connect-node": "^1.6.1",
|
||||
"@docker/actions-toolkit": "0.37.1",
|
||||
|
|
|
@ -3,7 +3,7 @@ import * as main from '../main';
|
|||
import * as reporter from '../reporter';
|
||||
import {getDockerfilePath} from '../context';
|
||||
import * as setupBuilder from '../setup_builder';
|
||||
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';
|
||||
|
||||
jest.mock('@actions/core', () => ({
|
||||
debug: jest.fn(),
|
||||
|
@ -34,7 +34,9 @@ jest.mock('../setup_builder', () => ({
|
|||
...jest.requireActual('../setup_builder'),
|
||||
startAndConfigureBuildkitd: jest.fn(),
|
||||
setupStickyDisk: jest.fn(),
|
||||
getNumCPUs: jest.fn().mockResolvedValue(4)
|
||||
getNumCPUs: jest.fn().mockResolvedValue(4),
|
||||
leaveTailnet: jest.fn().mockResolvedValue(undefined),
|
||||
getTailscaleIP: jest.fn()
|
||||
}));
|
||||
|
||||
describe('startBlacksmithBuilder', () => {
|
||||
|
@ -42,7 +44,7 @@ describe('startBlacksmithBuilder', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
mockInputs = {nofallback: false};
|
||||
mockInputs = {nofallback: false, platforms: []};
|
||||
});
|
||||
|
||||
test('should handle missing dockerfile path with nofallback=false', async () => {
|
||||
|
@ -110,7 +112,7 @@ describe('startBlacksmithBuilder', () => {
|
|||
buildId: mockBuildId,
|
||||
exposeId: mockExposeId
|
||||
});
|
||||
expect(setupBuilder.startAndConfigureBuildkitd).toHaveBeenCalledWith(mockParallelism);
|
||||
expect(setupBuilder.startAndConfigureBuildkitd).toHaveBeenCalledWith(mockParallelism, []);
|
||||
expect(reporter.reportBuildPushActionFailure).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
|
32
src/main.ts
32
src/main.ts
|
@ -20,37 +20,13 @@ import * as context from './context';
|
|||
import {promisify} from 'util';
|
||||
import {exec} from 'child_process';
|
||||
import * as reporter from './reporter';
|
||||
import {setupStickyDisk, startAndConfigureBuildkitd, getNumCPUs} from './setup_builder';
|
||||
import {setupStickyDisk, startAndConfigureBuildkitd, getNumCPUs, leaveTailnet} from './setup_builder';
|
||||
import {Metric_MetricType} from '@buf/blacksmith_vm-agent.bufbuild_es/stickydisk/v1/stickydisk_pb';
|
||||
|
||||
const buildxVersion = 'v0.17.0';
|
||||
const mountPoint = '/var/lib/buildkit';
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
async function joinTailnet(): Promise<void> {
|
||||
const token = process.env.BLACKSMITH_TAILSCALE_TOKEN;
|
||||
if (!token || token === 'unset') {
|
||||
core.debug('BLACKSMITH_TAILSCALE_TOKEN environment variable not set, skipping tailnet join');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await execAsync(`sudo tailscale up --authkey=${token} --hostname=${process.env.VM_ID}`);
|
||||
|
||||
core.info('Successfully joined tailnet');
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to join tailnet: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function leaveTailnet(): Promise<void> {
|
||||
try {
|
||||
await execAsync('sudo tailscale down');
|
||||
} catch (error) {
|
||||
core.warning(`Error leaving tailnet: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function setupBuildx(version: string, toolkit: Toolkit): Promise<void> {
|
||||
let toolPath;
|
||||
const standalone = await toolkit.buildx.isStandalone();
|
||||
|
@ -94,8 +70,6 @@ async function setupBuildx(version: string, toolkit: Toolkit): Promise<void> {
|
|||
*/
|
||||
export async function startBlacksmithBuilder(inputs: context.Inputs): Promise<{addr: string | null; buildId: string | null; exposeId: string}> {
|
||||
try {
|
||||
await joinTailnet();
|
||||
|
||||
const dockerfilePath = context.getDockerfilePath(inputs);
|
||||
if (!dockerfilePath) {
|
||||
throw new Error('Failed to resolve dockerfile path');
|
||||
|
@ -107,7 +81,7 @@ export async function startBlacksmithBuilder(inputs: context.Inputs): Promise<{a
|
|||
const parallelism = await getNumCPUs();
|
||||
|
||||
const buildkitdStartTime = Date.now();
|
||||
const buildkitdAddr = await startAndConfigureBuildkitd(parallelism);
|
||||
const buildkitdAddr = await startAndConfigureBuildkitd(parallelism, inputs.platforms);
|
||||
const buildkitdDurationMs = Date.now() - buildkitdStartTime;
|
||||
await reporter.reportMetric(Metric_MetricType.BPA_BUILDKITD_READY_DURATION_MS, buildkitdDurationMs);
|
||||
|
||||
|
@ -128,6 +102,8 @@ export async function startBlacksmithBuilder(inputs: context.Inputs): Promise<{a
|
|||
|
||||
core.warning(`${errorMessage}. Falling back to a local build.`);
|
||||
return {addr: null, buildId: null, exposeId: ''};
|
||||
} finally {
|
||||
await leaveTailnet();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,18 @@
|
|||
import * as core from '@actions/core';
|
||||
import axios, {AxiosError, AxiosInstance, AxiosResponse } from 'axios';
|
||||
import axios, {AxiosError, AxiosInstance, AxiosResponse} from 'axios';
|
||||
import axiosRetry from 'axios-retry';
|
||||
import {ExportRecordResponse} from '@docker/actions-toolkit/lib/types/buildx/history';
|
||||
import FormData from 'form-data';
|
||||
import { createClient } from "@connectrpc/connect";
|
||||
import { createGrpcTransport } from "@connectrpc/connect-node";
|
||||
import { StickyDiskService } from "@buf/blacksmith_vm-agent.connectrpc_es/stickydisk/v1/stickydisk_connect";
|
||||
import { Metric, Metric_MetricType } from "@buf/blacksmith_vm-agent.bufbuild_es/stickydisk/v1/stickydisk_pb";
|
||||
import {createClient} from '@connectrpc/connect';
|
||||
import {createGrpcTransport} from '@connectrpc/connect-node';
|
||||
import {StickyDiskService} from '@buf/blacksmith_vm-agent.connectrpc_es/stickydisk/v1/stickydisk_connect';
|
||||
import {Metric, Metric_MetricType} from '@buf/blacksmith_vm-agent.bufbuild_es/stickydisk/v1/stickydisk_pb';
|
||||
|
||||
// Configure base axios instance for Blacksmith API.
|
||||
const createBlacksmithAPIClient = () => {
|
||||
const apiUrl = process.env.BLACKSMITH_BACKEND_URL || (
|
||||
process.env.BLACKSMITH_ENV?.includes('staging')
|
||||
? 'https://stagingapi.blacksmith.sh'
|
||||
: 'https://api.blacksmith.sh'
|
||||
);
|
||||
const apiUrl = process.env.BLACKSMITH_BACKEND_URL || (process.env.BLACKSMITH_ENV?.includes('staging') ? 'https://stagingapi.blacksmith.sh' : 'https://api.blacksmith.sh');
|
||||
core.debug(`Using Blacksmith API URL: ${apiUrl}`);
|
||||
|
||||
|
||||
const client = axios.create({
|
||||
baseURL: apiUrl,
|
||||
headers: {
|
||||
|
@ -30,8 +26,7 @@ const createBlacksmithAPIClient = () => {
|
|||
retries: 5,
|
||||
retryDelay: axiosRetry.exponentialDelay,
|
||||
retryCondition: (error: AxiosError) => {
|
||||
return axiosRetry.isNetworkOrIdempotentRequestError(error) ||
|
||||
(error.response?.status ? error.response.status >= 500 : false);
|
||||
return axiosRetry.isNetworkOrIdempotentRequestError(error) || (error.response?.status ? error.response.status >= 500 : false);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -41,7 +36,7 @@ const createBlacksmithAPIClient = () => {
|
|||
export function createBlacksmithAgentClient() {
|
||||
const transport = createGrpcTransport({
|
||||
baseUrl: 'http://192.168.127.1:5557',
|
||||
httpVersion: '2',
|
||||
httpVersion: '2'
|
||||
});
|
||||
|
||||
return createClient(StickyDiskService, transport);
|
||||
|
@ -58,7 +53,7 @@ export async function reportBuildPushActionFailure(error?: Error, event?: string
|
|||
message: event ? `${event}: ${error?.message || ''}` : error?.message || '',
|
||||
warning: isWarning || false
|
||||
};
|
||||
|
||||
|
||||
const client = createBlacksmithAPIClient();
|
||||
const response = await client.post('/stickydisks/report-failed', requestOptions);
|
||||
return response.data;
|
||||
|
@ -72,7 +67,7 @@ export async function reportBuildCompleted(exportRes?: ExportRecordResponse, bla
|
|||
|
||||
try {
|
||||
const agentClient = createBlacksmithAgentClient();
|
||||
|
||||
|
||||
await agentClient.commitStickyDisk({
|
||||
exposeId: exposeId || '',
|
||||
stickyDiskKey: process.env.GITHUB_REPO_NAME || '',
|
||||
|
@ -175,22 +170,19 @@ export async function post(client: AxiosInstance, url: string, formData: FormDat
|
|||
return await client.post(url, formData, {
|
||||
headers: {
|
||||
...client.defaults.headers.common,
|
||||
...(formData && { 'Content-Type': 'multipart/form-data' }),
|
||||
...(formData && {'Content-Type': 'multipart/form-data'})
|
||||
},
|
||||
signal: options?.signal
|
||||
});
|
||||
}
|
||||
|
||||
export async function reportMetric(
|
||||
metricType: Metric_MetricType,
|
||||
value: number
|
||||
): Promise<void> {
|
||||
export async function reportMetric(metricType: Metric_MetricType, value: number): Promise<void> {
|
||||
try {
|
||||
const agentClient = createBlacksmithAgentClient();
|
||||
|
||||
|
||||
const metric = new Metric({
|
||||
type: metricType,
|
||||
value: { case: "intValue", value: BigInt(value) }
|
||||
value: {case: 'intValue', value: BigInt(value)}
|
||||
});
|
||||
|
||||
await agentClient.reportMetric({
|
||||
|
@ -202,4 +194,4 @@ export async function reportMetric(
|
|||
// We can enable this once all agents are updated to support metrics.
|
||||
// core.warning('Error reporting metric to BlacksmithAgent:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,16 @@ const BUILDKIT_DAEMON_ADDR = 'tcp://127.0.0.1:1234';
|
|||
const mountPoint = '/var/lib/buildkit';
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
export async function getTailscaleIP(): Promise<string | null> {
|
||||
try {
|
||||
const {stdout} = await execAsync('tailscale ip -4');
|
||||
return stdout.trim();
|
||||
} catch (error) {
|
||||
core.debug(`Error getting tailscale IP: ${error.message}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function maybeFormatBlockDevice(device: string): Promise<string> {
|
||||
try {
|
||||
// Check if device is formatted with ext4
|
||||
|
@ -52,11 +62,11 @@ export async function getNumCPUs(): Promise<number> {
|
|||
}
|
||||
}
|
||||
|
||||
async function writeBuildkitdTomlFile(parallelism: number): Promise<void> {
|
||||
async function writeBuildkitdTomlFile(parallelism: number, addr: string): Promise<void> {
|
||||
const jsonConfig: TOML.JsonMap = {
|
||||
root: '/var/lib/buildkit',
|
||||
grpc: {
|
||||
address: [BUILDKIT_DAEMON_ADDR]
|
||||
address: [addr]
|
||||
},
|
||||
registry: {
|
||||
'docker.io': {
|
||||
|
@ -95,13 +105,12 @@ async function writeBuildkitdTomlFile(parallelism: number): Promise<void> {
|
|||
}
|
||||
}
|
||||
|
||||
async function startBuildkitd(parallelism: number): Promise<string> {
|
||||
export async function startBuildkitd(parallelism: number, addr: string): Promise<string> {
|
||||
try {
|
||||
await writeBuildkitdTomlFile(parallelism);
|
||||
const addr = BUILDKIT_DAEMON_ADDR;
|
||||
await writeBuildkitdTomlFile(parallelism, addr);
|
||||
|
||||
const logStream = fs.createWriteStream('buildkitd.log');
|
||||
const buildkitd = spawn('sudo', ['buildkitd', '--debug', '--addr', addr, '--allow-insecure-entitlement', 'security.insecure', '--config=buildkitd.toml', '--allow-insecure-entitlement', 'network.host'], {
|
||||
const buildkitd = spawn('sudo', ['buildkitd', '--debug', '--config=buildkitd.toml', '--allow-insecure-entitlement', 'security.insecure', '--allow-insecure-entitlement', 'network.host'], {
|
||||
stdio: ['ignore', 'pipe', 'pipe']
|
||||
});
|
||||
|
||||
|
@ -138,20 +147,6 @@ async function startBuildkitd(parallelism: number): Promise<string> {
|
|||
}
|
||||
}
|
||||
|
||||
async function getDiskSize(device: string): Promise<number> {
|
||||
try {
|
||||
const {stdout} = await execAsync(`sudo lsblk -b -n -o SIZE ${device}`);
|
||||
const sizeInBytes = parseInt(stdout.trim(), 10);
|
||||
if (isNaN(sizeInBytes)) {
|
||||
throw new Error('Failed to parse disk size');
|
||||
}
|
||||
return sizeInBytes;
|
||||
} catch (error) {
|
||||
console.error(`Error getting disk size: ${error.message}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getStickyDisk(options?: {signal?: AbortSignal}): Promise<{expose_id: string; device: string}> {
|
||||
const client = await reporter.createBlacksmithAgentClient();
|
||||
|
||||
|
@ -181,14 +176,65 @@ export async function getStickyDisk(options?: {signal?: AbortSignal}): Promise<{
|
|||
};
|
||||
}
|
||||
|
||||
export async function joinTailnet(): Promise<void> {
|
||||
const token = process.env.BLACKSMITH_TAILSCALE_TOKEN;
|
||||
if (!token || token === 'unset') {
|
||||
core.debug('BLACKSMITH_TAILSCALE_TOKEN environment variable not set, skipping tailnet join');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await execAsync(`sudo tailscale up --authkey=${token} --hostname=${process.env.VM_ID}`);
|
||||
|
||||
core.info('Successfully joined tailnet');
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to join tailnet: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function leaveTailnet(): Promise<void> {
|
||||
try {
|
||||
// Check if we're part of a tailnet before trying to leave
|
||||
const {stdout} = await execAsync('sudo tailscale status');
|
||||
if (stdout.trim() !== '') {
|
||||
await execAsync('sudo tailscale down');
|
||||
core.debug('Successfully left tailnet');
|
||||
} else {
|
||||
core.debug('Not part of a tailnet, skipping leave');
|
||||
}
|
||||
} catch (error) {
|
||||
core.warning(`Error leaving tailnet: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// buildkitdTimeoutMs states the max amount of time this action will wait for the buildkitd
|
||||
// daemon to start have its socket ready. It also additionally governs how long we will wait for
|
||||
// the buildkitd workers to be ready.
|
||||
const buildkitdTimeoutMs = 30000;
|
||||
|
||||
export async function startAndConfigureBuildkitd(parallelism: number): Promise<string> {
|
||||
const buildkitdAddr = await startBuildkitd(parallelism);
|
||||
core.debug(`buildkitd daemon started at addr ${buildkitdAddr}`);
|
||||
export async function startAndConfigureBuildkitd(parallelism: number, platforms?: string[]): Promise<string> {
|
||||
// For multi-platform builds, we need to use the tailscale IP
|
||||
let buildkitdAddr = BUILDKIT_DAEMON_ADDR;
|
||||
|
||||
// If we are doing a multi-platform build, we need to join the tailnet and bind buildkitd to the tailscale IP.
|
||||
// We do this so that the remote VM can join the same buildkitd cluster as a worker.
|
||||
if (platforms && platforms.length > 1) {
|
||||
await joinTailnet();
|
||||
const tailscaleIP = await getTailscaleIP();
|
||||
if (!tailscaleIP) {
|
||||
throw new Error('Failed to get tailscale IP for multi-platform build');
|
||||
}
|
||||
buildkitdAddr = `tcp://${tailscaleIP}:1234`;
|
||||
core.info(`Using tailscale IP for multi-platform build: ${buildkitdAddr}`);
|
||||
}
|
||||
|
||||
const addr = await startBuildkitd(parallelism, buildkitdAddr);
|
||||
core.debug(`buildkitd daemon started at addr ${addr}`);
|
||||
|
||||
if (platforms && platforms.length > 1) {
|
||||
// TODO(adityamaru): Queue docker job for multi-platform build with a well known tailscale hostname.
|
||||
// TODO(adityamaru): Wait until the VM joins the tailnet.
|
||||
}
|
||||
|
||||
// Check that buildkit instance is ready by querying workers for up to 30s
|
||||
const startTimeBuildkitReady = Date.now();
|
||||
|
@ -196,10 +242,12 @@ export async function startAndConfigureBuildkitd(parallelism: number): Promise<s
|
|||
|
||||
while (Date.now() - startTimeBuildkitReady < timeoutBuildkitReady) {
|
||||
try {
|
||||
const {stdout} = await execAsync(`sudo buildctl --addr ${BUILDKIT_DAEMON_ADDR} debug workers`);
|
||||
const {stdout} = await execAsync(`sudo buildctl --addr ${addr} debug workers`);
|
||||
const lines = stdout.trim().split('\n');
|
||||
if (lines.length > 1) {
|
||||
// Check if we have output lines beyond the header
|
||||
// For multi-platform builds, we need at least 2 workers
|
||||
const requiredWorkers = platforms && platforms.length > 1 ? 2 : 1;
|
||||
if (lines.length > requiredWorkers) {
|
||||
core.info(`Found ${lines.length - 1} workers, required ${requiredWorkers}`);
|
||||
break;
|
||||
}
|
||||
} catch (error) {
|
||||
|
@ -210,10 +258,11 @@ export async function startAndConfigureBuildkitd(parallelism: number): Promise<s
|
|||
|
||||
// Final check after timeout.
|
||||
try {
|
||||
const {stdout} = await execAsync(`sudo buildctl --addr ${BUILDKIT_DAEMON_ADDR} debug workers`);
|
||||
const {stdout} = await execAsync(`sudo buildctl --addr ${addr} debug workers`);
|
||||
const lines = stdout.trim().split('\n');
|
||||
if (lines.length <= 1) {
|
||||
throw new Error('buildkit workers not ready after 15s timeout');
|
||||
const requiredWorkers = platforms && platforms.length > 1 ? 2 : 1;
|
||||
if (lines.length <= requiredWorkers) {
|
||||
throw new Error(`buildkit workers not ready after ${buildkitdTimeoutMs}ms timeout. Found ${lines.length - 1} workers, required ${requiredWorkers}`);
|
||||
}
|
||||
} catch (error) {
|
||||
core.warning(`Error checking buildkit workers: ${error.message}`);
|
||||
|
@ -225,7 +274,7 @@ export async function startAndConfigureBuildkitd(parallelism: number): Promise<s
|
|||
core.warning(`Background cache pruning failed: ${error.message}`);
|
||||
});
|
||||
|
||||
return buildkitdAddr;
|
||||
return addr;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue