8000 Add SBOM build step to run_release.py · python/release-tools@b1ce472 · GitHub
[go: up one dir, main page]

Skip to content

Commit b1ce472

Browse files
committed
Add SBOM build step to run_release.py
1 parent 9b1fdfa commit b1ce472

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

run_release.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import functools
1313
import getpass
1414
import itertools
15+
import json
1516
import os
1617
import pathlib
1718
import re
@@ -34,6 +35,7 @@
3435

3536
import release as release_mod
3637
from buildbotapi import BuildBotAPI
38+
import sbom
3739

3840
API_KEY_REGEXP = re.compile(r"(?P<major>\w+):(?P<minor>\w+)")
3941

@@ -486,6 +488,26 @@ def test_release_artifacts(db: DbfilenameShelf) -> None:
486488
raise ReleaseException("Test failed!")
487489

488490

491+
def build_sbom_artifacts(db):
492+
493+
# Skip building an SBOM if there isn't an 'Misc/sbom.spdx.json' file.
494+
if not (db["git_repo"] / "Misc/sbom.spdx.json").exists():
495+
print("Skipping building an SBOM, missing 'Misc/sbom.spdx.json'")
496+
return
497+
498+
release_version = db["release"]
499+
# For each source tarball build an SBOM.
500+
for ext in (".tgz", ".tar.xz"):
501+
tarball_name = f"Python-{release_version}{ext}"
502+
tarball_path = str(db["git_repo"] / str(db["release"]) / "src" / tarball_name)
503+
504+
print(f"Building an SBOM for artifact '{tarball_name}'")
505+
sbom_data = sbom.create_sbom_for_source_tarball(tarball_path)
506+
507+
with open(tarball_path + ".spdx.json", mode="w") as f:
508+
f.write(json.dumps(sbom_data, indent=2, sort_keys=True))
509+
510+
489511
class MySFTPClient(paramiko.SFTPClient):
490512
def put_dir(self, source, target, progress=None):
491513
for item in os.listdir(source):
@@ -1020,6 +1042,7 @@ def _api_key(api_key):
10201042
Task(create_tag, "Create tag"),
10211043
Task(build_release_artifacts, "Building release artifacts"),
10221044
Task(test_release_artifacts, "Test release artifacts"),
1045+
Task(build_sbom_artifacts, "Building SBOM artifacts"),
10231046
Task(upload_files_to_server, "Upload files to the PSF server"),
10241047
Task(place_files_in_download_folder, "Place files in the download folder"),
10251048
Task(upload_docs_to_the_docs_server, "Upload docs to the PSF docs server"),

sbom.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
"""
22
Utility which creates Software Bill-of-Materials (SBOM)
3-
for CPython release artifacts.
3+
for CPython release artifacts. Can also be run manually with:
4+
5+
$ python sbom.py <artifact>
6+
47
"""
58

69
import datetime
@@ -94,7 +97,10 @@ def calculate_package_verification_codes(sbom) -> None:
9497
def get_release_tools_commit_sha() -> str:
9598
"""Gets the git commit SHA of the release-tools repository"""
9699
git_prefix = os.path.abspath(os.path.dirname(__file__))
97-
stdout = subprocess.check_output(["git", "rev-parse", "--prefix", git_prefix, "HEAD"]).decode("ascii")
100+
stdout = subprocess.check_output(
101+
["git", "rev-parse", "--prefix", git_prefix, "HEAD"],
102+
cwd=git_prefix
103+
).decode("ascii")
98104
assert re.match(r"^[a-f0-9]{40,}$", stdout)
99105
return stdout
100106

@@ -117,13 +123,18 @@ def create_sbom_for_source_tarball(tarball_path: str):
117123
cpython_version_without_suffix = re.match(r"^([0-9.]+)", cpython_version).group(1)
118124
tarball_download_location = f"https://www.python.org/ftp/python/{cpython_version_without_suffix}/{tarball_name}"
119125

120-
# Take some hashes of the tarball
126+
# Take a hash of the tarball
121127
with open(tarball_path, mode="rb") as f:
122128
tarball_checksum_sha256 = hashlib.sha256(f.read()).hexdigest()
123129

124130
# There should be an SBOM included in the tarball.
125131
# If there's not we can't create an SBOM.
126-
sbom_tarball_member = tarball.getmember(f"Python-{cpython_version}/Misc/sbom.spdx.json")
132+
try:
133+
sbom_tarball_member = tarball.getmember(f"Python-{cpython_version}/Misc/sbom.spdx.json")
134+
5A0B except KeyError:
135+
raise ValueError(
136+
"Tarball doesn't contain an SBOM at 'Misc/sbom.spdx.json'"
137+
) from None
127138
sbom_bytes = tarball.extractfile(sbom_tarball_member).read()
128139

129140
sbom = json.loads(sbom_bytes)

0 commit comments

Comments
 (0)
0