Skip to content

reproducible builds - groovydoc 4, profile fixes, and ensuring gradle projects build docs #14710

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 7, 2025
38 changes: 19 additions & 19 deletions dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ ext {
'bootstrap.version' : '5.3.3',
'commons-codec.version' : '1.17.1',
'geb-spock.version' : '7.0',
'groovy.version' : '4.0.26',
'groovy.version' : '4.0.27-SNAPSHOT',
'h2.version' : '2.3.232',
'jackson.version' : '2.18.2',
'jquery.version' : '3.7.1',
Expand All @@ -107,24 +107,24 @@ ext {

// Note: the name of the dependency must be the prefix of the property name so properties in the pom are resolved correctly
bomDependencies = [
'asset-pipeline-grails' : "com.bertramlabs.plugins:asset-pipeline-grails:${bomDependencyVersions['asset-pipeline-grails.version']}",
'bootstrap' : "org.webjars.npm:bootstrap:${bomDependencyVersions['bootstrap.version']}",
'bootstrap-icons' : "org.webjars.npm:bootstrap-icons:${bomDependencyVersions['bootstrap-icons.version']}",
'commons-codec' : "commons-codec:commons-codec:${bomDependencyVersions['commons-codec.version']}",
'geb-spock' : "org.gebish:geb-spock:${bomDependencyVersions['geb-spock.version']}",
'h2' : "com.h2database:h2:${bomDependencyVersions['h2.version']}",
'jquery' : "org.webjars.npm:jquery:${bomDependencyVersions['jquery.version']}",
'liquibase-hibernate5' : "org.liquibase:liquibase:${bomDependencyVersions['liquibase-hibernate5.version']}",
'liquibase-hibernate5-cdi' : "org.liquibase:liquibase-cdi:${bomDependencyVersions['liquibase-hibernate5.version']}",
'liquibase-hibernate5-core' : "org.liquibase:liquibase-core:${bomDependencyVersions['liquibase-hibernate5.version']}",
'liquibase-hibernate5-ext' : "org.liquibase.ext:liquibase5-hibernate:${bomDependencyVersions['liquibase-hibernate5.version']}",
'mongodb-bson' : "org.mongodb:bson:${bomDependencyVersions['mongodb.version']}",
'mongodb-driver-core' : "org.mongodb:mongodb-driver-core:${bomDependencyVersions['mongodb.version']}",
'mongodb-driver-sync' : "org.mongodb:mongodb-driver-sync:${bomDependencyVersions['mongodb.version']}",
'mongodb-record-codec' : "org.mongodb:bson-record-codec:${bomDependencyVersions['mongodb.version']}",
'rxjava' : "io.reactivex:rxjava:${bomDependencyVersions['rxjava.version']}",
'rxjava2' : "io.reactivex.rxjava2:rxjava:${bomDependencyVersions['rxjava2.version']}",
'rxjava3' : "io.reactivex.rxjava3:rxjava:${bomDependencyVersions['rxjava3.version']}",
'asset-pipeline-grails' : "com.bertramlabs.plugins:asset-pipeline-grails:${bomDependencyVersions['asset-pipeline-grails.version']}",
'bootstrap' : "org.webjars.npm:bootstrap:${bomDependencyVersions['bootstrap.version']}",
'bootstrap-icons' : "org.webjars.npm:bootstrap-icons:${bomDependencyVersions['bootstrap-icons.version']}",
'commons-codec' : "commons-codec:commons-codec:${bomDependencyVersions['commons-codec.version']}",
'geb-spock' : "org.gebish:geb-spock:${bomDependencyVersions['geb-spock.version']}",
'h2' : "com.h2database:h2:${bomDependencyVersions['h2.version']}",
'jquery' : "org.webjars.npm:jquery:${bomDependencyVersions['jquery.version']}",
'liquibase-hibernate5' : "org.liquibase:liquibase:${bomDependencyVersions['liquibase-hibernate5.version']}",
'liquibase-hibernate5-cdi' : "org.liquibase:liquibase-cdi:${bomDependencyVersions['liquibase-hibernate5.version']}",
'liquibase-hibernate5-core': "org.liquibase:liquibase-core:${bomDependencyVersions['liquibase-hibernate5.version']}",
'liquibase-hibernate5-ext' : "org.liquibase.ext:liquibase5-hibernate:${bomDependencyVersions['liquibase-hibernate5.version']}",
'mongodb-bson' : "org.mongodb:bson:${bomDependencyVersions['mongodb.version']}",
'mongodb-driver-core' : "org.mongodb:mongodb-driver-core:${bomDependencyVersions['mongodb.version']}",
'mongodb-driver-sync' : "org.mongodb:mongodb-driver-sync:${bomDependencyVersions['mongodb.version']}",
'mongodb-record-codec' : "org.mongodb:bson-record-codec:${bomDependencyVersions['mongodb.version']}",
'rxjava' : "io.reactivex:rxjava:${bomDependencyVersions['rxjava.version']}",
'rxjava2' : "io.reactivex.rxjava2:rxjava:${bomDependencyVersions['rxjava2.version']}",
'rxjava3' : "io.reactivex.rxjava3:rxjava:${bomDependencyVersions['rxjava3.version']}",
]

// Because pom exclusions aren't properly supported by gradle, we can't inherit the grails-gradle-bom
Expand Down
10 changes: 8 additions & 2 deletions etc/bin/test-reproducible-builds.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ set -e

export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)

CWD=$(pwd)
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
cd "${SCRIPT_DIR}/../.."

Expand All @@ -29,19 +30,24 @@ mkdir -p "${SCRIPT_DIR}/results"

git clean -xdf --exclude='etc/bin'
killall -e java || true
cd grails-gradle
./gradlew build --rerun-tasks -PskipTests --no-build-cache
cd ..
./gradlew build --rerun-tasks -PskipTests --no-build-cache
"${SCRIPT_DIR}/generate-build-artifact-hashes.groovy" > "${SCRIPT_DIR}/results/first.txt"
mkdir -p "${SCRIPT_DIR}/results/first"
find . -path ./etc -prune -o -type f -path '*/build/libs/*.jar' -print0 | xargs -0 cp --parents -t "${SCRIPT_DIR}/results/first/"

git clean -xdf --exclude='etc/bin'
killall -e java || true
cd grails-gradle
./gradlew build --rerun-tasks -PskipTests --no-build-cache
cd ..
./gradlew build --rerun-tasks -PskipTests --no-build-cache
"${SCRIPT_DIR}/generate-build-artifact-hashes.groovy" > "${SCRIPT_DIR}/results/second.txt"
mkdir -p "${SCRIPT_DIR}/results/second"
find . -path ./etc -prune -o -type f -path '*/build/libs/*.jar' -print0 | xargs -0 cp --parents -t "${SCRIPT_DIR}/results/second/"

cd -
cd "${SCRIPT_DIR}/results"

# diff -u first.txt second.txt
Expand All @@ -61,4 +67,4 @@ find second -type f -name '*.jar' -print | sed 's|^second/||' | grep -F -x -v -f
done
rm toPurge.txt
find . -type d -empty -delete
cd -
cd "$CWD"
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ org.gradle.caching=true
# org.gradle.configuration-cache=true
org.gradle.parallel=true
org.gradle.daemon=true
org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Xmx1536M -XX:MaxMetaspaceSize=1024M
org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Xmx1792M -XX:MaxMetaspaceSize=1024M

# libraries only specific to test apps, these should not be exposed
jbossTransactionApiVersion=2.0.0.Final
Expand Down
16 changes: 8 additions & 8 deletions gradle/docs-config.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ ext {
includeInApiDocs = true
}

tasks.named('groovydoc', Groovydoc).configure {
tasks.named('groovydoc', Groovydoc).configure { Groovydoc it ->
// TODO: Fix this for testFixtures
classpath = configurations.documentation
groovyClasspath = configurations.documentation
access = GroovydocAccess.PROTECTED
includeAuthor = true
includeMainForScripts = false
processScripts = false
noTimestamp = true
it.classpath = configurations.documentation
it.groovyClasspath = configurations.documentation
it.access = GroovydocAccess.PROTECTED
it.includeAuthor = false
it.includeMainForScripts = false
it.processScripts = false
it.noTimestamp = true
}
21 changes: 15 additions & 6 deletions gradle/docs-dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,24 @@
* specific language governing permissions and limitations
* under the License.
*/
configurations.register('documentation') {
canBeConsumed = false
canBeResolved = true
attributes {
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))
}
}

