From 541b161612512863d47e7d090756f07838cfd08c Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Tue, 7 Jan 2025 08:58:20 +0100 Subject: [PATCH 1/5] ci: Fix and cleanup Github workflows --- .github/workflows/gradle.yml | 27 ++++++++++----------------- .github/workflows/release.yml | 16 ++++++++-------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index b718f091..50428b06 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: ['17'] + java: ['17', '21'] env: WORKSPACE: ${{ github.workspace }} GRADLE_OPTS: -Xmx1500m -Dfile.encoding=UTF-8 @@ -36,35 +36,28 @@ jobs: - name: "🏃 Run Tests" if: github.event_name == 'pull_request' id: tests - run: ./gradlew check + run: ./gradlew check --continue - name: "🔨 Build project" if: github.event_name == 'push' id: build - run: ./gradlew build - - name: "📄 Publish Test Report" - if: steps.build.outcome == 'failure' || steps.tests.outcome == 'failure' - uses: scacap/action-surefire-report@v1 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - report_paths: '**/build/test-results/test/TEST-*.xml' + run: ./gradlew build --continue - name: "📤 Publish Snapshot" - if: steps.build.outcome == 'success' && github.event_name == 'push' && matrix.java == '17' + if: github.event_name == 'push' && steps.build.outcome == 'success' && matrix.java == '17' env: ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }} ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }} - run: publish + run: ./gradlew publish - name: "✍️ Generate Documentation" id: docs if: success() && github.event_name == 'push' && matrix.java == '17' run: ./gradlew docs - name: "📤 Publish to Github Pages" - if: steps.publish.outcome == 'success' && github.event_name == 'push' && matrix.java == '17' + if: github.event_name == 'push' && steps.publish.outcome == 'success' && matrix.java == '17' uses: grails/github-pages-deploy-action@grails env: - TARGET_REPOSITORY: ${{ github.repository }} - GH_TOKEN: ${{ secrets.GH_TOKEN }} BRANCH: gh-pages - FOLDER: build/docs - DOC_FOLDER: gh-pages COMMIT_EMAIL: grails-build@users.noreply.github.com - COMMIT_NAME: grails-build \ No newline at end of file + COMMIT_NAME: grails-build + DOC_FOLDER: gh-pages + FOLDER: build/docs + GH_TOKEN: ${{ secrets.GH_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c2218bf8..204f8887 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,16 +6,16 @@ jobs: release: runs-on: ubuntu-latest env: - GIT_USER_NAME: 'grails-build' - GIT_USER_EMAIL: 'grails-build@users.noreply.github.com' + GIT_USER_NAME: grails-build + GIT_USER_EMAIL: grails-build@users.noreply.github.com steps: - name: "📥 Checkout repository" uses: actions/checkout@v4 - name: "☕️ Setup JDK" uses: actions/setup-java@v4 with: - distribution: 'liberica' - java-version: '17' + java-version: 17 + distribution: liberica - name: "🐘 Setup Gradle" uses: gradle/actions/setup-gradle@v4 with: @@ -55,13 +55,13 @@ jobs: uses: grails/github-pages-deploy-action@grails env: BETA: ${{ contains(steps.release_version.outputs.release_version, 'M') || contains(steps.release_version.outputs.release_version, 'RC') }} - TARGET_REPOSITORY: ${{ github.repository }} - GH_TOKEN: ${{ secrets.GH_TOKEN }} BRANCH: gh-pages - FOLDER: docs/build/docs - DOC_FOLDER: gh-pages COMMIT_EMAIL: ${{ env.GIT_USER_EMAIL }} COMMIT_NAME: ${{ env.GIT_USER_NAME }} + DOC_FOLDER: gh-pages + FOLDER: docs/build/docs + GH_TOKEN: ${{ secrets.GH_TOKEN }} + TARGET_REPOSITORY: ${{ github.repository }} VERSION: ${{ steps.release_version.outputs.release_version }} - name: "⚙️ Run post-release" if: steps.publish.outcome == 'success' && steps.docs.outcome == 'success' && success() From 69403cfaeff8893de325373ffe720822395025ba Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Tue, 7 Jan 2025 14:18:33 +0100 Subject: [PATCH 2/5] refactor: remove dependency on `commons-lang3` Replaced `HashCodeBuilder` from `commons-lang3` with Groovy `HashCodeHelper` to reduce external dependencies. --- .../extended/grails-app/domain/test/UserRole.groovy | 11 +++++------ .../simple/grails-app/domain/test/UserRole.groovy | 11 +++++------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/examples/extended/grails-app/domain/test/UserRole.groovy b/examples/extended/grails-app/domain/test/UserRole.groovy index 18dd166e..ab3312ed 100644 --- a/examples/extended/grails-app/domain/test/UserRole.groovy +++ b/examples/extended/grails-app/domain/test/UserRole.groovy @@ -2,8 +2,7 @@ package test import grails.gorm.DetachedCriteria import groovy.transform.ToString - -import org.apache.commons.lang3.builder.HashCodeBuilder +import org.codehaus.groovy.util.HashCodeHelper @ToString(cache=true, includeNames=true, includePackage=false) class UserRole implements Serializable { @@ -30,10 +29,10 @@ class UserRole implements Serializable { @Override int hashCode() { - def builder = new HashCodeBuilder() - if (user) builder.append(user.id) - if (role) builder.append(role.id) - builder.toHashCode() + int hashCode = HashCodeHelper.initHash() + if (user) hashCode = HashCodeHelper.updateHash(hashCode, user.id) + if (role) hashCode = HashCodeHelper.updateHash(hashCode, role.id) + return hashCode } static UserRole get(long userId, long roleId) { diff --git a/examples/simple/grails-app/domain/test/UserRole.groovy b/examples/simple/grails-app/domain/test/UserRole.groovy index 18dd166e..ab3312ed 100644 --- a/examples/simple/grails-app/domain/test/UserRole.groovy +++ b/examples/simple/grails-app/domain/test/UserRole.groovy @@ -2,8 +2,7 @@ package test import grails.gorm.DetachedCriteria import groovy.transform.ToString - -import org.apache.commons.lang3.builder.HashCodeBuilder +import org.codehaus.groovy.util.HashCodeHelper @ToString(cache=true, includeNames=true, includePackage=false) class UserRole implements Serializable { @@ -30,10 +29,10 @@ class UserRole implements Serializable { @Override int hashCode() { - def builder = new HashCodeBuilder() - if (user) builder.append(user.id) - if (role) builder.append(role.id) - builder.toHashCode() + int hashCode = HashCodeHelper.initHash() + if (user) hashCode = HashCodeHelper.updateHash(hashCode, user.id) + if (role) hashCode = HashCodeHelper.updateHash(hashCode, role.id) + return hashCode } static UserRole get(long userId, long roleId) { From 45e50aeca4d0316ba4ea6fa9eb96becc5fb8e1ca Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Tue, 7 Jan 2025 14:30:53 +0100 Subject: [PATCH 3/5] build: cleanup build files --- build.gradle | 33 +---- docs/build.gradle | 238 ++++++++------------------------- examples/extended/build.gradle | 90 +++++-------- examples/simple/build.gradle | 79 +++++------ gradle.properties | 24 +--- plugin/build.gradle | 204 ++++++++-------------------- settings.gradle | 4 +- 7 files changed, 185 insertions(+), 487 deletions(-) diff --git a/build.gradle b/build.gradle index ec8e96e9..521f2887 100644 --- a/build.gradle +++ b/build.gradle @@ -1,32 +1 @@ -buildscript { - repositories { - maven { url "https://plugins.gradle.org/m2/" } - } - dependencies { - classpath "io.github.gradle-nexus:publish-plugin:1.3.0" - } -} - -version = project.projectVersion - -ext.isSnapshot = project.projectVersion.endsWith('-SNAPSHOT') -ext.isReleaseVersion = !isSnapshot - -if (isReleaseVersion) { - apply plugin: 'maven-publish' - apply plugin: "io.github.gradle-nexus.publish-plugin" - - nexusPublishing { - repositories { - sonatype { - def ossUser = System.getenv("SONATYPE_USERNAME") ?: project.hasProperty("sonatypeOssUsername") ? project.sonatypeOssUsername : '' - def ossPass = System.getenv("SONATYPE_PASSWORD") ?: project.hasProperty("sonatypeOssPassword") ? project.sonatypeOssPassword : '' - def ossStagingProfileId = System.getenv("SONATYPE_STAGING_PROFILE_ID") ?: project.hasProperty("sonatypeOssStagingProfileId") ? project.sonatypeOssStagingProfileId : '' - nexusUrl = uri("https://s01.oss.sonatype.org/service/local/") - username = ossUser - password = ossPass - stagingProfileId = ossStagingProfileId - } - } - } -} +version = project.projectVersion \ No newline at end of file diff --git a/docs/build.gradle b/docs/build.gradle index 3b92fed9..e9a8593c 100644 --- a/docs/build.gradle +++ b/docs/build.gradle @@ -1,207 +1,79 @@ buildscript { - repositories { - maven { url 'https://repo.grails.org/grails/core' } - } - dependencies { - classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.6.1' - classpath 'org.asciidoctor:asciidoctorj-epub3:2.1.3' - classpath 'org.asciidoctor:asciidoctorj-pdf:2.3.18' - } -} - -import org.apache.tools.ant.taskdefs.condition.Os -apply plugin: 'org.asciidoctor.convert' - -def asciidoctorAttributes = [ - copyright : 'Apache License, Version 2.0', - docinfo1 : 'true', - doctype : 'book', - encoding : 'utf-8', - 'front-cover-image' : 'image:cover.png[Front Cover,800,600]', - icons : 'font', - id : project.name + ':' + project.version, - idprefix : '', - idseparator : '-', - lang : 'en', - linkattrs : true, - numbered : '', - producer : 'Asciidoctor', - revnumber : project.version, - setanchors : true, - 'source-highlighter' : 'prettify', - toc : 'left', - toc2 : '', - toclevels : '2', - projectVersion : project.projectVersion -] - - -import org.apache.tools.ant.taskdefs.condition.Os -import org.asciidoctor.gradle.AsciidoctorTask - -tasks.withType(AsciidoctorTask) { - attributes asciidoctorAttributes - outputDir new File(buildDir, 'docs') - separateOutputDirs = false - sourceDir = file('src/docs') - sources { - include 'index.adoc' - } -} - -task getKindlegen { - group 'documentation' - ext { - kindlegenfolder = "${rootProject.projectDir}/kindlegen" - kindlegenFilename = "${kindlegenfolder}/kindlegen" - - - } - - doLast { - if (Os.isFamily(Os.FAMILY_MAC)) { - - } else { - File tgz = file(kindlegenGz) - if (!tgz.exists()) { - tgz.parentFile.mkdirs() - def url = kindlegenLinuxUrl - println "Downloading Kindlegen from $url" - ant.get(src: url, dest: tgz) - } - File kindlegenFile = file(kindlegenFilename) - if (!kindlegenFile.exists()) { - - ant.chmod(file: kindlegenFile, perm: '+x') + configurations.classpath { + resolutionStrategy.eachDependency { + if (requested.group == 'com.burgstaller' && requested.name == 'okhttp-digest' && requested.version == '1.10') { + useTarget('io.github.rburgst:okhttp-digest:1.21') + because('Dependency was on Bintray which is no longer available') } } } -} - -task cleanKindlegen { - group 'documentation' - ext { - kindlegenfolder = "${rootProject.projectDir}/kindlegen" - } - doLast { - delete kindlegenfolder - } -} - -task downloadKindlegenMac { - group 'documentation' - ext { - kindlegenUrl = 'http://kindlegen.s3.amazonaws.com/KindleGen_Mac_i386_v2_9.zip' - kindlegenZip = "${cleanKindlegen.ext.kindlegenfolder}/kindlegen.zip" - } - doLast { - if (Os.isFamily(Os.FAMILY_MAC)) { - File zipFile = file(kindlegenZip) - if (!zipFile.exists()) { - zipFile.parentFile.mkdirs() - } - def url = kindlegenUrl - println "Downloading Kindlegen from $url" - ant.get(src: url, dest: zipFile) - } + repositories { + mavenCentral() } } -task downloadKindlegenLinux { - group 'documentation' - ext { - kindlegenUrl = 'http://kindlegen.s3.amazonaws.com/kindlegen_linux_2.6_i386_v2_9.tar.gz' - kindlegenGz = "${cleanKindlegen.ext.kindlegenfolder}/kindlegen.tar.gz" - } - doLast { - if (!Os.isFamily(Os.FAMILY_MAC) && !Os.isFamily(Os.FAMILY_WINDOWS)) { - File tgz = file(kindlegenGz) - if (!tgz.exists()) { - tgz.parentFile.mkdirs() - } - def url = kindlegenUrl - println "Downloading Kindlegen from $url" - ant.get(src: url, dest: tgz) - } - } +plugins { + id 'org.asciidoctor.jvm.convert' version '4.0.2' + id 'org.asciidoctor.jvm.gems' version '4.0.2' } - -task unzipKidlengen { - group 'documentation' - dependsOn 'downloadKindlegenMac' - doLast { - File zipFile = file(downloadKindlegenMac.ext.kindlegenZip) - if ( zipFile.exists() ) { - copy { - from zipTree(zipFile) - into file(cleanKindlegen.ext.kindlegenfolder) - } - } +repositories { + mavenCentral() + ruby { + gems() } - } -task untarKidlengen(dependsOn: downloadKindlegenLinux) { - group 'documentation' - doLast { - File tgz = file(downloadKindlegenLinux.ext.kindlegenGz) - if ( tgz.exists() ) { - ant.untar(src: tgz, dest: cleanKindlegen.ext.kindlegenfolder, compression: 'gzip') - } - } -} +def asciidoctorAttributes = [ + copyright : 'Apache License, Version 2.0', + docinfo1 : 'true', + doctype : 'book', + encoding : 'utf-8', + 'front-cover-image' : 'image:cover.png[Front Cover,800,600]', + icons : 'font', + id : "$rootProject.name:$projectVersion", + idprefix : '', + idseparator : '-', + lang : 'en', + linkattrs : true, + numbered : '', + producer : 'Asciidoctor', + revnumber : projectVersion, + setanchors : true, + 'source-highlighter' : 'prettify', + toc : 'left', + toc2 : '', + toclevels : '2', + projectVersion : projectVersion +] -task chmodXKindlegen { - group 'documentation' - dependsOn 'untarKidlengen' - dependsOn 'unzipKidlengen' - ext { - kindlegenFile = "${cleanKindlegen.ext.kindlegenfolder}/kindlegen" +asciidoctor { + attributes = asciidoctorAttributes + baseDir = file('src/docs') + sourceDir = file('src/docs') + outputDir = file('build/docs') + sources { + include 'index.adoc' } - doLast { - ant.chmod(file: kindlegenFile, perm: '+x') + jvm { + jvmArgs += [ + '--add-opens', 'java.base/sun.nio.ch=ALL-UNNAMED', + '--add-opens', 'java.base/java.io=ALL-UNNAMED' + ] } - } -clean.dependsOn cleanKindlegen - -task asciidoc(type: AsciidoctorTask, description: 'Generates single-page HTML, PDF, and EPUB3') { - group 'documentation' - backends 'html5', 'pdf', 'epub3' -} - -task asciidocMobi(type: AsciidoctorTask, description: 'Generates MOBI for Kindle', dependsOn: chmodXKindlegen) { - group 'documentation' - backends 'epub3' - attributes(['ebook-format': 'kf8'] + asciidoctorAttributes) - mustRunAfter asciidoc -} - -task docs(dependsOn: [asciidoc]) { - group 'documentation' +tasks.register('docs') { + group = 'documentation' + dependsOn('asciidoctor') doLast { - File dir = new File(buildDir, 'docs') - ['epub', 'mobi', 'pdf'].each { String ext -> - File f = new File(dir, 'index.' + ext) - if (f.exists()) { - f.renameTo new File(dir, project.name + '.' + ext) - } - } - - new File(buildDir, 'docs/ghpages.html') << file('src/docs/index.tmpl').text.replaceAll('@VERSION@', project.version) - + delete file('build/docs/ghpages.html') + file('build/docs/ghpages.html') << file('src/docs/index.tmpl').text.replaceAll('@VERSION@', project.version.toString()) copy { from 'src/docs' - into new File(buildDir, 'docs').path + into 'build/docs' include '**/*.png' } } -} - -task docsMobi(dependsOn: [asciidoc, asciidocMobi]) { - group 'documentation' - finalizedBy docs -} +} \ No newline at end of file diff --git a/examples/extended/build.gradle b/examples/extended/build.gradle index 7ebdd137..9e9aa17f 100644 --- a/examples/extended/build.gradle +++ b/examples/extended/build.gradle @@ -1,78 +1,58 @@ buildscript { repositories { - maven { url "https://repo.grails.org/grails/core" } + maven { url = 'https://repo.grails.org/grails/core' } } dependencies { classpath "org.grails:grails-gradle-plugin:$grailsVersion" - classpath "org.grails.plugins:hibernate5:${hibernateGormVersion}" - classpath "com.bertramlabs.plugins:asset-pipeline-gradle:${assetPipelineVersion}" } } -version "0.1" -group "functional.test" +version = '0.1' +group = 'functional.test' -apply plugin:"eclipse" -apply plugin:"idea" -apply plugin:"war" -apply plugin:"org.grails.grails-web" -apply plugin: "com.bertramlabs.asset-pipeline" -apply plugin:"org.grails.grails-gsp" +apply plugin: 'groovy' +apply plugin: 'org.grails.grails-gsp' +apply plugin: 'org.grails.grails-web' repositories { - maven { url "https://repo.grails.org/grails/core" } + maven { url = 'https://repo.grails.org/grails/core' } } dependencies { - implementation "org.springframework.boot:spring-boot-starter-logging" - implementation "org.springframework.boot:spring-boot-autoconfigure" - implementation "org.grails:grails-core" - implementation "org.springframework.boot:spring-boot-starter-actuator" - implementation "org.springframework.boot:spring-boot-starter-tomcat" - implementation "org.grails:grails-web-boot" - implementation "org.grails:grails-logging" - implementation "org.grails:grails-plugin-rest" - implementation "org.grails:grails-plugin-databinding" - implementation "org.grails:grails-plugin-i18n" - implementation "org.grails:grails-plugin-services" - implementation "org.grails:grails-plugin-url-mappings" - implementation "org.grails:grails-plugin-interceptors" - implementation "org.grails.plugins:async" - implementation "org.grails.plugins:scaffolding" - implementation "org.grails.plugins:events" - implementation "org.grails.plugins:hibernate5" - implementation "org.hibernate:hibernate-core-jakarta:$hibernateCoreVersion" - implementation "org.grails.plugins:gsp" - console "org.grails:grails-console" - profile "org.grails.profiles:web" - runtimeOnly "com.h2database:h2" - runtimeOnly "org.apache.tomcat:tomcat-jdbc" - runtimeOnly "com.bertramlabs.plugins:asset-pipeline-grails:$assetPipelineVersion" - testImplementation "org.grails:grails-gorm-testing-support" - testImplementation "org.grails:grails-web-testing-support" - testImplementation "org.spockframework:spock-core" - integrationTestImplementation testFixtures('org.grails.plugins:geb') - implementation "dumbster:dumbster:$dumbsterVersion", { transitive = false } + implementation project(':spring-security-ui') + + implementation 'org.grails:grails-core' + implementation 'org.grails:grails-plugin-interceptors' + implementation 'org.grails:grails-plugin-databinding' + implementation 'org.grails:grails-plugin-rest' // Needed for respond method in controllers + implementation "org.grails.plugins:spring-security-acl:$grailsSpringSecurityAclVersion" + implementation "org.grails.plugins:spring-security-core:$grailsSpringSecurityCoreVersion" + + implementation "dumbster:dumbster:$dumbsterVersion", { transitive = false } // Uses javax implementation "org.grails.plugins:mail:$mailVersion" + compileOnly 'org.slf4j:slf4j-nop' // Remove warning about missing slf4j implementation during gsp compilation - implementation("org.grails.plugins:spring-security-acl:$springSecurityAclVersion") { - exclude group: 'org.grails.plugins', module: 'spring-security-core' - } - - implementation project(":spring-security-ui") -} + runtimeOnly 'com.bertramlabs.plugins:asset-pipeline-grails' + runtimeOnly 'com.h2database:h2' + runtimeOnly 'com.zaxxer:HikariCP' + runtimeOnly 'org.grails:grails-plugin-i18n' + runtimeOnly 'org.grails:grails-plugin-services' + runtimeOnly 'org.grails:grails-plugin-url-mappings' + runtimeOnly 'org.grails.plugins:hibernate5' + runtimeOnly 'org.springframework.boot:spring-boot-autoconfigure' + runtimeOnly 'org.springframework.boot:spring-boot-starter-logging' + runtimeOnly 'org.springframework.boot:spring-boot-starter-tomcat' -bootRun { - jvmArgs('-Dspring.output.ansi.enabled=always') - sourceResources sourceSets.main -} + testImplementation 'org.grails:grails-gorm-testing-support' + testImplementation 'org.spockframework:spock-core' + + integrationTestImplementation "org.hibernate:hibernate-core-jakarta:$hibernateCoreVersion" // Needed for access to SessionFactory + integrationTestImplementation testFixtures('org.grails.plugins:geb') -assets { - minifyJs = true - minifyCss = true } +compileJava.options.release = javaVersion.toInteger() -apply from: "${rootProject.projectDir}/gradle/integrationTestVerbose.gradle" \ No newline at end of file +apply from: rootProject.layout.projectDirectory.file('gradle/integrationTestVerbose.gradle') \ No newline at end of file diff --git a/examples/simple/build.gradle b/examples/simple/build.gradle index e5264a7e..a1e71923 100644 --- a/examples/simple/build.gradle +++ b/examples/simple/build.gradle @@ -1,68 +1,53 @@ buildscript { repositories { - maven { url "https://repo.grails.org/grails/core" } + maven { url = 'https://repo.grails.org/grails/core' } } dependencies { classpath "org.grails:grails-gradle-plugin:$grailsVersion" - classpath "org.grails.plugins:hibernate5:$hibernateGormVersion" - classpath "com.bertramlabs.plugins:asset-pipeline-gradle:$assetPipelineVersion" } } -version "0.1" -group "functional.test" +version = '0.1' +group = 'functional.test' -apply plugin:"eclipse" -apply plugin:"idea" -apply plugin:"war" -apply plugin:"org.grails.grails-web" -apply plugin: "com.bertramlabs.asset-pipeline" -apply plugin:"org.grails.grails-gsp" +apply plugin: 'groovy' +apply plugin: 'org.grails.grails-gsp' +apply plugin: 'org.grails.grails-web' repositories { - maven { url "https://repo.grails.org/grails/core" } + maven { url = 'https://repo.grails.org/grails/core' } } dependencies { - implementation "org.springframework.boot:spring-boot-starter-logging" - implementation "org.springframework.boot:spring-boot-autoconfigure" - implementation "org.grails:grails-core" - implementation "org.springframework.boot:spring-boot-starter-actuator" - implementation "org.springframework.boot:spring-boot-starter-tomcat" - implementation "org.grails:grails-web-boot" - implementation "org.grails:grails-logging" - implementation "org.grails:grails-plugin-rest" - implementation "org.grails:grails-plugin-databinding" - implementation "org.grails:grails-plugin-i18n" - implementation "org.grails:grails-plugin-services" - implementation "org.grails:grails-plugin-url-mappings" - implementation "org.grails:grails-plugin-interceptors" - implementation "org.grails.plugins:async" - implementation "org.grails.plugins:scaffolding" - implementation "org.grails.plugins:events" - implementation "org.grails.plugins:hibernate5" - implementation "org.hibernate:hibernate-core-jakarta:$hibernateCoreVersion" - implementation "org.grails.plugins:gsp" - console "org.grails:grails-console" - profile "org.grails.profiles:web" - runtimeOnly "com.h2database:h2" - runtimeOnly "org.apache.tomcat:tomcat-jdbc" - runtimeOnly "com.bertramlabs.plugins:asset-pipeline-grails:$assetPipelineVersion" - testImplementation "org.grails:grails-gorm-testing-support" - testImplementation "org.grails:grails-web-testing-support" - testImplementation "org.spockframework:spock-core" - integrationTestImplementation testFixtures('org.grails.plugins:geb') - implementation "dumbster:dumbster:$dumbsterVersion", { transitive = false } + implementation project(':spring-security-ui') + + implementation 'org.grails:grails-core' + implementation 'org.grails:grails-plugin-interceptors' + implementation 'org.grails:grails-plugin-databinding' + implementation "org.grails.plugins:spring-security-core:$grailsSpringSecurityCoreVersion" + + implementation "dumbster:dumbster:$dumbsterVersion", { transitive = false } // Uses javax implementation "org.grails.plugins:mail:$mailVersion" - implementation project(":spring-security-ui") -} + compileOnly 'org.slf4j:slf4j-nop' // Remove warning about missing slf4j implementation during gsp compilation + + runtimeOnly 'com.bertramlabs.plugins:asset-pipeline-grails' + runtimeOnly 'com.h2database:h2' + runtimeOnly 'com.zaxxer:HikariCP' + runtimeOnly 'org.grails:grails-plugin-i18n' + runtimeOnly 'org.grails:grails-plugin-services' + runtimeOnly 'org.grails:grails-plugin-url-mappings' + runtimeOnly 'org.grails.plugins:hibernate5' + runtimeOnly 'org.springframework.boot:spring-boot-autoconfigure' + runtimeOnly 'org.springframework.boot:spring-boot-starter-logging' + runtimeOnly 'org.springframework.boot:spring-boot-starter-tomcat' + + integrationTestImplementation "org.hibernate:hibernate-core-jakarta:$hibernateCoreVersion" // Needed for access to SessionFactory + integrationTestImplementation testFixtures('org.grails.plugins:geb') -assets { - minifyJs = true - minifyCss = true } +compileJava.options.release = javaVersion.toInteger() -apply from: "${rootProject.projectDir}/gradle/integrationTestVerbose.gradle" +apply from: rootProject.layout.projectDirectory.file('gradle/integrationTestVerbose.gradle') diff --git a/gradle.properties b/gradle.properties index 30fe9162..2c24a717 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,23 +1,13 @@ projectVersion=5.0.0-SNAPSHOT -title=Spring Security UI Plugin -authors=Puneet Behl -projectDesc=Provides CRUD screens and other user management workflows. -projectUrl=https://github.com/grails/grails-spring-security-ui -githubSlug=grails-plugins/grails-spring-security-ui -githubBranch=5.0.x -developers=Puneet Behl -vcsUrl=https://github.com/grails/grails-spring-security-ui -websiteUrl=https://github.com/grails/grails-spring-security-ui -issueTrackerUrl=https://github.com/grails/grails-spring-security-ui/issues grailsVersion=7.0.0-SNAPSHOT -gormVersion=9.0.0-SNAPSHOT -hibernateGormVersion=9.0.0-SNAPSHOT -hibernateCoreVersion=5.6.15.Final -assetPipelineVersion=5.0.5 +javaVersion=17 + dumbsterVersion=1.6 +grailsSpringSecurityAclVersion=5.0.0-SNAPSHOT +grailsSpringSecurityCoreVersion=7.0.0-SNAPSHOT +hibernateCoreVersion=5.6.15.Final mailVersion=5.0.0-SNAPSHOT -springSecurityAclVersion=5.0.0-SNAPSHOT -springSecurityCoreVersion=7.0.0-SNAPSHOT + org.gradle.daemon=true -org.gradle.parallel=false +org.gradle.parallel=true org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Xmx1024M diff --git a/plugin/build.gradle b/plugin/build.gradle index dc6557e5..1f5ebf71 100644 --- a/plugin/build.gradle +++ b/plugin/build.gradle @@ -1,184 +1,86 @@ buildscript { repositories { - maven { url "https://repo.grails.org/grails/core" } + maven { url = 'https://repo.grails.org/grails/core' } } dependencies { + classpath "org.grails:grails-bom:$grailsVersion" + classpath 'com.bertramlabs.plugins:asset-pipeline-gradle' classpath "org.grails:grails-gradle-plugin:$grailsVersion" - classpath "com.bertramlabs.plugins:asset-pipeline-gradle:$assetPipelineVersion" } } version = projectVersion group = 'org.grails.plugins' -apply plugin: "eclipse" -apply plugin: "idea" -apply plugin: "org.grails.grails-plugin" -apply plugin: "com.bertramlabs.asset-pipeline" -apply plugin: "org.grails.grails-gsp" +apply plugin: 'com.bertramlabs.asset-pipeline' +apply plugin: 'java-library' apply plugin: 'maven-publish' +apply plugin: 'org.grails.grails-gsp' +apply plugin: 'org.grails.grails-plugin' +apply plugin: 'org.grails.grails-publish' apply plugin: 'signing' -apply plugin: 'java-library' - -ext."signing.keyId" = project.hasProperty("signing.keyId") ? project.getProperty('signing.keyId') : System.getenv('SIGNING_KEY') -ext."signing.secretKeyRingFile" = project.hasProperty("signing.secretKeyRingFile") ? project.getProperty('signing.secretKeyRingFile') : "${System.properties['user.home']}${File.separator}.gnupg${File.separator}secring.gpg" -ext."signing.password" = project.hasProperty("signing.password") ? project.getProperty('signing.password') : System.getenv('SIGNING_PASSPHRASE') -ext.pomInfo = { - delegate.name "Grails Spring Security UI" - delegate.description 'The Spring Security UI plugin provides CRUD screens and other user management workflows.' - delegate.url project.hasProperty('vcsUrl') ? project.vcsUrl : "https://github.com/grails/$project.name" - - delegate.licenses { - delegate.license { - delegate.name 'The Apache Software License, Version 2.0' - delegate.url 'https://www.apache.org/licenses/LICENSE-2.0.txt' - delegate.distribution 'repo' - } - } - - delegate.scm { - delegate.url "scm:git@github.com:${githubSlug}.git" - delegate.connection "scm:git@github.com:${githubSlug}.git" - delegate.developerConnection "scm:git@github.com:${githubSlug}.git" - } - - if (developers) { - delegate.developers { - delegate.developer { - delegate.id "puneetbehl" - delegate.name "Puneet Behl" - } - } - } -} repositories { - maven { url "https://repo.grails.org/grails/core" } -} - -dependencies { - implementation "org.springframework.boot:spring-boot-starter-logging" - implementation "org.springframework.boot:spring-boot-autoconfigure" - implementation "org.grails:grails-core" - implementation "org.springframework.boot:spring-boot-starter-actuator" - implementation "org.springframework.boot:spring-boot-starter-tomcat" - implementation "org.grails:grails-web-boot" - implementation "org.grails:grails-logging" - implementation "org.grails:grails-plugin-rest" - implementation "org.grails:grails-plugin-databinding" - implementation "org.grails:grails-plugin-i18n" - implementation "org.grails:grails-plugin-services" - implementation "org.grails:grails-plugin-url-mappings" - implementation "org.grails:grails-plugin-interceptors" - implementation "org.grails.plugins:gsp" - console "org.grails:grails-console" - profile "org.grails.profiles:web-plugin" - compileOnly "org.grails:grails-plugin-services" - compileOnly "org.grails:grails-plugin-domain-class" - runtimeOnly "com.bertramlabs.plugins:asset-pipeline-grails:$assetPipelineVersion" - api "org.grails.plugins:spring-security-core:$springSecurityCoreVersion" - testImplementation "org.grails:grails-gorm-testing-support" - testImplementation "org.grails:grails-web-testing-support" - testImplementation "org.spockframework:spock-core" - implementation "org.springframework.security:spring-security-core", { - ['spring-aop', 'spring-beans', 'spring-context', 'spring-core', 'spring-expression'].each { - exclude module: it - } - } -} - -apply from: "${rootProject.projectDir}/gradle/testVerbose.gradle" - -assets { - packagePlugin = true -} - -task copyGspIntoTemplates { - ext.inputFolders = ['aclClass', - 'aclEntry', - 'aclObjectIdentity', - 'aclSid', - 'includes', - 'layouts', - 'login', - 'persistentLogin', - 'register', - 'registrationCode', - 'requestmap', - 'role', - 'securityInfo', - 'user'] - doLast { - mkdir "${project.projectDir}/src/main/templates/views" - for ( String folder : inputFolders ) { - mkdir "${project.projectDir}/src/main/templates/views/${folder}" - } - for ( int i = 0; i < inputFolders.size(); i++ ) { - copy { - from(fileTree("${project.projectDir}/grails-app/views/${inputFolders[i]}")) { - include '*.gsp' - } - into "${project.projectDir}/src/main/templates/views/${inputFolders[i]}" + maven { url = 'https://repo.grails.org/grails/core' } + mavenCentral() + if (System.getenv('GITHUB_MAVEN_PASSWORD') && !grailsVersion.endsWith('-SNAPSHOT')) { + logger.lifecycle('Adding Milestone Grails Core Repo for project {}', project.name) + maven { + url = 'https://maven.pkg.github.com/grails/grails-core' + credentials { + username = 'DOES_NOT_MATTER' + password = System.getenv('GITHUB_MAVEN_PASSWORD') } } } } -task removeGspFromTemplates { - doLast { - for ( String folder : copyGspIntoTemplates.inputFolders ) { - delete "${project.projectDir}/src/main/templates/views/${folder}" - } - delete "${project.projectDir}/src/main/templates/views" - } +compileJava.options.release = javaVersion.toInteger() +grailsPublish { + githubSlug = 'grails/grails-spring-security-ui' + license { + name = 'Apache-2.0' + } + title = 'Grails Spring Security UI' + desc = 'The Spring Security UI plugin provides CRUD screens and other user management workflows.' + developers = [burtbeckwith: 'Burt Beckwith'] } -compileAstJava.dependsOn copyGspIntoTemplates +dependencies { -publishing { - if (isSnapshot) { - repositories { - maven { - credentials { - def u = System.getenv("ARTIFACTORY_USERNAME") ?: project.hasProperty("artifactoryPublishUsername") ? project.artifactoryPublishUsername : '' - def p = System.getenv("ARTIFACTORY_PASSWORD") ?: project.hasProperty("artifactoryPublishPassword") ? project.artifactoryPublishPassword : '' - username = u - password = p - } - url "https://repo.grails.org/grails/plugins3-snapshots-local" - } - } - } + // Needed to compile subclasses of AbstractS2UiDomainController in consuming applications + compileOnlyApi 'org.grails.plugins:converters' - publications { - maven(MavenPublication) { - artifactId project.name - from components.java + implementation 'org.grails:grails-plugin-controllers' + implementation 'org.grails.plugins:converters' + implementation 'org.grails.plugins:gsp' + implementation "org.grails.plugins:spring-security-core:$grailsSpringSecurityCoreVersion" + implementation 'org.springframework.security:spring-security-core' + implementation 'org.springframework.security:spring-security-web' - artifact sourcesJar - artifact javadocJar - artifact source: "${buildDir}/classes/groovy/main/META-INF/grails-plugin.xml", - classifier: "plugin", - extension: 'xml' - pom.withXml { - def xml = asNode() + compileOnly 'org.grails:grails-core' // Provided, as this is a Grails plugin + compileOnly 'org.grails:grails-plugin-services' + compileOnly 'org.grails:grails-plugin-domain-class' - xml.children().last() + pomInfo - // dependency management shouldn't be included - def n = xml.get("dependencyManagement") - if (n) - xml.remove(n) - } + runtimeOnly 'com.bertramlabs.plugins:asset-pipeline-grails' + runtimeOnly 'org.grails:grails-plugin-i18n' - } - } + testImplementation 'org.grails:grails-web-testing-support' + testImplementation 'org.spockframework:spock-core' } -signing { - sign publishing.publications.maven +tasks.register('copyGspIntoTemplates', Copy) { + from "${layout.projectDirectory}/grails-app/views" + into "${layout.projectDirectory}/src/main/templates/views" + dependsOn 'copyTemplates', 'processResources' } -tasks.withType(Sign) { - onlyIf { isReleaseVersion } +tasks.register('removeGspFromTemplates', Delete) { + delete "${layout.projectDirectory}/src/main/templates/views" } + +assets.packagePlugin = true +compileAstJava.dependsOn('copyGspIntoTemplates') + +apply from: "${rootProject.projectDir}/gradle/testVerbose.gradle" \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 20a035a9..9b2e5865 100644 --- a/settings.gradle +++ b/settings.gradle @@ -24,10 +24,10 @@ buildCache { include 'docs' include 'examples-simple' -project(":examples-simple").projectDir = new File(settingsDir, "examples/simple") +project(':examples-simple').projectDir = new File(settingsDir, 'examples/simple') include 'examples-extended' -project (':examples-extended').projectDir = new File(settingsDir, "examples/extended") +project (':examples-extended').projectDir = new File(settingsDir, 'examples/extended') include 'plugin' findProject(':plugin').name = 'spring-security-ui' From 7052d4c41ba62cce89b5a8bfcabc7490c7170e52 Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Tue, 7 Jan 2025 14:31:20 +0100 Subject: [PATCH 4/5] ci: remove unused environment variable --- .github/workflows/release.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 204f8887..f2a72388 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,7 +38,6 @@ jobs: SONATYPE_STAGING_PROFILE_ID: ${{ secrets.SONATYPE_STAGING_PROFILE_ID }} SIGNING_KEY: ${{ secrets.SIGNING_KEY }} SIGNING_PASSPHRASE: ${{ secrets.SIGNING_PASSPHRASE }} - SECRING_FILE: ${{ secrets.SECRING_FILE }} run: > ./gradlew -Psigning.secretKeyRingFile=${{ github.workspace }}/secring.gpg From 29b88b19f673f72b7e1b7d9a07d0d210880f42ef Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Tue, 7 Jan 2025 15:34:17 +0100 Subject: [PATCH 5/5] docs: update documentation - Fix links - Update installation instruction - Update landing page --- docs/build.gradle | 2 +- docs/src/docs/index.tmpl | 42 +++++++---------------------- docs/src/docs/introduction.adoc | 36 +++++++++---------------- docs/src/docs/persistentCookie.adoc | 2 +- docs/src/docs/user.adoc | 2 +- 5 files changed, 25 insertions(+), 59 deletions(-) diff --git a/docs/build.gradle b/docs/build.gradle index e9a8593c..838cdc20 100644 --- a/docs/build.gradle +++ b/docs/build.gradle @@ -69,7 +69,7 @@ tasks.register('docs') { dependsOn('asciidoctor') doLast { delete file('build/docs/ghpages.html') - file('build/docs/ghpages.html') << file('src/docs/index.tmpl').text.replaceAll('@VERSION@', project.version.toString()) + file('build/docs/ghpages.html') << file('src/docs/index.tmpl').text.replaceAll('@VERSION@', projectVersion) copy { from 'src/docs' into 'build/docs' diff --git a/docs/src/docs/index.tmpl b/docs/src/docs/index.tmpl index c18731ad..40c607ed 100644 --- a/docs/src/docs/index.tmpl +++ b/docs/src/docs/index.tmpl @@ -59,21 +59,18 @@ img { - - Fork me on GitHub - - + Fork me on GitHub

Grails Spring Security UI Plugin

- - + @@ -84,15 +81,17 @@ img {
-

Current Documentation (4.0.x)

+

Current Documentation (5.0.x)

+

4.0.x Documentation

+ +

3.0.x Documentation

-
- - - -

Download Source

-

- You can download this project in either - zip or - tar formats. -

-

You can also clone the project with Git by running: -

$ git clone git://github.com/grails-plugins/grails-spring-security-ui
-

-
Version4.0.0.M2 + @VERSION@
Grails Version4.0.x > *7.0.x > *
Author