@@ -335,11 +335,46 @@ jobs:
335335 if (!def) {
336336 throw new Error('Bake definition not set');
337337 }
338- const targets = Object.keys(def.target);
339- if (targets.length > 1) {
340- throw new Error(`Only one target can be built at once, found: ${targets.join(', ')}`);
338+ const targetDefs = def.target || {};
339+ const targets = Object.keys(targetDefs);
340+ if (targets.length === 0) {
341+ throw new Error('Bake definition does not contain any targets');
342+ }
343+ const parseContextTarget = value => {
344+ if (typeof value !== 'string') {
345+ return undefined;
346+ }
347+ const match = value.match(/^target:(.+)$/);
348+ return match ? match[1] : undefined;
349+ };
350+ const resolveTarget = () => {
351+ if (targetDefs[inpTarget]) {
352+ return inpTarget;
353+ }
354+ throw new Error(`Unable to resolve ${inpTarget} target, found: ${targets.join(', ')}`);
355+ };
356+ target = resolveTarget();
357+ const allowedTargets = new Set([target]);
358+ const stack = [target];
359+ while (stack.length > 0) {
360+ const current = stack.pop();
361+ const contexts = targetDefs[current]?.contexts || {};
362+ for (const contextValue of Object.values(contexts)) {
363+ const dependencyTarget = parseContextTarget(contextValue);
364+ if (!dependencyTarget || allowedTargets.has(dependencyTarget)) {
365+ continue;
366+ }
367+ if (!targetDefs[dependencyTarget]) {
368+ throw new Error(`Target ${current} uses unknown named context target ${dependencyTarget}`);
369+ }
370+ allowedTargets.add(dependencyTarget);
371+ stack.push(dependencyTarget);
372+ }
373+ }
374+ const unsupportedTargets = targets.filter(name => !allowedTargets.has(name));
375+ if (unsupportedTargets.length > 0) {
376+ throw new Error(`Only one target can be built at once, found unsupported targets: ${unsupportedTargets.join(', ')}`);
341377 }
342- target = targets[0];
343378 });
344379 } catch (error) {
345380 core.setFailed(error);
@@ -581,7 +616,6 @@ jobs:
581616 with :
582617 script : |
583618 const os = require('os');
584- const { Bake } = require('@docker/actions-toolkit/lib/buildx/bake');
585619 const { Build } = require('@docker/actions-toolkit/lib/buildx/build');
586620 const { GitHub } = require('@docker/actions-toolkit/lib/github');
587621 const { Util } = require('@docker/actions-toolkit/lib/util');
@@ -613,11 +647,16 @@ jobs:
613647 const inpGitHubToken = core.getInput('github-token');
614648
615649 const bakeSource = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}.git#${process.env.GITHUB_REF}:${inpContext}`;
616- await core.group(`Set bake source`, async () => {
650+ await core.group(`Set source output `, async () => {
617651 core.info(bakeSource);
618652 core.setOutput('source', bakeSource);
619653 });
620654
655+ await core.group(`Set target output`, async () => {
656+ core.info(inpTarget);
657+ core.setOutput('target', inpTarget);
658+ });
659+
621660 const sbom = inpSbom ? `generator=${inpSbomImage}` : 'false';
622661 await core.group(`Set sbom`, async () => {
623662 core.info(sbom);
@@ -642,34 +681,6 @@ jobs:
642681 core.setOutput('envs', JSON.stringify(envs));
643682 });
644683
645- let target;
646- try {
647- await core.group(`Validating definition`, async () => {
648- const bake = new Bake();
649- const def = await bake.getDefinition({
650- files: inpFiles,
651- overrides: inpSet,
652- sbom: sbom,
653- source: bakeSource,
654- targets: [inpTarget]
655- }, {
656- env: Object.keys(envs).length > 0 ? envs : undefined
657- });
658- if (!def) {
659- throw new Error('Bake definition not set');
660- }
661- const targets = Object.keys(def.target);
662- if (targets.length > 1) {
663- throw new Error(`Only one target can be built at once, found: ${targets.join(', ')}`);
664- }
665- target = targets[0];
666- core.setOutput('target', target);
667- });
668- } catch (error) {
669- core.setFailed(error);
670- return;
671- }
672-
673684 let bakeFiles = inpFiles;
674685 await core.group(`Set bake files`, async () => {
675686 if (bakeFiles.length === 0) {
@@ -719,8 +730,8 @@ jobs:
719730 bakeOverrides.push(`*.platform=${inpPlatform}`);
720731 }
721732 if (inpCache) {
722- bakeOverrides.push(`*.cache-from=type=gha,scope=${inpCacheScope || target }${platformPairSuffix}`);
723- bakeOverrides.push(`*.cache-to=type=gha,ignore-error=true,scope=${inpCacheScope || target }${platformPairSuffix},mode=${inpCacheMode}`);
733+ bakeOverrides.push(`*.cache-from=type=gha,scope=${inpCacheScope || inpTarget }${platformPairSuffix}`);
734+ bakeOverrides.push(`*.cache-to=type=gha,ignore-error=true,scope=${inpCacheScope || inpTarget }${platformPairSuffix},mode=${inpCacheMode}`);
724735 }
725736 core.info(JSON.stringify(bakeOverrides, null, 2));
726737 core.setOutput('overrides', bakeOverrides.join(os.EOL));
0 commit comments