Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package apko for openSUSE:Factory checked in at 2026-07-01 16:47:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/apko (Old) and /work/SRC/openSUSE:Factory/.apko.new.11887 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "apko" Wed Jul 1 16:47:41 2026 rev:121 rq:1362789 version:1.2.20 Changes: -------- --- /work/SRC/openSUSE:Factory/apko/apko.changes 2026-06-25 10:57:26.477862093 +0200 +++ /work/SRC/openSUSE:Factory/.apko.new.11887/apko.changes 2026-07-01 16:47:43.792195674 +0200 @@ -1,0 +2,11 @@ +Wed Jul 01 05:48:29 UTC 2026 - Johannes Kastl <[email protected]> + +- Update to version 1.2.20: + * apk: don't disqualify a package for an unversioned provide + * Add support for gzip-compressed CPIO output (#2253) + * build(deps): bump actions/setup-go from 6.4.0 to 6.5.0 (#2300) + * build(deps): bump github.com/chainguard-dev/clog from 1.8.0 to + 1.8.1 (#2302) + * build(deps): bump imjasonh/setup-crane from 0.6 to 0.7 (#2303) + +------------------------------------------------------------------- Old: ---- apko-1.2.19.obscpio New: ---- apko-1.2.20.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ apko.spec ++++++ --- /var/tmp/diff_new_pack.N4rBGP/_old 2026-07-01 16:47:53.212522172 +0200 +++ /var/tmp/diff_new_pack.N4rBGP/_new 2026-07-01 16:47:53.216522311 +0200 @@ -17,7 +17,7 @@ Name: apko -Version: 1.2.19 +Version: 1.2.20 Release: 0 Summary: Build OCI images from APK packages directly without Dockerfile License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.N4rBGP/_old 2026-07-01 16:47:53.268524113 +0200 +++ /var/tmp/diff_new_pack.N4rBGP/_new 2026-07-01 16:47:53.276524390 +0200 @@ -3,7 +3,7 @@ <param name="url">https://github.com/chainguard-dev/apko.git</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">refs/tags/v1.2.19</param> + <param name="revision">refs/tags/v1.2.20</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> <param name="changesgenerate">enable</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.N4rBGP/_old 2026-07-01 16:47:53.308525499 +0200 +++ /var/tmp/diff_new_pack.N4rBGP/_new 2026-07-01 16:47:53.312525638 +0200 @@ -3,6 +3,6 @@ <param name="url">https://github.com/chainguard-dev/apko</param> <param name="changesrevision">861f83f69e6fa9114405a2f7bb5cf6585ad00421</param></service><service name="tar_scm"> <param name="url">https://github.com/chainguard-dev/apko.git</param> - <param name="changesrevision">5558f35b5b5fd27b50fe000f64395d8c6616216f</param></service></servicedata> + <param name="changesrevision">589da44360c7ffc7a5c1d9219bbbff750d614dc4</param></service></servicedata> (No newline at EOF) ++++++ apko-1.2.19.obscpio -> apko-1.2.20.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-1.2.19/go.mod new/apko-1.2.20/go.mod --- old/apko-1.2.19/go.mod 2026-06-23 16:10:56.000000000 +0200 +++ new/apko-1.2.20/go.mod 2026-06-30 10:51:32.000000000 +0200 @@ -4,7 +4,7 @@ require ( chainguard.dev/sdk v0.1.74 - github.com/chainguard-dev/clog v1.8.0 + github.com/chainguard-dev/clog v1.8.1 github.com/charmbracelet/log v1.0.0 github.com/go-git/go-git/v5 v5.19.1 github.com/google/go-cmp v0.7.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-1.2.19/go.sum new/apko-1.2.20/go.sum --- old/apko-1.2.19/go.sum 2026-06-23 16:10:56.000000000 +0200 +++ new/apko-1.2.20/go.sum 2026-06-30 10:51:32.000000000 +0200 @@ -31,8 +31,8 @@ github.com/buger/jsonparser v1.1.2/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chainguard-dev/clog v1.8.0 h1:frlTMEdg3XQR+ioQ6O9i92uigY8GTUcWKpuCFkhcCHA= -github.com/chainguard-dev/clog v1.8.0/go.mod h1:5MQOZi+Iu7fV7GcJG8ag8rCB5elEOpqRMKEASgnGVdo= +github.com/chainguard-dev/clog v1.8.1 h1:Lab3GEDsVm1J9XGlpWEBuzXX7eETRmd0vN5PYoNyT+Y= +github.com/chainguard-dev/clog v1.8.1/go.mod h1:5MQOZi+Iu7fV7GcJG8ag8rCB5elEOpqRMKEASgnGVdo= github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs= github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk= github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-1.2.19/internal/cli/build-cpio.go new/apko-1.2.20/internal/cli/build-cpio.go --- old/apko-1.2.19/internal/cli/build-cpio.go 2026-06-23 16:10:56.000000000 +0200 +++ new/apko-1.2.20/internal/cli/build-cpio.go 1970-01-01 01:00:00.000000000 +0100 @@ -1,116 +0,0 @@ -// Copyright 2022, 2023 Chainguard, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cli - -import ( - "context" - "fmt" - "os" - "runtime" - - "github.com/spf13/cobra" - - "github.com/chainguard-dev/clog" - - apkfs "chainguard.dev/apko/pkg/apk/fs" - "chainguard.dev/apko/pkg/build" - "chainguard.dev/apko/pkg/build/types" - "chainguard.dev/apko/pkg/cpio" - "chainguard.dev/apko/pkg/options" -) - -func buildCPIO() *cobra.Command { - var buildDate string - var buildArch string - var sbomPath string - var extraKeys []string - var extraBuildRepos []string - var extraRepos []string - var extraPackages []string - var sizeLimits options.SizeLimits - - cmd := &cobra.Command{ - Use: "build-cpio", - Short: "Build a cpio file from a YAML configuration file", - Long: "Build a cpio file from a YAML configuration file", - Example: ` apko build-cpio <config.yaml> <output.cpio>`, - Hidden: true, - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - return BuildCPIOCmd(cmd.Context(), args[1], - build.WithConfig(args[0], []string{}), - build.WithExtraKeys(extraKeys), - build.WithExtraBuildRepos(extraBuildRepos), - build.WithExtraRepos(extraRepos), - build.WithExtraPackages(extraPackages), - build.WithBuildDate(buildDate), - build.WithSBOM(sbomPath), - build.WithArch(types.ParseArchitecture(buildArch)), - build.WithSizeLimits(sizeLimits), - ) - }, - } - - cmd.Flags().StringVar(&buildDate, "build-date", "", "date used for the timestamps of the files inside the image") - cmd.Flags().StringVar(&buildArch, "build-arch", runtime.GOARCH, "architecture to build for -- default is Go runtime architecture") - cmd.Flags().StringVar(&sbomPath, "sbom-path", "", "generate an SBOM") - cmd.Flags().StringSliceVarP(&extraKeys, "keyring-append", "k", []string{}, "path to extra keys to include in the keyring") - cmd.Flags().StringSliceVarP(&extraBuildRepos, "build-repository-append", "b", []string{}, "path to extra repositories to include") - cmd.Flags().StringSliceVarP(&extraRepos, "repository-append", "r", []string{}, "path to extra repositories to include") - cmd.Flags().StringSliceVarP(&extraPackages, "package-append", "p", []string{}, "extra packages to include") - addClientLimitFlags(cmd, &sizeLimits) - - return cmd -} - -func BuildCPIOCmd(ctx context.Context, dest string, opts ...build.Option) error { - log := clog.FromContext(ctx) - wd, err := os.MkdirTemp("", "apko-*") - if err != nil { - return fmt.Errorf("failed to create working directory: %w", err) - } - defer os.RemoveAll(wd) - - fs := apkfs.DirFS(ctx, wd, apkfs.WithCreateDir()) - bc, err := build.New(ctx, fs, opts...) - if err != nil { - return err - } - - ic := bc.ImageConfiguration() - - if len(ic.Archs) != 0 { - log.Warnf("ignoring archs in config, only building for current arch (%s)", bc.Arch()) - } - - _, layer, err := bc.BuildLayer(ctx) - if err != nil { - return fmt.Errorf("failed to build layer image: %w", err) - } - log.Debugf("converting layer to cpio %s", dest) - - // Create the CPIO file, and set up a deduplicating writer - // to produce the gzip-compressed CPIO archive. - f, err := os.Create(dest) - if err != nil { - return err - } - defer f.Close() - - // TODO(mattmoor): Consider wrapping in a gzip writer if the filename - // ends in .gz - - return cpio.FromLayer(layer, f) -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-1.2.19/internal/cli/build_cpio.go new/apko-1.2.20/internal/cli/build_cpio.go --- old/apko-1.2.19/internal/cli/build_cpio.go 1970-01-01 01:00:00.000000000 +0100 +++ new/apko-1.2.20/internal/cli/build_cpio.go 2026-06-30 10:51:32.000000000 +0200 @@ -0,0 +1,125 @@ +// Copyright 2022, 2023 Chainguard, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cli + +import ( + "compress/gzip" + "context" + "fmt" + "os" + "runtime" + "strings" + + "github.com/spf13/cobra" + + "github.com/chainguard-dev/clog" + + apkfs "chainguard.dev/apko/pkg/apk/fs" + "chainguard.dev/apko/pkg/build" + "chainguard.dev/apko/pkg/build/types" + "chainguard.dev/apko/pkg/cpio" + "chainguard.dev/apko/pkg/options" +) + +func buildCPIO() *cobra.Command { + var buildDate string + var buildArch string + var sbomPath string + var extraKeys []string + var extraBuildRepos []string + var extraRepos []string + var extraPackages []string + var sizeLimits options.SizeLimits + + cmd := &cobra.Command{ + Use: "build-cpio", + Short: "Build a cpio file from a YAML configuration file", + Long: "Build a cpio file from a YAML configuration file", + Example: ` apko build-cpio <config.yaml> <output.cpio>`, + Hidden: true, + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + return BuildCPIOCmd(cmd.Context(), args[1], + build.WithConfig(args[0], []string{}), + build.WithExtraKeys(extraKeys), + build.WithExtraBuildRepos(extraBuildRepos), + build.WithExtraRepos(extraRepos), + build.WithExtraPackages(extraPackages), + build.WithBuildDate(buildDate), + build.WithSBOM(sbomPath), + build.WithArch(types.ParseArchitecture(buildArch)), + build.WithSizeLimits(sizeLimits), + ) + }, + } + + cmd.Flags().StringVar(&buildDate, "build-date", "", "date used for the timestamps of the files inside the image") + cmd.Flags().StringVar(&buildArch, "build-arch", runtime.GOARCH, "architecture to build for -- default is Go runtime architecture") + cmd.Flags().StringVar(&sbomPath, "sbom-path", "", "generate an SBOM") + cmd.Flags().StringSliceVarP(&extraKeys, "keyring-append", "k", []string{}, "path to extra keys to include in the keyring") + cmd.Flags().StringSliceVarP(&extraBuildRepos, "build-repository-append", "b", []string{}, "path to extra repositories to include") + cmd.Flags().StringSliceVarP(&extraRepos, "repository-append", "r", []string{}, "path to extra repositories to include") + cmd.Flags().StringSliceVarP(&extraPackages, "package-append", "p", []string{}, "extra packages to include") + addClientLimitFlags(cmd, &sizeLimits) + + return cmd +} + +func BuildCPIOCmd(ctx context.Context, dest string, opts ...build.Option) error { + log := clog.FromContext(ctx) + wd, err := os.MkdirTemp("", "apko-*") + if err != nil { + return fmt.Errorf("failed to create working directory: %w", err) + } + defer os.RemoveAll(wd) + + fs := apkfs.DirFS(ctx, wd, apkfs.WithCreateDir()) + bc, err := build.New(ctx, fs, opts...) + if err != nil { + return err + } + + ic := bc.ImageConfiguration() + + if len(ic.Archs) != 0 { + log.Warnf("ignoring archs in config, only building for current arch (%s)", bc.Arch()) + } + + _, layer, err := bc.BuildLayer(ctx) + if err != nil { + return fmt.Errorf("failed to build layer image: %w", err) + } + log.Debugf("converting layer to cpio %s", dest) + + // Create the CPIO file, and set up a deduplicating writer + // to produce the gzip-compressed CPIO archive. + f, err := os.Create(dest) + if err != nil { + return err + } + defer f.Close() + + // Use a gzip-compressed writer when the output filename ends with .gz. + if strings.HasSuffix(dest, ".gz") { + gzw := gzip.NewWriter(f) + if err := cpio.FromLayer(layer, gzw); err != nil { + gzw.Close() + return err + } + return gzw.Close() + } + + return cpio.FromLayer(layer, f) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-1.2.19/internal/cli/build_cpio_test.go new/apko-1.2.20/internal/cli/build_cpio_test.go --- old/apko-1.2.19/internal/cli/build_cpio_test.go 1970-01-01 01:00:00.000000000 +0100 +++ new/apko-1.2.20/internal/cli/build_cpio_test.go 2026-06-30 10:51:32.000000000 +0200 @@ -0,0 +1,62 @@ +// Copyright 2026 Chainguard, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cli_test + +import ( + "compress/gzip" + "context" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" + + "chainguard.dev/apko/internal/cli" + + "chainguard.dev/apko/pkg/build" +) + +func TestBuildCPIOCmd(t *testing.T) { + ctx := context.Background() + + t.Run("gz suffix produces gzip-compressed output", func(t *testing.T) { + dest := filepath.Join(t.TempDir(), "out.cpio.gz") + + err := cli.BuildCPIOCmd(ctx, dest, build.WithConfig("testdata/apko.yaml", []string{})) + require.NoError(t, err) + + f, err := os.Open(dest) + require.NoError(t, err) + defer f.Close() + + gzr, err := gzip.NewReader(f) + require.NoError(t, err, "expected output to be valid gzip") + defer gzr.Close() + }) + + t.Run("non-gz suffix produces plain cpio output", func(t *testing.T) { + dest := filepath.Join(t.TempDir(), "out.cpio") + + err := cli.BuildCPIOCmd(ctx, dest, build.WithConfig("testdata/apko.yaml", []string{})) + require.NoError(t, err) + + f, err := os.Open(dest) + require.NoError(t, err) + defer f.Close() + + _, err = gzip.NewReader(f) + require.Error(t, err, "expected plain cpio, got gzip") + }) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-1.2.19/pkg/apk/apk/repo.go new/apko-1.2.20/pkg/apk/apk/repo.go --- old/apko-1.2.19/pkg/apk/apk/repo.go 2026-06-23 16:10:56.000000000 +0200 +++ new/apko-1.2.20/pkg/apk/apk/repo.go 2026-06-30 10:51:32.000000000 +0200 @@ -470,6 +470,11 @@ if pp.Name != parsed.Name { continue } + // An unversioned provide can't satisfy a versioned + // constraint, and must not disqualify the package either. + if pp.Version == "" { + continue + } actualVersion, err := cachedParseVersion(pp.Version) // skip invalid ones if err != nil { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-1.2.19/pkg/apk/apk/repo_test.go new/apko-1.2.20/pkg/apk/apk/repo_test.go --- old/apko-1.2.19/pkg/apk/apk/repo_test.go 2026-06-23 16:10:56.000000000 +0200 +++ new/apko-1.2.20/pkg/apk/apk/repo_test.go 2026-06-30 10:51:32.000000000 +0200 @@ -999,6 +999,63 @@ require.Equal(t, []string{"py3.10-pybind11-3.0.4-r0.apk"}, got) } +// A package that carries an unversioned provide can still satisfy a versioned pin +// on its own name. A pinned closure names every package as a versioned +// constraint, so here both unbound-mailcow-compat (which provides unbound-config +// unversioned) and the unbound-config pin resolve cleanly. +// +// The unbound-config pin resolves to the compat package alone through the compat +// package's own version: filterPackages matches a candidate against its package +// version, and because unbound-config and unbound-mailcow-compat are subpackages +// of the same origin they share the version the pin asks for. +// TestUnversionedProvideVersionMismatchDivergesFromApk covers differing versions. +func TestUnversionedProvideDoesNotDisqualifyAgainstVersionedConstraint(t *testing.T) { + repo := Repository{} + index := repo.WithIndex(&APKIndex{ + Packages: []*Package{ + {Name: "unbound-config", Version: "1.25.1-r2", Origin: "unbound"}, + {Name: "unbound-mailcow-compat", Version: "1.25.1-r2", Origin: "unbound", + Provides: []string{"unbound-config"}}, + }, + }) + resolver := NewPkgResolver(context.Background(), testNamedRepositoryFromIndexes([]*RepositoryWithIndex{index})) + pkgs, _, err := resolver.GetPackagesWithDependencies(context.Background(), + []string{"unbound-mailcow-compat=1.25.1-r2", "unbound-config=1.25.1-r2"}, nil) + require.NoError(t, err) + + got := make([]string, 0, len(pkgs)) + for _, p := range pkgs { + got = append(got, p.Filename()) + } + require.Equal(t, []string{"unbound-mailcow-compat-1.25.1-r2.apk"}, got) +} + +// apko satisfies a versioned pin from a candidate's own package version or from a +// versioned provides: entry. apk-tools is more permissive: it treats an +// unversioned provide as a null version that matches any versioned constraint, +// since apk_dep_is_provided defers to apk_version_match where a null version +// compares equal to anything: +// https://github.com/alpinelinux/apk-tools/blob/097d611f2b7da0f6aa42955d53de7ad569133503/src/version.c#L285-L289 +// +// So apko looks to the named package for the version, and a pin that only a +// differently-versioned, unversioned provider could satisfy goes unmet. This is a +// deliberate, known difference from apk-tools; the pinned closures that motivate +// the fix above stay within apko's behaviour, because the provider and the +// provided name share an origin and so a version. +func TestUnversionedProvideVersionMismatchDivergesFromApk(t *testing.T) { + repo := Repository{} + index := repo.WithIndex(&APKIndex{ + Packages: []*Package{ + {Name: "unbound-mailcow-compat", Version: "9.9.9-r9", Origin: "unbound", + Provides: []string{"unbound-config"}}, + }, + }) + resolver := NewPkgResolver(context.Background(), testNamedRepositoryFromIndexes([]*RepositoryWithIndex{index})) + _, _, err := resolver.GetPackagesWithDependencies(context.Background(), + []string{"unbound-config=1.25.1-r2"}, nil) + require.ErrorContains(t, err, "unbound-config=1.25.1-r2") +} + // Between different packages providing the same unversioned virtual name, // provider priority decides, as in apk-tools' compare_providers: // https://github.com/alpinelinux/apk-tools/blob/20fe3dccc423bd401b9828958124664704dedb00/src/solver.c#L641-L667 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-1.2.19/pkg/build/layers.go new/apko-1.2.20/pkg/build/layers.go --- old/apko-1.2.19/pkg/build/layers.go 2026-06-23 16:10:56.000000000 +0200 +++ new/apko-1.2.20/pkg/build/layers.go 2026-06-30 10:51:32.000000000 +0200 @@ -299,8 +299,8 @@ // Maintain our "main" stack. if f.header.Typeflag == tar.TypeDir { // Pop off any directories that are not parents of the current file's directory. - for i := len(stack) - 1; i >= 0; i-- { - if stack[i].path == path.Dir(f.path) { + for i, v := range slices.Backward(stack) { + if v.path == path.Dir(f.path) { break } ++++++ apko.obsinfo ++++++ --- /var/tmp/diff_new_pack.N4rBGP/_old 2026-07-01 16:47:54.336561130 +0200 +++ /var/tmp/diff_new_pack.N4rBGP/_new 2026-07-01 16:47:54.344561407 +0200 @@ -1,5 +1,5 @@ name: apko -version: 1.2.19 -mtime: 1782223856 -commit: 5558f35b5b5fd27b50fe000f64395d8c6616216f +version: 1.2.20 +mtime: 1782809492 +commit: 589da44360c7ffc7a5c1d9219bbbff750d614dc4 ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/apko/vendor.tar.gz /work/SRC/openSUSE:Factory/.apko.new.11887/vendor.tar.gz differ: char 132, line 1
