feat: 为 PikaOA PaC 添加 registry cache

This commit is contained in:
Codex
2026-07-17 23:57:32 +02:00
parent 4712f7b2bd
commit 5b01722f46
4 changed files with 45 additions and 5 deletions
+12
View File
@@ -67,6 +67,12 @@ developmentRuntime:
api: 127.0.0.1:5000/pikaoa/api
worker: 127.0.0.1:5000/pikaoa/worker
web: 127.0.0.1:5000/pikaoa/web
cache:
mode: registry
refs:
api: 127.0.0.1:5000/pikaoa/cache-api:development
worker: 127.0.0.1:5000/pikaoa/cache-worker:development
web: 127.0.0.1:5000/pikaoa/cache-web:development
networkMode: host
gitops:
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikainc-pikaoa.git
@@ -371,6 +377,12 @@ releaseRuntime:
api: 127.0.0.1:5000/pikaoa/api
worker: 127.0.0.1:5000/pikaoa/worker
web: 127.0.0.1:5000/pikaoa/web
cache:
mode: registry
refs:
api: 127.0.0.1:5000/pikaoa/cache-api:release
worker: 127.0.0.1:5000/pikaoa/cache-worker:release
web: 127.0.0.1:5000/pikaoa/cache-web:release
networkMode: host
gitops:
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikainc-pikaoa.git
+12 -2
View File
@@ -64,6 +64,11 @@ describe("PikaOA development PaC renderer", () => {
expect(serialized).toContain("pikaoa-nc01-pac");
expect(serialized).toContain("refs/unidesk/snapshots/gitea-actions/pikaoa-release-nc01");
expect(serialized).toContain("pac-gitea-pikaoa-nc01");
for (const component of ["api", "worker", "web"]) {
expect(serialized).toContain(`--import-cache 'type=registry,ref=127.0.0.1:5000/pikaoa/cache-${component}:release'`);
expect(serialized).toContain(`--export-cache 'type=registry,ref=127.0.0.1:5000/pikaoa/cache-${component}:release,mode=max'`);
}
expect(serialized).not.toContain(":development'");
expect(serialized).not.toContain("pikaoa-dev-nc01-pac");
} finally {
rmSync(source, { recursive: true, force: true });
@@ -87,6 +92,7 @@ describe("PikaOA development PaC renderer", () => {
}
for (const name of ["build-api", "build-worker", "build-web"]) {
const task = tasks.find((item) => item.name === name);
const component = name.replace("build-", "");
expect(task?.runAfter).toEqual(["source"]);
expect(JSON.stringify(task)).toContain("buildctl-daemonless.sh build");
expect(JSON.stringify(task)).toContain("$(params.revision)");
@@ -97,10 +103,14 @@ describe("PikaOA development PaC renderer", () => {
expect(buildScript).not.toContain("\u0001");
expect(buildScript).toContain("Docker-Content-Digest:");
expect(buildScript).toContain("build_status=$?");
expect(buildScript).toContain(`--import-cache 'type=registry,ref=127.0.0.1:5000/pikaoa/cache-${component}:development'`);
expect(buildScript).toContain(`--export-cache 'type=registry,ref=127.0.0.1:5000/pikaoa/cache-${component}:development,mode=max'`);
expect(buildScript).not.toContain(`cache-${component}:$revision`);
expect(buildScript).toContain('if [ -f "$metadata" ]');
expect(buildScript).toContain("grep -Eq '^sha256:[0-9a-f]{64}$'");
expect(buildScript).toContain('"code":"buildctl-nonzero-artifact-verified"');
expect(buildScript).toContain('"artifactVerified":true');
expect(buildScript).toContain('"code":"buildctl-failed"');
expect(buildScript).toContain('exit "$build_status"');
expect(buildScript).not.toContain('"code":"buildctl-nonzero-artifact-verified"');
}
const digest = "sha256:" + "a".repeat(64);
const metadata = JSON.stringify({ "containerimage.digest": digest }, null, 2);
+7 -3
View File
@@ -162,6 +162,7 @@ function imageBuildTask(target: PikaoaRuntimeSpec, component: "api" | "worker" |
const taskName = `build-${component}`;
const imageRepository = target.build.images[component];
const dockerfile = target.build.dockerfiles[component];
const cacheRef = target.build.cache.refs[component];
return {
name: taskName,
runAfter: ["source"],
@@ -188,9 +189,15 @@ buildctl-daemonless.sh build \\
--opt filename=${shellSingleQuote(dockerfile)} \\
--opt network=${shellSingleQuote(target.build.networkMode)} \\
--output "type=image,name=$tag,push=true" \\
--import-cache ${shellSingleQuote(`type=${target.build.cache.mode},ref=${cacheRef}`)} \\
--export-cache ${shellSingleQuote(`type=${target.build.cache.mode},ref=${cacheRef},mode=max`)} \\
--metadata-file "$metadata"
build_status=$?
set -e
if [ "$build_status" -ne 0 ]; then
printf '{"level":"error","code":"buildctl-failed","component":"${component}","buildctlExitCode":%s,"valuesPrinted":false}\n' "$build_status" >&2
exit "$build_status"
fi
metadata_compact=
if [ -f "$metadata" ]; then
metadata_compact=$(tr -d '\\n\\r' < "$metadata")
@@ -206,9 +213,6 @@ if ! printf '%s' "$digest" | grep -Eq '^sha256:[0-9a-f]{64}$'; then
echo 'build digest missing from metadata and registry manifest' >&2
exit 3
fi
if [ "$build_status" -ne 0 ]; then
printf '{"level":"warning","code":"buildctl-nonzero-artifact-verified","component":"${component}","buildctlExitCode":%s,"artifactVerified":true,"valuesPrinted":false}\\n' "$build_status" >&2
fi
printf '%s' "$digest" > "$(results.digest.path)"
printf '%s@%s' ${shellSingleQuote(imageRepository)} "$digest" > "$(results.image.path)"
printf '{"ok":true,"phase":"${taskName}","sourceCommit":"%s","imageTag":"%s","digest":"%s","valuesPrinted":false}\n' "$revision" "$tag" "$digest"
+14
View File
@@ -146,6 +146,10 @@ export interface PikaoaRuntimeSpec {
build: {
dockerfiles: { api: string; worker: string; web: string };
images: { api: string; worker: string; web: string };
cache: {
mode: "registry";
refs: { api: string; worker: string; web: string };
};
networkMode: string;
};
gitops: {
@@ -278,6 +282,8 @@ function parseRuntime(id: string, root: Record<string, unknown>, configLabel: st
const build = record(root.build, `${path}.build`);
const dockerfiles = record(build.dockerfiles, `${path}.build.dockerfiles`);
const buildImages = record(build.images, `${path}.build.images`);
const buildCache = record(build.cache, `${path}.build.cache`);
const buildCacheRefs = record(buildCache.refs, `${path}.build.cache.refs`);
const gitops = record(root.gitops, `${path}.gitops`);
const gitopsCredential = record(gitops.credential, `${path}.gitops.credential`);
const gitopsAuthor = record(gitops.author, `${path}.gitops.author`);
@@ -346,6 +352,14 @@ function parseRuntime(id: string, root: Record<string, unknown>, configLabel: st
worker: imageRepository(buildImages.worker, `${path}.build.images.worker`),
web: imageRepository(buildImages.web, `${path}.build.images.web`),
},
cache: {
mode: exact(buildCache.mode, `${path}.build.cache.mode`, "registry"),
refs: {
api: imageReference(buildCacheRefs.api, `${path}.build.cache.refs.api`),
worker: imageReference(buildCacheRefs.worker, `${path}.build.cache.refs.worker`),
web: imageReference(buildCacheRefs.web, `${path}.build.cache.refs.web`),
},
},
networkMode: exact(build.networkMode, `${path}.build.networkMode`, "host"),
},
gitops: {