Fix verification container execution
This commit is contained in:
@@ -54,8 +54,16 @@ export function writableMountArgs(
|
|||||||
return ['-v', `${hostPath}:${containerPath}`];
|
return ['-v', `${hostPath}:${containerPath}`];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function tmpfsMountArgs(containerPath: string): string[] {
|
export function tmpfsMountArgs(
|
||||||
|
containerPath: string,
|
||||||
|
options?: string | string[],
|
||||||
|
): string[] {
|
||||||
|
if (!options || (Array.isArray(options) && options.length === 0)) {
|
||||||
return ['--tmpfs', containerPath];
|
return ['--tmpfs', containerPath];
|
||||||
|
}
|
||||||
|
|
||||||
|
const optionText = Array.isArray(options) ? options.join(',') : options;
|
||||||
|
return ['--tmpfs', `${containerPath}:${optionText}`];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stopContainer(name: string): string {
|
export function stopContainer(name: string): string {
|
||||||
|
|||||||
@@ -5,12 +5,16 @@ import path from 'path';
|
|||||||
import { describe, expect, it } from 'vitest';
|
import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
buildDockerRunArgs,
|
||||||
buildVerificationCommand,
|
buildVerificationCommand,
|
||||||
computeVerificationSnapshot,
|
computeVerificationSnapshot,
|
||||||
isVerificationProfile,
|
isVerificationProfile,
|
||||||
runVerificationRequest,
|
runVerificationRequest,
|
||||||
} from './verification.js';
|
} from './verification.js';
|
||||||
import { hasInstalledNodeModules } from './workspace-package-manager.js';
|
import {
|
||||||
|
ensureWorkspaceDependenciesInstalled,
|
||||||
|
hasInstalledNodeModules,
|
||||||
|
} from './workspace-package-manager.js';
|
||||||
|
|
||||||
describe('verification helpers', () => {
|
describe('verification helpers', () => {
|
||||||
it('recognizes only fixed verification profiles', () => {
|
it('recognizes only fixed verification profiles', () => {
|
||||||
@@ -190,4 +194,38 @@ describe('verification helpers', () => {
|
|||||||
expect(result.ok).toBe(false);
|
expect(result.ok).toBe(false);
|
||||||
expect(result.error).toContain('Snapshot mismatch before verification');
|
expect(result.error).toContain('Snapshot mismatch before verification');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('runs verification commands via docker entrypoint override', () => {
|
||||||
|
const repoDir = fs.mkdtempSync(
|
||||||
|
path.join(os.tmpdir(), 'ejclaw-verification-docker-'),
|
||||||
|
);
|
||||||
|
fs.mkdirSync(path.join(repoDir, 'node_modules', '.bin'), {
|
||||||
|
recursive: true,
|
||||||
|
});
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(repoDir, 'package.json'),
|
||||||
|
JSON.stringify({
|
||||||
|
name: 'verification-docker',
|
||||||
|
packageManager: 'bun@1.3.11',
|
||||||
|
scripts: {
|
||||||
|
typecheck: 'tsc --noEmit',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
fs.writeFileSync(path.join(repoDir, 'bun.lock'), '');
|
||||||
|
fs.writeFileSync(path.join(repoDir, 'node_modules', '.bin', 'tsc'), '');
|
||||||
|
ensureWorkspaceDependenciesInstalled(repoDir);
|
||||||
|
|
||||||
|
const command = buildVerificationCommand('typecheck', repoDir);
|
||||||
|
const args = buildDockerRunArgs('/tmp/verify-workspace', repoDir, command);
|
||||||
|
const imageIndex = args.findIndex((value) => value === 'ejclaw-reviewer:latest');
|
||||||
|
|
||||||
|
expect(args).toContain('--entrypoint');
|
||||||
|
expect(args[args.indexOf('--entrypoint') + 1]).toBe(command.file);
|
||||||
|
expect(imageIndex).toBeGreaterThan(args.indexOf('--entrypoint'));
|
||||||
|
expect(args.slice(imageIndex + 1)).toEqual(command.args);
|
||||||
|
expect(args).toContain(
|
||||||
|
'/workspace/project/node_modules/.vite-temp:uid=1000,gid=1000,mode=1777',
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -152,9 +152,10 @@ function detectRuntimeVersion(): string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildDockerRunArgs(
|
export function buildDockerRunArgs(
|
||||||
scratchWorkspace: string,
|
scratchWorkspace: string,
|
||||||
sourceRepoDir: string,
|
sourceRepoDir: string,
|
||||||
|
command: Pick<VerificationCommandSpec, 'file' | 'args'>,
|
||||||
): string[] {
|
): string[] {
|
||||||
const args = [
|
const args = [
|
||||||
'run',
|
'run',
|
||||||
@@ -162,6 +163,8 @@ function buildDockerRunArgs(
|
|||||||
'-i',
|
'-i',
|
||||||
'--workdir',
|
'--workdir',
|
||||||
PRIMARY_PROJECT_MOUNT,
|
PRIMARY_PROJECT_MOUNT,
|
||||||
|
'--entrypoint',
|
||||||
|
command.file,
|
||||||
'-e',
|
'-e',
|
||||||
`TZ=${TIMEZONE}`,
|
`TZ=${TIMEZONE}`,
|
||||||
'-e',
|
'-e',
|
||||||
@@ -196,6 +199,12 @@ function buildDockerRunArgs(
|
|||||||
path.join(PRIMARY_PROJECT_MOUNT, 'node_modules'),
|
path.join(PRIMARY_PROJECT_MOUNT, 'node_modules'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
args.push(
|
||||||
|
...tmpfsMountArgs(
|
||||||
|
path.join(PRIMARY_PROJECT_MOUNT, 'node_modules', '.vite-temp'),
|
||||||
|
['uid=1000', 'gid=1000', 'mode=1777'],
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const pnpmStore = detectPnpmStorePath(sourceRepoDir);
|
const pnpmStore = detectPnpmStorePath(sourceRepoDir);
|
||||||
@@ -204,6 +213,7 @@ function buildDockerRunArgs(
|
|||||||
}
|
}
|
||||||
|
|
||||||
args.push(...tmpfsMountArgs('/tmp'));
|
args.push(...tmpfsMountArgs('/tmp'));
|
||||||
|
args.push(REVIEWER_CONTAINER_IMAGE, ...command.args);
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
@@ -346,8 +356,7 @@ export async function runVerificationRequest(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const dockerArgs = buildDockerRunArgs(scratchWorkspace, repoDir);
|
const dockerArgs = buildDockerRunArgs(scratchWorkspace, repoDir, command);
|
||||||
dockerArgs.push(REVIEWER_CONTAINER_IMAGE, command.file, ...command.args);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { stdout, stderr } = await execFileCapture(
|
const { stdout, stderr } = await execFileCapture(
|
||||||
|
|||||||
Reference in New Issue
Block a user