diff --git a/features/report-sbom.feature b/features/report-sbom.feature index 721e0d7b9..73ae6b36f 100644 --- a/features/report-sbom.feature +++ b/features/report-sbom.feature @@ -214,7 +214,7 @@ Feature: Create an CycloneDX sbom ], "name": "cyclonedx-python-lib", "type": "library", - "version": "11.4.0" + "version": "11.5.0" } ] } diff --git a/pyproject.toml b/pyproject.toml index 6477ab126..1e79217e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,7 +49,7 @@ dependencies = [ "sarif-om==1.0.4", "semver==3.0.4", "patch-ng==1.19.0", - "cyclonedx-python-lib==11.4.0", + "cyclonedx-python-lib==11.5.0", "infer-license==0.1.0; python_version <= '3.10.0'", "infer-license==0.2.0; python_version > '3.10.0'", 'setuptools; python_version >= "3.12"', # contains 'pkg_resources' for infer-license diff --git a/script/dependabot_hook.py b/script/dependabot_hook.py new file mode 100755 index 000000000..0d38f88ee --- /dev/null +++ b/script/dependabot_hook.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +"""This file performs any updates needed after a Dependabot PR.""" + +import re +import sys +from pathlib import Path +from typing import Optional + +# Config +SBOM_FILE = "sbom.json" # path to your CycloneDX SBOM +PYPROJECT_FILE = "pyproject.toml" +PACKAGE_NAME = "cyclonedx-python-lib" +FEATURE_FILE = "features/report-sbom.feature" + + +def get_new_version_from_pyproject(name: str) -> str: + """Extract the updated version of a package from pyproject.toml assuming '==' pin.""" + content = Path(PYPROJECT_FILE).read_text(encoding="UTF-8") + + # Match lines like: cyclonedx-python-lib=="11.5.0" + pattern = re.compile(rf'{re.escape(name)}==["\']?([\d\.]+)["\']?', re.MULTILINE) + + match = pattern.search(content) + if match: + return match.group(1) + + raise ValueError(f"{name} not found in {PYPROJECT_FILE}") + + +def replace_cyclonedx_version_if_outdated( + new_version: str, +) -> Optional[str]: + """Update the SBOM JSON file with the new version""" + feature_file_path = Path(FEATURE_FILE) + content = feature_file_path.read_text(encoding="UTF-8") + + pattern = re.compile( + r'("name":\s*"cyclonedx-python-lib",\s*' + r'"type":\s*"library",\s*' + r'"version":\s*")(?P[^"]+)(")', + re.MULTILINE, + ) + + match = pattern.search(content) + if not match: + print("Error: cyclonedx-python-lib block not found in feature file") + sys.exit(1) + + old_version = match.group("version") + if old_version == new_version: + print(f'No update needed: "{PACKAGE_NAME}" is already {new_version}') + return None + + def replacer(m): + return m.group(1) + new_version + m.group(3) + + new_content = pattern.sub(replacer, content) + feature_file_path.write_text(new_content, encoding="UTF-8") + print( + f'Updated "{PACKAGE_NAME}" version: {old_version} → {new_version} in "{FEATURE_FILE}"' + ) + return old_version + + +def main(): + """Main entry point.""" + new_version = get_new_version_from_pyproject("cyclonedx-python-lib") + replace_cyclonedx_version_if_outdated(new_version) + + +if __name__ == "__main__": + main()