Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions src/server/lib/nativeBuild/__tests__/buildkit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,17 @@ describe('buildkitBuild', () => {
});

it('uses custom buildkit configuration from global config', async () => {
const configWithCache = {
...mockGlobalConfig,
buildDefaults: {
...mockGlobalConfig.buildDefaults,
cacheRegistry: 'lifecycle-distribution.lifecycle-app.svc.cluster.local',
},
};
(GlobalConfigService.getInstance as jest.Mock).mockReturnValue({
getAllConfigs: jest.fn().mockResolvedValue(configWithCache),
});

await buildkitBuild(mockDeploy, mockOptions);

const kubectlCalls = (shellPromise as jest.Mock).mock.calls;
Expand All @@ -144,8 +155,10 @@ describe('buildkitBuild', () => {
// Check custom endpoint is used
expect(fullCommand).toContain('value: "tcp://buildkit-custom.svc.cluster.local:1234"');

// Check cache uses ECR repo cache when custom buildkit endpoint is configured
expect(fullCommand).toContain('ref=123456789.dkr.ecr.us-east-1.amazonaws.com/test-repo:cache');
// Check cache uses local distribution registry with service name to avoid collisions
expect(fullCommand).toContain(
'ref=lifecycle-distribution.lifecycle-app.svc.cluster.local/test-repo/test-service:cache'
);

// Check custom resources are applied
expect(fullCommand).toContain('cpu: "1"');
Expand Down
24 changes: 19 additions & 5 deletions src/server/lib/nativeBuild/engines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,18 @@ buildctl ${buildctlArgs.join(' \\\n ')}
},
};

/**
* Appends service name to cache reference for non-ECR registries to avoid cache collisions
* @param cacheRef - Cache reference (e.g., 'registry/repo:cache' or 'registry/repo/cache')
* @param serviceName - Service name to append (e.g., 'psp-web')
* @returns Modified cache reference with service name (e.g., 'registry/repo/psp-web:cache')
*/
function appendServiceNameToCacheRef(cacheRef: string, serviceName: string): string {
// Insert service name before the cache suffix (supports :cache and /cache)
const suffix = cacheRef.includes(':cache') ? ':cache' : '/cache';
return cacheRef.replace(suffix, `/${serviceName}${suffix}`);
}

function createBuildContainer(
name: string,
engine: BuildEngine,
Expand Down Expand Up @@ -235,10 +247,7 @@ export async function buildWithEngine(
const jobTimeout = options.jobTimeout || buildDefaults.jobTimeout || 2100;
const resources = options.resources || buildDefaults.resources?.[engineName] || DEFAULT_BUILD_RESOURCES[engineName];

let cacheRegistry = options.cacheRegistry || buildDefaults.cacheRegistry;
if (engineName === 'buildkit' && buildDefaults.buildkit?.endpoint) {
cacheRegistry = options.ecrDomain;
}
const cacheRegistry = options.cacheRegistry || buildDefaults.cacheRegistry;

const serviceName = deploy.deployable!.name;
const shortRepoName = options.repo.split('/')[1] || options.repo;
Expand Down Expand Up @@ -312,7 +321,12 @@ export async function buildWithEngine(
}

const containers = [];
const cacheRef = engine.getCacheRef(cacheRegistry, options.ecrRepo);
let cacheRef = engine.getCacheRef(cacheRegistry, options.ecrRepo);

// For non-ECR registries (like local distribution), append service name to avoid cache collisions
if (cacheRegistry && !cacheRegistry.includes('ecr') && !cacheRef.includes(`/${serviceName}`)) {
cacheRef = appendServiceNameToCacheRef(cacheRef, serviceName);
}

const mainDestination = `${options.ecrDomain}/${options.ecrRepo}:${options.tag}`;
containers.push(
Expand Down