configurations.register('documentation')
dependencies {
add('documentation', platform("org.apache.grails:grails-gradle-bom:${projectVersion}"))
add('documentation', platform(project(':grails-bom')))
add('documentation', 'org.fusesource.jansi:jansi')
add('documentation', 'jline:jline')
add('documentation', 'com.github.javaparser:javaparser-core')
add('documentation', 'org.codehaus.groovy:groovy')
add('documentation', 'org.codehaus.groovy:groovy-ant')
add('documentation', 'org.codehaus.groovy:groovy-docgenerator')
add('documentation', 'org.codehaus.groovy:groovy-templates')
add('documentation', 'org.apache.groovy:groovy')
add('documentation', 'org.apache.groovy:groovy-groovydoc')
add('documentation', 'org.apache.groovy:groovy-ant')
add('documentation', 'org.apache.groovy:groovy-docgenerator')
add('documentation', 'org.apache.groovy:groovy-templates')
}
10 changes: 4 additions & 6 deletions grails-bootstrap/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,10 @@ dependencies {
exclude group: 'org.codehaus.groovy'
}

// we have to continue to compile with groovy 3 only because of grails-shell
// the grails-shell will run under gradle and thus this must remain compatible
compileOnly "org.codehaus.groovy:groovy:$GroovySystem.version"
compileOnly "org.codehaus.groovy:groovy-templates:$GroovySystem.version"
compileOnly "org.codehaus.groovy:groovy-xml:$GroovySystem.version"
compileOnly "org.codehaus.groovy:groovy-ant:$GroovySystem.version"
compileOnly 'org.apache.groovy:groovy'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I spoke to @jamesfredley about this change. Since bootstrap is included by both gorm, and core, we should be compiling with 4. We'll know if it breaks b/c shell still uses 3.

