fix: run Electron artifact builds in the bounded worker [CI SKIP]

This commit is contained in:
2026-11-02 17:39:58 +09:00
parent ca4a819506
commit 6007e99985
9 changed files with 163 additions and 100 deletions
+27
View File
@@ -0,0 +1,27 @@
const fs = require('node:fs');
const path = require('node:path');
const { spawnSync } = require('node:child_process');
const config = JSON.parse(fs.readFileSync('/run/secrets/build-config', 'utf8'));
const env = {
...process.env,
NODE_ENV: 'development',
...config.env,
NODE_OPTIONS: '--max-old-space-size=4096',
npm_config_jobs: '2',
MAKEFLAGS: '-j2',
CMAKE_BUILD_PARALLEL_LEVEL: '2',
UV_THREADPOOL_SIZE: '2',
GOMAXPROCS: '2',
};
for (const [phase, command] of [['install', config.installCommand], ['build', config.buildCommand]]) {
console.log(`[artifact] ${phase} started inside resource-limited worker`);
const result = spawnSync('/bin/sh', ['-c', command], { cwd: '/workspace', env, stdio: 'inherit' });
if (result.error || result.status !== 0) {
console.error(`[artifact] ${phase} failed: ${result.error?.message || result.signal || result.status}`);
process.exit(result.status || 1);
}
}
const output = fs.realpathSync(path.resolve('/workspace', config.outputDir));
if (!output.startsWith('/workspace/')) throw new Error('Artifact output escaped the checkout');
fs.cpSync(output, '/build-output', { recursive: true });
+14
View File
@@ -0,0 +1,14 @@
# syntax=docker/dockerfile:1
FROM node:22-bookworm-slim AS build
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates curl git python3 make g++ \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /workspace
COPY source/ ./
COPY runner.cjs /build-runner.cjs
ARG BUILD_REQUEST_ID
RUN --mount=type=secret,id=build-config,required=true \
test -n "$BUILD_REQUEST_ID" && timeout --signal=TERM --kill-after=10s 1800 node /build-runner.cjs
FROM scratch AS artifact
COPY --from=build /build-output/ /
+5
View File
@@ -39,4 +39,9 @@ limits=$("$docker_bin" inspect "$container" --format '{{.HostConfig.CpuPeriod}}
}
echo '[limits] shared image builder: 2 CPUs, 8 GiB RAM, no swap'
if [ "${1:-}" = --prepare-only ]; then exit 0; fi
if [ "${1:-}" = --artifact-output ]; then
destination=$2
shift 2
exec "$docker_bin" buildx build --builder "$builder" --output "type=local,dest=$destination" --progress plain "$@"
fi
exec "$docker_bin" buildx build --builder "$builder" --load --progress plain "$@"
+6
View File
@@ -62,3 +62,9 @@ test('prepare-only never builds an application', () => {
assert.equal(result.status, 0, result.stderr);
assert.ok(!result.calls.some((a) => a[0] === 'buildx' && a[1] === 'build'));
});
test('Electron artifacts use the same bounded worker and local output exporter', () => {
const result = run({}, ['--artifact-output', '/tmp/artifacts', '-f', '/tmp/artifact.Dockerfile', '/tmp/context']);
assert.equal(result.status, 0, result.stderr);
assert.deepEqual(result.calls.at(-1), ['buildx', 'build', '--builder', 'studio-limited', '--output', 'type=local,dest=/tmp/artifacts', '--progress', 'plain', '-f', '/tmp/artifact.Dockerfile', '/tmp/context']);
});