diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2bb885f2c..961575ac3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,8 @@ +Release 0.14.0 (unreleased) +=========================== + +* Use github purl, repo and version for a github release archive in SBOM (#1063) + Release 0.13.0 (released 2026-03-30) ==================================== diff --git a/dfetch/reporting/sbom_reporter.py b/dfetch/reporting/sbom_reporter.py index ab5f0aef3..e8ede9896 100644 --- a/dfetch/reporting/sbom_reporter.py +++ b/dfetch/reporting/sbom_reporter.py @@ -206,6 +206,7 @@ def add_project( else: purl = vcs_url_to_purl(project.remote_url, version=version, subpath=subpath) name = project.name if purl.type == "generic" else purl.name + version = purl.version or version location = self.manifest.find_name_in_manifest(project.name) component = Component( name=name, diff --git a/dfetch/vcs/archive.py b/dfetch/vcs/archive.py index d74c0c0db..f587c1314 100644 --- a/dfetch/vcs/archive.py +++ b/dfetch/vcs/archive.py @@ -27,6 +27,7 @@ import http.client import os import pathlib +import re import shutil import stat import sys @@ -47,6 +48,7 @@ copy_src_subset, prune_files_by_pattern, ) +from dfetch.util.versions import coerce logger = get_logger(__name__) @@ -82,7 +84,21 @@ def archive_url_to_purl( version: str | None = None, subpath: str | None = None, ) -> PackageURL: - """Build a generic PackageURL for an archive download URL.""" + """Build a github or generic PackageURL for an archive download URL.""" + if match := re.search( + r"https://github\.com/(?P[^/]+)/(?P[^/]+)/releases/download/(?P[^/]+)/", + download_url, + ): + prefix, current_version, _ = coerce( + match["version"], + ) + return PackageURL( + type="github", + namespace=match["org"].lower(), + name=match["repo"].lower(), + version=str(current_version) if current_version else prefix, + ) + parsed = urllib.parse.urlparse(download_url) basename = os.path.basename(parsed.path) name = strip_archive_extension(basename) or "unknown" diff --git a/features/report-sbom-archive.feature b/features/report-sbom-archive.feature index 886be9737..8cace1900 100644 --- a/features/report-sbom-archive.feature +++ b/features/report-sbom-archive.feature @@ -116,3 +116,39 @@ Feature: Create a CycloneDX SBOM for archive dependencies ] } """ + + Scenario: An github release archive uses github purl and repo + Given the manifest 'dfetch.yaml' + """ + manifest: + version: '0.1' + + remotes: + - name: github + url-base: https://github.com/ + + projects: + - name: TF-PSA-Crypto + vcs: archive + remote: github + dst: ext/TF-PSA-Crypto + repo-path: Mbed-TLS/TF-PSA-Crypto/releases/download/tf-psa-crypto-1.0.0/tf-psa-crypto-1.0.0.tar.bz2 + integrity: + hash: sha256:31f0df2ca17897b5db2757cb0307dcde267292ba21ade831663d972a7a5b7d40 + """ + And all projects are updated + When I run "dfetch report -t sbom" + Then the 'report.json' json file includes + """ + { + "components": [ + { + "group": "mbed-tls", + "name": "tf-psa-crypto", + "purl": "pkg:github/mbed-tls/tf-psa-crypto@1.0.0", + "type": "library", + "version": "1.0.0" + } + ] + } + """