Files
Mesut Oezdil 0310cbed6c fix(sbom): detect sha256 hashes in expression-form licenses in needs_fix (#1911)
* fix(sbom): detect sha256 hashes in expression-form licenses in needs_fix

CycloneDX allows licenses as either {"license": {"id": "..."}} or
{"expression": "..."}. needs_fix only checked the license form, so
expression entries with sha256 hashes were silently skipped.

Add expression-form check to needs_fix, mirroring the fix in
extract_licenses (#1898). Add tests covering both forms.

* fix(sbom): align license checks with current test layout

Reuse needs_fix from sbom:check so expression-form hashes are detected. Fold coverage into the existing SBOM test module and task introduced on main.

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>

---------

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
2026-08-11 18:45:22 +00:00

92 lines
2.4 KiB
TOML

# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# SBOM generation, license resolution, and CSV export tasks
#
# Usage:
# mise run sbom # generate SBOMs, resolve licenses, export CSVs
# mise run sbom:check # advisory license check (for CI)
[sbom]
description = "Generate SBOMs, resolve licenses, and export CSVs to deploy/sbom/output/"
depends = ["sbom:csv"]
["sbom:generate"]
description = "Generate CycloneDX SBOMs with Syft"
hide = true
run = """
#!/usr/bin/env bash
set -euo pipefail
OUTPUT_DIR="deploy/sbom/output"
mkdir -p "$OUTPUT_DIR"
VERSION=$(uv run python tasks/scripts/release.py get-version --cargo)
echo "Generating SBOM for workspace (version ${VERSION})..."
syft dir:. \
--exclude './.github/**' \
--exclude './.venv/**' \
--exclude './.cache/**' \
--output "cyclonedx-json=$OUTPUT_DIR/openshell-source-${VERSION}.cdx.json" \
--source-name openshell \
--source-version "$VERSION"
echo ""
echo "SBOM written to $OUTPUT_DIR/"
ls -la "$OUTPUT_DIR"/*.cdx.json
"""
["sbom:resolve"]
description = "Resolve missing licenses in SBOM JSON files via public registries"
depends = ["sbom:generate"]
hide = true
run = "uv run python deploy/sbom/resolve_licenses.py"
["sbom:csv"]
description = "Convert SBOM JSON files to CSV"
depends = ["sbom:resolve"]
hide = true
run = "uv run python deploy/sbom/sbom_to_csv.py"
["sbom:check"]
description = "Check SBOMs for unresolved licenses (advisory, non-blocking)"
hide = true
run = """
#!/usr/bin/env bash
set -euo pipefail
OUTPUT_DIR="deploy/sbom/output"
if [ ! -d "$OUTPUT_DIR" ] || [ -z "$(ls -A "$OUTPUT_DIR"/*.cdx.json 2>/dev/null)" ]; then
echo "No SBOM files found in $OUTPUT_DIR/. Run 'mise run sbom' first."
exit 0
fi
echo "Checking for unresolved licenses..."
UNRESOLVED=0
for f in "$OUTPUT_DIR"/*.cdx.json; do
COUNT=$(uv run python -c "
import json, sys
sys.path.insert(0, 'deploy/sbom')
from resolve_licenses import needs_fix
with open('$f') as fh:
sbom = json.load(fh)
print(sum(1 for c in sbom.get('components', []) if needs_fix(c)))
")
if [ "$COUNT" -gt 0 ]; then
echo " $(basename "$f"): $COUNT components with unresolved licenses"
UNRESOLVED=$((UNRESOLVED + COUNT))
fi
done
if [ "$UNRESOLVED" -gt 0 ]; then
echo ""
echo "WARNING: $UNRESOLVED total components with unresolved licenses."
echo "This is advisory -- not blocking the build."
else
echo "All licenses resolved."
fi
"""