fix: share env reuse image across ts services

This commit is contained in:
UniDesk Codex
2026-07-06 14:24:19 +08:00
parent fac4b7ead9
commit 4ae933eeef
5 changed files with 3673 additions and 8 deletions
+60 -2
View File
@@ -1299,7 +1299,7 @@ async function buildService({ args, repo, commitId, shortCommit, service, buildC
}
async function buildEnvReuseService({ args, repo, commitId, service, buildCreatedAt }) {
const ref = envReuseImageRef(args.registryPrefix, service.serviceId, service.environmentInputHash);
const ref = service.environmentImage ?? envReuseImageRef(args.registryPrefix, service.serviceId, service.environmentInputHash);
const buildSource = `${repo}@env:${service.environmentInputHash}`;
const labels = [
["org.opencontainers.image.source", "https://github.com/pikasTech/HWLAB"],
@@ -1308,6 +1308,8 @@ async function buildEnvReuseService({ args, repo, commitId, service, buildCreate
["org.opencontainers.image.title", `${service.serviceId}-env`],
["hwlab.pikastech.local/runtime-mode", v02EnvReuseRuntimeMode],
["hwlab.pikastech.local/service-id", service.serviceId],
["hwlab.pikastech.local/env-artifact-group", service.envArtifactGroupId ?? ""],
["hwlab.pikastech.local/env-artifact-build-service", service.envArtifactBuildServiceId ?? service.serviceId],
["hwlab.pikastech.local/environment-input-hash", service.environmentInputHash],
["hwlab.pikastech.local/build-created-at", buildCreatedAt]
];
@@ -1323,7 +1325,7 @@ async function buildEnvReuseServiceWithBuildkit({ args, service, ref, buildCreat
const contextDir = await prepareEnvReuseBuildContext(tmpDir, normalizedRecipe, goCacheEnabled);
const metadataPath = path.join(tmpDir, "metadata.json");
const dockerfilePath = path.join(tmpDir, "Dockerfile");
const cacheRef = envReuseCacheRef(args.registryPrefix, service.serviceId);
const cacheRef = service.envArtifactCacheRef ?? envReuseCacheRef(args.registryPrefix, service.serviceId);
const registryOption = buildkitRegistryOption(args.registryPrefix);
const buildkitAddrArgs = args.buildkitAddr ? ["--addr", args.buildkitAddr] : [];
const startedAt = Date.now();
@@ -1432,6 +1434,12 @@ function withEnvReuseArtifactFields({ artifact, service, commitId, buildCreatedA
environmentDigest,
environmentInputHash: service.environmentInputHash ?? null,
codeInputHash: service.codeInputHash ?? null,
envArtifactGroupId: service.envArtifactGroupId ?? null,
envArtifactGroup: service.envArtifactGroup ?? null,
envArtifactBuildServiceId: service.envArtifactBuildServiceId ?? service.serviceId,
envArtifactSourceServiceId: service.envArtifactSourceServiceId ?? service.serviceId,
envArtifactCacheRef: service.envArtifactCacheRef ?? null,
sharedEnvBuildSkipped: service.sharedEnvBuildSkipped === true,
bootRepo: service.bootRepo ?? "git@github.com:pikasTech/HWLAB.git",
bootCommit,
bootSh: service.bootSh ?? `deploy/runtime/boot/${service.serviceId}.sh`,
@@ -1928,6 +1936,36 @@ async function readExternalServiceArtifacts({ dir, services, commitId }) {
return { artifacts, blockers };
}
function artifactRecordFromSharedEnvArtifact({ service, sourceArtifact, commitId }) {
const environmentImage = sourceArtifact.environmentImage ?? sourceArtifact.image ?? service.environmentImage ?? null;
const environmentDigest = sourceArtifact.environmentDigest ?? sourceArtifact.digest ?? service.environmentDigest ?? "not_published";
const artifact = withEnvReuseArtifactFields({
artifact: {
...sourceArtifact,
...service,
serviceId: service.serviceId,
status: publishReadyStatuses.has(sourceArtifact.status) ? "reused" : sourceArtifact.status,
image: environmentImage,
imageTag: imageTagFromReference(environmentImage),
digest: environmentDigest,
repositoryDigest: repositoryDigestFor(environmentImage, environmentDigest),
buildBackend: "shared-env-artifact",
reusedFrom: sourceArtifact.serviceId ?? service.envArtifactSourceServiceId ?? service.envArtifactGroupId ?? null,
notPublishedReason: null
},
service,
commitId,
buildCreatedAt: sourceArtifact.buildCreatedAt ?? null,
buildSource: sourceArtifact.buildSource ?? null
});
return {
...artifact,
envArtifactSourceServiceId: sourceArtifact.serviceId ?? service.envArtifactSourceServiceId ?? null,
sharedEnvBuildSkipped: true,
ciReason: uniquePreserveOrder([...(Array.isArray(service.reason) ? service.reason : []), "shared-env-artifact-consumer"])
};
}
function serviceRequiresCurrentBuildArtifact(service) {
return service?.buildRequired === true || service?.ciBuildRequired === true;
}
@@ -2425,6 +2463,26 @@ async function main() {
if (externalArtifacts.has(service.serviceId)) {
return externalArtifacts.get(service.serviceId);
}
const sharedEnvSourceServiceId = service.envReuse === true && service.envArtifactSourceServiceId && service.envArtifactSourceServiceId !== service.serviceId
? service.envArtifactSourceServiceId
: null;
if (sharedEnvSourceServiceId && externalArtifacts.has(sharedEnvSourceServiceId)) {
const sharedArtifact = artifactRecordFromSharedEnvArtifact({
service,
sourceArtifact: externalArtifacts.get(sharedEnvSourceServiceId),
commitId
});
emit("artifact_reuse", {
serviceId: service.serviceId,
status: sharedArtifact.status,
image: sharedArtifact.image,
digest: sharedArtifact.digest,
reusedFrom: sharedArtifact.reusedFrom ?? null,
envArtifactGroupId: sharedArtifact.envArtifactGroupId ?? null,
envArtifactSourceServiceId: sharedArtifact.envArtifactSourceServiceId ?? null
});
return sharedArtifact;
}
if (!service.artifactRequired || (buildServiceIds.has(service.serviceId) && serviceRequiresCurrentBuildArtifact(service))) {
return artifactRecord({
args,