From af6928ce6c70c84bbc200635a6277bd7677b2185 Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 1 Jan 2026 16:38:15 +0000 Subject: [PATCH 1/4] Create script for generating sbom --- .gitignore | 1 + pyproject.toml | 1 + script/create_sbom.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 script/create_sbom.py diff --git a/.gitignore b/.gitignore index 9f68b6a0..f420ad5d 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ doc/_build doc/landing-page/_build example/Tests/ venv* +*.cdx.json diff --git a/pyproject.toml b/pyproject.toml index 56aa9f4e..b2a782a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -105,6 +105,7 @@ build = [ 'nuitka==2.8.9', "tomli; python_version < '3.11'", # Tomllib is default in 3.11, required for letting codespell read the pyproject.toml] ] +sbom = ["cyclonedx-bom==7.2.1"] [project.scripts] dfetch = "dfetch.__main__:main" diff --git a/script/create_sbom.py b/script/create_sbom.py new file mode 100644 index 00000000..7b35eba5 --- /dev/null +++ b/script/create_sbom.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +"""Generate an sbom of the tool.""" +import contextlib +import logging +import subprocess +import sys +import tempfile +import venv +from pathlib import Path + +from dfetch import __version__ + +logging.basicConfig(level=logging.INFO) + +PROJECT_DIR = Path(__file__).parent.parent.resolve() +OUTPUT_FILE = PROJECT_DIR / f"dfetch-{__version__}.{sys.platform}.cdx.json" + +DEPS = f"{PROJECT_DIR}[sbom]" + + +@contextlib.contextmanager +def temporary_venv(): + """Create a temporary virtual environment and clean it up on exit.""" + with tempfile.TemporaryDirectory(prefix="venv_sbom_") as tmpdir: + venv_dir = Path(tmpdir) + logging.info(f"Creating temporary virtual environment at {venv_dir}") + venv.create(venv_dir, with_pip=True, upgrade_deps=True) + + if sys.platform.startswith("win"): + python_bin = venv_dir / "Scripts" / "python.exe" + else: + python_bin = venv_dir / "bin" / "python" + + yield str(python_bin) + + +with temporary_venv() as python: + subprocess.check_call([python, "-m", "pip", "install", DEPS]) + subprocess.check_call( + [python, "-m", "cyclonedx_py", "environment", "-o", str(OUTPUT_FILE)] + ) + +logging.info(f"SBOM generated at {OUTPUT_FILE}") From 9788a027209216f44ce1effd08c94aabd6494977 Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 1 Jan 2026 16:39:34 +0000 Subject: [PATCH 2/4] Generate and archive sboms --- .github/workflows/build.yml | 2 ++ script/create_sbom.py | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b42d730d..dcc0ef6a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -80,6 +80,7 @@ jobs: NUITKA_CCACHE_BINARY: /usr/bin/ccache run: | pip install .[build] + python script/create_sbom.py python script/build.py python script/package.py @@ -92,6 +93,7 @@ jobs: build/dfetch-package/*.rpm build/dfetch-package/*.pkg build/dfetch-package/*.msi + *.cdx.json test-binary: name: test binary diff --git a/script/create_sbom.py b/script/create_sbom.py index 7b35eba5..80f3dce3 100644 --- a/script/create_sbom.py +++ b/script/create_sbom.py @@ -2,7 +2,7 @@ """Generate an sbom of the tool.""" import contextlib import logging -import subprocess +import subprocess # nosec import sys import tempfile import venv @@ -35,8 +35,8 @@ def temporary_venv(): with temporary_venv() as python: - subprocess.check_call([python, "-m", "pip", "install", DEPS]) - subprocess.check_call( + subprocess.check_call([python, "-m", "pip", "install", DEPS]) # nosec + subprocess.check_call( # nosec [python, "-m", "cyclonedx_py", "environment", "-o", str(OUTPUT_FILE)] ) From 846e41089f1c08820caf6a0fcaa6655002c1cfb5 Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 1 Jan 2026 17:28:17 +0000 Subject: [PATCH 3/4] Keep sbom together with package --- .github/workflows/build.yml | 2 +- script/create_sbom.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dcc0ef6a..1981cb14 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -93,7 +93,7 @@ jobs: build/dfetch-package/*.rpm build/dfetch-package/*.pkg build/dfetch-package/*.msi - *.cdx.json + build/dfetch-package/*.cdx.json test-binary: name: test binary diff --git a/script/create_sbom.py b/script/create_sbom.py index 80f3dce3..ed1ea6b6 100644 --- a/script/create_sbom.py +++ b/script/create_sbom.py @@ -13,7 +13,12 @@ logging.basicConfig(level=logging.INFO) PROJECT_DIR = Path(__file__).parent.parent.resolve() -OUTPUT_FILE = PROJECT_DIR / f"dfetch-{__version__}.{sys.platform}.cdx.json" +OUTPUT_FILE = ( + PROJECT_DIR + / "build" + / "dfetch-package" + / f"dfetch-{__version__}.{sys.platform}.cdx.json" +) DEPS = f"{PROJECT_DIR}[sbom]" From 129da0fa07da759d9c83eb21abdd34267b23e989 Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 1 Jan 2026 19:40:02 +0100 Subject: [PATCH 4/4] make sure output dir exists --- script/create_sbom.py | 1 + 1 file changed, 1 insertion(+) diff --git a/script/create_sbom.py b/script/create_sbom.py index ed1ea6b6..ddf3b5cf 100644 --- a/script/create_sbom.py +++ b/script/create_sbom.py @@ -40,6 +40,7 @@ def temporary_venv(): with temporary_venv() as python: + OUTPUT_FILE.parent.mkdir(parents=True, exist_ok=True) subprocess.check_call([python, "-m", "pip", "install", DEPS]) # nosec subprocess.check_call( # nosec [python, "-m", "cyclonedx_py", "environment", "-o", str(OUTPUT_FILE)]