fix(registry): use persistent local registry and OCI Distribution API image copy for pushes

This commit is contained in:
2026-02-07 09:41:22 +00:00
parent aa0425f9bc
commit 0cb5515b93
6 changed files with 616 additions and 75 deletions

View File

@@ -187,11 +187,7 @@ export class TsDockerManager {
const total = toBuild.length;
const overallStart = Date.now();
const useRegistry = Dockerfile.needsLocalRegistry(toBuild, options);
if (useRegistry) {
await Dockerfile.startLocalRegistry(this.dockerContext.contextInfo?.isRootless);
}
await Dockerfile.startLocalRegistry(this.dockerContext.contextInfo?.isRootless);
try {
if (options?.parallel) {
@@ -230,7 +226,7 @@ export class TsDockerManager {
await Dockerfile.runWithConcurrency(tasks, concurrency);
// After the entire level completes, tag + push for dependency resolution
// After the entire level completes, push all to local registry + tag for deps
for (const df of level) {
const dependentBaseImages = new Set<string>();
for (const other of toBuild) {
@@ -242,7 +238,8 @@ export class TsDockerManager {
logger.log('info', `Tagging ${df.buildTag} as ${fullTag} for local dependency resolution`);
await smartshellInstance.exec(`docker tag ${df.buildTag} ${fullTag}`);
}
if (useRegistry && toBuild.some(other => other.localBaseDockerfile === df)) {
// Push ALL images to local registry (skip if already pushed via buildx)
if (!df.localRegistryTag) {
await Dockerfile.pushToLocalRegistry(df);
}
}
@@ -281,16 +278,14 @@ export class TsDockerManager {
await smartshellInstance.exec(`docker tag ${dockerfileArg.buildTag} ${fullTag}`);
}
// Push to local registry for buildx (even for cache hits — image exists but registry doesn't)
if (useRegistry && toBuild.some(other => other.localBaseDockerfile === dockerfileArg)) {
// Push ALL images to local registry (skip if already pushed via buildx)
if (!dockerfileArg.localRegistryTag) {
await Dockerfile.pushToLocalRegistry(dockerfileArg);
}
}
}
} finally {
if (useRegistry) {
await Dockerfile.stopLocalRegistry();
}
await Dockerfile.stopLocalRegistry();
}
logger.log('info', `Total build time: ${formatDuration(Date.now() - overallStart)}`);
@@ -398,11 +393,17 @@ export class TsDockerManager {
return;
}
// Push each Dockerfile to each registry
for (const dockerfile of this.dockerfiles) {
for (const registry of registriesToPush) {
await dockerfile.push(registry);
// Start local registry (reads from persistent .nogit/docker-registry/)
await Dockerfile.startLocalRegistry(this.dockerContext.contextInfo?.isRootless);
try {
// Push each Dockerfile to each registry via OCI copy
for (const dockerfile of this.dockerfiles) {
for (const registry of registriesToPush) {
await dockerfile.push(registry);
}
}
} finally {
await Dockerfile.stopLocalRegistry();
}
logger.log('success', 'All images pushed successfully');
@@ -429,7 +430,8 @@ export class TsDockerManager {
}
/**
* Runs tests for all Dockerfiles
* Runs tests for all Dockerfiles.
* Starts the local registry so multi-platform images can be auto-pulled.
*/
public async test(): Promise<void> {
if (this.dockerfiles.length === 0) {
@@ -443,7 +445,14 @@ export class TsDockerManager {
logger.log('info', '');
logger.log('info', '=== TEST PHASE ===');
await Dockerfile.testDockerfiles(this.dockerfiles);
await Dockerfile.startLocalRegistry(this.dockerContext.contextInfo?.isRootless);
try {
await Dockerfile.testDockerfiles(this.dockerfiles);
} finally {
await Dockerfile.stopLocalRegistry();
}
logger.log('success', 'All tests completed');
}