compileOnly 'org.apache.groovy:groovy-templates'
compileOnly 'org.apache.groovy:groovy-xml'
compileOnly 'org.apache.groovy:groovy-ant'

compileOnly 'io.methvin:directory-watcher'
compileOnly 'org.fusesource.jansi:jansi'
Expand Down
2 changes: 1 addition & 1 deletion grails-data-graphql/examples/spring-boot-app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath platform("org.apache.grails:grails-bom:$projectVersion")
classpath platform(project(":grails-bom"))
classpath("org.springframework.boot:spring-boot-gradle-plugin")
}
}
Expand Down
24 changes: 14 additions & 10 deletions grails-data-hibernate5/docs/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,23 @@ dependencies {
.each { documentation project(":$it.name") }
}

tasks.named('asciidoctor', AsciidoctorTask) {
inputs.dir layout.projectDirectory.dir('src/docs')
outputs.dir layout.buildDirectory.dir('asciidoc/manual')
baseDirFollowsSourceDir()
tasks.named('asciidoctor', AsciidoctorTask) { AsciidoctorTask it ->
it.inputs.dir layout.projectDirectory.dir('src/docs/asciidoc')
it.outputs.dir layout.buildDirectory.dir('asciidoc/manual')

it.jvm {
jvmArgs('--add-opens', 'java.base/sun.nio.ch=ALL-UNNAMED', '--add-opens', 'java.base/java.io=ALL-UNNAMED')
}
it.baseDirFollowsSourceDir()
it.sourceDir layout.projectDirectory.dir('src/docs/asciidoc')
it.outputDir = layout.buildDirectory.dir('asciidoc/manual')

resources {
from("$project.projectDir/src/docs/asciidoc/images")
from(project.layout.projectDirectory.dir("src/docs/asciidoc/images"))
into './images'
}

attributes(
it.attributes = [
'experimental': 'true',
'compat-mode': 'true',
'toc': 'left',
Expand All @@ -81,10 +88,7 @@ tasks.named('asciidoctor', AsciidoctorTask) {
'migrationPluginGroupId': rootProject.findProject(':grails-data-hibernate5-dbmigration').group,
'migrationPluginArtifactId': rootProject.findProject(':grails-data-hibernate5-dbmigration').name,
'liquibaseHibernate5Version': liquibaseHibernate5Version
)
jvm {
jvmArgs('--add-opens', 'java.base/sun.nio.ch=ALL-UNNAMED', '--add-opens', 'java.base/java.io=ALL-UNNAMED')
}
]
}

tasks.withType(Groovydoc).configureEach {
Expand Down
8 changes: 4 additions & 4 deletions grails-data-mongodb/docs/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,15 @@ dependencies {
tasks.named('asciidoctor', AsciidoctorTask) { AsciidoctorTask it ->
dependsOn('resolveMongodbVersion')

inputs.dir project.layout.projectDirectory.dir('src/docs')
outputs.dir layout.buildDirectory.dir('asciidoc/manual')
it.inputs.dir project.layout.projectDirectory.dir('src/docs/asciidoc')
it.outputs.dir layout.buildDirectory.dir('asciidoc/manual')

it.jvm {
jvmArgs("--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED", "--add-opens", "java.base/java.io=ALL-UNNAMED")
}
it.baseDirFollowsSourceFile()
it.sourceDir layout.projectDirectory.dir('src/docs')
it.outputDir = layout.buildDirectory.dir('docs')
it.sourceDir layout.projectDirectory.dir('src/docs/asciidoc')
it.outputDir = layout.buildDirectory.dir('asciidoc/manual')
it.attributes = [
'experimental' : 'true',
'compat-mode' : 'true',
Expand Down
7 changes: 0 additions & 7 deletions grails-data-neo4j/grails-plugin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,6 @@
sourceCompatibility = "1.11"
targetCompatibility = "1.11"

dependencyManagement {
imports {
mavenBom "org.apache.grails:grails-bom:$pluginGrailsVersion"
}
applyMavenExclusions false
}

// TODO: Use bom
//configurations.configureEach {
// exclude group: 'org.apache.grails.data', module: 'grails-data-simple'
Expand Down
1 change: 1 addition & 0 deletions grails-gradle/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ allprojects {
// mavenLocal()
mavenCentral()
gradlePluginPortal()
maven { url = 'https://repository.apache.org/content/groups/snapshots' }
}

props.forEach { k, v -> project.ext.set(k as String, v) }
Expand Down
2 changes: 1 addition & 1 deletion grails-gradle/docs-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ tasks.named('jar', Jar).configure { Jar it ->
jar.dependsOn docFilesJar

apply {
from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
from rootProject.layout.projectDirectory.file('gradle/java-config.gradle')
from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
}

Expand Down
67 changes: 43 additions & 24 deletions grails-gradle/gradle/docs-config.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,42 +17,61 @@
* under the License.
*/

configurations.register('documentation')
configurations.register('documentation') {
canBeConsumed = false
canBeResolved = true
attributes {
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))
}
}
dependencies {
add('documentation', platform(project(':grails-gradle-bom')))
add('documentation', 'org.fusesource.jansi:jansi')
add('documentation', 'jline:jline')
add('documentation', 'com.github.javaparser:javaparser-core')
add('documentation', 'org.codehaus.groovy:groovy')
add('documentation', 'org.codehaus.groovy:groovy-ant')
add('documentation', 'org.codehaus.groovy:groovy-docgenerator')
add('documentation', 'org.codehaus.groovy:groovy-templates')
add('documentation', "org.apache.groovy:groovy:${bomDependencyVersions['groovy.version']}")
add('documentation', "org.apache.groovy:groovy-groovydoc:${bomDependencyVersions['groovy.version']}")
add('documentation', "org.apache.groovy:groovy-ant:${bomDependencyVersions['groovy.version']}")
add('documentation', "org.apache.groovy:groovy-docgenerator:${bomDependencyVersions['groovy.version']}")
add('documentation', "org.apache.groovy:groovy-templates:${bomDependencyVersions['groovy.version']}")
}

ext {
includeInApiDocs = true
}

tasks.named('groovydoc', Groovydoc).configure {
classpath = configurations.documentation
groovyClasspath = configurations.documentation
access = GroovydocAccess.PROTECTED
includeAuthor = true
includeMainForScripts = false
processScripts = false
destinationDir = project.file('build/docs/api')
TaskProvider<Groovydoc> groovydocTask = tasks.named('groovydoc', Groovydoc)
groovydocTask.configure { Groovydoc it ->
it.classpath = configurations.documentation
it.groovyClasspath = configurations.documentation
it.access = GroovydocAccess.PROTECTED
it.includeAuthor = false
it.includeMainForScripts = false
it.processScripts = false
it.noTimestamp = true
it.destinationDir = project.file('build/docs/api')
}

tasks.named('javadoc', Javadoc).configure { Javadoc it ->
(it.options as StandardJavadocDocletOptions).with {
encoding = 'UTF-8'
docEncoding = 'UTF-8'
charSet = 'UTF-8'
addStringOption('Xms64M')
addStringOption('Xmx512M')
}
tasks.named('javadoc').configure {
it.enabled = false
}

tasks.named('javadocJar', Jar).configure { Jar jar ->
jar.reproducibleFileOrder = true
jar.preserveFileTimestamps = false
jar.dirMode = 0755 // To avoid platform specific defaults
jar.fileMode = 0644 // to avoid platform specific defaults

jar.dependsOn(groovydocTask)

// Ensure the java source set is included in the groovydoc source set
SourceSetContainer sourceSets = project.extensions.getByType(SourceSetContainer)
groovydocTask.get().source(project.files(sourceSets.main.java.srcDirs))

ConfigurableFileCollection groovyDocFiles = project.files(groovydocTask.get().destinationDir)
jar.from(groovyDocFiles)
jar.inputs.files(groovyDocFiles)
}

tasks.named('build').configure {
finalizedBy('groovydoc')
}
14 changes: 11 additions & 3 deletions grails-gradle/gradle/java-config.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,17 @@ extensions.configure(JavaPluginExtension) {
it.withSourcesJar()
}

tasks.withType(Javadoc).configureEach { Javadoc it ->
it.options.noTimestamp true // prevent the file header with the date
it.options.bottom "Generated ${formattedBuildDate} (UTC)"
tasks.named('sourcesJar', Jar).configure { Jar jar ->
SourceSetContainer sourceSets = project.extensions.getByType(JavaPluginExtension).sourceSets
jar.reproducibleFileOrder = true
jar.preserveFileTimestamps = false
jar.dirMode = 0755 // To avoid platform specific defaults
jar.fileMode = 0644 // to avoid platform specific defaults
jar.duplicatesStrategy = DuplicatesStrategy.EXCLUDE

// don't only include main, but any source set
jar.from sourceSets.collect { it.allSource }
jar.inputs.files(sourceSets.collect { it.allSource })
}

// JavaCompile is not configured because we put java files inside of the groovy source sets
Expand Down
2 changes: 1 addition & 1 deletion grails-gradle/model/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ dependencies {
}

apply {
from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
from rootProject.layout.projectDirectory.file('gradle/java-config.gradle')
from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
}

Expand Down
Loading
Loading