This is an automated email from the ASF dual-hosted git repository.
matrei pushed a commit to branch 7.0.x
in repository https://gitbox.apache.org/repos/asf/grails-core.git
The following commit(s) were added to refs/heads/7.0.x by this push:
new 56a0381d35 Update cyclonedx to `2.4.1` (#15099)
56a0381d35 is described below
commit 56a0381d35284822b0edd6d5968f91ba94179363
Author: Mattias Reichel <[email protected]>
AuthorDate: Tue Sep 30 16:08:01 2025 +0200
Update cyclonedx to `2.4.1` (#15099)
* fix(deps): `cyclonedx` `2.4.0` -> `2.4.1`
* fix(sbom): adapt to `2.4.1` and simplify
---
gradle.properties | 4 +-
gradle/sbom-config.gradle | 103 +++++++++++++++++++++++++---------------------
2 files changed, 57 insertions(+), 50 deletions(-)
diff --git a/gradle.properties b/gradle.properties
index 31b231d02c..d98938fc95 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -47,8 +47,8 @@ yakworksHibernateGroovyProxyVersion=1.1
# Build dependency versions not managed by BOMs
apacheRatVersion=0.8.1
gradleChecksumPluginVersion=1.4.0
-# note: the cyclonedx 3.0.0-alpha-1 still does not set the project correctly,
so we must use the older version
-gradleCycloneDxPluginVersion=2.4.0
+# note: the cyclonedx 3 requires Gradle 9
+gradleCycloneDxPluginVersion=2.4.1
# micronaut libraries not in the bom due to the potential for spring mismatches
micronautPlatformVersion=4.9.2
diff --git a/gradle/sbom-config.gradle b/gradle/sbom-config.gradle
index d856d99e16..89aaef58f2 100644
--- a/gradle/sbom-config.gradle
+++ b/gradle/sbom-config.gradle
@@ -33,53 +33,62 @@ import java.time.temporal.ChronoUnit
apply plugin: 'org.cyclonedx.bom'
-project.ext.setProperty('sbomOutputLocation',
project.layout.buildDirectory.file("${findProperty('pomArtifactId') ?:
project.name}-${projectVersion}-sbom.json"))
+ext {
+ sbomOutputLocation = layout.buildDirectory.file(
+ "${findProperty('pomArtifactId') ?:
name}-$projectVersion-sbom.json"
+ )
+}
-def sbomTask = tasks.named('cyclonedxBom', CycloneDxTask)
-sbomTask.configure { CycloneDxTask it ->
+tasks.withType(CycloneDxTask).configureEach {
// the 2.x version of Cyclonedx uses a legacy syntax & helpers for setting
inputs so the syntax below
// is required until the 3.x version is GA
- it.setProjectType(findProperty('sbomProjectType')?.toString() ?:
Component.Type.FRAMEWORK.name())
- [email protected](findProperty('pomArtifactId')?.toString() ?:
project.name)
- [email protected](new OrganizationalEntity().tap {
- name = 'Apache Software Foundation'
- urls = ['https://www.apache.org/', 'https://security.apache.org/']
- addContact(new OrganizationalContact().tap {
- name = 'Apache Grails Development Team'
- email = '[email protected]'
- })
- })
- [email protected](new LicenseChoice().tap {
- addLicense(new License().tap {
- name = 'Apache-2.0'
- url = 'https://www.apache.org/licenses/LICENSE-2.0.txt'
- })
- })
-
+ projectType =
Component.Type.valueOf(findProperty('sbomProjectType')?.toString() ?:
'FRAMEWORK')
+ componentName = findProperty('pomArtifactId')?.toString() ?: project.name
+ [email protected](new OrganizationalEntity(
+ name: 'Apache Software Foundation',
+ urls: [
+ 'https://www.apache.org/',
+ 'https://security.apache.org/'
+ ],
+ contacts: [
+ new OrganizationalContact(
+ name: 'Apache Grails Development Team',
+ email: '[email protected]'
+ )
+ ]
+ ))
+ [email protected](new LicenseChoice(
+ licenses: [
+ new License(
+ name: 'Apache-2.0',
+ url: 'https://www.apache.org/licenses/LICENSE-2.0.txt'
+ )
+ ]
+ ))
[email protected]([
- new ExternalReference().tap {
- url = 'https://grails.apache.org/'
- type = ExternalReference.Type.WEBSITE
- }
+ new ExternalReference(
+ url: 'https://grails.apache.org/',
+ type: ExternalReference.Type.WEBSITE
+ )
])
// sboms are published for the purposes of vulnerability analysis so only
include the runtime classpath
- [email protected](['runtimeClasspath'])
- [email protected](['compileClasspath', 'testRuntimeClasspath'])
+ includeConfigs = ['runtimeClasspath']
+ skipConfigs = ['compileClasspath', 'testRuntimeClasspath']
// turn off license text since it's base64 encoded & will inflate the jar
sizes
- [email protected](false)
+ includeLicenseText = false
// disable xml output
- it.xmlOutput.unsetConvention()
+ xmlOutput.unsetConvention()
- def sbomOutputLocation = findProperty('sbomOutputLocation')
- it.jsonOutput.set(sbomOutputLocation.get())
- it.outputs.file(sbomOutputLocation)
+ def sbomOutputLocation = findProperty('sbomOutputLocation') as
Provider<RegularFile>
+ jsonOutput = sbomOutputLocation.get()
+ outputs.file(sbomOutputLocation)
// cyclonedx does not support "choosing" the license placed in the sbom
// see: https://github.com/CycloneDX/cyclonedx-gradle-plugin/issues/16
- it.doLast {
+ doLast {
// ordered so that first value is the most preferred, this list is
from https://www.apache.org/legal/resolved.html
def preferredLicenses = ['Apache-2.0', 'EPL-1.0', 'BSD-3-Clause',
'EPL-2.0', 'MIT', 'MIT-0', '0BSD', 'UPL-1.0',
'CC0-1.0', 'ICU', 'Xnet', 'NCSA', 'W3C',
'Zlib', 'AFL-3.0', 'MS-PL', 'PSF-2.0', 'APAFML',
@@ -87,17 +96,17 @@ sbomTask.configure { CycloneDxTask it ->
// licenses are standardized @ https://spdx.org/licenses/
def licenses = [
- 'Apache-2.0' : [
- id : 'Apache-2.0',
- url : 'https://www.apache.org/licenses/LICENSE-2.0'
+ 'Apache-2.0': [
+ id: 'Apache-2.0',
+ url: 'https://www.apache.org/licenses/LICENSE-2.0'
],
'BSD-2-Clause': [
- id : 'BSD-2-Clause',
- url : 'https://opensource.org/license/bsd-3-clause/'
+ id: 'BSD-2-Clause',
+ url: 'https://opensource.org/license/bsd-3-clause/'
],
'BSD-3-Clause': [
- id : 'BSD-3-Clause',
- url : 'https://opensource.org/license/bsd-3-clause/'
+ id: 'BSD-3-Clause',
+ url: 'https://opensource.org/license/bsd-3-clause/'
],
// Variant of Apache 1.1 license. Approved by legal LEGAL-707
'OpenSymphony' : [
@@ -105,11 +114,10 @@ sbomTask.configure { CycloneDxTask it ->
name: 'The OpenSymphony Software License, Version 1.1',
url:
'https://raw.githubusercontent.com/sitemesh/sitemesh2/refs/heads/master/LICENSE.txt'
],
- 'UPL-1.0' : [
+ 'UPL-1.0': [
id: 'UPL-1.0',
url: 'https://oss.oracle.com/licenses/upl/'
],
-
]
def licenseMapping = [
@@ -127,11 +135,11 @@ sbomTask.configure { CycloneDxTask it ->
// Require a whitelist of any case of category X licenses to prevent
accidental inclusion in a distributed artifact
// this list will need to be updated anytime we change versions so we
can revise the licenses
def licenseExceptions = [
- 'grails-data-hibernate5-core' : [
+ 'grails-data-hibernate5-core': [
'pkg:maven/org.hibernate.common/[email protected]?type=jar':
'LGPL-2.1-only', // hibernate 5 is LGPL, we are migrating to ASF license in
hibernate 7
'pkg:maven/org.hibernate/[email protected]?type=jar':
'LGPL-2.1-only', // hibernate 5 is LGPL, we are migrating to ASF license in
hibernate 7
],
- 'grails-data-hibernate5' : [
+ 'grails-data-hibernate5': [
'pkg:maven/org.hibernate.common/[email protected]?type=jar':
'LGPL-2.1-only', // hibernate 5 is LGPL, we are migrating to ASF license in
hibernate 7
'pkg:maven/org.hibernate/[email protected]?type=jar':
'LGPL-2.1-only', // hibernate 5 is LGPL, we are migrating to ASF license in
hibernate 7
],
@@ -195,12 +203,12 @@ sbomTask.configure { CycloneDxTask it ->
def bom = new JsonSlurper().parse(f)
// timestamp is not reproducible:
https://github.com/CycloneDX/cyclonedx-gradle-plugin/issues/292
- bom.metadata.timestamp =
DateTimeFormatter.ISO_INSTANT.format(buildDate.truncatedTo(ChronoUnit.SECONDS))
+ bom['metadata']['timestamp'] =
DateTimeFormatter.ISO_INSTANT.format(buildDate.truncatedTo(ChronoUnit.SECONDS))
// components[*].licenses
def comps = (bom instanceof Map && bom.components instanceof List)
? bom.components : []
comps.each { c ->
- if (c instanceof Map && c.licenses instanceof List &&
!c.licenses.isEmpty()) {
+ if (c instanceof Map && c.licenses instanceof List &&
!(c.licenses as List).isEmpty()) {
def chosen = pickLicense(c['bom-ref'] as String,
c.licenses as List)
if (chosen != null) {
c.licenses = [chosen]
@@ -209,11 +217,10 @@ sbomTask.configure { CycloneDxTask it ->
}
// force the serialNumber to be reproducible by removing it &
recalculating
- bom.serialNumber = ''
+ bom['serialNumber'] = ''
String withOutSerial =
JsonOutput.prettyPrint(JsonOutput.toJson(bom))
def uuid =
UUID.nameUUIDFromBytes(withOutSerial.getBytes(StandardCharsets.UTF_8.name()))
- def urn = "urn:uuid:${uuid.toString()}" as String
- bom.serialNumber = urn
+ bom['serialNumber'] = "urn:uuid:$uuid".toString()
f.setText(JsonOutput.prettyPrint(JsonOutput.toJson(bom)),
StandardCharsets.UTF_8.name())