fix: add aipod imageRef work-ready runner reuse

This commit is contained in:
AgentRun Codex
2026-06-11 01:21:56 +08:00
parent 59272f8edb
commit 5a6e5a4bbd
22 changed files with 598 additions and 32 deletions
+37 -3
View File
@@ -1,11 +1,13 @@
import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";
import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
import { execFile } from "node:child_process";
import { promisify } from "node:util";
import path from "node:path";
import type { SelfTestCase } from "../harness.js";
import { imageRefSourceIdentity, imageRefSourceSummary, isDigestPinnedImage, validateAipodImageRef } from "../../common/env-image-ref.js";
import { smokeBundledWorkReadyCapabilities, smokeImageWorkReadyCapabilities, staticWorkReadyCapabilitySummary } from "../../common/work-ready.js";
const requiredRunnerPackages = Object.freeze(["git", "openssh-client", "ripgrep"]);
const requiredRunnerPackages = Object.freeze(["ca-certificates", "curl", "git", "github-cli", "kubectl", "nodejs", "npm", "openssh-client", "ripgrep"]);
const execFileAsync = promisify(execFile);
const selfTest: SelfTestCase = async (context) => {
@@ -18,6 +20,9 @@ const selfTest: SelfTestCase = async (context) => {
for (const packageName of requiredRunnerPackages) {
assert.equal(apkPackages.has(packageName), true, `runner image must install ${packageName}`);
}
assert.equal(containerfile.includes("bun install --production"), true, "runner image must install AgentRun npm dependencies at image build time");
assert.equal(containerfile.includes("npm --version"), true, "runner image build smoke must verify npm");
assert.equal(containerfile.includes("gh --version"), true, "runner image build smoke must verify GitHub CLI");
assert.equal(tran.startsWith("#!/usr/bin/env bun\n"), true, "tools/tran must be a shebang executable discovered by gitbundle tools");
assert.equal(trans.startsWith("#!/bin/sh\n"), true, "tools/trans must be a shebang executable discovered by gitbundle tools");
@@ -35,10 +40,39 @@ const selfTest: SelfTestCase = async (context) => {
assert.equal(parsed.unsupported?.includes("apply-patch"), false);
const patchHelp = await execFileAsync(path.join(context.root, "tools/apply_patch"), ["--help"], { cwd: context.root, timeout: 10_000 });
assert.equal(patchHelp.stdout.includes("reads *** Begin Patch format"), true);
const summary = staticWorkReadyCapabilitySummary();
assert.equal(summary.valuesPrinted, false);
assert.ok((summary.requiredImageTools as string[]).includes("npm"), "work-ready capability must include npm");
assert.ok((summary.requiredImageTools as string[]).includes("gh"), "work-ready capability must include gh");
assert.equal(((summary.dependencyStrategy as { projectDependencies?: unknown }).projectDependencies), "not-installed-by-default");
const fakeBin = await createFakeToolBin(path.join(context.tmp, "work-ready-bin"));
const smokeEnv = { PATH: fakeBin, AGENTRUN_RESOURCE_BIN_PATH: path.join(context.root, "tools") };
const imageSmoke = await smokeImageWorkReadyCapabilities(smokeEnv);
assert.equal(((imageSmoke.smoke as { ok?: unknown }).ok), true);
assert.equal(imageSmoke.valuesPrinted, false);
const bundleSmoke = await smokeBundledWorkReadyCapabilities(smokeEnv);
assert.equal(((bundleSmoke.smoke as { ok?: unknown }).ok), true);
assert.equal(bundleSmoke.valuesPrinted, false);
assert.equal(JSON.stringify({ imageSmoke, bundleSmoke }).includes("GH_TOKEN"), false);
const imageRef = validateAipodImageRef({ kind: "env-image-dockerfile", repoUrl: "git@github.com:pikasTech/agentrun.git", commitId: "59272f8edb4e23d805b7b9da0050ec40cfc0233d", dockerfilePath: "deploy/container/Containerfile" });
assert.equal(imageRefSourceIdentity(imageRef).length, 20);
assert.equal((imageRefSourceSummary(imageRef).valuesPrinted), false);
assert.equal(isDigestPinnedImage("127.0.0.1:5000/agentrun/agentrun-mgr@sha256:1111111111111111111111111111111111111111111111111111111111111111"), true);
assert.equal(isDigestPinnedImage("127.0.0.1:5000/agentrun/agentrun-mgr:self-test"), false);
return { name: "90-runner-image-tools", tests: ["runner image installs required CLI tools", "gitbundle tran tools are executable and documented", "runner apply-patch helper is bundled"] };
return { name: "90-runner-image-tools", tests: ["runner image installs required CLI tools", "runner image build verifies work-ready tools", "gitbundle tran tools are executable and documented", "runner apply-patch helper is bundled", "work-ready smoke runs without printing secrets", "aipod imageRef validates env image source identity"] };
};
async function createFakeToolBin(dir: string): Promise<string> {
await mkdir(dir, { recursive: true });
for (const tool of ["bun", "node", "npm", "git", "ssh", "gh", "rg", "curl", "kubectl"]) {
const file = path.join(dir, tool);
await writeFile(file, `#!/bin/sh\necho ${tool}-selftest-version\n`, "utf8");
await chmod(file, 0o755);
}
return dir;
}
function installedApkPackages(containerfile: string): Set<string> {
const packages = new Set<string>();
const normalized = containerfile.replace(/\\\s*\r?\n\s*/gu, " ");