From mboxrd@z Thu Jan 1 00:00:00 1970 Delivery-date: Sat, 17 Oct 2026 12:13:11 +0200 Received: from metis.whiteo.stw.pengutronix.de ([2a0a:edc0:2:b01:1d::104]) by lore.white.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1xI1Pb-00Ekwi-1n for lore@lore.pengutronix.de; Sat, 17 Oct 2026 12:13:11 +0200 Received: from [127.0.0.1] (helo=metis.whiteo.stw.pengutronix.de) by metis.whiteo.stw.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1xI1Pa-0006Bv-E1; Sat, 17 Oct 2026 12:13:10 +0200 Received: from mx1.white.stw.pengutronix.de ([185.203.200.13]) by metis.whiteo.stw.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1xI1PW-0006AR-03 for ptxdist@pengutronix.de; Sat, 17 Oct 2026 12:13:06 +0200 Received: from h2.cmg2.smtp.forpsi.com (h2.cmg2.smtp.forpsi.com [81.2.195.189]) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPS id 863E12005A6 for ; Sat, 17 Oct 2026 12:13:05 +0200 (CEST) ARC-Seal: i=1; s=20260414; d=pengutronix.de; t=1792231985; a=rsa-sha256; cv=none; b=dKBa1rofHeA7+DszXOVWdS2YQtxMGYo5ov77Z4aPLXVVOkBO6hfczWTFbOgtoU7UKgtSSP CJ8HpPNlnirQf3iC4FRW4oflr+ys4eeZjv2mJibson07E/IQFnsUE1UbPp30MBAUvWbL3H ARPccufTjtbBOiq36aVhuQ26EPjH4pr7WjLlS5O3SKLVmCZlz98EYzCbAhgFeuf9Xy7FkP MrQyfqi8ItKnYa55svBUknWv2Hrp7v3qE9c5X61X3TM0clNqW03/DqbQoz7L2O4YalDxpd 36n5dMvT1pTZDC/+yPDceJ0PR4IRQxQFIAU6kOp3y820k9fJylpEzRaL7Q4mmw== ARC-Authentication-Results: i=1; mx1.white.stw.pengutronix.de; dkim=pass header.d=triops.cz header.s=f2019 header.b=FdfHFqo6; spf=none (mx1.white.stw.pengutronix.de: domain of oss-lists@triops.cz has no SPF policy when checking 81.2.195.189) smtp.mailfrom=oss-lists@triops.cz; dmarc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=pengutronix.de; s=20260414; t=1792231985; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: dkim-signature; bh=mmztjgHYq4/6vRn96FJwFwlCcbaQc8/jafWEOpWnkNw=; b=AlqwUdP0/ogyY3LjW/k+NhkTWSa8F+H0aeC9HA94LSJfq1vCvgj9YYPE8+a46Etaw6bmk+ VZszKIEHdcv/02PwBMXFYuck1k0xHGC72ID+ctjv2025sfrCom17oMGqxW23bxWheV4xxO 0UMOEPppmNpS/ocvR9TBxjvDzneePZyBidJjkOrgdyf73O0UGWXdg7ENTMqVsJUgt/WUbi aWnFxURlKUu0V4e/6lZvaTxzbWiuf1/omkXf53htIkyzJ4LyBCTNlZ30Foxcf0mH8Z3H1F MLQ47/c+ByTCPzGiWPqpWROC0nyix0IY87LIcuQbNQPyv2P2z8OLHmjW2eyG2Q== Received: from lenoch ([91.218.190.200]) by cmgsmtp with ESMTPSA id I1PTxgou1NbEUI1PUx5jxs; Sat, 17 Oct 2026 12:13:05 +0200 Date: Sat, 17 Oct 2026 12:13:03 +0200 From: Ladislav Michl To: ptxdist@pengutronix.de Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-CMAE-Envelope: MS4xfM108zxcTZKZ7nmclw+4CGxo9+NnhBhlUUBqhK4O7KpR2N9LAljZBLftRjTIIMybZ2U52YN9iyCvBwLBHuXoxASg4VHDlMLxRPyn9WX+VMW93AtsmpaA g4RlvXpT4oo7mQTr6vckiCk6sQdw900Na+ecG8r23/cm556k2ZJ81hv6PACbTg/DdU2o6z5X92qMeA== X-Rspamd-Server: mx1 X-Rspamd-Queue-Id: 863E12005A6 X-Spamd-Result: default: False [-2.60 / 15.00]; BAYES_HAM(-3.00)[100.00%]; MID_RHS_NOT_FQDN(0.50)[]; ONCE_RECEIVED(0.20)[]; R_DKIM_ALLOW(-0.20)[triops.cz:s=f2019]; MIME_GOOD(-0.10)[text/plain]; TO_MATCH_ENVRCPT_ALL(0.00)[]; R_SPF_NA(0.00)[no SPF record]; DMARC_NA(0.00)[triops.cz]; RCVD_TLS_ALL(0.00)[]; ARC_NA(0.00)[]; RCPT_COUNT_ONE(0.00)[1]; DKIM_TRACE(0.00)[triops.cz:+]; MISSING_XM_UA(0.00)[]; RCVD_COUNT_ONE(0.00)[1]; TO_DN_NONE(0.00)[]; FROM_EQ_ENVFROM(0.00)[]; FROM_HAS_DN(0.00)[]; MIME_TRACE(0.00)[0:+]; NEURAL_HAM(-0.00)[-1.000]; RCVD_VIA_SMTP_AUTH(0.00)[]; RWL_MAILSPIKE_POSSIBLE(0.00)[81.2.195.189:from]; ASN(0.00)[asn:24806, ipnet:81.2.192.0/18, country:CZ]; ARC_SIGNED(0.00)[pengutronix.de:s=20260414:i=1] X-Rspamd-Action: no action X-Stat-Signature: ffetwqjn4co57o3qbbpqxtdsks57h8kr X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on metis.whiteo.stw.pengutronix.de X-Spam-Level: X-Spam-Status: No, score=-2.3 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS autolearn=ham autolearn_force=no version=3.4.2 Subject: [ptxdist] [PATCH] report: make SBoMs reproducible X-BeenThere: ptxdist@pengutronix.de X-Mailman-Version: 2.1.29 Precedence: list List-Id: PTXdist Development Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: ptxdist@pengutronix.de Sender: "ptxdist" X-SA-Exim-Connect-IP: 127.0.0.1 X-SA-Exim-Mail-From: ptxdist-bounces@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false From: Ladislav Michl Use SOURCE_DATE_EPOCH for timestamp. Signed-off-by: Ladislav Michl --- scripts/report/cyclonedx_sbom.py | 7 +++++-- scripts/report/sbom.py | 8 +++++++- scripts/report/spdx_sbom.py | 3 +-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/scripts/report/cyclonedx_sbom.py b/scripts/report/cyclonedx_sbom.py index 28f31c480..8a2cc0a85 100644 --- a/scripts/report/cyclonedx_sbom.py +++ b/scripts/report/cyclonedx_sbom.py @@ -8,9 +8,9 @@ import json from base64 import b64encode -from datetime import datetime from os import path from shutil import copy +from uuid import NAMESPACE_DNS, UUID, uuid5 from cyclonedx.factory.license import LicenseFactory from cyclonedx.model import ( @@ -49,6 +49,9 @@ class CycloneDXSbomGenerator(SbomGenerator): self.lc_factory = LicenseFactory() def write(self, file, bom): + bom.serial_number = UUID(int=0) + content = JsonV1Dot6(bom).output_as_string(indent=2) + bom.serial_number = uuid5(uuid5(NAMESPACE_DNS, "sbom.ptxdist.org"), content) outputter = JsonV1Dot6(bom) file.write(outputter.output_as_string(indent=2).encode("utf-8")) @@ -216,7 +219,7 @@ class CycloneDXSbomGenerator(SbomGenerator): document = Bom() document.metadata = BomMetaData( - timestamp=datetime.now(), + timestamp=self.timestamp(), properties=SortedSet( [ Property(name="vendor", value=data["bsp"]["vendor"]), diff --git a/scripts/report/sbom.py b/scripts/report/sbom.py index 95a91c876..1c7790bac 100644 --- a/scripts/report/sbom.py +++ b/scripts/report/sbom.py @@ -7,7 +7,8 @@ # import re -from os import path +from datetime import datetime, timezone +from os import environ, path from report.generator import Generator from report.report import ReportException @@ -104,6 +105,11 @@ class SbomGenerator(Generator): patches.append((tag, patch)) return patches + def timestamp(self): + if epoch := environ.get("SOURCE_DATE_EPOCH"): + return datetime.fromtimestamp(int(epoch), timezone.utc) + return datetime.now(timezone.utc) + def setup_env(self): env = {} for tmp in self._env: diff --git a/scripts/report/spdx_sbom.py b/scripts/report/spdx_sbom.py index 252828bc5..958471b3b 100644 --- a/scripts/report/spdx_sbom.py +++ b/scripts/report/spdx_sbom.py @@ -8,7 +8,6 @@ import hashlib import uuid -from datetime import datetime, timezone from os import path from shutil import copy @@ -145,7 +144,7 @@ class SpdxSbomGenerator(SbomGenerator): def build(self, data): creationInfo = spdx.SPDXCreationInfo() creationInfo.created = ( - datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace('+00:00', 'Z') + self.timestamp().replace(microsecond=0).isoformat().replace("+00:00", "Z") ) creationInfo.creators = [ f"Organization: {data['bsp']['vendor']}", -- 2.47.3