Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .sdkmanrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
java=17.0.18-librca
# Keep gradle version synced with gradle.properties (gradleToolingApiVersion), all gradle-wrapper.properties files,
# and grails-forge/grails-forge-core/src/main/java/org/grails/forge/feature/build/gradle/templates/gradleWrapperProperties.rocker.raw
gradle=8.14.4
gradle=9.3.1

9 changes: 4 additions & 5 deletions build-logic/docs-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,9 @@ apply {
dependencies {
gradleConf gradleApi()

// grails-docs classes are used in Gradle builds,
// so we must compile with Groovy 3 until Gradle upgrades to Groovy 4.
compileOnly "org.codehaus.groovy:groovy:${GroovySystem.version}"
compileOnly "org.codehaus.groovy:groovy-ant:${GroovySystem.version}"
// grails-docs classes are used in Gradle builds, using Gradle's embedded Groovy version
compileOnly "org.apache.groovy:groovy:${GroovySystem.version}"
compileOnly "org.apache.groovy:groovy-ant:${GroovySystem.version}"

api "org.apache.commons:commons-text:${gradleBomDependencyVersions['commons-text.version']}"
api "org.apache.ant:ant:${gradleBomDependencyVersions['ant.version']}"
Expand All @@ -56,7 +55,7 @@ dependencies {
transitive = false
}

testImplementation "org.codehaus.groovy:groovy-test-junit5:${GroovySystem.version}"
testImplementation "org.apache.groovy:groovy-test-junit5:${GroovySystem.version}"
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.12.2'
testImplementation 'org.junit.platform:junit-platform-runner:1.12.2'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.12.2'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
package grails.doc.ant

import groovy.ant.AntBuilder
import org.apache.tools.ant.BuildException
import org.apache.tools.ant.Project
import org.apache.tools.ant.Task
Expand Down
Binary file modified build-logic/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion build-logic/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# and grails-forge/grails-forge-core/src/main/java/org/grails/forge/feature/build/gradle/templates/gradleWrapperProperties.rocker.raw
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
5 changes: 1 addition & 4 deletions build-logic/gradlew

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions build-logic/gradlew.bat

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,14 @@ class PublishPlugin implements Plugin<Project> {
task.group = 'publishing'
task.outputs.dir(artifactsDir)
task.dependsOn(project.tasks.withType(Jar))

// Capture publishing extension at configuration time to avoid Task.project access at execution time
// See: https://docs.gradle.org/current/userguide/configuration_cache.html#config_cache:requirements:use_project_during_execution
def publishingExtension = project.extensions.getByType(PublishingExtension)

task.doLast {
Map<String, String> artifacts = [:]
project.extensions.getByType(PublishingExtension).publications.withType(MavenPublication).each { MavenPublication publication ->
publishingExtension.publications.withType(MavenPublication).each { MavenPublication publication ->
publication.artifacts.each { MavenArtifact artifact ->
if (!artifact.file.exists() || artifact.file.name in ['grails-plugin.xml', 'profile.yml']) {
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class SbomPlugin implements Plugin<Project> {
'pkg:maven/org.jline/jline@3.23.0?type=jar' : 'BSD-2-Clause', // maps incorrectly because of https://github.com/CycloneDX/cyclonedx-core-java/issues/205
'pkg:maven/org.liquibase.ext/liquibase-hibernate5@4.27.0?type=jar': 'Apache-2.0', // maps incorrectly because of https://github.com/liquibase/liquibase/issues/2445 & the base pom does not define a license
'pkg:maven/com.oracle.coherence.ce/coherence-bom@25.03.1?type=pom': 'UPL-1.0', // does not have map based on license id
'pkg:maven/com.oracle.coherence.ce/coherence-bom@25.03.2?type=pom': 'UPL-1.0', // does not have map based on license id
'pkg:maven/com.oracle.coherence.ce/coherence-bom@22.06.2?type=pom': 'UPL-1.0', // does not have map based on license id
'pkg:maven/opensymphony/sitemesh@2.6.0?type=jar' : 'OpenSymphony', // custom license approved by legal LEGAL-707
'pkg:maven/org.jruby/jzlib@1.1.5?type=jar' : 'BSD-3-Clause'// https://web.archive.org/web/20240822213507/http://www.jcraft.com/jzlib/LICENSE.txt shows it's a 3 clause
Expand Down Expand Up @@ -205,21 +206,25 @@ class SbomPlugin implements Plugin<Project> {

// cyclonedx does not support "choosing" the license placed in the sbom
// see: https://github.com/CycloneDX/cyclonedx-gradle-plugin/issues/16
// Capture project name at configuration time to avoid deprecated Task.project access at execution time
// See: https://docs.gradle.org/current/userguide/configuration_cache.html#config_cache:requirements:use_project_during_execution
def projectName = project.name
def projectPath = project.path
ZonedDateTime buildDate = lookupProperty(project, 'buildDate')
doLast {
// json schema is documented here: https://cyclonedx.org/docs/1.6/json/
def rewriteSbom = { File f ->
def bom = new JsonSlurper().parse(f)

// timestamp is not reproducible: https://github.com/CycloneDX/cyclonedx-gradle-plugin/issues/292
ZonedDateTime buildDate = lookupProperty(project, 'buildDate')
bom['metadata']['timestamp'] = DateTimeFormatter.ISO_INSTANT.format(buildDate.truncatedTo(ChronoUnit.SECONDS))

// components[*]
def comps = (bom instanceof Map && bom.components instanceof List) ? bom.components : []
comps.each { c ->
// .licenses => choose a license that is compatible with ASF policy if multiple licensed
if (c instanceof Map && c.licenses instanceof List && !(c.licenses as List).empty) {
def chosen = pickLicense(task, c['bom-ref'] as String, c.licenses as List)
def chosen = pickLicense(logger, projectName, c['bom-ref'] as String, c.licenses as List)
if (chosen != null) {
c.licenses = [chosen]
}
Expand Down Expand Up @@ -252,7 +257,7 @@ class SbomPlugin implements Plugin<Project> {

f.setText(JsonOutput.prettyPrint(JsonOutput.toJson(bom)), StandardCharsets.UTF_8.name())

logger.info('Rewrote JSON SBOM ({}) to pick preferred license', project.relativePath(f))
logger.info('Rewrote JSON SBOM ({}) to pick preferred license', projectPath)
}

sbomOutputLocation.get().with { rewriteSbom(it.asFile) }
Expand All @@ -262,29 +267,39 @@ class SbomPlugin implements Plugin<Project> {
}
}

/**
* Picks the most appropriate license for a dependency from a list of license choices.
* This method is called at execution time and should not access Task.project.
*
* @param logger the logger to use for logging
* @param projectName the name of the project (captured at configuration time)
* @param bomRef the bom reference for the dependency
* @param licenseChoices the list of license choices
* @return the chosen license
*/
@CompileDynamic
private static Object pickLicense(CycloneDxTask task, String bomRef, List licenseChoices) {
private static Object pickLicense(org.gradle.api.logging.Logger logger, String projectName, String bomRef, List licenseChoices) {
if (!bomRef) {
throw new GradleException("No bomRef found for a dependency of ${task.project.name}, cannot pick license")
throw new GradleException("No bomRef found for a dependency of ${projectName}, cannot pick license")
}

task.logger.info('Picking license for {} from {} choices', bomRef, licenseChoices.size())
logger.info('Picking license for {} from {} choices', bomRef, licenseChoices.size())
if (LICENSE_MAPPING.containsKey(bomRef)) {
// There are several reasons that cyclone will get the license wrong, usually due to upstream not publishing information or publishing it incorrectly
// see the licenseMapping map above for details
def licenseId = LICENSE_MAPPING[bomRef]
task.logger.lifecycle('Forcing license for {} to {}', bomRef, licenseId)
logger.lifecycle('Forcing license for {} to {}', bomRef, licenseId)

def licenseBlock = LICENSES[licenseId]
if (!licenseBlock) {
throw new GradleException("Cannot find license information for id ${licenseId} to use for bomRef ${bomRef} in project ${task.project.name}")
throw new GradleException("Cannot find license information for id ${licenseId} to use for bomRef ${bomRef} in project ${projectName}")
}

return licenseBlock
}

if (!(licenseChoices instanceof List) || licenseChoices.isEmpty()) {
throw new GradleException("No License was found for dependency: ${bomRef} in project ${task.project.name}")
throw new GradleException("No License was found for dependency: ${bomRef} in project ${projectName}")
}

def licenseIds = licenseChoices.findAll { it instanceof Map && it.license instanceof Map && it.license.id }
Expand All @@ -296,13 +311,13 @@ class SbomPlugin implements Plugin<Project> {
def defaultLicense = licenseChoices[0] // pick the first one found
def defaultLicenseId = defaultLicense.license.id as String
if (defaultLicenseId == null) {
throw new GradleException("Could not determine License id for dependency: ${bomRef} in project ${task.project.name} for value ${defaultLicense}")
throw new GradleException("Could not determine License id for dependency: ${bomRef} in project ${projectName} for value ${defaultLicense}")
}
if (!(defaultLicenseId in PREFERRED_LICENSES)) {
def projectLicenseExemptions = LICENSE_EXCEPTIONS[task.project.name] ?: [:]
def projectLicenseExemptions = LICENSE_EXCEPTIONS[projectName] ?: [:]
def permittedLicense = projectLicenseExemptions.get(bomRef) == defaultLicenseId
if (!permittedLicense) {
throw new GradleException("Unpermitted License found for bom dependency: ${bomRef} in project ${task.project.name} : ${defaultLicenseId}")
throw new GradleException("Unpermitted License found for bom dependency: ${bomRef} in project ${projectName} : ${defaultLicenseId}")
}
}

Expand Down
4 changes: 2 additions & 2 deletions build-logic/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ pluginManagement {
}

plugins {
id 'com.gradle.develocity' version '4.1.1'
id 'com.gradle.common-custom-user-data-gradle-plugin' version '2.3'
id 'com.gradle.develocity' version '4.3.2'
id 'com.gradle.common-custom-user-data-gradle-plugin' version '2.4.0'
}

def isCI = System.getenv().containsKey('CI')
Expand Down
2 changes: 1 addition & 1 deletion dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ ext {
'byte-buddy.version' : '1.17.7',
'commons-text.version' : '1.13.1',
'directory-watcher.version' : '0.19.1',
'gradle-spock.version' : '2.3-groovy-3.0',
'gradle-spock.version' : '2.3-groovy-4.0',
'grails-publish-plugin.version' : '0.0.4',
'jansi.version' : '1.18',
'javaparser-core.version' : '3.27.0',
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ expectitCoreVersion=0.9.0
gparsVersion=1.2.1
# Keep gradle version synced with .sdkmanrc, all gradle-wrapper.properties files,
# and grails-forge/grails-forge-core/src/main/java/org/grails/forge/feature/build/gradle/templates/gradleWrapperProperties.rocker.raw
gradleToolingApiVersion=8.14.4
gradleToolingApiVersion=9.3.1
hibernate5Version=5.6.15.Final
javassistVersion=3.30.2-GA
jnrPosixVersion=3.1.20
Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# and grails-forge/grails-forge-core/src/main/java/org/grails/forge/feature/build/gradle/templates/gradleWrapperProperties.rocker.raw
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
5 changes: 1 addition & 4 deletions gradlew

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions gradlew.bat

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 23 additions & 15 deletions grails-data-graphql/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,37 @@
*/

plugins {
id "com.gradle.enterprise" version "3.15.1"
id 'com.gradle.common-custom-user-data-gradle-plugin' version '1.12.1'
id 'com.gradle.develocity' version '4.3.2'
id 'com.gradle.common-custom-user-data-gradle-plugin' version '2.4.0'
}

gradleEnterprise {
def isCI = System.getenv().containsKey('CI')
def isLocal = !isCI
def isReproducibleBuild = System.getenv('SOURCE_DATE_EPOCH') != null
if (isReproducibleBuild) {
gradle.settingsEvaluated {
logger.warn('*************** Remote Build Cache Disabled due to Reproducible Build ********************')
logger.warn("Build date will be set to (SOURCE_DATE_EPOCH=${System.getenv("SOURCE_DATE_EPOCH")})")
}
}

develocity {
server = 'https://develocity.apache.org'
buildScan {
publishAlwaysIf(System.getenv('CI') == 'true')
publishIfAuthenticated()
uploadInBackground = System.getenv("CI") == null
capture {
taskInputFiles = true
}
tag('grails')
tag('grails-data-graphql')
publishing.onlyIf { it.authenticated }
uploadInBackground = isLocal
}
}

buildCache {
local { enabled = System.getenv('CI') != 'true' }
remote(gradleEnterprise.buildCache) {
def isAuthenticated = System.getenv('GRADLE_ENTERPRISE_ACCESS_KEY')
push = System.getenv('CI') == 'true' && isAuthenticated
enabled = true
}}
local { enabled = (isLocal && !isReproducibleBuild) || (isCI && isReproducibleBuild) }
remote(develocity.buildCache) {
push = isCI
enabled = !isReproducibleBuild
}
}

include 'core'
include 'plugin'
Expand Down
6 changes: 5 additions & 1 deletion grails-data-hibernate5/docs/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,12 @@ ext {

configurations {
documentation {
canBeConsumed = false
canBeResolved = true
attributes {
attribute(Bundling.BUNDLING_ATTRIBUTE, (Bundling) (objects.named(Bundling, 'external')))
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category, Category.LIBRARY))
attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling, Bundling.EXTERNAL))
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, Usage.JAVA_RUNTIME))
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion grails-data-mongodb/docs/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,12 @@ ext {

configurations {
documentation {
canBeConsumed = false
canBeResolved = true
attributes {
attribute(Bundling.BUNDLING_ATTRIBUTE, (Bundling) (objects.named(Bundling, 'external')))
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category, Category.LIBRARY))
attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling, Bundling.EXTERNAL))
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, Usage.JAVA_RUNTIME))
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion grails-data-neo4j/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ buildscript {
dependencies {
classpath "org.codehaus.groovy.modules.http-builder:http-builder:0.7.2"
classpath "org.apache.grails:grails-gradle-plugins:$grailsGradlePluginVersion"
classpath "org.asciidoctor:asciidoctor-gradle-jvm:4.0.2"
classpath "org.asciidoctor:asciidoctor-gradle-jvm:4.0.5"
classpath "com.github.erdi:webdriver-binaries-gradle-plugin:3.2"
}
}
Expand Down
Loading
Loading