From 5020afc10e5f72e2e2307451b97dcccf3aa9e9f4 Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Fri, 7 Mar 2025 15:22:35 +0100 Subject: [PATCH 1/6] chore: major project cleanup Goal of cleanup was to use the `org.grails.grails-publish` plugin and use a more composition based build approach. --- .github/dependabot.yml | 2 +- .github/renovate.json | 5 +- .github/workflows/docs.yml | 75 ++-- .github/workflows/gradle.yml | 104 +++-- .github/workflows/groovy-joint-workflow.yml | 211 +++++----- .github/workflows/release-notes.yml | 43 +- .github/workflows/release.yml | 83 ++-- boot-plugin/build.gradle | 20 + build.gradle | 372 +++--------------- buildSrc/build.gradle | 35 ++ docs/build.gradle | 222 ++++++----- examples/grails-data-service/build.gradle | 11 +- .../grails-database-per-tenant/build.gradle | 13 +- .../example/DatabasePerTenantSpec.groovy | 1 - .../build.gradle | 11 +- examples/grails-hibernate/build.gradle | 13 +- .../grails-multiple-datasources/build.gradle | 10 +- .../build.gradle | 15 +- .../grails-schema-per-tenant/build.gradle | 15 +- examples/issue450/build.gradle | 13 +- examples/spring-boot-hibernate/build.gradle | 33 +- examples/standalone-hibernate/build.gradle | 12 +- gradle.properties | 10 +- gradle/example-config.gradle | 3 + gradle/java-config.gradle | 6 + gradle/publish-config.gradle | 23 ++ gradle/tck-config.gradle | 71 ++++ gradle/test-config.gradle | 37 ++ gradle/testVerbose.gradle | 33 -- grails-database-migration/build.gradle | 133 ++----- .../init/databasemigration/Application.groovy | 8 +- .../resources/logback-test.xml | 4 +- grails-datastore-gorm-hibernate/build.gradle | 97 ++--- grails-plugin/build.gradle | 50 ++- grails-plugin/grails-app/.gitkeep | 0 .../Application.groovy | 13 - .../hibernate/HibernateGrailsPlugin.groovy | 6 +- .../test/resources}/application.yml | 4 - settings.gradle | 26 +- 39 files changed, 805 insertions(+), 1038 deletions(-) create mode 100644 buildSrc/build.gradle create mode 100644 gradle/example-config.gradle create mode 100644 gradle/java-config.gradle create mode 100644 gradle/publish-config.gradle create mode 100644 gradle/tck-config.gradle create mode 100644 gradle/test-config.gradle delete mode 100644 gradle/testVerbose.gradle delete mode 100644 grails-plugin/grails-app/.gitkeep delete mode 100644 grails-plugin/grails-app/init/grails.plugin.hibernate/Application.groovy rename grails-plugin/{grails-app/conf => src/test/resources}/application.yml (79%) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 20de5b9e15..133387e57f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,7 +5,7 @@ updates: schedule: interval: daily open-pull-requests-limit: 10 - target-branch: 7.3.x + target-branch: 9.0.x labels: - "type: dependency upgrade" ignore: diff --git a/.github/renovate.json b/.github/renovate.json index bc76c18850..2b7b266a98 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -10,7 +10,7 @@ }, { "matchPackagePatterns": [ - "^org\\.codehaus\\.groovy" + "^org\\.apache\\.groovy" ], "groupName": "groovy monorepo" }, @@ -83,8 +83,7 @@ "org.grails:grails-web-databinding", "org.grails:grails-web-fileupload", "org.grails:grails-web-mvc", - "org.grails:grails-web-url-mappings", - "org.grails:grails-gradle-plugin" + "org.grails:grails-web-url-mappings" ], "groupName": "grails monorepo" } diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index efb83c4fc7..ac0a0c4439 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -1,56 +1,57 @@ -name: Publish Docs +name: "Publish Docs" on: workflow_dispatch: inputs: ref: description: 'The Tag or Branch Name' required: true +env: + GIT_USER_NAME: grails-build + GIT_USER_EMAIL: grails-build@users.noreply.github.com jobs: docs: - runs-on: ubuntu-latest - env: - GIT_USER_NAME: 'grails-build' - GIT_USER_EMAIL: 'grails-build@users.noreply.github.com' + runs-on: ubuntu-24.04 steps: - - name: Checkout repository + - name: "ðŸ“Ĩ Checkout repository" uses: actions/checkout@v4 with: - token: ${{ secrets.GH_TOKEN }} - ref: ${{github.event.inputs.ref}} - - name: Set up JDK + ref: ${{ github.event.inputs.ref }} + - name: "👀 Find the project version for the checked out tag or branch" + run: | + PROJECT_VERSION=$(grep '^projectVersion=' gradle.properties | cut -d'=' -f2) + echo "PROJECT_VERSION=${PROJECT_VERSION}" >> $GITHUB_ENV + echo "Project version: ${PROJECT_VERSION}" + - name: "☕ïļ Setup JDK" uses: actions/setup-java@v4 with: + java-version: 17 distribution: liberica - java-version: '17' - - name: Publish Documentation - id: docs - uses: gradle/gradle-build-action@v3 + - name: "🐘 Setup Gradle" + uses: gradle/actions/setup-gradle@v4 + with: + develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + - name: "📖 Generate documentation" env: - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} - GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER: ${{ secrets.GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER }} - GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY: ${{ secrets.GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY }} GITHUB_MAVEN_PASSWORD: ${{ secrets.GITHUB_TOKEN }} - with: - arguments: docs:docs - - name: Determine docs target repository - if: success() - uses: haya14busa/action-cond@v1 - id: docs_target - with: - cond: ${{ github.repository == 'grails/gorm-hibernate5' }} - if_true: "grails/grails-data-mapping" - if_false: ${{ github.repository }} - - name: Publish to Github Pages - if: success() - uses: grails/github-pages-deploy-action@grails + run: ./gradlew docs:docs + - name: "👀 Determine docs target repository" + run: | + if [ "${{ github.repository }}" = "grails/gorm-hibernate5" ]; then + DOCS_TARGET_REPOSITORY="grails/grails-data-mapping" + else + DOCS_TARGET_REPOSITORY="${{ github.repository }}" + fi + echo "DOCS_TARGET_REPOSITORY=${DOCS_TARGET_REPOSITORY}" >> $GITHUB_ENV + echo "Target Repository: ${DOCS_TARGET_REPOSITORY}" + - name: "ðŸ“Ī Publish documentation to Github Pages" + uses: grails/github-pages-deploy-action@v3 env: - SKIP_LATEST: ${{ contains(steps.release_version.outputs.release_version, 'M') }} - TARGET_REPOSITORY: ${{ steps.docs_target.outputs.value }} - GH_TOKEN: ${{ secrets.GH_TOKEN }} + BETA: ${{ contains(env.PROJECT_VERSION, 'M') || contains(env.PROJECT_VERSION, 'RC') }} BRANCH: gh-pages - FOLDER: docs/build/docs + COMMIT_EMAIL: ${{ env.GIT_USER_EMAIL }} + COMMIT_NAME: ${{ env.GIT_USER_NAME }} DOC_SUB_FOLDER: hibernate - DOC_FOLDER: gh-pages - COMMIT_EMAIL: 'grails-build@users.noreply.github.com' - COMMIT_NAME: 'grails-build' - VERSION: ${{ steps.release_version.outputs.release_version }} \ No newline at end of file + FOLDER: docs/build/docs + GH_TOKEN: ${{ secrets.GH_TOKEN }} + TARGET_REPOSITORY: ${{ env.DOCS_TARGET_REPOSITORY }} + VERSION: ${{ env.PROJECT_VERSION }} \ No newline at end of file diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 7cb6db645c..0cd313c68a 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -1,4 +1,4 @@ -name: Java CI +name: "Java CI" on: push: branches: @@ -7,77 +7,75 @@ on: branches: - '[7-9]+.[0-9]+.x' workflow_dispatch: +env: + GIT_USER_NAME: grails-build + GIT_USER_EMAIL: grails-build@users.noreply.github.com jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 env: - WORKSPACE: ${{ github.workspace }} GRADLE_OPTS: -Xmx1500m -Dfile.encoding=UTF-8 steps: - - uses: actions/checkout@v4 - - name: Set up JDK + - name: "ðŸ“Ĩ Checkout repository" + uses: actions/checkout@v4 + - name: "☕ïļ Setup JDK" uses: actions/setup-java@v4 with: + java-version: 17 distribution: liberica - java-version: '17' - - name: Run Build + - name: "🐘 Setup Gradle" + uses: gradle/actions/setup-gradle@v4 + with: + develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + - name: "ðŸ”Ļ Run Build" id: build - uses: gradle/gradle-build-action@v3 env: - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} - GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER: ${{ secrets.GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER }} - GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY: ${{ secrets.GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY }} GITHUB_MAVEN_PASSWORD: ${{ secrets.GITHUB_TOKEN }} - with: - arguments: build + run: ./gradlew build --continue publish: if: github.event_name == 'push' - runs-on: ubuntu-latest - needs: ['build'] + needs: 'build' + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 - - name: Set up JDK + - name: "ðŸ“Ĩ Checkout repository" + uses: actions/checkout@v4 + - name: "☕ïļ Setup JDK" uses: actions/setup-java@v4 with: + java-version: 17 distribution: liberica - java-version: '17' - - name: Publish Artifacts To Grails Artifactory (repo.grails.org) - uses: gradle/gradle-build-action@v3 - env: - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} - GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER: ${{ secrets.GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER }} - GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY: ${{ secrets.GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY }} - ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }} - ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }} + - name: "🐘 Setup Gradle" + uses: gradle/actions/setup-gradle@v4 with: - arguments: -Dorg.gradle.internal.publish.checksums.insecure=true publish - - name: Build Docs - if: success() - uses: gradle/gradle-build-action@v3 + develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + - name: "ðŸ“Ī Publish Snapshot to repo.grails.org" env: - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} - GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER: ${{ secrets.GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER }} - GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY: ${{ secrets.GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY }} - with: - arguments: docs:docs - - name: Determine docs target repository - if: success() - uses: haya14busa/action-cond@v1 - id: docs_target - with: - cond: ${{ github.repository == 'grails/gorm-hibernate5' }} - if_true: "grails/grails-data-mapping" - if_false: ${{ github.repository }} - - name: Publish to Github Pages - if: success() - uses: grails/github-pages-deploy-action@grails + GITHUB_MAVEN_PASSWORD: ${{ secrets.GITHUB_TOKEN }} + GRADLE_PUBLISH_RELEASE: 'false' + MAVEN_PUBLISH_USERNAME: ${{ secrets.MAVEN_PUBLISH_USERNAME }} + MAVEN_PUBLISH_PASSWORD: ${{ secrets.MAVEN_PUBLISH_PASSWORD }} + run: ./gradlew publish --no-build-cache + - name: "ðŸ”Ļ Build Docs" + env: + GITHUB_MAVEN_PASSWORD: ${{ secrets.GITHUB_TOKEN }} + run: ./gradlew docs:docs + - name: "👀 Determine docs target repository" + run: | + if [ "${{ github.repository }}" = "grails/gorm-hibernate5" ]; then + DOCS_TARGET_REPOSITORY="grails/grails-data-mapping" + else + DOCS_TARGET_REPOSITORY="${{ github.repository }}" + fi + echo "DOCS_TARGET_REPOSITORY=${DOCS_TARGET_REPOSITORY}" >> $GITHUB_ENV + echo "Target Repository: ${DOCS_TARGET_REPOSITORY}" + - name: "ðŸ“Ī Publish to Github Pages" + uses: grails/github-pages-deploy-action@v3 env: - SKIP_SNAPSHOT: ${{ contains(steps.release_version.outputs.release_version, 'M') }} - TARGET_REPOSITORY: ${{ steps.docs_target.outputs.value }} - GH_TOKEN: ${{ secrets.GH_TOKEN }} BRANCH: gh-pages - FOLDER: docs/build/docs - DOC_SUB_FOLDER: hibernate + COMMIT_EMAIL: ${{ env.GIT_USER_EMAIL }} + COMMIT_NAME: ${{ env.GIT_USER_NAME }} DOC_FOLDER: gh-pages - COMMIT_EMAIL: 'grails-build@users.noreply.github.com' - COMMIT_NAME: 'grails-build' \ No newline at end of file + DOC_SUB_FOLDER: hibernate + FOLDER: docs/build/docs + GH_TOKEN: ${{ secrets.GH_TOKEN }} + TARGET_REPOSITORY: ${{ env.DOCS_TARGET_REPOSITORY }} \ No newline at end of file diff --git a/.github/workflows/groovy-joint-workflow.yml b/.github/workflows/groovy-joint-workflow.yml index cf8eeef9a4..29c7ee8cc9 100644 --- a/.github/workflows/groovy-joint-workflow.yml +++ b/.github/workflows/groovy-joint-workflow.yml @@ -1,22 +1,4 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: "Grails Joint Validation Build" -# GROOVY_2_5_X == Grails 4.0.x -# GROOVY_3_0_X == grails master -# Groovy master branch does not map to any due to changed package names. +name: "Groovy Joint Validation Build" on: push: branches: @@ -27,136 +9,131 @@ on: workflow_dispatch: permissions: contents: read -env: - CI_GROOVY_VERSION: + packages: read jobs: build_groovy: - strategy: - fail-fast: true - runs-on: ubuntu-latest + name: "Build Groovy" + runs-on: ubuntu-24.04 outputs: groovyVersion: ${{ steps.groovy-version.outputs.value }} steps: - - name: Set up JDK + - name: "☕ïļ Setup JDK" uses: actions/setup-java@v4 with: - distribution: liberica java-version: 17 - - name: Cache local Maven repository & Groovy + distribution: liberica + - name: "🗄ïļ Cache local Maven repository" uses: actions/cache@v4 with: - path: | - ~/groovy - ~/.m2/repository - key: cache-local-groovy-maven-${{ github.sha }} - - name: Checkout Groovy 4_0_X (Grails 7 and later) - run: cd .. && git clone --depth 1 https://github.com/apache/groovy.git -b GROOVY_4_0_X --single-branch - - name: Set CI_GROOVY_VERSION for Grails + path: ~/.m2/repository + key: cache-local-maven-${{ github.sha }} + - name: "ðŸ“Ĩ Checkout this project to fetch Gradle Plugin versions it uses" + uses: actions/checkout@v4 + with: + sparse-checkout-cone-mode: false + sparse-checkout: settings.gradle + - name: "📝 Store the Gradle Plugin versions used in this project" + id: gradle-plugin-versions + run: | + DEVELOCITY_PLUGIN_VERSION=$(grep -m 1 'id\s*\(\"com.gradle.develocity\"\|'"'com.gradle.develocity'"'\)\s*version' settings.gradle | sed -E "s/.*version[[:space:]]*['\"]?([0-9]+\.[0-9]+(\.[0-9]+)?)['\"]?.*/\1/" | tr -d [:space:]) + COMMON_CUSTOM_USER_DATA_PLUGIN_VERSION=$(grep -m 1 'id\s*\(\"com.gradle.common-custom-user-data-gradle-plugin\"\|'"'com.gradle.common-custom-user-data-gradle-plugin'"'\)\s*version' settings.gradle | sed -E "s/.*version[[:space:]]*['\"]?([0-9]+\.[0-9]+(\.[0-9]+)?)['\"]?.*/\1/" | tr -d [:space:]) + echo "Project uses Develocity Plugin version: $DEVELOCITY_PLUGIN_VERSION" + echo "Project uses Common Custom User Data Plugin version: $COMMON_CUSTOM_USER_DATA_PLUGIN_VERSION" + echo "develocity_plugin_version=$DEVELOCITY_PLUGIN_VERSION" >> $GITHUB_OUTPUT + echo "common_custom_user_data_plugin_version=$COMMON_CUSTOM_USER_DATA_PLUGIN_VERSION" >> $GITHUB_OUTPUT + rm settings.gradle + - name: "ðŸ“Ĩ Checkout Groovy 4_0_X (Grails 7 and later)" + run: git clone --depth 1 https://github.com/apache/groovy.git -b GROOVY_4_0_X --single-branch + - name: "🐘 Setup Gradle" + uses: gradle/actions/setup-gradle@v4 + with: + develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + - name: "📝 Store Groovy version to use when building the project" id: groovy-version run: | - cd ../groovy - echo "CI_GROOVY_VERSION=$(cat gradle.properties | grep groovyVersion | cut -d\= -f2 | tr -d '[:space:]')" >> $GITHUB_ENV - echo "value=$(cat gradle.properties | grep groovyVersion | cut -d\= -f2 | tr -d '[:space:]')" >> $GITHUB_OUTPUT - - name: Prepare Develocity Setup 1 - id: develocity_conf_1 + cd groovy + GROOVY_VERSION=$(cat gradle.properties | grep groovyVersion | cut -d\= -f2 | tr -d '[:space:]') + echo "Groovy version $GROOVY_VERSION stored" + echo "value=$GROOVY_VERSION" >> $GITHUB_OUTPUT + - name: "🐘 Configure Gradle Plugins (Step 1/3)" + id: develocity-conf-1 run: | echo "VALUE<> $GITHUB_OUTPUT echo "plugins { " >> $GITHUB_OUTPUT - echo " id 'com.gradle.enterprise' version '3.15.1'" >> $GITHUB_OUTPUT - echo " id 'com.gradle.common-custom-user-data-gradle-plugin' version '1.11.3'" >> $GITHUB_OUTPUT + echo " id 'com.gradle.develocity' version '${{ steps.gradle-plugin-versions.outputs.develocity_plugin_version }}'" >> $GITHUB_OUTPUT + echo " id 'com.gradle.common-custom-user-data-gradle-plugin' version '${{ steps.gradle-plugin-versions.outputs.common_custom_user_data_plugin_version }}'" >> $GITHUB_OUTPUT echo "}" >> $GITHUB_OUTPUT echo "" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - - name: Prepare Develocity Setup 2 - id: develocity_conf_2 + - name: "🐘 Configure Gradle Plugins (Step 2/3)" + id: develocity-conf-2 run: | echo "VALUE<> $GITHUB_OUTPUT - echo "gradleEnterprise {" >> $GITHUB_OUTPUT - echo " server = 'https://ge.grails.org'" >> $GITHUB_OUTPUT - echo " buildScan {" >> $GITHUB_OUTPUT - echo " publishAlways()" >> $GITHUB_OUTPUT - echo " publishIfAuthenticated()" >> $GITHUB_OUTPUT - echo " uploadInBackground = System.getenv('CI') == null" >> $GITHUB_OUTPUT - echo " capture {" >> $GITHUB_OUTPUT - echo " taskInputFiles = true" >> $GITHUB_OUTPUT - echo " }" >> $GITHUB_OUTPUT - echo " }" >> $GITHUB_OUTPUT - echo "}" >> $GITHUB_OUTPUT - echo "" >> $GITHUB_OUTPUT - echo "buildCache {" >> $GITHUB_OUTPUT - echo " local { enabled = System.getenv('CI') != 'true' }" >> $GITHUB_OUTPUT - echo " remote(HttpBuildCache) {" >> $GITHUB_OUTPUT - echo " push = System.getenv('CI') == 'true'" >> $GITHUB_OUTPUT - echo " enabled = true" >> $GITHUB_OUTPUT - echo " url = 'https://ge.grails.org/cache/'" >> $GITHUB_OUTPUT - echo " credentials {" >> $GITHUB_OUTPUT - echo " username = System.getenv('GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER')" >> $GITHUB_OUTPUT - echo " password = System.getenv('GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY')" >> $GITHUB_OUTPUT - echo " }" >> $GITHUB_OUTPUT - echo " }" >> $GITHUB_OUTPUT - echo "}" >> $GITHUB_OUTPUT + echo "def isAuthenticated = System.getenv('DEVELOCITY_ACCESS_KEY') != null" >> $GITHUB_OUTPUT + echo "develocity {" >> $GITHUB_OUTPUT + echo " server = 'https://ge.grails.org'" >> $GITHUB_OUTPUT + echo " buildScan {" >> $GITHUB_OUTPUT + echo " tag('groovy')" >> $GITHUB_OUTPUT + echo " tag('gorm-hibernate5')" >> $GITHUB_OUTPUT + echo " publishing.onlyIf { isAuthenticated }" >> $GITHUB_OUTPUT + echo " uploadInBackground = false" >> $GITHUB_OUTPUT + echo " }" >> $GITHUB_OUTPUT + echo "}" >> $GITHUB_OUTPUT + echo "buildCache {" >> $GITHUB_OUTPUT + echo " local { enabled = false }" >> $GITHUB_OUTPUT + echo " remote(develocity.buildCache) {" >> $GITHUB_OUTPUT + echo " push = isAuthenticated" >> $GITHUB_OUTPUT + echo " enabled = true" >> $GITHUB_OUTPUT + echo " }" >> $GITHUB_OUTPUT + echo "}" >> $GITHUB_OUTPUT echo "" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - - name: Develocity Set-up + - name: "🐘 Configure Gradle Plugins (step 3/3)" run: | - cd ../groovy + cd groovy # Delete existing plugins from settings.gradle file sed -i '32,37d' settings.gradle - # Add Gradle Enterprise set-up related configuration after line no 31 in settings.gradle - echo "${{ steps.develocity_conf_1.outputs.value }}" | sed -i -e "31r /dev/stdin" settings.gradle + # Add Develocity setup related configuration after line no 31 in settings.gradle + echo "${{ steps.develocity-conf-1.outputs.value }}" | sed -i -e "31r /dev/stdin" settings.gradle # Delete existing buildCache configuration from gradle/build-scans.gradle file sed -i '23,46d' gradle/build-scans.gradle - # Add Gradle Enterprise set-up related configuration after line no 22 in gradle/build-scans.gradle - echo "${{ steps.develocity_conf_2.outputs.value }}" | sed -i -e "22r /dev/stdin" gradle/build-scans.gradle - - name: Build and install groovy (no docs) - uses: gradle/gradle-build-action@v3 - env: - GRADLE_SCANS_ACCEPT: yes - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} - GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER: ${{ secrets.GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER }} - GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY: ${{ secrets.GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY }} - GITHUB_MAVEN_PASSWORD: ${{ secrets.GITHUB_TOKEN }} - with: - build-root-directory: ../groovy - arguments: | - publishToMavenLocal - -x groovydoc - -x javadoc - -x javadocAll - -x groovydocAll - -x asciidoc - -x docGDK - build_gorm_hibernate5: - needs: [build_groovy] - strategy: - fail-fast: true - runs-on: ubuntu-latest + # Add Develocity setup related configuration after line no 22 in gradle/build-scans.gradle + echo "${{ steps.develocity-conf-2.outputs.value }}" | sed -i -e "22r /dev/stdin" gradle/build-scans.gradle + - name: "ðŸ”Ļ Publish Groovy to local maven repository (no docs)" + run: | + cd groovy + ./gradlew pTML -x groovydoc -x javadoc -x javadocAll -x groovydocAll -x asciidoc -x docGDK + + build_project: + name: "Build Project" + needs: build_groovy + runs-on: ubuntu-24.04 + permissions: + contents: read + packages: read steps: - - uses: actions/checkout@v4 - - name: Set up JDK + - name: "ðŸ“Ĩ Checkout project" + uses: actions/checkout@v4 + - name: "☕ïļ Setup JDK" uses: actions/setup-java@v4 with: - distribution: liberica java-version: 17 - - name: Cache local Maven repository & Groovy + distribution: liberica + - name: "🐘 Setup Gradle" + uses: gradle/actions/setup-gradle@v4 + with: + develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + - name: "🗄ïļ Restore local Maven repository from cache" uses: actions/cache@v4 with: - path: | - ~/groovy - ~/.m2/repository - key: cache-local-groovy-maven-${{ github.sha }} - - name: Set CI_GROOVY_VERSION for Grails - run: | - echo "CI_GROOVY_VERSION=${{needs.build_groovy.outputs.groovyVersion}}" >> $GITHUB_ENV - - name: Build GORM Hibernate5 - id: build_gorm_hibernate5 - uses: gradle/gradle-build-action@v3 + path: ~/.m2/repository + key: cache-local-maven-${{ github.sha }} + - name: "ðŸŠķ Add mavenLocal repository to build" + run: sed -i 's|// mavenLocal() // Keep|mavenLocal() // Keep|' build.gradle + - name: "ðŸ”Ļ Build and test the project using the locally built Groovy snapshot" env: - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} - GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER: ${{ secrets.GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER }} - GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY: ${{ secrets.GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY }} GITHUB_MAVEN_PASSWORD: ${{ secrets.GITHUB_TOKEN }} - with: - arguments: | - build - -x groovydoc \ No newline at end of file + run: > + ./gradlew build --continue + -PgroovyVersion=${{needs.build_groovy.outputs.groovyVersion}} + -x groovydoc \ No newline at end of file diff --git a/.github/workflows/release-notes.yml b/.github/workflows/release-notes.yml index 97906e28a4..6eb2391a3c 100644 --- a/.github/workflows/release-notes.yml +++ b/.github/workflows/release-notes.yml @@ -1,49 +1,22 @@ -name: Changelog +name: "Release Drafter" on: issues: types: [closed,reopened] push: branches: - - '[7-9]+.[0-9]+.x' + - '[6-9]+.[0-9]+.x' pull_request: types: [opened, reopened, synchronize] pull_request_target: - types: [opened, reopened, synchronize] + types: [opened, reopened, synchronize] workflow_dispatch: jobs: - release_notes: + update_release_draft: + permissions: + contents: read # limit to read access runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: Check if it has release drafter config file - id: check_release_drafter - run: | - has_release_drafter=$([ -f .github/release-drafter.yml ] && echo "true" || echo "false") - echo "has_release_drafter=${has_release_drafter}" >> $GITHUB_OUTPUT - - name: Extract branch name - id: extract_branch - run: echo "value=${GITHUB_REF:11}" >> $GITHUB_OUTPUT - # If it has release drafter: - - uses: release-drafter/release-drafter@v6 - if: steps.check_release_drafter.outputs.has_release_drafter == 'true' + - name: "📝 Update Release Draft" + uses: release-drafter/release-drafter@v6 env: GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - # Otherwise: - - name: Export Gradle Properties - if: steps.check_release_drafter.outputs.has_release_drafter == 'false' - uses: grails/github-actions/export-gradle-properties@main - - uses: grails/github-actions/release-notes@main - if: steps.check_release_drafter.outputs.has_release_drafter == 'false' - id: release_notes - with: - token: ${{ secrets.GH_TOKEN }} - - uses: ncipollo/release-action@v1 - if: steps.check_release_drafter.outputs.has_release_drafter == 'false' && steps.release_notes.outputs.generated_changelog == 'true' - with: - allowUpdates: true - commit: ${{ steps.release_notes.outputs.current_branch }} - draft: true - name: ${{ env.title }} ${{ steps.release_notes.outputs.next_version }} - tag: v${{ steps.release_notes.outputs.next_version }} - bodyFile: CHANGELOG.md - token: ${{ secrets.GH_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9c4a93063b..8497610523 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,4 +1,4 @@ -name: Release +name: "Release" on: release: types: [published] @@ -28,20 +28,20 @@ jobs: with: develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - name: "⚙ïļ Run pre-release" - uses: grails/github-actions/pre-release@main - - name: "🔍 Determine Target Branch" + uses: grails/github-actions/pre-release@v3 + - name: "👀 Determine Target Branch" id: extract_branch run: | - echo "Determining Target Branch" TARGET_BRANCH=`cat $GITHUB_EVENT_PATH | jq '.release.target_commitish' | sed -e 's/^"\(.*\)"$/\1/g'` - echo $TARGET_BRANCH echo "value=${TARGET_BRANCH}" >> $GITHUB_OUTPUT + echo "Target branch: ${TARGET_BRANCH}" - name: "📝 Store the current release version" id: release_version - run: echo "value=${GITHUB_REF:11}" >> $GITHUB_OUTPUT + run: | + RELEASE_VERSION=${GITHUB_REF:11} + echo "value=${RELEASE_VERSION}" >> $GITHUB_OUTPUT + echo "Release version: ${RELEASE_VERSION}" - name: "ðŸ§Đ Run Assemble" - if: success() - id: assemble env: GITHUB_MAVEN_PASSWORD: ${{ secrets.GITHUB_TOKEN }} run: ./gradlew --refresh-dependencies assemble @@ -50,18 +50,15 @@ jobs: SECRING_FILE: ${{ secrets.SECRING_FILE }} run: echo $SECRING_FILE | base64 -d > ${{ github.workspace }}/secring.gpg - name: "ðŸ“Ī Publish to and close Sonatype staging repository" - id: publish env: - SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} - SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} - SONATYPE_STAGING_PROFILE_ID: ${{ secrets.SONATYPE_STAGING_PROFILE_ID }} + GITHUB_MAVEN_PASSWORD: ${{ secrets.GITHUB_TOKEN }} + GRAILS_PUBLISH_RELEASE: 'true' + NEXUS_PUBLISH_USERNAME: ${{ secrets.NEXUS_PUBLISH_USERNAME }} + NEXUS_PUBLISH_PASSWORD: ${{ secrets.NEXUS_PUBLISH_PASSWORD }} + NEXUS_PUBLISH_URL: ${{ secrets.NEXUS_PUBLISH_RELEASE_URL }} + NEXUS_PUBLISH_STAGING_PROFILE_ID: ${{ secrets.NEXUS_PUBLISH_STAGING_PROFILE_ID }} SIGNING_KEY: ${{ secrets.SIGNING_KEY }} SIGNING_PASSPHRASE: ${{ secrets.SIGNING_PASSPHRASE }} - SECRING_FILE: ${{ secrets.SECRING_FILE }} - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} - GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER: ${{ secrets.GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER }} - GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY: ${{ secrets.GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY }} - GITHUB_MAVEN_PASSWORD: ${{ secrets.GITHUB_TOKEN }} run: > ./gradlew --no-build-cache -Psigning.secretKeyRingFile=${{ github.workspace }}/secring.gpg @@ -91,23 +88,20 @@ jobs: develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - name: "🚀 Release Sonatype Staging Repository" env: - SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} - SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} - SONATYPE_STAGING_PROFILE_ID: ${{ secrets.SONATYPE_STAGING_PROFILE_ID }} + GITHUB_MAVEN_PASSWORD: ${{ secrets.GITHUB_TOKEN }} + GRAILS_PUBLISH_RELEASE: 'true' + NEXUS_PUBLISH_USERNAME: ${{ secrets.NEXUS_PUBLISH_USERNAME }} + NEXUS_PUBLISH_PASSWORD: ${{ secrets.NEXUS_PUBLISH_PASSWORD }} + NEXUS_PUBLISH_URL: ${{ secrets.NEXUS_PUBLISH_RELEASE_URL }} + NEXUS_PUBLISH_STAGING_PROFILE_ID: ${{ secrets.NEXUS_PUBLISH_STAGING_PROFILE_ID }} SIGNING_KEY: ${{ secrets.SIGNING_KEY }} SIGNING_PASSPHRASE: ${{ secrets.SIGNING_PASSPHRASE }} - SECRING_FILE: ${{ secrets.SECRING_FILE }} - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} - GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER: ${{ secrets.GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER }} - GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY: ${{ secrets.GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY }} - GITHUB_MAVEN_PASSWORD: ${{ secrets.GITHUB_TOKEN }} run: > ./gradlew findSonatypeStagingRepository releaseSonatypeStagingRepository - name: "⚙ïļ Run post-release" - if: success() - uses: grails/github-actions/post-release@main + uses: grails/github-actions/post-release@v3 docs: environment: release name: "Publish Documentation" @@ -124,35 +118,32 @@ jobs: - 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: develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - name: "📖 Generate documentation" env: - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} - GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER: ${{ secrets.GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER }} - GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY: ${{ secrets.GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY }} GITHUB_MAVEN_PASSWORD: ${{ secrets.GITHUB_TOKEN }} run: ./gradlew docs:docs - - name: Export Gradle Properties - uses: grails/github-actions/export-gradle-properties@main - - name: Determine docs target repository - if: success() - uses: haya14busa/action-cond@v1 - id: docs_target - with: - cond: ${{ github.repository == 'grails/gorm-hibernate5' }} - if_true: "grails/grails-data-mapping" - if_false: ${{ github.repository }} + - name: "ðŸ›Ŧ Export Gradle Properties" + uses: grails/github-actions/export-gradle-properties@v3 + - name: "👀 Determine docs target repository" + run: | + if [ "${{ github.repository }}" = "grails/gorm-hibernate5" ]; then + DOCS_TARGET_REPOSITORY="grails/grails-data-mapping" + else + DOCS_TARGET_REPOSITORY="${{ github.repository }}" + fi + echo "DOCS_TARGET_REPOSITORY=${DOCS_TARGET_REPOSITORY}" >> $GITHUB_ENV + echo "Target Repository: ${DOCS_TARGET_REPOSITORY}" - name: "ðŸ“Ī Publish documentation to Github Pages" - if: success() - uses: grails/github-pages-deploy-action@grails + uses: grails/github-pages-deploy-action@v3 env: - SKIP_LATEST: ${{ contains(steps.release_version.outputs.release_version, 'M') }} - TARGET_REPOSITORY: ${{ steps.docs_target.outputs.value }} + BETA: ${{ contains(needs.publish.outputs.release_version, 'M') || contains(needs.publish.outputs.release_version, 'RC') }} + TARGET_REPOSITORY: ${{ env.DOCS_TARGET_REPOSITORY }} GH_TOKEN: ${{ secrets.GH_TOKEN }} BRANCH: gh-pages FOLDER: docs/build/docs diff --git a/boot-plugin/build.gradle b/boot-plugin/build.gradle index ffb70447df..66ccc767ac 100644 --- a/boot-plugin/build.gradle +++ b/boot-plugin/build.gradle @@ -1,4 +1,18 @@ +plugins { + id 'groovy' + id 'java-library' +} + +version = projectVersion +group = 'org.grails' + +ext { + apiDocs = true + snapshotPublishUrl = 'https://repo.grails.org/grails/libs-snapshots-local' +} + dependencies { + // TODO: Clarify and clean up dependencies implementation platform("org.grails:grails-bom:$grailsVersion") compileOnly "org.grails:grails-shell", { @@ -16,3 +30,9 @@ dependencies { testRuntimeOnly "org.apache.tomcat:tomcat-jdbc" testRuntimeOnly "com.h2database:h2" } + +apply { + from rootProject.layout.projectDirectory.file('gradle/java-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/test-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/publish-config.gradle') +} diff --git a/build.gradle b/build.gradle index 6245928591..1981cd014f 100644 --- a/build.gradle +++ b/build.gradle @@ -1,350 +1,82 @@ -buildscript { - repositories { - maven { url "https://repo.grails.org/grails/core" } - maven { url "https://plugins.gradle.org/m2/" } - if (System.getenv("GITHUB_MAVEN_PASSWORD") && !grailsVersion.endsWith('-SNAPSHOT')) { - System.out.println("Adding Grails Core Repo for ${project.name}") - maven { - url = 'https://maven.pkg.github.com/grails/grails-core' - credentials { - username = 'DOES_NOT_MATTER' - password = System.getenv("GITHUB_MAVEN_PASSWORD") - } - } - } - } - dependencies { - classpath platform("org.grails:grails-bom:$grailsVersion") - classpath "io.github.gradle-nexus:publish-plugin:$gradleNexusPublishPluginVersion" - classpath "org.grails:grails-gradle-plugin" - classpath "org.grails.plugins:views-gradle" - classpath "org.asciidoctor:asciidoctor-gradle-jvm:$asciidoctorGradleVersion" - } +ext { + isCiBuild = System.getenv().containsKey('CI') } -group "org.grails" -version project.projectVersion -logger.info("GORM VERSION = ${project.gormVersion}") - -ext { - isTravisBuild = System.getenv().get("TRAVIS") == 'true' - isCiBuild = project.hasProperty("isCiBuild") || System.getenv().get("CI") as Boolean - isBuildSnapshot = version.endsWith('-SNAPSHOT') - isReleaseVersion = !isBuildSnapshot - nexusUsername = System.getenv("SONATYPE_USERNAME") ?: project.hasProperty("sonatypeOssUsername") ? project.sonatypeOssUsername : '' - nexusPassword = System.getenv("SONATYPE_PASSWORD") ?: project.hasProperty("sonatypeOssPassword") ? project.sonatypeOssPassword : '' - isSnapshot = project.projectVersion.endsWith("-SNAPSHOT") - groovyVersion = System.getenv('CI_GROOVY_VERSION') +String customGroovyVersion = findProperty('groovyVersion') ?: System.getenv('GROOVY_VERSION') +if (customGroovyVersion) { + logger.lifecycle('Using custom Groovy version: ', customGroovyVersion) } -ext."signing.keyId" = System.getenv("SIGNING_KEY") ?: project.hasProperty("signing.keyId") ? project.getProperty('signing.keyId') : null -ext."signing.password" = System.getenv("SIGNING_PASSPHRASE") ?: project.hasProperty("signing.password") ? project.getProperty('signing.password') : null -ext."signing.secretKeyRingFile" = project.hasProperty("signing.secretKeyRingFile") ? project.getProperty('signing.secretKeyRingFile') : null +logger.info('GORM VERSION = {}', datastoreVersion) + +static boolean isDataMappingDependency(DependencyResolveDetails details) { + return details.requested.group == 'org.grails' && + details.requested.name.startsWith('grails-datastore') && + details.requested.name != 'grails-datastore-gorm-hibernate5' +} -if (isReleaseVersion) { - apply plugin: 'maven-publish' - apply plugin: "io.github.gradle-nexus.publish-plugin" +allprojects { - 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 + if (customGroovyVersion) { + configurations.configureEach { + resolutionStrategy.eachDependency { DependencyResolveDetails details -> + if (details.requested.group == 'org.apache.groovy') { + details.useVersion(customGroovyVersion) + } } } } -} -allprojects { - - ext.groovyVersion = System.getenv('CI_GROOVY_VERSION') + configurations.configureEach { + resolutionStrategy.eachDependency { DependencyResolveDetails details -> + // Use the GORM version from the datastoreVersion property, not from the grails-bom + if(isDataMappingDependency(details)) { + details.useVersion(datastoreVersion) + } + } + } repositories { mavenCentral() maven { url = 'https://repo.grails.org/grails/core' } - maven { url = 'https://oss.sonatype.org/content/repositories/snapshots' } // mavenLocal() // Keep, this will be uncommented and used by CI (groovy-joint-workflow) - if(isSnapshot) { - maven { url = 'https://repo.grails.org/grails/libs-snapshots-local' } - } - if(groovyVersion && groovyVersion.endsWith('-SNAPSHOT')) { + if (customGroovyVersion?.endsWith('-SNAPSHOT')) { + // Used for testing locally against the latest snapshot of Groovy + // Usage: ./gradlew build -P"groovyVersion=X.X.X-SNAPSHOT" + logger.lifecycle('Adding Groovy Snapshot Repo for project: {}, Using Groovy {}', name, customGroovyVersion) maven { name = 'ASF Snapshot repo' url = 'https://repository.apache.org/content/repositories/snapshots' } } - if (System.getenv("GITHUB_MAVEN_PASSWORD") && !grailsVersion.endsWith('-SNAPSHOT')) { - System.out.println("Adding Grails Core Repo for ${project.name}") + if (System.getenv('GITHUB_MAVEN_PASSWORD') && !grailsVersion.endsWith('-SNAPSHOT')) { + logger.lifecycle('Adding Grails Core Staging Repo for project: {}', name) maven { url = 'https://maven.pkg.github.com/grails/grails-core' credentials { username = 'DOES_NOT_MATTER' - password = System.getenv("GITHUB_MAVEN_PASSWORD") - } - } - } - } -} - -subprojects { Project subproject -> - - ext { - isExample = subproject.name.startsWith('example') - isPluginProject = subproject.name.endsWith("-plugin") && (subproject.name.startsWith("grails") || subproject.name.startsWith("rx-")) - isGrails3PluginProject = subproject.name.endsWith("-plugin") - } - - if(isExample) { - apply plugin: "groovy" - - ext['gorm.version'] = gormVersion - - if(subproject.name.startsWith("examples-grails")) { - - if (subproject.name != "examples-grails-data-service") { - apply plugin:"org.grails.grails-web" - apply plugin:"org.grails.grails-gsp" - } - } - - dependencies { - testImplementation "jakarta.annotation:jakarta.annotation-api" - testImplementation "io.micrometer:micrometer-core:latest.integration" - testImplementation "io.projectreactor:reactor-test" - testImplementation "org.apache.groovy:groovy-test-junit5" - testImplementation "org.spockframework:spock-core" - testImplementation "org.junit.jupiter:junit-jupiter-api" - testImplementation "org.junit.platform:junit-platform-runner" - testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine" - } - - apply from: "${rootProject.projectDir}/gradle/testVerbose.gradle" - - tasks.withType(Jar) { - duplicatesStrategy = DuplicatesStrategy.INCLUDE - } - return - } - - ext { - projectInfo = new PublishingConvention(project) - pomInfo = { - delegate.name projectInfo.projectName - delegate.description projectInfo.projectDescription - delegate.url projectInfo.projectURL - - delegate.licenses { - delegate.license { - delegate.name 'The Apache Software License, Version 2.0' - delegate.url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - delegate.distribution 'repo' - } - } - - delegate.scm { - delegate.url projectInfo.projectVcsUrl - delegate.connection projectInfo.projectVcsUrl - delegate.developerConnection projectInfo.projectVcsUrl - } - - - delegate.developers { - delegate.developer { - delegate.id 'graemerocher' - delegate.name 'Graeme Rocher' - } - delegate.developer { - delegate.id 'jeffscottbrown' - delegate.name 'Jeff Brown' - } - delegate.developer { - delegate.id 'burtbeckwith' - delegate.name 'Burt Beckwith' - } - delegate.developer { - delegate.id 'puneetbehl' - delegate.name 'Puneet Behl' - } - } - - } - } - - apply plugin: 'groovy' - - configurations { - documentation.extendsFrom(compileClasspath) - } - - if(isPluginProject) { - group "org.grails.plugins" - version project.rootProject.version - } - else { - group "org.grails" - version project.rootProject.version - } - - if(subproject.name == 'docs') { - return - } - - if(isGrails3PluginProject) { - apply plugin: "org.grails.grails-plugin" - } - else { - apply plugin:"groovy" - } - - apply plugin: 'java-library' - apply plugin: 'maven-publish' - apply plugin: 'signing' - - compileJava.options.release = 17 - java { - withJavadocJar() - withSourcesJar() - } - - dependencies { - documentation platform("org.grails:grails-bom:$grailsVersion") - documentation "org.fusesource.jansi:jansi" - documentation "org.apache.groovy:groovy-dateutil" - documentation "info.picocli:picocli:$picocliVersion" - documentation "com.github.javaparser:javaparser-core" - - implementation "org.apache.groovy:groovy" - testImplementation "org.apache.groovy:groovy-test-junit5" - testImplementation "org.spockframework:spock-core" - testImplementation "org.junit.jupiter:junit-jupiter-api" - testImplementation "org.junit.platform:junit-platform-runner" - testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine" - } - - apply from: "${rootProject.projectDir}/gradle/testVerbose.gradle" - - tasks.withType(Test) { - configure { - retry { - maxRetries = 2 - maxFailures = 20 - failOnPassedAfterRetry = true - filter { - excludeClasses.add("*GroovyChangeLogSpec") - } - } - } - } - - groovydoc.classpath = configurations.documentation - - publishing { - - if (isBuildSnapshot) { - 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 - } - if(isGrails3PluginProject) { - url "https://repo.grails.org/grails/plugins3-snapshots-local" - } else { - url "https://repo.grails.org/grails/libs-snapshots-local" - } - } - } - } - - publications { - maven(MavenPublication) { - - pom { - name = projectInfo.projectName - description = projectInfo.projectDescription - url = projectInfo.projectURL - - licenses { - license { - name = 'The Apache Software License, Version 2.0' - url = 'https://www.apache.org/licenses/LICENSE-2.0.txt' - distribution = 'repo' - } - } - - scm { - url = 'scm:git@github.com:grails/gorm-hibernate5.git' - connection = 'scm:git@github.com:grails/gorm-hibernate5.git' - developerConnection = 'scm:git@github.com:grails/gorm-hibernate5.git' - } - - developers { - developer { - id = 'puneetbehl' - name = 'Puneet Behl' - email = 'behlp@unityfoundation.io' - } - } + password = System.getenv('GITHUB_MAVEN_PASSWORD') } - - artifactId projectInfo.projectArtifactId - - from components.java - - afterEvaluate { - if(isGrails3PluginProject) { - artifact source:"${sourceSets.main.groovy.getClassesDirectory().get().getAsFile()}/META-INF/grails-plugin.xml", - classifier:"plugin", - extension:'xml' - } - } - } } } - - afterEvaluate { - signing { - required { isReleaseVersion && gradle.taskGraph.hasTask("publish") } - sign publishing.publications.maven - } - } - - tasks.withType(Sign) { - onlyIf { isReleaseVersion } - } - - //do not generate extra load on Nexus with new staging repository if signing fails - tasks.withType(io.github.gradlenexus.publishplugin.InitializeNexusStagingRepository).configureEach { - shouldRunAfter(tasks.withType(Sign)) - } -} - -class PublishingConvention { - Project project - - String projectArtifactId - String projectName = 'GORM for Hibernate 5' - String projectDescription = 'Provides a GORM Object Mapping implementations for Hibernate 5' - String projectURL = 'https://gorm.grails.org/latest/hibernate' - String projectIssueTrackerUrl = 'https://github.com/grails/gorm-hibernate5/issues' - String projectVcsUrl = 'https://github.com/grails/gorm-hibernate5' - - PublishingConvention(Project project) { - this.project = project - - def name = project.name - if(name.startsWith('grails') && name.endsWith('-plugin')) { - name = 'hibernate5' - } - projectArtifactId = name - } } +// Workaround needed for nexus publishing bug +// version and group must be specified in the root project +// https://github.com/gradle-nexus/publish-plugin/issues/310 +version = projectVersion +group = 'this.will.be.overridden' + +def publishedProjects = [ + 'database-migration', + 'gorm-hibernate5-spring-boot', + 'grails-datastore-gorm-hibernate5', + 'grails-plugin', +] +subprojects { + if (name in publishedProjects) { + // This has to be applied here + apply plugin: 'org.grails.grails-publish' + } +} \ No newline at end of file diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle new file mode 100644 index 0000000000..179fd6d253 --- /dev/null +++ b/buildSrc/build.gradle @@ -0,0 +1,35 @@ +plugins { + id 'groovy-gradle-plugin' +} + +file('../gradle.properties').withInputStream { + def props = new Properties() + props.load(it) + props.each { k, v -> ext.set(k, v) } +} + +repositories { + mavenCentral() + maven { url = 'https://repo.grails.org/grails/core' } + if (System.getenv('GITHUB_MAVEN_PASSWORD') && !grailsVersion.endsWith('-SNAPSHOT')) { + maven { + url = 'https://maven.pkg.github.com/grails/grails-core' + credentials { + username = 'DOES_NOT_MATTER' + password = System.getenv('GITHUB_MAVEN_PASSWORD') + } + } + } +} + +dependencies { + + implementation platform("org.grails:grails-bom:$grailsVersion") + + implementation "org.asciidoctor:asciidoctor-gradle-jvm:$asciidoctorGradleVersion" + implementation 'org.grails:grails-gradle-plugin' + + runtimeOnly 'com.bertramlabs.plugins:asset-pipeline-gradle' + runtimeOnly "io.github.gradle-nexus:publish-plugin:$gradleNexusPublishPluginVersion" + runtimeOnly 'org.grails.plugins:views-gradle' +} \ No newline at end of file diff --git a/docs/build.gradle b/docs/build.gradle index eb2c100a5a..d90e7e7a85 100644 --- a/docs/build.gradle +++ b/docs/build.gradle @@ -1,145 +1,157 @@ -ext { - datastoreGithubBranch = "8.0.x" - checkOutDir = "build/checkout" - explicitGormSrc = System.getProperty("gorm.src") ?: (project.hasProperty('gorm.src') ? project.getProperty("gorm.src") : null) - gormSrc = explicitGormSrc ? file(explicitGormSrc).absolutePath : "$checkOutDir/gorm-src" - zipFile = "build/source.zip" - - coreProjects = [ - 'core', - 'gorm' - ] +import org.asciidoctor.gradle.jvm.AsciidoctorTask +plugins { + id 'groovy' + id 'org.asciidoctor.jvm.convert' } -version rootProject.version +version = projectVersion -apply plugin: 'groovy' -apply plugin: 'org.asciidoctor.jvm.convert' +ext { + isReleaseVersion = !projectVersion.endsWith('-SNAPSHOT') + checkoutDirName = 'checkout' + explicitGormSrc = System.getProperty('gorm.src') ?: project.findProperty('gorm.src') + gormSrc = (explicitGormSrc ? file(explicitGormSrc) : "$checkoutDirName/gorm-src") as String + zipFile = 'build/source.zip' + coreProjects = ['grails-datastore-core', 'grails-datastore-gorm'] +} + +configurations { + documentation { + attributes { + attribute(Bundling.BUNDLING_ATTRIBUTE, (Bundling) (objects.named(Bundling, 'external'))) + } + } +} dependencies { - documentation "org.grails:grails-core" - documentation "org.grails:grails-bootstrap" - documentation "org.grails:grails-spring" + documentation platform("org.grails:grails-bom:$grailsVersion") + documentation 'com.github.javaparser:javaparser-core' documentation "info.picocli:picocli:$picocliVersion" - documentation "org.fusesource.jansi:jansi" - documentation "org.apache.groovy:groovy-dateutil" - documentation "com.github.javaparser:javaparser-core" - - documentation "org.fusesource.jansi:jansi" - for(p in coreProjects) { - documentation "org.grails:grails-datastore-$p" - } - project.rootProject.subprojects.each { subproject -> - if(subproject.name != "docs" && !subproject.name.startsWith('examples')) { - documentation project(":$subproject.name") - } + documentation 'org.apache.groovy:groovy-dateutil' + documentation 'org.fusesource.jansi:jansi' + documentation 'org.grails:grails-bootstrap' + documentation 'org.grails:grails-core' + documentation 'org.grails:grails-spring' + documentation "org.hibernate:hibernate-core-jakarta:$hibernateVersion" + coreProjects.each { + documentation "org.grails:$it" } + rootProject.subprojects + .findAll { it.findProperty('apiDocs') } + .each { documentation project(":$it.name") } } -asciidoctor { - inputs.dir layout.projectDirectory.dir('src/docs/asciidoc') - outputs.dir layout.buildDirectory.dir('docs/manual') +tasks.named('asciidoctor', AsciidoctorTask) { + inputs.dir layout.projectDirectory.dir('src/docs') + outputs.dir layout.buildDirectory.dir('docs') baseDirFollowsSourceDir() resources { - from("${project.projectDir}/src/docs/asciidoc/images") - into "./images" + from("$project.projectDir/src/docs/asciidoc/images") + into './images' } - attributes 'experimental' : 'true', - 'compat-mode' : 'true', - 'toc' : 'left', - 'icons' : 'font', - 'reproducible' : '', - 'version' : project.version, - 'pluginVersion' : project.version, - 'groupId' : project.group, - 'artifactId' : project.name, - 'sourcedir' : "${project.projectDir}/src/main/groovy", - 'migrationPluginExamplesDir' : rootProject.layout.projectDirectory.dir('grails-database-migration/src/integration-test/resources').asFile.absolutePath, - 'migrationPluginGroupId' : rootProject.findProject(':database-migration').group, - 'migrationPluginArtifactId' : rootProject.findProject(':database-migration').name, - 'liquibaseHibernate5Version': liquibaseHibernate5Version + attributes( + 'experimental' : 'true', + 'compat-mode' : 'true', + 'toc' : 'left', + 'icons' : 'font', + 'reproducible' : '', + 'version' : projectVersion, + 'pluginVersion' : projectVersion, + 'groupId' : project.group, + 'artifactId' : project.name, + 'sourcedir' : "$project.rootDir", + 'migrationPluginExamplesDir' : rootProject.layout.projectDirectory.dir('grails-database-migration/src/integration-test/resources').asFile.absolutePath, + 'migrationPluginGroupId' : rootProject.findProject(':database-migration').group, + 'migrationPluginArtifactId' : rootProject.findProject(':database-migration').name, + 'liquibaseHibernate5Version': liquibaseHibernate5Version + ) + jvm { + jvmArgs('--add-opens', 'java.base/sun.nio.ch=ALL-UNNAMED', '--add-opens', 'java.base/java.io=ALL-UNNAMED') + } } -task fetchSource { - outputs.dir layout.buildDirectory.dir('checkout') - inputs.properties(branch: datastoreGithubBranch) +tasks.register('fetchGormSource') { + group = 'documentation' + outputs.dir(layout.buildDirectory.dir(checkoutDirName)) + inputs.property('branch', datastoreGithubBranch) onlyIf { - println "GORM SRC=$explicitGormSrc" + // Only download if no local GORM source is provided return !explicitGormSrc } doLast { - println "Downloading GORM source code." - if (isReleaseVersion) { - ant.get src: "https://github.com/grails/grails-data-mapping/archive/refs/tags/v${gormVersion}.zip", dest: zipFile, verbose: true - } else { - ant.get src: "https://github.com/grails/grails-data-mapping/archive/refs/heads/${datastoreGithubBranch}.zip", dest: zipFile, verbose: true - } - - ant.unzip src: zipFile, dest: checkOutDir, { - mapper type: "regexp", from: "(grails-\\S*?/)(.*)", to: "gorm-src/\\2" + def checkoutDir = layout.buildDirectory.dir(checkoutDirName).get().asFile + ant.mkdir(dir: layout.buildDirectory.get().asFile) + ant.mkdir(dir: checkoutDir) + logger.lifecycle('Downloading GORM source code...') + def ref = isReleaseVersion ? "tags/v$datastoreVersion" : "heads/$datastoreGithubBranch" + ant.get(src: "https://github.com/grails/grails-data-mapping/archive/refs/${ref}.zip", dest: zipFile, verbose: true) + ant.unzip(src: zipFile, dest: checkoutDir) { + mapper(type: 'regexp', from: '(grails-\\S*?/)(.*)', to: "gorm-src/\\2") } - println "GORM source code downloaded." + logger.lifecycle('GORM source code downloaded!') } } -task copyDocs(type:Copy, dependsOn:asciidoctor) { +tasks.register('copyDocs', Copy) { + group = 'documentation' + dependsOn('asciidoctor') mustRunAfter('asciidoctor', 'groovydoc', 'copyResources') finalizedBy('cleanAsciidoc') - from project(':docs').layout.buildDirectory.dir('docs/asciidoc') - into project(':docs').layout.buildDirectory.dir('docs/manual') + from(layout.buildDirectory.dir('docs/asciidoc')) + into(layout.buildDirectory.dir('docs/manual')) } -task cleanAsciidoc(type: Delete, dependsOn: copyDocs) { - dependsOn('copyDocs') - delete project(':docs').layout.buildDirectory.dir('docs/asciidoc') +tasks.register('cleanAsciidoc', Delete) { + group = 'documentation' + delete(layout.buildDirectory.dir('docs/asciidoc')) } -tasks.withType(Groovydoc) { - dependsOn('fetchSource') - docTitle = "GORM for Hibernate 5 - ${project.version}" - destinationDir = project.file('build/docs/api') - - def files - for (p in coreProjects) { - if (files == null) { - files = project.files("${checkOutDir}/gorm-src/grails-datastore-${p}/src/main/groovy") - } else { - files += project.files("${checkOutDir}/gorm-src/grails-datastore-${p}/src/main/groovy") - } - } - project.rootProject.subprojects - .findAll { !it.name.contains('-rx-') && !it.name.startsWith('examples') } - .each { subproject -> - if (subproject.file('src/main/groovy').exists()) { - files += subproject.files("src/main/groovy") - } - } - source = files - classpath += configurations.documentation +tasks.withType(Groovydoc).configureEach { + dependsOn('fetchGormSource') + docTitle = "GORM for Hibernate 5 - $project.version" + + def sourceFiles = coreProjects.collect { + layout.buildDirectory.files("$checkoutDirName/gorm-src/$it/src/main/groovy") + }.sum() + + rootProject.subprojects + .findAll { it.findProperty('apiDocs') } + .each { sourceFiles += it.files('src/main/groovy') } + + source = sourceFiles + destinationDir = layout.buildDirectory.dir('docs/api').get().asFile + access = GroovydocAccess.PROTECTED + processScripts = false + includeMainForScripts = false + includeAuthor = false + classpath = configurations.documentation + groovyClasspath += configurations.documentation } -task copyResources(type:Copy) { - from 'src/docs/resources' - into "${project.layout.buildDirectory.get()}/docs" +tasks.register('copyResources', Copy) { + group = 'documentation' + from(layout.projectDirectory.dir('src/docs/resources')) + into(layout.buildDirectory.dir('docs')) } -task docs(dependsOn:[asciidoctor, groovydoc, copyDocs, copyResources] + - subprojects.findAll { project -> project.tasks.findByName('groovydoc')} - .collect { project -> project.tasks.groovydoc } -) { +tasks.register('docs') { + group = 'documentation' + dependsOn('asciidoctor', 'copyDocs', 'cleanAsciidoc', 'groovydoc', 'copyResources', + rootProject.subprojects + .findAll { it.findProperty('apiDocs') } + .collect { ":${it.name}:groovydoc" } + ) + finalizedBy('assembleDocsDist') } -task assembleDocsDist(type: Zip) { - dependsOn 'docs', 'copyDocs' - from "${project.layout.buildDirectory.get()}/docs" - include '*' - include '*/**' +tasks.register('assembleDocsDist', Zip) { + group = 'documentation' + dependsOn('docs', 'copyDocs') + from(layout.buildDirectory.dir('docs')) archiveFileName = "${project.name}-${project.version}.zip" destinationDirectory = project.layout.buildDirectory.dir('distributions') -} - -docs.finalizedBy assembleDocsDist +} \ No newline at end of file diff --git a/examples/grails-data-service/build.gradle b/examples/grails-data-service/build.gradle index cbaa20fdb5..8ad7832c0e 100644 --- a/examples/grails-data-service/build.gradle +++ b/examples/grails-data-service/build.gradle @@ -1,10 +1,9 @@ plugins { - id 'groovy' id 'org.grails.grails-web' id 'org.grails.plugins.views-json' } -version = rootProject.version +version = projectVersion group = 'examples' dependencies { @@ -14,6 +13,8 @@ dependencies { implementation 'org.grails:grails-core' implementation 'org.grails.plugins:views-json' + compileOnly 'org.slf4j:slf4j-nop' // Remove warning during Gson views compilation + runtimeOnly 'com.h2database:h2' runtimeOnly 'com.zaxxer:HikariCP' runtimeOnly 'org.grails:grails-plugin-databinding' @@ -26,3 +27,9 @@ dependencies { integrationTestImplementation 'org.grails:grails-testing-support' } + +apply { + from rootProject.layout.projectDirectory.file('gradle/java-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/test-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/example-config.gradle') +} \ No newline at end of file diff --git a/examples/grails-database-per-tenant/build.gradle b/examples/grails-database-per-tenant/build.gradle index 1fa1d5a53d..27d4041b28 100644 --- a/examples/grails-database-per-tenant/build.gradle +++ b/examples/grails-database-per-tenant/build.gradle @@ -1,11 +1,10 @@ plugins { - id 'com.bertramlabs.asset-pipeline' version '5.0.1' - id 'groovy' - id 'org.grails.grails-gsp' id 'org.grails.grails-web' + id 'org.grails.grails-gsp' + id 'com.bertramlabs.asset-pipeline' } -version = rootProject.version +version = projectVersion group = 'examples' dependencies { @@ -31,3 +30,9 @@ dependencies { testImplementation 'org.grails:grails-gorm-testing-support' testImplementation 'org.spockframework:spock-core' } + +apply { + from rootProject.layout.projectDirectory.file('gradle/java-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/test-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/example-config.gradle') +} diff --git a/examples/grails-database-per-tenant/src/test/groovy/example/DatabasePerTenantSpec.groovy b/examples/grails-database-per-tenant/src/test/groovy/example/DatabasePerTenantSpec.groovy index 2f40a910a2..ee45a06900 100644 --- a/examples/grails-database-per-tenant/src/test/groovy/example/DatabasePerTenantSpec.groovy +++ b/examples/grails-database-per-tenant/src/test/groovy/example/DatabasePerTenantSpec.groovy @@ -9,7 +9,6 @@ import org.grails.datastore.mapping.config.Settings */ import org.grails.datastore.mapping.multitenancy.exceptions.TenantNotFoundException import org.grails.datastore.mapping.multitenancy.resolvers.SystemPropertyTenantResolver -import spock.lang.Ignore class DatabasePerTenantSpec extends HibernateSpec { diff --git a/examples/grails-hibernate-groovy-proxy/build.gradle b/examples/grails-hibernate-groovy-proxy/build.gradle index c537c3900b..bb7f3a4e92 100644 --- a/examples/grails-hibernate-groovy-proxy/build.gradle +++ b/examples/grails-hibernate-groovy-proxy/build.gradle @@ -1,9 +1,8 @@ plugins { - id 'groovy' id 'org.grails.grails-web' } -version = rootProject.version +version = projectVersion group = 'examples' dependencies { @@ -12,7 +11,7 @@ dependencies { implementation project(':grails-plugin') implementation 'org.grails:grails-core' implementation "org.yakworks:hibernate-groovy-proxy:$yakworksHibernateGroovyProxyVersion", { - exclude group: "org.codehaus.groovy", module: "groovy" + exclude group: 'org.codehaus.groovy', module: 'groovy' } runtimeOnly 'com.h2database:h2' @@ -21,4 +20,10 @@ dependencies { runtimeOnly 'org.springframework.boot:spring-boot-starter-logging' testImplementation 'org.grails:grails-testing-support' +} + +apply { + from rootProject.layout.projectDirectory.file('gradle/java-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/test-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/example-config.gradle') } \ No newline at end of file diff --git a/examples/grails-hibernate/build.gradle b/examples/grails-hibernate/build.gradle index c61e18651d..ab6b56bb4e 100644 --- a/examples/grails-hibernate/build.gradle +++ b/examples/grails-hibernate/build.gradle @@ -1,11 +1,10 @@ plugins { - id 'com.bertramlabs.asset-pipeline' version '5.0.1' - id 'groovy' - id 'org.grails.grails-gsp' id 'org.grails.grails-web' + id 'org.grails.grails-gsp' + id 'com.bertramlabs.asset-pipeline' } -version = rootProject.version +version = projectVersion group = 'examples' dependencies { @@ -41,4 +40,10 @@ dependencies { testImplementation 'org.grails:grails-web-testing-support' integrationTestImplementation testFixtures('org.grails.plugins:geb') +} + +apply { + from rootProject.layout.projectDirectory.file('gradle/java-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/test-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/example-config.gradle') } \ No newline at end of file diff --git a/examples/grails-multiple-datasources/build.gradle b/examples/grails-multiple-datasources/build.gradle index 0cce99b7f6..886dc336b8 100644 --- a/examples/grails-multiple-datasources/build.gradle +++ b/examples/grails-multiple-datasources/build.gradle @@ -1,8 +1,8 @@ plugins { - id 'groovy' + id 'org.grails.grails-web' } -version = rootProject.version +version = projectVersion group = 'examples' configurations { @@ -39,4 +39,10 @@ sourceSets { integrationTest { compileClasspath += configurations.astTransformation } +} + +apply { + from rootProject.layout.projectDirectory.file('gradle/java-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/test-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/example-config.gradle') } \ No newline at end of file diff --git a/examples/grails-partitioned-multi-tenancy/build.gradle b/examples/grails-partitioned-multi-tenancy/build.gradle index fe681a2d65..32ba1c66c6 100644 --- a/examples/grails-partitioned-multi-tenancy/build.gradle +++ b/examples/grails-partitioned-multi-tenancy/build.gradle @@ -1,11 +1,10 @@ plugins { - id 'com.bertramlabs.asset-pipeline' version '5.0.1' - id 'groovy' - id 'org.grails.grails-gsp' id 'org.grails.grails-web' + id 'org.grails.grails-gsp' + id 'com.bertramlabs.asset-pipeline' } -version = rootProject.version +version = projectVersion group = 'examples' dependencies { @@ -24,9 +23,15 @@ dependencies { runtimeOnly 'org.grails:grails-plugin-services' runtimeOnly 'org.grails:grails-plugin-url-mappings' runtimeOnly 'org.grails.plugins:fields' - runtimeOnly 'org.springframework.boot:spring-boot-starter-logging' runtimeOnly 'org.springframework.boot:spring-boot-autoconfigure' + runtimeOnly 'org.springframework.boot:spring-boot-starter-logging' runtimeOnly 'org.springframework.boot:spring-boot-starter-tomcat' testImplementation 'org.grails:grails-testing-support' } + +apply { + from rootProject.layout.projectDirectory.file('gradle/java-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/test-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/example-config.gradle') +} \ No newline at end of file diff --git a/examples/grails-schema-per-tenant/build.gradle b/examples/grails-schema-per-tenant/build.gradle index d296d43798..32ba1c66c6 100644 --- a/examples/grails-schema-per-tenant/build.gradle +++ b/examples/grails-schema-per-tenant/build.gradle @@ -1,11 +1,10 @@ plugins { - id 'com.bertramlabs.asset-pipeline' version '5.0.1' - id 'groovy' - id 'org.grails.grails-gsp' id 'org.grails.grails-web' + id 'org.grails.grails-gsp' + id 'com.bertramlabs.asset-pipeline' } -version = rootProject.version +version = projectVersion group = 'examples' dependencies { @@ -24,9 +23,15 @@ dependencies { runtimeOnly 'org.grails:grails-plugin-services' runtimeOnly 'org.grails:grails-plugin-url-mappings' runtimeOnly 'org.grails.plugins:fields' - runtimeOnly 'org.springframework.boot:spring-boot-starter-logging' runtimeOnly 'org.springframework.boot:spring-boot-autoconfigure' + runtimeOnly 'org.springframework.boot:spring-boot-starter-logging' runtimeOnly 'org.springframework.boot:spring-boot-starter-tomcat' testImplementation 'org.grails:grails-testing-support' +} + +apply { + from rootProject.layout.projectDirectory.file('gradle/java-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/test-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/example-config.gradle') } \ No newline at end of file diff --git a/examples/issue450/build.gradle b/examples/issue450/build.gradle index 9bc8756c2f..6fcf4e64d5 100644 --- a/examples/issue450/build.gradle +++ b/examples/issue450/build.gradle @@ -1,11 +1,10 @@ plugins { - id 'com.bertramlabs.asset-pipeline' version '5.0.1' - id 'groovy' - id 'org.grails.grails-gsp' id 'org.grails.grails-web' + id 'org.grails.grails-gsp' + id 'com.bertramlabs.asset-pipeline' } -version = rootProject.version +version = projectVersion group = 'multitenantcomposite' dependencies { @@ -35,3 +34,9 @@ dependencies { integrationTestRuntimeOnly 'io.micronaut.serde:micronaut-serde-jackson' } + +apply { + from rootProject.layout.projectDirectory.file('gradle/java-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/test-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/example-config.gradle') +} \ No newline at end of file diff --git a/examples/spring-boot-hibernate/build.gradle b/examples/spring-boot-hibernate/build.gradle index 48f95fecef..885760e5b6 100644 --- a/examples/spring-boot-hibernate/build.gradle +++ b/examples/spring-boot-hibernate/build.gradle @@ -1,28 +1,9 @@ -buildscript { - repositories { - mavenCentral() - maven { url "https://repo.grails.org/grails/core" } - if (System.getenv("GITHUB_MAVEN_PASSWORD") && !grailsVersion.endsWith('-SNAPSHOT')) { - System.out.println("Adding Grails Core Repo for ${project.name}") - maven { - url = 'https://maven.pkg.github.com/grails/grails-core' - credentials { - username = 'DOES_NOT_MATTER' - password = System.getenv("GITHUB_MAVEN_PASSWORD") - } - } - } - } - dependencies { - classpath platform("org.grails:grails-bom:$grailsVersion") - classpath "org.springframework.boot:spring-boot-gradle-plugin" - } +plugins { + id 'groovy' + id 'org.springframework.boot' } -apply plugin: 'groovy' -apply plugin: 'org.springframework.boot' - -version = rootProject.version +version = projectVersion group = 'examples' dependencies { @@ -40,3 +21,9 @@ dependencies { testImplementation 'org.spockframework:spock-core' } + +apply { + from rootProject.layout.projectDirectory.file('gradle/java-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/test-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/example-config.gradle') +} \ No newline at end of file diff --git a/examples/standalone-hibernate/build.gradle b/examples/standalone-hibernate/build.gradle index 14b6a14368..cdb9ee73ab 100644 --- a/examples/standalone-hibernate/build.gradle +++ b/examples/standalone-hibernate/build.gradle @@ -1,6 +1,8 @@ -group = 'examples' +plugins { + id 'groovy' +} -apply plugin: 'groovy' +group = 'examples' dependencies { @@ -15,3 +17,9 @@ dependencies { testRuntimeOnly 'org.slf4j:slf4j-simple' } + +apply { + from rootProject.layout.projectDirectory.file('gradle/java-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/test-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/example-config.gradle') +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 4e6a842427..1b6b7f8b36 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,11 @@ projectVersion=9.0.0-SNAPSHOT +grailsVersion=7.0.0-SNAPSHOT + +javaVersion=17 + asciidoctorGradleVersion=4.0.4 -gormVersion=9.0.0-M3 +datastoreVersion=9.0.0-SNAPSHOT gradleNexusPublishPluginVersion=2.0.0 -grailsVersion=7.0.0-M3 hibernateVersion=5.6.15.Final liquibaseHibernate5Version=4.27.0 jbossTransactionApiVersion=2.0.0.Final @@ -10,6 +13,9 @@ yakworksHibernateGroovyProxyVersion=1.1 micronautPlatformVersion=4.6.3 picocliVersion=4.7.6 +# For downloading GORM source code for groovydoc generation +datastoreGithubBranch=9.0.x + org.gradle.caching=true org.gradle.parallel=false org.gradle.daemon=true diff --git a/gradle/example-config.gradle b/gradle/example-config.gradle new file mode 100644 index 0000000000..c94729090f --- /dev/null +++ b/gradle/example-config.gradle @@ -0,0 +1,3 @@ +tasks.withType(Groovydoc).configureEach { + enabled = false +} \ No newline at end of file diff --git a/gradle/java-config.gradle b/gradle/java-config.gradle new file mode 100644 index 0000000000..a35c39de64 --- /dev/null +++ b/gradle/java-config.gradle @@ -0,0 +1,6 @@ +compileJava.options.release = javaVersion.toInteger() + +java { + withSourcesJar() + withJavadocJar() +} diff --git a/gradle/publish-config.gradle b/gradle/publish-config.gradle new file mode 100644 index 0000000000..30af5f294e --- /dev/null +++ b/gradle/publish-config.gradle @@ -0,0 +1,23 @@ +import org.grails.gradle.plugin.publishing.GrailsPublishExtension + +if (project.hasProperty('snapshotPublishUrl')) { + ext.set('mavenPublishUrl', property('snapshotPublishUrl')) + logger.lifecycle('Configuring {}:{} snapshot publish repo: {}', group, findProperty('pomArtifactId') ?: name, mavenPublishUrl) +} + +extensions.configure(GrailsPublishExtension) { + // Explicit `it` is required here + it.githubSlug = 'grails/gorm-hibernate5' + it.license.name = 'Apache-2.0' + it.title = findProperty('pomTitle') ?: 'GORM for Hibernate 5' + it.desc = findProperty('pomDescription') ?: 'Provides a GORM Object Mapping implementations for Hibernate 5' + it.developers = findProperty('pomDevelopers') as Map ?: [ + 'graemerocher': 'Graeme Rocher', + 'jeffscottbrown': 'Jeff Brown', + 'burtbeckwith': 'Burt Beckwith', + 'puneetbehl': 'Puneet Behl', + ] + if (findProperty('pomArtifactId')) { + it.artifactId = findProperty('pomArtifactId') + } +} \ No newline at end of file diff --git a/gradle/tck-config.gradle b/gradle/tck-config.gradle new file mode 100644 index 0000000000..bfca804d9f --- /dev/null +++ b/gradle/tck-config.gradle @@ -0,0 +1,71 @@ +dependencies { + testImplementation 'org.grails:grails-datastore-gorm-tck' +} + +tasks.withType(Test).configureEach { + if (isCiBuild) { + maxParallelForks = 2 + forkEvery = 10 + } + else { + maxParallelForks = 4 + forkEvery = 20 + } + jvmArgs = ['-Xmx1028M'] + afterSuite { + System.out.print('.') + System.out.flush() + } + // Used in the TCK test suite to selectively enable/disable tests + systemProperty('hibernate5.gorm.suite', 'true') + + doFirst { + def toBaseClassRelativePathWithoutExtension = { String base, String classFile -> + if (classFile.startsWith(base)) { + def sansClass = classFile[0 .. classFile.size() - ".class".size() - 1] + def dollarIndex = sansClass.indexOf('$') + def baseClass = dollarIndex > 0 ? sansClass[0..dollarIndex - 1] : sansClass + def relative = baseClass - base - '/' + relative + } + else { + null + } + } + def tckClassesFile = project + .configurations + .testCompileClasspath + .resolvedConfiguration + .getResolvedArtifacts() + .find { resolved -> + resolved.moduleVersion.id.name == 'grails-datastore-gorm-tck' + }.file + + def tckClassesDir = project.file("${project.layout.buildDirectory.asFile.get()}/tck") + copy { + from zipTree(tckClassesFile) + into tckClassesDir + } + copy { + from tckClassesDir + into sourceSets.test.output.classesDirs.find { it.path.contains('classes' + File.separator + 'groovy') } + include "**/*.class" + exclude { details -> + // Do not copy across any TCK class (or nested classes of that class) + // If there is a corresponding source file in the particular modules + // test source tree. Allows a module to override a test/helper. + if (!details.file.isFile()) { + return false + } + def candidatePath = details.file.absolutePath + def relativePath = toBaseClassRelativePathWithoutExtension(tckClassesDir.absolutePath, candidatePath) + + if (relativePath == null) { + throw new IllegalStateException("$candidatePath does not appear to be in the TCK") + } + + project.file("src/test/groovy/${relativePath}.groovy").exists() + } + } + } +} \ No newline at end of file diff --git a/gradle/test-config.gradle b/gradle/test-config.gradle new file mode 100644 index 0000000000..c09ad38298 --- /dev/null +++ b/gradle/test-config.gradle @@ -0,0 +1,37 @@ +dependencies { + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' +} + +tasks.withType(Test).configureEach { + useJUnitPlatform() + systemProperty('hibernate5.gorm.suite', System.getProperty('hibernate5.gorm.suite') ?: true) + reports.html.required = !System.getenv('CI') + reports.junitXml.required = !System.getenv('CI') + testLogging { + events('passed', 'skipped', 'failed') + showExceptions = true + exceptionFormat = 'full' + showCauses = true + showStackTraces = true + + // set options for log level DEBUG and INFO + debug { + events('started', 'passed', 'skipped', 'failed', 'standardOut', 'standardError') + exceptionFormat = 'full' + } + info.events = debug.events + info.exceptionFormat = debug.exceptionFormat + } + afterTest { desc, result -> + logger.quiet(' -- Executed test {} [{}] with result: {}', desc.name, desc.className, result.resultType) + } + afterSuite { desc, result -> + if (!desc.parent) { // will match the outermost suite + def output = "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)" + def startItem = '| ', endItem = ' |' + def repeatLength = startItem.length() + output.length() + endItem.length() + def dashes = '-' * repeatLength + logger.quiet('\n{}\n{}{}{}\n{}', dashes, startItem, output, endItem, dashes) + } + } +} diff --git a/gradle/testVerbose.gradle b/gradle/testVerbose.gradle deleted file mode 100644 index a2e688efc2..0000000000 --- a/gradle/testVerbose.gradle +++ /dev/null @@ -1,33 +0,0 @@ -tasks.withType(Test) { - systemProperty("hibernate5.gorm.suite", System.getProperty("hibernate5.gorm.suite") ?: true) - useJUnitPlatform() - reports.html.required.set(!System.getenv("TRAVIS")) - reports.junitXml.required.set(!System.getenv("TRAVIS")) - afterTest { desc, result -> - logger.quiet " -- Executed test ${desc.name} [${desc.className}] with result: ${result.resultType}" - } - testLogging { - events "passed", "skipped", "failed"//, "standardOut" - showExceptions true - exceptionFormat "full" - showCauses true - showStackTraces true - - // set options for log level DEBUG and INFO - debug { - events "started", "passed", "skipped", "failed", "standardOut", "standardError" - exceptionFormat "full" - } - info.events = debug.events - info.exceptionFormat = debug.exceptionFormat - - afterSuite { desc, result -> - if (!desc.parent) { // will match the outermost suite - def output = "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)" - def startItem = '| ', endItem = ' |' - def repeatLength = startItem.length() + output.length() + endItem.length() - logger.quiet "\n${'-' * repeatLength}\n${startItem}${output}${endItem}\n${'-' * repeatLength}" - } - } - } -} diff --git a/grails-database-migration/build.gradle b/grails-database-migration/build.gradle index 50505cd607..19a58e88f5 100644 --- a/grails-database-migration/build.gradle +++ b/grails-database-migration/build.gradle @@ -1,54 +1,24 @@ -buildscript { - repositories { - maven { url "https://repo.grails.org/grails/core" } - if (System.getenv("GITHUB_MAVEN_PASSWORD") && !grailsVersion.endsWith('-SNAPSHOT')) { - System.out.println("Adding Grails Core Repo for ${project.name}") - maven { - url = 'https://maven.pkg.github.com/grails/grails-core' - credentials { - username = 'DOES_NOT_MATTER' - password = System.getenv("GITHUB_MAVEN_PASSWORD") - } - } - } - } - dependencies { - classpath platform("org.grails:grails-bom:$grailsVersion") - classpath "org.grails:grails-gradle-plugin" - classpath "org.asciidoctor:asciidoctor-gradle-jvm:$asciidoctorGradleVersion" - } +plugins { + id 'java-library' + id 'org.grails.grails-plugin' } -version project.projectVersion -group "org.grails.plugins" - -apply plugin:"eclipse" -apply plugin:"idea" -apply plugin:"java-library" -apply plugin:"org.grails.grails-plugin" -apply plugin:"org.grails.grails-gsp" -apply plugin: "org.asciidoctor.jvm.convert" - -repositories { - maven { url "https://repo.grails.org/grails/core" } - mavenCentral() - if (System.getenv("GITHUB_MAVEN_PASSWORD") && !grailsVersion.endsWith('-SNAPSHOT')) { - System.out.println("Adding 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") - } - } - } -} +version = projectVersion +group = 'org.grails.plugins' -configurations { - documentation +ext { + apiDocs = true + pomTitle = 'Grails Database Migration Plugin' + pomDescription = 'The Database Migration plugin helps you manage database changes, via Liquibase, while developing Grails applications' + pomDevelopers = [ + 'kazukiyamamoto': 'Kazuki YAMAMOTO', + 'jamesfredley': 'James Fredley', + ] + snapshotPublishUrl = 'https://repo.grails.org/grails/plugins3-snapshots-local' } dependencies { + // TODO: Clarify and clean up dependencies implementation platform("org.grails:grails-bom:$grailsVersion") api("org.liquibase:liquibase-core:$liquibaseHibernate5Version") @@ -59,9 +29,8 @@ dependencies { exclude group: 'com.h2database', module: 'h2' exclude group: 'org.liquibase', module: 'liquibase-commercial' } - - api "org.apache.commons:commons-lang3" - api("org.grails:grails-shell") { + api 'org.apache.commons:commons-lang3' + api('org.grails:grails-shell') { exclude group: 'org.slf4j', module: 'slf4j-simple' } @@ -76,63 +45,27 @@ dependencies { testImplementation "org.grails:grails-gorm-testing-support" testImplementation "org.grails:grails-web-testing-support" testImplementation "com.h2database:h2" - - documentation "org.apache.groovy:groovy" - documentation "org.apache.groovy:groovy-ant" - documentation "org.apache.groovy:groovy-templates" - documentation "com.github.javaparser:javaparser-core" -} - -compileJava.options.release = 17 - -ext { - pomTitle = 'Grails Database Migration Plugin' - pomDescription = 'The Database Migration plugin helps you manage database changes, via Liquibase, while developing Grails applications' - pomDevelopers = [ - [id: 'kazukiyamamoto', name: 'Kazuki YAMAMOTO'], - [id: 'jamesfredley', name: 'James Fredley'] - ] -} - -tasks.withType(GroovyCompile) { - configure(groovyOptions) { - forkOptions.jvmArgs = ['-Xmx1024m'] - } } -tasks.withType(Test) { - useJUnitPlatform() +tasks.named('jar', Jar) { + exclude('testapp/**/**') } -tasks.withType(Groovydoc) { - configure { - docTitle = "Grails Database Migration Plugin ${version}" - source = project.files('src/main/groovy') - destinationDir = layout.buildDirectory.dir('docs/api').get().getAsFile() - classpath = configurations.documentation - groovyClasspath = configurations.documentation +tasks.withType(Test).configureEach { + develocity.testRetry { + if (isCiBuild) { + maxRetries = 2 + maxFailures = 20 + failOnPassedAfterRetry = true + filter { + excludeTestsMatching '*.GroovyChangeLogSpec' + } + } } } -jar { - exclude "testapp/**/**" -} - -test { - testLogging { - events "passed", "skipped", "failed" - - showExceptions true - exceptionFormat "full" - showCauses true - showStackTraces true - } - retry { - maxRetries = 2 - maxFailures = 20 - failOnPassedAfterRetry = true - filter { - excludeClasses.add("*GroovyChangeLogSpec") - } - } +apply { + from rootProject.layout.projectDirectory.file('gradle/java-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/test-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/publish-config.gradle') } diff --git a/grails-database-migration/grails-app/init/databasemigration/Application.groovy b/grails-database-migration/grails-app/init/databasemigration/Application.groovy index e8efe756b8..debb892ba6 100644 --- a/grails-database-migration/grails-app/init/databasemigration/Application.groovy +++ b/grails-database-migration/grails-app/init/databasemigration/Application.groovy @@ -1,11 +1,11 @@ /* - * Copyright 2015 original authors + * Copyright 2015-2025 original authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,7 +17,11 @@ package databasemigration import grails.boot.GrailsApp import grails.boot.config.GrailsAutoConfiguration +import grails.plugins.metadata.PluginSource +import groovy.transform.CompileStatic +@PluginSource +@CompileStatic class Application extends GrailsAutoConfiguration { static void main(String[] args) { GrailsApp.run(Application) diff --git a/grails-database-migration/src/integration-test/resources/logback-test.xml b/grails-database-migration/src/integration-test/resources/logback-test.xml index 2f5733472a..25794ab3e3 100644 --- a/grails-database-migration/src/integration-test/resources/logback-test.xml +++ b/grails-database-migration/src/integration-test/resources/logback-test.xml @@ -1,8 +1,8 @@ - - + + diff --git a/grails-datastore-gorm-hibernate/build.gradle b/grails-datastore-gorm-hibernate/build.gradle index a3bf45fc30..f56efc2d57 100644 --- a/grails-datastore-gorm-hibernate/build.gradle +++ b/grails-datastore-gorm-hibernate/build.gradle @@ -1,4 +1,18 @@ +plugins { + id 'groovy' + id 'java-library' +} + +version = projectVersion +group = 'org.grails' + +ext { + apiDocs = true + snapshotPublishUrl = 'https://repo.grails.org/grails/libs-snapshots-local' +} + dependencies { + // TODO: Clarify and clean up dependencies implementation platform("org.grails:grails-bom:$grailsVersion") api "org.slf4j:slf4j-api" @@ -21,21 +35,18 @@ dependencies { exclude group:'org.slf4j', module:'slf4j-api' } + testImplementation "com.h2database:h2" + testImplementation 'junit:junit' // JUnit 4 testImplementation "org.apache.groovy:groovy-test-junit5" testImplementation "org.apache.groovy:groovy-sql" testImplementation "org.apache.groovy:groovy-json" - testImplementation "org.grails:grails-datastore-gorm-tck", { - exclude group: "org.spockframework" - } - testImplementation "com.h2database:h2" - - // groovy proxy fixes bytebuddy to be a bit smarter when it comes to groovy metaClass + testImplementation "org.apache.tomcat:tomcat-jdbc" + testImplementation 'org.spockframework:spock-core' testImplementation "org.yakworks:hibernate-groovy-proxy:$yakworksHibernateGroovyProxyVersion", { + // groovy proxy fixes bytebuddy to be a bit smarter when it comes to groovy metaClass exclude group: "org.codehaus.groovy", module: "groovy" } - testImplementation "org.apache.tomcat:tomcat-jdbc" - testRuntimeOnly "org.hibernate:hibernate-ehcache:$hibernateVersion", { // exclude javax variant of hibernate-core 5.6 exclude group: 'org.hibernate', module: 'hibernate-core' @@ -48,69 +59,9 @@ dependencies { testRuntimeOnly "org.springframework:spring-aop" } -test { - if (isTravisBuild || isCiBuild) { - maxParallelForks = 2 - forkEvery = 10 - } - else { - maxParallelForks = 4 - forkEvery = 20 - } - - jvmArgs = ['-Xmx1028M'] - afterSuite { - System.out.print('.') - System.out.flush() - } -} - -test.doFirst { - def toBaseClassRelativePathWithoutExtension = { String base, String classFile -> - if (classFile.startsWith(base)) { - def sansClass = classFile[0 .. classFile.size() - ".class".size() - 1] - def dollarIndex = sansClass.indexOf('$') - def baseClass = dollarIndex > 0 ? sansClass[0..dollarIndex - 1] : sansClass - def relative = baseClass - base - '/' - relative - } - else { - null - } - } - def tckClassesFile = project - .configurations - .testCompileClasspath - .resolvedConfiguration - .getResolvedArtifacts() - .find { resolved -> - resolved.moduleVersion.id.name == 'grails-datastore-gorm-tck' - }.file - - def tckClassesDir = project.file("${project.buildDir}/tck") - copy { - from zipTree(tckClassesFile) - into tckClassesDir - } - copy { - from tckClassesDir - into sourceSets.test.output.classesDirs.find { it.path.contains('classes' + File.separator + 'groovy') } - include "**/*.class" - exclude { details -> - // Do not copy across any TCK class (or nested classes of that class) - // If there is a corresponding source file in the particular modules - // test source tree. Allows a module to override a test/helper. - if (!details.file.isFile()) { - return false - } - def candidatePath = details.file.absolutePath - def relativePath = toBaseClassRelativePathWithoutExtension(tckClassesDir.absolutePath, candidatePath) - - if (relativePath == null) { - throw new IllegalStateException("$candidatePath does not appear to be in the TCK") - } - - project.file("src/test/groovy/${relativePath}.groovy").exists() - } - } +apply { + from rootProject.layout.projectDirectory.file('gradle/java-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/test-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/tck-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/publish-config.gradle') } diff --git a/grails-plugin/build.gradle b/grails-plugin/build.gradle index e7d9e24fa9..59eefe0581 100644 --- a/grails-plugin/build.gradle +++ b/grails-plugin/build.gradle @@ -1,26 +1,20 @@ -configurations.all { - resolutionStrategy.eachDependency { DependencyResolveDetails details -> - if(details.requested.group == 'org.grails' && - details.requested.name.startsWith('grails-datastore') && - details.requested.name != 'grails-datastore-gorm-hibernate5') { - details.useVersion(gormVersion) - } - } +plugins { + id 'java-library' + id 'org.grails.grails-plugin' } -dependencies { - documentation "org.grails:grails-core" - documentation "org.grails:grails-bootstrap" - documentation "org.grails:grails-spring" - documentation "com.github.javaparser:javaparser-core" +version = projectVersion +group = 'org.grails.plugins' - compileOnly "org.grails:grails-bootstrap" - compileOnly "org.grails:grails-core" - compileOnly "org.spockframework:spock-core", { - exclude group: "junit", module: "junit-dep" - exclude group: 'org.codehaus.groovy', module: 'groovy-all' - exclude group: 'org.hamcrest', module: 'hamcrest-core' - } +ext { + apiDocs = true + pomArtifactId = 'hibernate5' + snapshotPublishUrl = 'https://repo.grails.org/grails/plugins3-snapshots-local' +} + +dependencies { + // TODO: Clarify and clean up dependencies + implementation platform("org.grails:grails-bom:$grailsVersion") api "org.springframework.boot:spring-boot" api "org.springframework:spring-orm" @@ -38,7 +32,17 @@ dependencies { exclude group:'javax.transaction', module:'jta' } + compileOnly "org.grails:grails-bootstrap" + compileOnly "org.grails:grails-core" + + compileOnly "org.spockframework:spock-core", { + exclude group: "junit", module: "junit-dep" + exclude group: 'org.codehaus.groovy', module: 'groovy-all' + exclude group: 'org.hamcrest', module: 'hamcrest-core' + } + testImplementation "org.grails:grails-gorm-testing-support" + testImplementation "org.spockframework:spock-core" testRuntimeOnly "com.h2database:h2" testRuntimeOnly "org.apache.tomcat:tomcat-jdbc" @@ -54,4 +58,8 @@ dependencies { testRuntimeOnly "org.yaml:snakeyaml" } -groovydoc.classpath += configurations.documentation +apply { + from rootProject.layout.projectDirectory.file('gradle/java-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/test-config.gradle') + from rootProject.layout.projectDirectory.file('gradle/publish-config.gradle') +} \ No newline at end of file diff --git a/grails-plugin/grails-app/.gitkeep b/grails-plugin/grails-app/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/grails-plugin/grails-app/init/grails.plugin.hibernate/Application.groovy b/grails-plugin/grails-app/init/grails.plugin.hibernate/Application.groovy deleted file mode 100644 index e6889fc1ea..0000000000 --- a/grails-plugin/grails-app/init/grails.plugin.hibernate/Application.groovy +++ /dev/null @@ -1,13 +0,0 @@ -package grails.plugin.hibernate - -import grails.boot.GrailsApp -import grails.boot.config.GrailsAutoConfiguration -import grails.plugins.metadata.PluginSource -import groovy.transform.CompileStatic - -@PluginSource -class Application extends GrailsAutoConfiguration { - static void main(String[] args) { - GrailsApp.run((Class)Application, args) - } -} \ No newline at end of file diff --git a/grails-plugin/src/main/groovy/grails/plugin/hibernate/HibernateGrailsPlugin.groovy b/grails-plugin/src/main/groovy/grails/plugin/hibernate/HibernateGrailsPlugin.groovy index 520afe3493..3d6eb1c372 100644 --- a/grails-plugin/src/main/groovy/grails/plugin/hibernate/HibernateGrailsPlugin.groovy +++ b/grails-plugin/src/main/groovy/grails/plugin/hibernate/HibernateGrailsPlugin.groovy @@ -26,12 +26,12 @@ class HibernateGrailsPlugin extends Plugin { public static final String DEFAULT_DATA_SOURCE_NAME = HibernateDatastoreSpringInitializer.DEFAULT_DATA_SOURCE_NAME - def grailsVersion = '3.1.0 > *' + def grailsVersion = '7.0.0 > *' def author = 'Grails Core Team' def title = 'Hibernate 5 for Grails' def description = 'Provides integration between Grails and Hibernate 5 through GORM' - def documentation = 'http://grails.github.io/grails-data-mapping/latest/' + def documentation = 'https://grails.github.io/grails-data-mapping/latest/' def observe = ['domainClass'] def loadAfter = ['controllers', 'domainClass'] @@ -39,7 +39,7 @@ class HibernateGrailsPlugin extends Plugin { def pluginExcludes = ['src/templates/**'] def license = 'APACHE' - def organization = [name: 'Grails', url: 'http://grails.org'] + def organization = [name: 'Grails', url: 'https://grails.org'] def issueManagement = [system: 'Github', url: 'https://github.com/grails/grails-data-mapping/issues'] def scm = [url: 'https://github.com/grails/grails-data-mapping'] diff --git a/grails-plugin/grails-app/conf/application.yml b/grails-plugin/src/test/resources/application.yml similarity index 79% rename from grails-plugin/grails-app/conf/application.yml rename to grails-plugin/src/test/resources/application.yml index 7d032f29af..4c1e51b37d 100644 --- a/grails-plugin/grails-app/conf/application.yml +++ b/grails-plugin/src/test/resources/application.yml @@ -1,7 +1,3 @@ ---- -grails: - profile: plugin ---- dataSource: logSql: true --- diff --git a/settings.gradle b/settings.gradle index 321fd87ee5..b01113fe4e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,26 +1,26 @@ plugins { - id "com.gradle.enterprise" version "3.19.2" + id 'com.gradle.enterprise' version '3.19.2' id 'com.gradle.common-custom-user-data-gradle-plugin' version '2.1' } -gradleEnterprise { +def isCI = System.getenv('CI') != null +def isLocal = !isCI +def isAuthenticated = System.getenv('DEVELOCITY_ACCESS_KEY') != null + +develocity { server = 'https://ge.grails.org' buildScan { - publishAlwaysIf(System.getenv('CI') == 'true') - publishIfAuthenticated() - uploadInBackground = System.getenv("CI") == null - capture { - taskInputFiles = true - } + tag('grails') + tag('gorm-hibernate5') + publishing.onlyIf { isAuthenticated } + 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 + local { enabled = isLocal } + remote(develocity.buildCache) { + push = isCI && isAuthenticated enabled = true } } From eeaae75580c5360a16c06a24713b282d2c326672 Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Fri, 7 Mar 2025 15:48:34 +0100 Subject: [PATCH 2/6] ci: fix problems --- grails-database-migration/build.gradle | 2 +- settings.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/grails-database-migration/build.gradle b/grails-database-migration/build.gradle index 19a58e88f5..fe337d7926 100644 --- a/grails-database-migration/build.gradle +++ b/grails-database-migration/build.gradle @@ -58,7 +58,7 @@ tasks.withType(Test).configureEach { maxFailures = 20 failOnPassedAfterRetry = true filter { - excludeTestsMatching '*.GroovyChangeLogSpec' + excludeClasses.add('*.GroovyChangeLogSpec') } } } diff --git a/settings.gradle b/settings.gradle index b01113fe4e..98ad8189ab 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,5 @@ plugins { - id 'com.gradle.enterprise' version '3.19.2' + id 'com.gradle.develocity' version '3.19.2' id 'com.gradle.common-custom-user-data-gradle-plugin' version '2.1' } From 5901ff44fb44a0e90e9ecbfb091a273598642a8f Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Fri, 7 Mar 2025 16:08:51 +0100 Subject: [PATCH 3/6] build: add the `slf4jPreventExclusion` property --- gradle.properties | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gradle.properties b/gradle.properties index 1b6b7f8b36..2fe9e3945c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,6 +16,10 @@ picocliVersion=4.7.6 # For downloading GORM source code for groovydoc generation datastoreGithubBranch=9.0.x +# This prevents the Grails Gradle Plugin from unnecessarily excluding slf4j-simple in the generated POMs +# https://github.com/grails/grails-gradle-plugin/issues/222 +slf4jPreventExclusion=true + org.gradle.caching=true org.gradle.parallel=false org.gradle.daemon=true From 8f7cdb7a63dc3840481ec4563e6337a8fde8b9e2 Mon Sep 17 00:00:00 2001 From: James Fredley Date: Fri, 7 Mar 2025 10:37:05 -0500 Subject: [PATCH 4/6] use GrailsStringUtils.trimToNull() instead of apache commons version https://github.com/grails/grails-core/pull/13807 --- grails-database-migration/build.gradle | 4 +++- .../liquibase/GroovyDiffToChangeLogCommandStep.groovy | 4 ++-- .../liquibase/GroovyGenerateChangeLogCommandStep.groovy | 8 ++++---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/grails-database-migration/build.gradle b/grails-database-migration/build.gradle index fe337d7926..ac74677d4f 100644 --- a/grails-database-migration/build.gradle +++ b/grails-database-migration/build.gradle @@ -29,7 +29,7 @@ dependencies { exclude group: 'com.h2database', module: 'h2' exclude group: 'org.liquibase', module: 'liquibase-commercial' } - api 'org.apache.commons:commons-lang3' + api('org.grails:grails-shell') { exclude group: 'org.slf4j', module: 'slf4j-simple' } @@ -37,11 +37,13 @@ dependencies { compileOnly "org.springframework.boot:spring-boot-starter-logging" compileOnly "org.springframework.boot:spring-boot-autoconfigure" compileOnly "org.grails.plugins:hibernate5" + compileOnly "org.grails:grails-core" compileOnly "org.apache.groovy:groovy-sql" compileOnly "org.apache.groovy:groovy-xml" testImplementation "org.springframework.boot:spring-boot-starter-tomcat" testImplementation "org.grails.plugins:hibernate5" + testImplementation "org.grails:grails-core" testImplementation "org.grails:grails-gorm-testing-support" testImplementation "org.grails:grails-web-testing-support" testImplementation "com.h2database:h2" diff --git a/grails-database-migration/src/main/groovy/org/grails/plugins/databasemigration/liquibase/GroovyDiffToChangeLogCommandStep.groovy b/grails-database-migration/src/main/groovy/org/grails/plugins/databasemigration/liquibase/GroovyDiffToChangeLogCommandStep.groovy index 1e3b901c41..e995918350 100644 --- a/grails-database-migration/src/main/groovy/org/grails/plugins/databasemigration/liquibase/GroovyDiffToChangeLogCommandStep.groovy +++ b/grails-database-migration/src/main/groovy/org/grails/plugins/databasemigration/liquibase/GroovyDiffToChangeLogCommandStep.groovy @@ -28,7 +28,7 @@ import liquibase.database.ObjectQuotingStrategy import liquibase.diff.DiffResult import liquibase.diff.output.DiffOutputControl import liquibase.serializer.ChangeLogSerializerFactory -import org.apache.commons.lang3.StringUtils +import grails.util.GrailsStringUtils @CompileStatic class GroovyDiffToChangeLogCommandStep extends DiffChangelogCommandStep { @@ -55,7 +55,7 @@ class GroovyDiffToChangeLogCommandStep extends DiffChangelogCommandStep { try { referenceDatabase.setObjectQuotingStrategy(ObjectQuotingStrategy.QUOTE_ALL_OBJECTS); - if (StringUtils.trimToNull(changeLogFile) == null) { + if (GrailsStringUtils.trimToNull(changeLogFile) == null) { createDiffToChangeLogObject(diffResult, diffOutputControl, false).print(outputStream, ChangeLogSerializerFactory.instance.getSerializer('groovy')) } else { createDiffToChangeLogObject(diffResult, diffOutputControl, false).print(changeLogFile, ChangeLogSerializerFactory.instance.getSerializer(changeLogFile)) diff --git a/grails-database-migration/src/main/groovy/org/grails/plugins/databasemigration/liquibase/GroovyGenerateChangeLogCommandStep.groovy b/grails-database-migration/src/main/groovy/org/grails/plugins/databasemigration/liquibase/GroovyGenerateChangeLogCommandStep.groovy index 7ea2aa2b9c..a46547c0cd 100644 --- a/grails-database-migration/src/main/groovy/org/grails/plugins/databasemigration/liquibase/GroovyGenerateChangeLogCommandStep.groovy +++ b/grails-database-migration/src/main/groovy/org/grails/plugins/databasemigration/liquibase/GroovyGenerateChangeLogCommandStep.groovy @@ -30,7 +30,7 @@ import liquibase.diff.DiffResult import liquibase.diff.output.DiffOutputControl import liquibase.diff.output.changelog.DiffToChangeLog import liquibase.serializer.ChangeLogSerializerFactory -import org.apache.commons.lang3.StringUtils +import grails.util.GrailsStringUtils @CompileStatic class GroovyGenerateChangeLogCommandStep extends GenerateChangelogCommandStep { @@ -46,7 +46,7 @@ class GroovyGenerateChangeLogCommandStep extends GenerateChangelogCommandStep { void run(CommandResultsBuilder resultsBuilder) throws Exception { CommandScope commandScope = resultsBuilder.getCommandScope(); - String changeLogFile = StringUtils.trimToNull(commandScope.getArgumentValue(CHANGELOG_FILE_ARG)); + String changeLogFile = GrailsStringUtils.trimToNull(commandScope.getArgumentValue(CHANGELOG_FILE_ARG)); if (changeLogFile != null && changeLogFile.toLowerCase().endsWith(".sql")) { Scope.getCurrentScope().getUI().sendMessage("\n" + INFO_MESSAGE + "\n"); Scope.getCurrentScope().getLog(getClass()).info("\n" + INFO_MESSAGE + "\n"); @@ -71,7 +71,7 @@ class GroovyGenerateChangeLogCommandStep extends GenerateChangelogCommandStep { ObjectQuotingStrategy originalStrategy = referenceDatabase.getObjectQuotingStrategy(); try { referenceDatabase.setObjectQuotingStrategy(ObjectQuotingStrategy.QUOTE_ALL_OBJECTS); - if (StringUtils.trimToNull(changeLogFile) != null) { + if (GrailsStringUtils.trimToNull(changeLogFile) != null) { changeLogWriter.print(changeLogFile, ChangeLogSerializerFactory.instance.getSerializer(changeLogFile)) } else { PrintStream outputStream = new PrintStream(resultsBuilder.getOutputStream()); @@ -82,7 +82,7 @@ class GroovyGenerateChangeLogCommandStep extends GenerateChangelogCommandStep { } } - if (StringUtils.trimToNull(changeLogFile) != null) { + if (GrailsStringUtils.trimToNull(changeLogFile) != null) { Scope.getCurrentScope().getUI().sendMessage("Generated changelog written to " + new File(changeLogFile).getAbsolutePath()); } } finally { From 9a2748cf002e1da76ad639c912d0a9c42b16aa28 Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Fri, 7 Mar 2025 17:15:29 +0100 Subject: [PATCH 5/6] build: pr feedback --- .github/workflows/gradle.yml | 2 ++ .github/workflows/release-notes.yml | 8 ++++++-- settings.gradle | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 0cd313c68a..d3c0cc4a61 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -13,6 +13,8 @@ env: jobs: build: runs-on: ubuntu-24.04 + permissions: + packages: read env: GRADLE_OPTS: -Xmx1500m -Dfile.encoding=UTF-8 steps: diff --git a/.github/workflows/release-notes.yml b/.github/workflows/release-notes.yml index 6eb2391a3c..e048cb8151 100644 --- a/.github/workflows/release-notes.yml +++ b/.github/workflows/release-notes.yml @@ -13,10 +13,14 @@ on: jobs: update_release_draft: permissions: - contents: read # limit to read access + # write permission is required to create a github release + contents: write + # write permission is required for autolabeler + # otherwise, read permission is required at least + pull-requests: write runs-on: ubuntu-latest steps: - name: "📝 Update Release Draft" uses: release-drafter/release-drafter@v6 env: - GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/settings.gradle b/settings.gradle index 98ad8189ab..af35c8b959 100644 --- a/settings.gradle +++ b/settings.gradle @@ -12,6 +12,7 @@ develocity { buildScan { tag('grails') tag('gorm-hibernate5') + tag('grails-database-migration') publishing.onlyIf { isAuthenticated } uploadInBackground = isLocal } From e0c7160252e53d2eaa5a490545a79962bdeb393a Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Fri, 7 Mar 2025 17:18:33 +0100 Subject: [PATCH 6/6] build: updated pr feedback --- .github/workflows/gradle.yml | 4 ++-- .github/workflows/release.yml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index d3c0cc4a61..85a5cb20db 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -10,11 +10,11 @@ on: env: GIT_USER_NAME: grails-build GIT_USER_EMAIL: grails-build@users.noreply.github.com +permissions: + packages: read jobs: build: runs-on: ubuntu-24.04 - permissions: - packages: read env: GRADLE_OPTS: -Xmx1500m -Dfile.encoding=UTF-8 steps: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8497610523..6fe470b6d8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,6 +5,8 @@ on: env: GIT_USER_NAME: grails-build GIT_USER_EMAIL: grails-build@users.noreply.github.com +permissions: + packages: read jobs: publish: name: "Publish to Sonatype Staging Repository"