Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package apko for openSUSE:Factory checked in at 2025-05-22 16:56:46 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/apko (Old) and /work/SRC/openSUSE:Factory/.apko.new.2732 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "apko" Thu May 22 16:56:46 2025 rev:52 rq:1279148 version:0.27.7 Changes: -------- --- /work/SRC/openSUSE:Factory/apko/apko.changes 2025-05-13 20:06:02.944292087 +0200 +++ /work/SRC/openSUSE:Factory/.apko.new.2732/apko.changes 2025-05-22 16:57:16.650960310 +0200 @@ -1,0 +2,9 @@ +Thu May 22 04:37:55 UTC 2025 - Johannes Kastl <opensuse_buildserv...@ojkastl.de> + +- Update to version 0.27.7: + * improve error messages in expandApk (#1675) + * [StepSecurity] Apply security best practices (#1674) + * sbom: resolve issues with missing/invalid image SBOM + information (#1672) + +------------------------------------------------------------------- Old: ---- apko-0.27.6.obscpio New: ---- apko-0.27.7.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ apko.spec ++++++ --- /var/tmp/diff_new_pack.e0X9ih/_old 2025-05-22 16:57:17.526997913 +0200 +++ /var/tmp/diff_new_pack.e0X9ih/_new 2025-05-22 16:57:17.530998085 +0200 @@ -17,7 +17,7 @@ Name: apko -Version: 0.27.6 +Version: 0.27.7 Release: 0 Summary: Build OCI images from APK packages directly without Dockerfile License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.e0X9ih/_old 2025-05-22 16:57:17.562999459 +0200 +++ /var/tmp/diff_new_pack.e0X9ih/_new 2025-05-22 16:57:17.566999630 +0200 @@ -3,7 +3,7 @@ <param name="url">https://github.com/chainguard-dev/apko</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v0.27.6</param> + <param name="revision">v0.27.7</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> <param name="changesgenerate">enable</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.e0X9ih/_old 2025-05-22 16:57:17.591000661 +0200 +++ /var/tmp/diff_new_pack.e0X9ih/_new 2025-05-22 16:57:17.591000661 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/chainguard-dev/apko</param> - <param name="changesrevision">f19d835ff999789c485ca1ec018c624f96bc7487</param></service></servicedata> + <param name="changesrevision">c0a179ee97c61c1c5bae7267166782d703c40a28</param></service></servicedata> (No newline at EOF) ++++++ apko-0.27.6.obscpio -> apko-0.27.7.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.27.6/pkg/apk/expandapk/expandapk.go new/apko-0.27.7/pkg/apk/expandapk/expandapk.go --- old/apko-0.27.6/pkg/apk/expandapk/expandapk.go 2025-05-13 02:12:44.000000000 +0200 +++ new/apko-0.27.7/pkg/apk/expandapk/expandapk.go 2025-05-15 18:57:42.000000000 +0200 @@ -258,7 +258,7 @@ func (w *expandApkWriter) Next() error { if w.f != nil { if err := w.CloseFile(); err != nil { - return fmt.Errorf("expandApkWriter.Next error 1: %v", err) + return fmt.Errorf("closing file before Next: %w", err) } } @@ -268,18 +268,18 @@ if w.streamId == 0 { f, err := os.Open(w.f.Name()) if err != nil { - return fmt.Errorf("expandApkWriter.Next error 2: %v", err) + return fmt.Errorf("opening: %w", err) } defer f.Close() gzipRead, err := gzip.NewReader(f) if err != nil { - return fmt.Errorf("expandApkWriter.Next error 3: %v", err) + return fmt.Errorf("creating gzip reader: %w", err) } defer gzipRead.Close() tarRead := tar.NewReader(gzipRead) hdr, err := tarRead.Next() if err != nil { - return fmt.Errorf("expandApkWriter.Next error 4: %v", err) + return fmt.Errorf("reading tar header: %w", err) } if strings.HasPrefix(hdr.Name, ".SIGN.") { w.maxStreams = 3 @@ -290,7 +290,7 @@ p := fmt.Sprintf("%s-%d.%s", filepath.Join(w.parentDir, w.baseName), w.streamId, w.ext) file, err := os.Create(p) if err != nil { - return fmt.Errorf("expandApkWriter.Next error 5: %w", err) + return fmt.Errorf("creating stream file: %w", err) } w.f = file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.27.6/pkg/sbom/generator/spdx/spdx.go new/apko-0.27.7/pkg/sbom/generator/spdx/spdx.go --- old/apko-0.27.6/pkg/sbom/generator/spdx/spdx.go 2025-05-13 02:12:44.000000000 +0200 +++ new/apko-0.27.7/pkg/sbom/generator/spdx/spdx.go 2025-05-15 18:57:42.000000000 +0200 @@ -141,31 +141,8 @@ } for _, pkg := range opts.Packages { - // add the package - p := sx.apkPackage(opts, pkg) - - nonce := "thismakestestspass" - - // Add the image ID to the package ID to avoid clashes. - // NB: imagePackage.ID here is actually not important. - // The important thing is that p.ID is different from the package ID we - // would find in the corresponding APK SBOM. The ProcessInternalApkSBOM - // logic does a "JOIN" against the APK SBOM and replaces references to - // this ID with references to the APK's SBOM's Package ID, which means - // that logic falls over if they match. Removing imagePackage.ID makes - // them match, so we have to have _something_. You could replace - // imagePackage.ID with a UUID or "" and this would still be correct. - if imagePackage != nil { - nonce = imagePackage.ID - } - p.ID = stringToIdentifier(fmt.Sprintf( - "SPDXRef-Package-%s-%s-%s", nonce, pkg.Name, pkg.Version, - )) - - doc.Packages = append(doc.Packages, p) - // Check to see if the apk contains an sbom describing itself - if err := sx.ProcessInternalApkSBOM(opts, doc, &p, pkg); err != nil { + if err := sx.ProcessInternalApkSBOM(opts, doc, pkg); err != nil { return fmt.Errorf("parsing internal apk SBOM: %w", err) } } @@ -189,49 +166,15 @@ return nil } -// replacePackage replaces a package with ID originalID with newID -func replacePackage(doc *Document, originalID, newID string) { - // First check if package is described at the top of the SBOM - for i := range doc.DocumentDescribes { - if doc.DocumentDescribes[i] == originalID { - doc.DocumentDescribes[i] = newID - break - } - } - - // Now, look at all relationships and replace - for i := range doc.Relationships { - if doc.Relationships[i].Element == originalID { - doc.Relationships[i].Element = newID - } - if doc.Relationships[i].Related == originalID { - doc.Relationships[i].Related = newID - } - } - - // Remove the old ID from the package list - newPackages := []Package{} - replaced := false - for _, r := range doc.Packages { - if r.ID != originalID { - newPackages = append(newPackages, r) - replaced = true - } - } - if replaced { - doc.Packages = newPackages - } -} - // locateApkSBOM returns the path to the SBOM in the given filesystem, using the // given Package's name and version. It returns an empty string if the SBOM is // not found. -func locateApkSBOM(fsys apkfs.FullFS, p *Package) (string, error) { +func locateApkSBOM(fsys apkfs.FullFS, ipkg *apk.InstalledPackage) (string, error) { re := regexp.MustCompile(`-r\d+$`) for _, s := range []string{ - fmt.Sprintf("%s/%s-%s.spdx.json", apkSBOMdir, p.Name, p.Version), - fmt.Sprintf("%s/%s-%s.spdx.json", apkSBOMdir, p.Name, re.ReplaceAllString(p.Version, "")), - fmt.Sprintf("%s/%s.spdx.json", apkSBOMdir, p.Name), + fmt.Sprintf("%s/%s-%s.spdx.json", apkSBOMdir, ipkg.Name, ipkg.Version), + fmt.Sprintf("%s/%s-%s.spdx.json", apkSBOMdir, ipkg.Name, re.ReplaceAllString(ipkg.Version, "")), + fmt.Sprintf("%s/%s.spdx.json", apkSBOMdir, ipkg.Name), } { info, err := fsys.Stat(s) if err != nil { @@ -249,9 +192,9 @@ return "", nil } -func (sx *SPDX) ProcessInternalApkSBOM(opts *options.Options, doc *Document, p *Package, ipkg *apk.InstalledPackage) error { +func (sx *SPDX) ProcessInternalApkSBOM(opts *options.Options, doc *Document, ipkg *apk.InstalledPackage) error { // Check if apk installed an SBOM - path, err := locateApkSBOM(sx.fs, p) + path, err := locateApkSBOM(sx.fs, ipkg) if err != nil { return fmt.Errorf("inspecting FS for internal apk SBOM: %w", err) } @@ -276,11 +219,6 @@ // ... searching for a 1st level package targetElementIDs := map[string]struct{}{} for _, pkg := range apkSBOMDoc.Packages { - // that matches the name - if p.Name != pkg.Name { - continue - } - if _, ok := idsDescribedByAPKSBOM[pkg.ID]; !ok { continue } @@ -306,18 +244,6 @@ return fmt.Errorf("merging LicensingInfos: %w", err) } - // TODO: This loop seems very wrong. - for id := range targetElementIDs { - // Search for a package in the new SBOM describing the same thing - for _, pkg := range doc.Packages { - // TODO: Think if we need to match version too - if pkg.Name == p.Name { - replacePackage(doc, pkg.ID, id) - break - } - } - } - return nil } @@ -477,53 +403,6 @@ }, }, } -} - -// apkPackage returns a SPDX package describing an apk -func (sx *SPDX) apkPackage(opts *options.Options, pkg *apk.InstalledPackage) Package { - url := pkg.URL - if url == "" { - url = NOASSERTION - } - return Package{ - ID: stringToIdentifier(fmt.Sprintf( - "SPDXRef-Package-%s-%s", pkg.Name, pkg.Version, - )), - Name: pkg.Name, - Version: pkg.Version, - Supplier: supplier(opts), - FilesAnalyzed: false, - LicenseConcluded: pkg.License, - Description: pkg.Description, - DownloadLocation: url, - Originator: fmt.Sprintf("Person: %s", pkg.Maintainer), - SourceInfo: "Package info from apk database", - // This is APKv2 APKINDEX SHA1 file checksum - // https://wiki.alpinelinux.org/wiki/Apk_spec#Package_Checksum_Field - // This is the only meaningful and signed checksum - // right now. This can be upgrade to SHA256 when - // switching to the v3 index format. Whilst SPDX - // supports other checksums, there is currently no - // other checksum that one can verify in APKINDEX or - // query with apk-tools - Checksums: []Checksum{ - { - Algorithm: "SHA1", - Value: fmt.Sprintf("%x", pkg.Checksum), - }, - }, - ExternalRefs: []ExternalRef{ - { - Category: ExtRefPackageManager, - Locator: purl.NewPackageURL( - "apk", opts.OS.ID, pkg.Name, pkg.Version, - purl.QualifiersFromMap( - map[string]string{"arch": opts.ImageInfo.Arch.ToAPK()}, - ), "").String(), - Type: ExtRefTypePurl, - }, - }, - } } // LayerPackage returns a package describing the layer diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.27.6/pkg/sbom/generator/spdx/spdx_test.go new/apko-0.27.7/pkg/sbom/generator/spdx/spdx_test.go --- old/apko-0.27.6/pkg/sbom/generator/spdx/spdx_test.go 2025-05-13 02:12:44.000000000 +0200 +++ new/apko-0.27.7/pkg/sbom/generator/spdx/spdx_test.go 2025-05-15 18:57:42.000000000 +0200 @@ -151,6 +151,40 @@ }, }, }, + { + name: "unbound-package-dedupe", + opts: &options.Options{ + ImageInfo: options.ImageInfo{ + Layers: []v1.Descriptor{{}}, + }, + OS: options.OSInfo{ + Name: "unknown", + ID: "unknown", + Version: "3.0", + }, + FileName: "sbom", + Packages: []*apk.InstalledPackage{ + { + Package: apk.Package{ + Name: "unbound-libs", + Version: "1.23.0-r0", + }, + }, + { + Package: apk.Package{ + Name: "unbound", + Version: "1.23.0-r0", + }, + }, + { + Package: apk.Package{ + Name: "unbound-config", + Version: "1.23.0-r0", + }, + }, + }, + }, + }, } for _, tt := range tests { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.27.6/pkg/sbom/generator/spdx/testdata/apk_sboms/_generate.sh new/apko-0.27.7/pkg/sbom/generator/spdx/testdata/apk_sboms/_generate.sh --- old/apko-0.27.6/pkg/sbom/generator/spdx/testdata/apk_sboms/_generate.sh 2025-05-13 02:12:44.000000000 +0200 +++ new/apko-0.27.7/pkg/sbom/generator/spdx/testdata/apk_sboms/_generate.sh 2025-05-15 18:57:42.000000000 +0200 @@ -8,6 +8,9 @@ "libattr1-2.5.1-r2" "logstash-8-8.15.3-r4" "logstash-8-compat-8.15.3-r4" + "unbound-1.23.0-r0" + "unbound-libs-1.23.0-r0" + "unbound-config-1.23.0-r0" ) # Base URL for downloading APKs diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.27.6/pkg/sbom/generator/spdx/testdata/apk_sboms/unbound-1.23.0-r0.spdx.json new/apko-0.27.7/pkg/sbom/generator/spdx/testdata/apk_sboms/unbound-1.23.0-r0.spdx.json --- old/apko-0.27.6/pkg/sbom/generator/spdx/testdata/apk_sboms/unbound-1.23.0-r0.spdx.json 1970-01-01 01:00:00.000000000 +0100 +++ new/apko-0.27.7/pkg/sbom/generator/spdx/testdata/apk_sboms/unbound-1.23.0-r0.spdx.json 2025-05-15 18:57:42.000000000 +0200 @@ -0,0 +1,87 @@ +{ + "SPDXID": "SPDXRef-DOCUMENT", + "name": "apk-unbound-1.23.0-r0", + "spdxVersion": "SPDX-2.3", + "creationInfo": { + "created": "2025-04-24T08:25:21Z", + "creators": [ + "Tool: melange (v0.23.9+dirty)", + "Organization: Chainguard, Inc" + ], + "licenseListVersion": "3.22" + }, + "dataLicense": "CC0-1.0", + "documentNamespace": "https://spdx.org/spdxdocs/chainguard/melange/6107945343eac5611a87a2eb5a482b79", + "documentDescribes": [ + "SPDXRef-Package-unbound-1.23.0-r0" + ], + "packages": [ + { + "SPDXID": "SPDXRef-Package-unbound-1.23.0-r0", + "name": "unbound", + "versionInfo": "1.23.0-r0", + "filesAnalyzed": false, + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "BSD-3-Clause", + "downloadLocation": "NOASSERTION", + "originator": "Organization: Wolfi", + "supplier": "Organization: Wolfi", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceLocator": "pkg:apk/wolfi/unbound@1.23.0-r0?arch=x86_64", + "referenceType": "purl" + } + ] + }, + { + "SPDXID": "SPDXRef-Package-unbound.yaml-23e8ff8479b39f3f2e97fdca28d814f0c434c39b", + "name": "unbound.yaml", + "versionInfo": "23e8ff8479b39f3f2e97fdca28d814f0c434c39b", + "filesAnalyzed": false, + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "Apache-2.0", + "downloadLocation": "NOASSERTION", + "originator": "Organization: Wolfi", + "supplier": "Organization: Wolfi", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceLocator": "pkg:github/wolfi-dev/os@23e8ff8479b39f3f2e97fdca28d814f0c434c39b#unbound.yaml", + "referenceType": "purl" + } + ] + }, + { + "SPDXID": "SPDXRef-Package-github.com-NLnetLabs-unbound-release-1.23.0-30c13d0351abd2edc3d6dc76365f576c87b9736e-0", + "name": "unbound", + "versionInfo": "release-1.23.0", + "filesAnalyzed": false, + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "BSD-3-Clause", + "downloadLocation": "NOASSERTION", + "originator": "Organization: Nlnetlabs", + "supplier": "Organization: Nlnetlabs", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceLocator": "pkg:github/nlnetlabs/unbound@release-1.23.0", + "referenceType": "purl" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-Package-unbound-1.23.0-r0", + "relationshipType": "DESCRIBED_BY", + "relatedSpdxElement": "SPDXRef-Package-unbound.yaml-23e8ff8479b39f3f2e97fdca28d814f0c434c39b" + }, + { + "spdxElementId": "SPDXRef-Package-unbound-1.23.0-r0", + "relationshipType": "GENERATED_FROM", + "relatedSpdxElement": "SPDXRef-Package-github.com-NLnetLabs-unbound-release-1.23.0-30c13d0351abd2edc3d6dc76365f576c87b9736e-0" + } + ] +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.27.6/pkg/sbom/generator/spdx/testdata/apk_sboms/unbound-config-1.23.0-r0.spdx.json new/apko-0.27.7/pkg/sbom/generator/spdx/testdata/apk_sboms/unbound-config-1.23.0-r0.spdx.json --- old/apko-0.27.6/pkg/sbom/generator/spdx/testdata/apk_sboms/unbound-config-1.23.0-r0.spdx.json 1970-01-01 01:00:00.000000000 +0100 +++ new/apko-0.27.7/pkg/sbom/generator/spdx/testdata/apk_sboms/unbound-config-1.23.0-r0.spdx.json 2025-05-15 18:57:42.000000000 +0200 @@ -0,0 +1,87 @@ +{ + "SPDXID": "SPDXRef-DOCUMENT", + "name": "apk-unbound-config-1.23.0-r0", + "spdxVersion": "SPDX-2.3", + "creationInfo": { + "created": "2025-04-24T08:25:21Z", + "creators": [ + "Tool: melange (v0.23.9+dirty)", + "Organization: Chainguard, Inc" + ], + "licenseListVersion": "3.22" + }, + "dataLicense": "CC0-1.0", + "documentNamespace": "https://spdx.org/spdxdocs/chainguard/melange/6107945343eac5611a87a2eb5a482b79", + "documentDescribes": [ + "SPDXRef-Package-unbound-config-1.23.0-r0" + ], + "packages": [ + { + "SPDXID": "SPDXRef-Package-unbound-config-1.23.0-r0", + "name": "unbound-config", + "versionInfo": "1.23.0-r0", + "filesAnalyzed": false, + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "BSD-3-Clause", + "downloadLocation": "NOASSERTION", + "originator": "Organization: Wolfi", + "supplier": "Organization: Wolfi", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceLocator": "pkg:apk/wolfi/unbound-config@1.23.0-r0?arch=x86_64", + "referenceType": "purl" + } + ] + }, + { + "SPDXID": "SPDXRef-Package-unbound.yaml-23e8ff8479b39f3f2e97fdca28d814f0c434c39b", + "name": "unbound.yaml", + "versionInfo": "23e8ff8479b39f3f2e97fdca28d814f0c434c39b", + "filesAnalyzed": false, + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "Apache-2.0", + "downloadLocation": "NOASSERTION", + "originator": "Organization: Wolfi", + "supplier": "Organization: Wolfi", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceLocator": "pkg:github/wolfi-dev/os@23e8ff8479b39f3f2e97fdca28d814f0c434c39b#unbound.yaml", + "referenceType": "purl" + } + ] + }, + { + "SPDXID": "SPDXRef-Package-github.com-NLnetLabs-unbound-release-1.23.0-30c13d0351abd2edc3d6dc76365f576c87b9736e-0", + "name": "unbound", + "versionInfo": "release-1.23.0", + "filesAnalyzed": false, + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "BSD-3-Clause", + "downloadLocation": "NOASSERTION", + "originator": "Organization: Nlnetlabs", + "supplier": "Organization: Nlnetlabs", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceLocator": "pkg:github/nlnetlabs/unbound@release-1.23.0", + "referenceType": "purl" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-Package-unbound-config-1.23.0-r0", + "relationshipType": "DESCRIBED_BY", + "relatedSpdxElement": "SPDXRef-Package-unbound.yaml-23e8ff8479b39f3f2e97fdca28d814f0c434c39b" + }, + { + "spdxElementId": "SPDXRef-Package-unbound-config-1.23.0-r0", + "relationshipType": "GENERATED_FROM", + "relatedSpdxElement": "SPDXRef-Package-github.com-NLnetLabs-unbound-release-1.23.0-30c13d0351abd2edc3d6dc76365f576c87b9736e-0" + } + ] +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.27.6/pkg/sbom/generator/spdx/testdata/apk_sboms/unbound-libs-1.23.0-r0.spdx.json new/apko-0.27.7/pkg/sbom/generator/spdx/testdata/apk_sboms/unbound-libs-1.23.0-r0.spdx.json --- old/apko-0.27.6/pkg/sbom/generator/spdx/testdata/apk_sboms/unbound-libs-1.23.0-r0.spdx.json 1970-01-01 01:00:00.000000000 +0100 +++ new/apko-0.27.7/pkg/sbom/generator/spdx/testdata/apk_sboms/unbound-libs-1.23.0-r0.spdx.json 2025-05-15 18:57:42.000000000 +0200 @@ -0,0 +1,87 @@ +{ + "SPDXID": "SPDXRef-DOCUMENT", + "name": "apk-unbound-libs-1.23.0-r0", + "spdxVersion": "SPDX-2.3", + "creationInfo": { + "created": "2025-04-24T08:25:21Z", + "creators": [ + "Tool: melange (v0.23.9+dirty)", + "Organization: Chainguard, Inc" + ], + "licenseListVersion": "3.22" + }, + "dataLicense": "CC0-1.0", + "documentNamespace": "https://spdx.org/spdxdocs/chainguard/melange/6107945343eac5611a87a2eb5a482b79", + "documentDescribes": [ + "SPDXRef-Package-unbound-libs-1.23.0-r0" + ], + "packages": [ + { + "SPDXID": "SPDXRef-Package-unbound-libs-1.23.0-r0", + "name": "unbound-libs", + "versionInfo": "1.23.0-r0", + "filesAnalyzed": false, + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "BSD-3-Clause", + "downloadLocation": "NOASSERTION", + "originator": "Organization: Wolfi", + "supplier": "Organization: Wolfi", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceLocator": "pkg:apk/wolfi/unbound-libs@1.23.0-r0?arch=x86_64", + "referenceType": "purl" + } + ] + }, + { + "SPDXID": "SPDXRef-Package-unbound.yaml-23e8ff8479b39f3f2e97fdca28d814f0c434c39b", + "name": "unbound.yaml", + "versionInfo": "23e8ff8479b39f3f2e97fdca28d814f0c434c39b", + "filesAnalyzed": false, + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "Apache-2.0", + "downloadLocation": "NOASSERTION", + "originator": "Organization: Wolfi", + "supplier": "Organization: Wolfi", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceLocator": "pkg:github/wolfi-dev/os@23e8ff8479b39f3f2e97fdca28d814f0c434c39b#unbound.yaml", + "referenceType": "purl" + } + ] + }, + { + "SPDXID": "SPDXRef-Package-github.com-NLnetLabs-unbound-release-1.23.0-30c13d0351abd2edc3d6dc76365f576c87b9736e-0", + "name": "unbound", + "versionInfo": "release-1.23.0", + "filesAnalyzed": false, + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "BSD-3-Clause", + "downloadLocation": "NOASSERTION", + "originator": "Organization: Nlnetlabs", + "supplier": "Organization: Nlnetlabs", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceLocator": "pkg:github/nlnetlabs/unbound@release-1.23.0", + "referenceType": "purl" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-Package-unbound-libs-1.23.0-r0", + "relationshipType": "DESCRIBED_BY", + "relatedSpdxElement": "SPDXRef-Package-unbound.yaml-23e8ff8479b39f3f2e97fdca28d814f0c434c39b" + }, + { + "spdxElementId": "SPDXRef-Package-unbound-libs-1.23.0-r0", + "relationshipType": "GENERATED_FROM", + "relatedSpdxElement": "SPDXRef-Package-github.com-NLnetLabs-unbound-release-1.23.0-30c13d0351abd2edc3d6dc76365f576c87b9736e-0" + } + ] +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.27.6/pkg/sbom/generator/spdx/testdata/expected_image_sboms/unbound-package-dedupe.spdx.json new/apko-0.27.7/pkg/sbom/generator/spdx/testdata/expected_image_sboms/unbound-package-dedupe.spdx.json --- old/apko-0.27.6/pkg/sbom/generator/spdx/testdata/expected_image_sboms/unbound-package-dedupe.spdx.json 1970-01-01 01:00:00.000000000 +0100 +++ new/apko-0.27.7/pkg/sbom/generator/spdx/testdata/expected_image_sboms/unbound-package-dedupe.spdx.json 2025-05-15 18:57:42.000000000 +0200 @@ -0,0 +1,161 @@ +{ + "SPDXID": "SPDXRef-DOCUMENT", + "name": "sbom", + "spdxVersion": "SPDX-2.3", + "creationInfo": { + "created": "0001-01-01T00:00:00Z", + "creators": [ + "Tool: apko (devel)", + "Organization: Chainguard, Inc" + ], + "licenseListVersion": "3.16" + }, + "dataLicense": "CC0-1.0", + "documentNamespace": "https://spdx.org/spdxdocs/apko/", + "documentDescribes": [ + "SPDXRef-Package-" + ], + "packages": [ + { + "SPDXID": "SPDXRef-Package-", + "name": "", + "versionInfo": "3.0", + "filesAnalyzed": false, + "description": "apko operating system layer", + "downloadLocation": "NOASSERTION", + "supplier": "Organization: unknown", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceLocator": "pkg:oci/image?mediaType=\u0026os=linux", + "referenceType": "purl" + } + ] + }, + { + "SPDXID": "SPDXRef-Package-unbound-libs-1.23.0-r0", + "name": "unbound-libs", + "versionInfo": "1.23.0-r0", + "filesAnalyzed": false, + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "BSD-3-Clause", + "downloadLocation": "NOASSERTION", + "originator": "Organization: Wolfi", + "supplier": "Organization: Wolfi", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceLocator": "pkg:apk/wolfi/unbound-libs@1.23.0-r0?arch=x86_64", + "referenceType": "purl" + } + ] + }, + { + "SPDXID": "SPDXRef-Package-unbound.yaml-23e8ff8479b39f3f2e97fdca28d814f0c434c39b", + "name": "unbound.yaml", + "versionInfo": "23e8ff8479b39f3f2e97fdca28d814f0c434c39b", + "filesAnalyzed": false, + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "Apache-2.0", + "downloadLocation": "NOASSERTION", + "originator": "Organization: Wolfi", + "supplier": "Organization: Wolfi", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceLocator": "pkg:github/wolfi-dev/os@23e8ff8479b39f3f2e97fdca28d814f0c434c39b#unbound.yaml", + "referenceType": "purl" + } + ] + }, + { + "SPDXID": "SPDXRef-Package-github.com-NLnetLabs-unbound-release-1.23.0-30c13d0351abd2edc3d6dc76365f576c87b9736e-0", + "name": "unbound", + "versionInfo": "release-1.23.0", + "filesAnalyzed": false, + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "BSD-3-Clause", + "downloadLocation": "NOASSERTION", + "originator": "Organization: Nlnetlabs", + "supplier": "Organization: Nlnetlabs", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceLocator": "pkg:github/nlnetlabs/unbound@release-1.23.0", + "referenceType": "purl" + } + ] + }, + { + "SPDXID": "SPDXRef-Package-unbound-1.23.0-r0", + "name": "unbound", + "versionInfo": "1.23.0-r0", + "filesAnalyzed": false, + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "BSD-3-Clause", + "downloadLocation": "NOASSERTION", + "originator": "Organization: Wolfi", + "supplier": "Organization: Wolfi", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceLocator": "pkg:apk/wolfi/unbound@1.23.0-r0?arch=x86_64", + "referenceType": "purl" + } + ] + }, + { + "SPDXID": "SPDXRef-Package-unbound-config-1.23.0-r0", + "name": "unbound-config", + "versionInfo": "1.23.0-r0", + "filesAnalyzed": false, + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "BSD-3-Clause", + "downloadLocation": "NOASSERTION", + "originator": "Organization: Wolfi", + "supplier": "Organization: Wolfi", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceLocator": "pkg:apk/wolfi/unbound-config@1.23.0-r0?arch=x86_64", + "referenceType": "purl" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-Package-unbound-libs-1.23.0-r0", + "relationshipType": "DESCRIBED_BY", + "relatedSpdxElement": "SPDXRef-Package-unbound.yaml-23e8ff8479b39f3f2e97fdca28d814f0c434c39b" + }, + { + "spdxElementId": "SPDXRef-Package-unbound-libs-1.23.0-r0", + "relationshipType": "GENERATED_FROM", + "relatedSpdxElement": "SPDXRef-Package-github.com-NLnetLabs-unbound-release-1.23.0-30c13d0351abd2edc3d6dc76365f576c87b9736e-0" + }, + { + "spdxElementId": "SPDXRef-Package-unbound-1.23.0-r0", + "relationshipType": "DESCRIBED_BY", + "relatedSpdxElement": "SPDXRef-Package-unbound.yaml-23e8ff8479b39f3f2e97fdca28d814f0c434c39b" + }, + { + "spdxElementId": "SPDXRef-Package-unbound-1.23.0-r0", + "relationshipType": "GENERATED_FROM", + "relatedSpdxElement": "SPDXRef-Package-github.com-NLnetLabs-unbound-release-1.23.0-30c13d0351abd2edc3d6dc76365f576c87b9736e-0" + }, + { + "spdxElementId": "SPDXRef-Package-unbound-config-1.23.0-r0", + "relationshipType": "DESCRIBED_BY", + "relatedSpdxElement": "SPDXRef-Package-unbound.yaml-23e8ff8479b39f3f2e97fdca28d814f0c434c39b" + }, + { + "spdxElementId": "SPDXRef-Package-unbound-config-1.23.0-r0", + "relationshipType": "GENERATED_FROM", + "relatedSpdxElement": "SPDXRef-Package-github.com-NLnetLabs-unbound-release-1.23.0-30c13d0351abd2edc3d6dc76365f576c87b9736e-0" + } + ] +} ++++++ apko.obsinfo ++++++ --- /var/tmp/diff_new_pack.e0X9ih/_old 2025-05-22 16:57:17.963016629 +0200 +++ /var/tmp/diff_new_pack.e0X9ih/_new 2025-05-22 16:57:17.963016629 +0200 @@ -1,5 +1,5 @@ name: apko -version: 0.27.6 -mtime: 1747095164 -commit: f19d835ff999789c485ca1ec018c624f96bc7487 +version: 0.27.7 +mtime: 1747328262 +commit: c0a179ee97c61c1c5bae7267166782d703c40a28 ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/apko/vendor.tar.gz /work/SRC/openSUSE:Factory/.apko.new.2732/vendor.tar.gz differ: char 133, line 2