Skip to content

Commit 5edb4ea

Browse files
feat: support target architectures on subpackages
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
1 parent 9b69525 commit 5edb4ea

8 files changed

Lines changed: 88 additions & 39 deletions

File tree

docs/BUILD-FILE.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ The following are the high level sections for the build file, with detailed desc
2323
### subpackages
2424

2525
List of subpackages that this package also produces. For example, docs.
26+
Subpackages may define their own `target-architecture` entries to limit
27+
which architectures produce that subpackage.
2628

2729
### data
2830

@@ -499,4 +501,3 @@ TODO(vaikas): melange config points to apko here:
499501

500502
# pipeline
501503
Pipeline defines the ordered steps to build the package.
502-

pkg/build/build.go

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,39 @@ func (b *Build) Close(ctx context.Context) error {
296296
return errors.Join(errs...)
297297
}
298298

299+
func filterSubpackages(ctx context.Context, subpackages []config.Subpackage, arch apko_types.Architecture) []config.Subpackage {
300+
log := clog.FromContext(ctx)
301+
302+
return slices.DeleteFunc(subpackages, func(sp config.Subpackage) bool {
303+
result, err := shouldRun(sp.If)
304+
if err != nil {
305+
// This shouldn't give an error because we evaluate it in Compile.
306+
panic(err)
307+
}
308+
if !result {
309+
log.Infof("skipping subpackage %s because %s == false", sp.Name, sp.If)
310+
return true
311+
}
312+
313+
if !subpackageTargetsArch(sp, arch) {
314+
log.Infof("skipping subpackage %s because target-architecture does not include %s", sp.Name, arch.ToAPK())
315+
return true
316+
}
317+
318+
return false
319+
})
320+
}
321+
322+
func subpackageTargetsArch(sp config.Subpackage, arch apko_types.Architecture) bool {
323+
if len(sp.TargetArchitecture) == 0 {
324+
return true
325+
}
326+
if len(sp.TargetArchitecture) == 1 && sp.TargetArchitecture[0] == "all" {
327+
return true
328+
}
329+
return slices.Contains(sp.TargetArchitecture, arch.ToAPK())
330+
}
331+
299332
// buildGuest invokes apko to build the guest environment, returning a reference to the image
300333
// loaded by the OCI Image loader.
301334
//
@@ -594,19 +627,7 @@ func (b *Build) BuildPackage(ctx context.Context) error {
594627
return fmt.Errorf("compiling %s: %w", b.ConfigFile, err)
595628
}
596629

597-
// Filter out any subpackages with false If conditions.
598-
b.Configuration.Subpackages = slices.DeleteFunc(b.Configuration.Subpackages, func(sp config.Subpackage) bool {
599-
result, err := shouldRun(sp.If)
600-
if err != nil {
601-
// This shouldn't give an error because we evaluate it in Compile.
602-
panic(err)
603-
}
604-
if !result {
605-
log.Infof("skipping subpackage %s because %s == false", sp.Name, sp.If)
606-
}
607-
608-
return !result
609-
})
630+
b.Configuration.Subpackages = filterSubpackages(ctx, b.Configuration.Subpackages, b.Arch)
610631

611632
// Initialize SBOMGroup for the main package and all subpackages
612633
pkgNames := []string{b.Configuration.Package.Name}

pkg/build/compile_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,28 @@ func TestCompileTest(t *testing.T) {
121121
}
122122
}
123123

