This is an automated email from the ASF dual-hosted git repository. matrei pushed a commit to branch update-cyclonedx in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit 6316a4c550de87bb2cac2b7678640a153c43cbfa Author: Mattias Reichel <[email protected]> AuthorDate: Thu Sep 25 18:24:56 2025 +0200 fix(sbom): adapt to `2.4.1` and simplify --- gradle/sbom-config.gradle | 103 +++++++++++++++++++++++++--------------------- 1 file changed, 55 insertions(+), 48 deletions(-) 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())
