From 2fb782495102a01ac535fd255fd57447d2cf952b Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Tue, 11 Aug 2026 15:13:04 +0100 Subject: [PATCH 1/9] Add Pitloom to generate package SBOM in wheel Add "pitllom" to Hatchling build hook to get SBOM and put it in the wheel. Signed-off-by: Arthit Suriyawongkul --- pyproject.toml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index cf3110f1..51bb7e6e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,7 +55,7 @@ Issues = "https://github.com/JPEWdev/shacl2code/issues" shacl2code = "shacl2code:main" [build-system] -requires = ["hatchling"] +requires = ["hatchling>=1.28.0", "pitloom>=0.13.3"] build-backend = "hatchling.build" [tool.hatch.version] @@ -77,6 +77,11 @@ warn_redundant_casts = true # warn_unreachable = true # warn_unused_ignores = true +[[tool.pitloom.creator]] +name = "Joshua Watt" +email = "JPEWhacker@gmail.com" +type = "person" + [tool.pytest.ini_options] addopts = [ "--import-mode=importlib", From 8d5ca6ad9ac5b82f645ff30f1bde57302cbdee5d Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Tue, 11 Aug 2026 15:46:29 +0100 Subject: [PATCH 2/9] Update hatchling version requirement to 1.29.0 Signed-off-by: Arthit Suriyawongkul --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 51bb7e6e..e8ad61bf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,7 +55,7 @@ Issues = "https://github.com/JPEWdev/shacl2code/issues" shacl2code = "shacl2code:main" [build-system] -requires = ["hatchling>=1.28.0", "pitloom>=0.13.3"] +requires = ["hatchling>=1.29.0", "pitloom>=0.13.3"] build-backend = "hatchling.build" [tool.hatch.version] From 49e3673e25067205c3dcb4d4d5f1bbc90bbd8ce9 Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Sat, 15 Aug 2026 23:13:54 +0100 Subject: [PATCH 3/9] Use Pitloom GitHub Action instead of Hatchling hook Signed-off-by: Arthit Suriyawongkul --- .github/workflows/publish.yaml | 6 ++++++ pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index ebb99f1f..ece47853 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -33,5 +33,11 @@ jobs: - name: Build package run: python -m build + - name: Generate SBOM and embed to wheel + uses: bact/pitloom@b6414eb80037ccae70eadf94ad13e3bc1063b114 # v0.15.0 + with: + embed-wheel: "dist/*.whl" + extras: "content-type" + - name: Publish distribution to PyPI uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # release/v1 diff --git a/pyproject.toml b/pyproject.toml index 7d00e0a1..a71f869d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,7 +56,7 @@ Issues = "https://github.com/JPEWdev/shacl2code/issues" shacl2code = "shacl2code:main" [build-system] -requires = ["hatchling>=1.29.0", "pitloom>=0.13.3"] +requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.version] From 0f2868609bee349896c8a91fcbfecb112a7aebad Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Sat, 15 Aug 2026 23:16:32 +0100 Subject: [PATCH 4/9] Enable content-type scan Signed-off-by: Arthit Suriyawongkul --- .github/workflows/publish.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index ece47853..8afbdd51 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -33,11 +33,12 @@ jobs: - name: Build package run: python -m build - - name: Generate SBOM and embed to wheel + - name: Generate SBOM uses: bact/pitloom@b6414eb80037ccae70eadf94ad13e3bc1063b114 # v0.15.0 with: embed-wheel: "dist/*.whl" extras: "content-type" + content-type: "true" - name: Publish distribution to PyPI uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # release/v1 From d7259d473dad2c5ae42ed408cc0b78ebbd654d79 Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Tue, 18 Aug 2026 12:17:59 +0100 Subject: [PATCH 5/9] Update Pitloom to 0.16.0 Signed-off-by: Arthit Suriyawongkul --- .github/workflows/publish.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 8afbdd51..d8ec6a79 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -33,8 +33,8 @@ jobs: - name: Build package run: python -m build - - name: Generate SBOM - uses: bact/pitloom@b6414eb80037ccae70eadf94ad13e3bc1063b114 # v0.15.0 + - name: Embed SBOM into the wheel + uses: bact/pitloom@d0379c365f5c3c65c43b8570a639a1abdd1397d4 # v0.16.0 with: embed-wheel: "dist/*.whl" extras: "content-type" From f172589625aa5e6fbf72269f0732878da5b62305 Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Tue, 18 Aug 2026 14:13:44 +0100 Subject: [PATCH 6/9] Update pitloom action version to v0.16.1 Signed-off-by: Arthit Suriyawongkul --- .github/workflows/publish.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index d8ec6a79..1fc47b55 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -34,7 +34,7 @@ jobs: run: python -m build - name: Embed SBOM into the wheel - uses: bact/pitloom@d0379c365f5c3c65c43b8570a639a1abdd1397d4 # v0.16.0 + uses: bact/pitloom@03a76ceb35f53ebe74891c1d97c6a4021187785e # v0.16.1 with: embed-wheel: "dist/*.whl" extras: "content-type" From c90a09f994b29198a597e23338a79eeb902ddf8f Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Tue, 18 Aug 2026 14:29:31 +0100 Subject: [PATCH 7/9] Enable content-type detection Signed-off-by: Arthit Suriyawongkul --- pyproject.toml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index a71f869d..4450f4b8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,6 +59,9 @@ shacl2code = "shacl2code:main" requires = ["hatchling"] build-backend = "hatchling.build" +[tool.hatch.build.hooks.pitloom] +enabled = true + [tool.hatch.version] path = "src/shacl2code/version.py" @@ -78,6 +81,9 @@ warn_redundant_casts = true # warn_unreachable = true # warn_unused_ignores = true +[tool.pitloom.content-type] +enabled = true + [[tool.pitloom.creator]] name = "Joshua Watt" email = "JPEWhacker@gmail.com" From 1ed1771ade4a81d5b82f069f14af3e987babbfe6 Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Tue, 18 Aug 2026 14:32:22 +0100 Subject: [PATCH 8/9] Remove content-type config from pyproject.toml Better put it only during CI Signed-off-by: Arthit Suriyawongkul --- pyproject.toml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4450f4b8..a71f869d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,9 +59,6 @@ shacl2code = "shacl2code:main" requires = ["hatchling"] build-backend = "hatchling.build" -[tool.hatch.build.hooks.pitloom] -enabled = true - [tool.hatch.version] path = "src/shacl2code/version.py" @@ -81,9 +78,6 @@ warn_redundant_casts = true # warn_unreachable = true # warn_unused_ignores = true -[tool.pitloom.content-type] -enabled = true - [[tool.pitloom.creator]] name = "Joshua Watt" email = "JPEWhacker@gmail.com" From 1938b3652c3ce3bd6231888970091ebca875bd29 Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Wed, 19 Aug 2026 18:47:37 +0100 Subject: [PATCH 9/9] Add test-sbom.yml Signed-off-by: Arthit Suriyawongkul --- .github/workflows/publish.yaml | 35 +++++++++++++-- .github/workflows/test-sbom.yaml | 73 ++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/test-sbom.yaml diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 1fc47b55..28473fe5 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -18,27 +18,54 @@ jobs: id-token: write steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Set up Python - uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: '3.x' - name: Install dependencies run: | python -m pip install --upgrade pip - pip install build + pip install build spdx3-validate - name: Build package run: python -m build - name: Embed SBOM into the wheel - uses: bact/pitloom@03a76ceb35f53ebe74891c1d97c6a4021187785e # v0.16.1 + id: pitloom + uses: bact/pitloom@4842922f65fb7ed1c5e51507c0fb253c62d97960 # v0.16.2 with: embed-wheel: "dist/*.whl" extras: "content-type" content-type: "true" + artifact-name: "sbom" + + - name: Extract and validate embedded SBOM + env: + SBOM_PATH: ${{ steps.pitloom.outputs.sbom-path }} + run: | + set -euo pipefail + whl=$(ls dist/*.whl) + sbom_basename=$(basename "${SBOM_PATH}") + + entry="" + while IFS= read -r line; do + case "${line}" in + *".dist-info/sboms/${sbom_basename}") entry="${line}"; break ;; + esac + done < <(unzip -Z1 "${whl}") + + if [ -z "${entry}" ]; then + echo "::error::${sbom_basename} not found under */.dist-info/sboms/ in ${whl}" + exit 1 + fi + echo "Found: ${entry}" + + mkdir -p extracted-sbom + unzip -p "${whl}" "${entry}" > "extracted-sbom/${sbom_basename}" + spdx3-validate --json "extracted-sbom/${sbom_basename}" - name: Publish distribution to PyPI uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # release/v1 diff --git a/.github/workflows/test-sbom.yaml b/.github/workflows/test-sbom.yaml new file mode 100644 index 00000000..6e23d8a9 --- /dev/null +++ b/.github/workflows/test-sbom.yaml @@ -0,0 +1,73 @@ +--- +# Tests that the SBOM generation and embedding step works correctly on every PR. +name: Test SBOM generation + +on: + push: + paths-ignore: &ignore-paths + - "docs/**" + - "**/*.md" + - "LICENSE*" + pull_request: + paths-ignore: *ignore-paths + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + test-sbom: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Setup Python + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + with: + python-version: "3.x" + cache: pip + + - name: Install build tooling + run: | + python -m pip install --upgrade pip + pip install build spdx3-validate + + - name: Build wheel + run: python -m build --wheel + + - name: Embed SBOM into the wheel + id: pitloom + uses: bact/pitloom@4842922f65fb7ed1c5e51507c0fb253c62d97960 # v0.16.2 + with: + embed-wheel: "dist/*.whl" + extras: "content-type" + content-type: "true" + artifact-name: "sbom" + + - name: Extract and validate embedded SBOM + env: + SBOM_PATH: ${{ steps.pitloom.outputs.sbom-path }} + run: | + set -euo pipefail + whl=$(ls dist/*.whl) + sbom_basename=$(basename "${SBOM_PATH}") + + entry="" + while IFS= read -r line; do + case "${line}" in + *".dist-info/sboms/${sbom_basename}") entry="${line}"; break ;; + esac + done < <(unzip -Z1 "${whl}") + + if [ -z "${entry}" ]; then + echo "::error::${sbom_basename} not found under */.dist-info/sboms/ in ${whl}" + exit 1 + fi + echo "Found: ${entry}" + + mkdir -p extracted-sbom + unzip -p "${whl}" "${entry}" > "extracted-sbom/${sbom_basename}" + spdx3-validate --json "extracted-sbom/${sbom_basename}"