diff --git a/pkg/build/build.go b/pkg/build/build.go index 87a45978..6057740b 100644 --- a/pkg/build/build.go +++ b/pkg/build/build.go @@ -105,6 +105,8 @@ type Build struct { // mutated by Compile externalRefs []purl.PackageURL + + resolvedApkoConfig apko_types.ImageConfiguration } func New(ctx context.Context, opts ...Option) (*Build, error) { @@ -236,6 +238,26 @@ func (b *Build) Close(ctx context.Context) error { return errors.Join(errs...) } +func (b *Build) resolveConfig(ctx context.Context, bc *apko_build.Context) error { + ic := bc.ImageConfiguration() + pkgs, _, err := bc.BuildPackageList(ctx) + if err != nil { + return fmt.Errorf("resolving package versions: %w", err) + } + resolved := make([]string, 0, len(pkgs)) + for _, pkg := range pkgs { + resolved = append(resolved, fmt.Sprintf("%s=%s", pkg.Name, pkg.Version)) + } + ic.Contents.Packages = resolved + ic.Archs = []apko_types.Architecture{b.Arch} + ic.Contents.BuildRepositories = append(ic.Contents.BuildRepositories, b.ExtraRepos...) + ic.Contents.Keyring = append(ic.Contents.Keyring, b.ExtraKeys...) + + b.resolvedApkoConfig = ic + + return nil +} + // BuildGuest invokes apko to build the guest environment, returning a reference to the image // loaded by the OCI Image loader. func (b *Build) BuildGuest(ctx context.Context, imgConfig apko_types.ImageConfiguration, guestFS apkofs.FullFS) (string, error) { @@ -271,6 +293,10 @@ func (b *Build) BuildGuest(ctx context.Context, imgConfig apko_types.ImageConfig bc.Summarize(ctx) log.Infof("auth configured for: %s", maps.Keys(b.Auth)) // TODO: add this to Summarize + if err := b.resolveConfig(ctx, bc); err != nil { + return "", fmt.Errorf("locking apko config: %w", err) + } + // lay out the contents for the image in a directory. if err := bc.BuildImage(ctx); err != nil { return "", fmt.Errorf("unable to generate image: %w", err) diff --git a/pkg/build/package.go b/pkg/build/package.go index 1f793555..cc571bc0 100644 --- a/pkg/build/package.go +++ b/pkg/build/package.go @@ -210,6 +210,14 @@ func (pc *PackageBuild) generateControlSection(ctx context.Context) ([]byte, err return nil, fmt.Errorf("unable to build control FS: %w", err) } + locked, err := json.Marshal(pc.Build.resolvedApkoConfig) + if err != nil { + return nil, fmt.Errorf("unable to marshal apko config: %w", err) + } + if err := fsys.WriteFile(".BUILD.apko.json", locked, 0644); err != nil { + return nil, fmt.Errorf("unable to write .apko.lock.json: %w", err) + } + if scriptlets := pc.Scriptlets; scriptlets != nil { if scriptlets.Trigger.Script != "" { // #nosec G306 -- scriptlets must be executable