124+
func TestFilterSubpackagesTargetArchitecture(t *testing.T) {
125+
subpackages := []config.Subpackage{
126+
{Name: "default"},
127+
{Name: "all", TargetArchitecture: []string{"all"}},
128+
{Name: "native", TargetArchitecture: []string{"x86_64"}},
129+
{Name: "other", TargetArchitecture: []string{"aarch64"}},
130+
}
131+
132+
got := filterSubpackages(context.Background(), subpackages, apko_types.ParseArchitecture("x86_64"))
133+
if got, want := packageNames(got), []string{"default", "all", "native"}; !slices.Equal(got, want) {
134+
t.Errorf("subpackage names: want %v, got %v", want, got)
135+
}
136+
}
137+
138+
func packageNames(subpackages []config.Subpackage) []string {
139+
names := make([]string, 0, len(subpackages))
140+
for _, sp := range subpackages {
141+
names = append(names, sp.Name)
142+
}
143+
return names
144+
}
145+
124146
func Test_stripComments(t *testing.T) {
125147
tests := []struct {
126148
in, want string

pkg/build/test.go

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
"os"
2323
"path/filepath"
2424
"runtime"
25-
"slices"
2625
"time"
2726

2827
"chainguard.dev/apko/pkg/apk/apk"
@@ -251,19 +250,7 @@ func (t *Test) TestPackage(ctx context.Context) error {
251250
return fmt.Errorf("compiling %s tests: %w", t.ConfigFile, err)
252251
}
253252

254-
// Filter out any subpackages with false If conditions.
255-
t.Configuration.Subpackages = slices.DeleteFunc(t.Configuration.Subpackages, func(sp config.Subpackage) bool {
256-
result, err := shouldRun(sp.If)
257-
if err != nil {
258-
// This shouldn't give an error because we evaluate it in Compile.
259-
panic(err)
260-
}
261-
if !result {
262-
log.Infof("skipping subpackage %s because %s == false", sp.Name, sp.If)
263-
}
264-
265-
return !result
266-
})
253+
t.Configuration.Subpackages = filterSubpackages(ctx, t.Configuration.Subpackages, t.Arch)
267254

268255
// Unless a specific architecture is requests, we run the test for all.
269256
inarchs := len(pkg.TargetArchitecture) == 0

pkg/config/config.go

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,8 @@ type Subpackage struct {
861861
URL string `json:"url,omitempty" yaml:"url,omitempty"`
862862
// Optional: The git commit of the subpackage build configuration
863863
Commit string `json:"commit,omitempty" yaml:"commit,omitempty"`
864+
// List of target architectures for which this subpackage should be built
865+
TargetArchitecture []string `json:"target-architecture,omitempty" yaml:"target-architecture,omitempty"`
864866
// Optional: enabling, disabling, and configuration of build checks
865867
Checks Checks `json:"checks" yaml:"checks,omitempty"`
866868
// Test section for the subpackage.
@@ -1551,17 +1553,18 @@ func replacePackage(r *strings.Replacer, commit string, in Package) Package {
15511553

15521554
func replaceSubpackage(r *strings.Replacer, detectedCommit string, in Subpackage) Subpackage {
15531555
return Subpackage{
1554-
If: r.Replace(in.If),
1555-
Name: r.Replace(in.Name),
1556-
Pipeline: replacePipelines(r, in.Pipeline),
1557-
Dependencies: replaceDependencies(r, in.Dependencies),
1558-
Options: in.Options,
1559-
Scriptlets: replaceScriptlets(r, in.Scriptlets),
1560-
Description: r.Replace(in.Description),
1561-
URL: r.Replace(in.URL),
1562-
Commit: replaceCommit(detectedCommit, in.Commit),
1563-
Checks: in.Checks,
1564-
Test: replaceTest(r, in.Test),
1556+
If: r.Replace(in.If),
1557+
Name: r.Replace(in.Name),
1558+
Pipeline: replacePipelines(r, in.Pipeline),
1559+
Dependencies: replaceDependencies(r, in.Dependencies),
1560+
Options: in.Options,
1561+
Scriptlets: replaceScriptlets(r, in.Scriptlets),
1562+
Description: r.Replace(in.Description),
1563+
URL: r.Replace(in.URL),
1564+
Commit: replaceCommit(detectedCommit, in.Commit),
1565+
TargetArchitecture: replaceAll(r, in.TargetArchitecture),
1566+
Checks: in.Checks,
1567+
Test: replaceTest(r, in.Test),
15651568
}
15661569
}
15671570

pkg/config/config_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ environment:
9898
vars:
9999
foo: FOO
100100
bar: BAR
101+
arch: x86_64
101102
102103
var-transforms:
103104
- from: ${{package.version}}
@@ -107,6 +108,8 @@ var-transforms:
107108
108109
subpackages:
109110
- name: subpackage-${{vars.short-package-version}}
111+
target-architecture:
112+
- ${{vars.arch}}
110113
dependencies:
111114
runtime:
112115
- ${{package.name}}-config-${{package.version}}
@@ -181,6 +184,7 @@ test:
181184
}, cfg.Test.Environment.Contents.Packages)
182185

183186
require.Equal(t, cfg.Subpackages[0].Name, "subpackage-0.0")
187+
require.Equal(t, []string{"x86_64"}, cfg.Subpackages[0].TargetArchitecture)
184188

185189
require.Equal(t, "/usr/local/FOO", cfg.Test.Environment.Environment["LD_LIBRARY_PATH"])
186190
}

pkg/config/schema.cue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,10 @@
567567
// Optional: The git commit of the subpackage build configuration
568568
commit?: string
569569

570+
// List of target architectures for which this subpackage should be
571+
// built
572+
"target-architecture"?: [...string]
573+
570574
// Optional: enabling, disabling, and configuration of build
571575
// checks
572576
checks!: #Checks

pkg/config/schema.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,13 @@
10331033
"type": "string",
10341034
"description": "Optional: The git commit of the subpackage build configuration"
10351035
},
1036+
"target-architecture": {
1037+
"items": {
1038+
"type": "string"
1039+
},
1040+
"type": "array",
1041+
"description": "List of target architectures for which this subpackage should be built"
1042+
},
10361043
"checks": {
10371044
"$ref": "#/$defs/Checks",
10381045
"description": "Optional: enabling, disabling, and configuration of build checks"

0 commit comments

Comments
 (0)