diff --git a/.agents/skills/grails-developer/SKILL.md b/.agents/skills/grails-developer/SKILL.md index 00a6728513f..e004968c26c 100644 --- a/.agents/skills/grails-developer/SKILL.md +++ b/.agents/skills/grails-developer/SKILL.md @@ -1,28 +1,13 @@ - --- name: grails-developer description: Comprehensive guide for Grails 7 development, covering web applications, REST APIs, GORM, controllers, services, views, plugins, and testing with Spock and Geb license: Apache-2.0 -compatibility: opencode, claude, grok, gemini, copilot, cursor, windsurf -metadata: - audience: developers - frameworks: grails - versions: 7 --- + ## What I Do diff --git a/.agents/skills/groovy-developer/SKILL.md b/.agents/skills/groovy-developer/SKILL.md index 5931bf5add8..0b7feab35f9 100644 --- a/.agents/skills/groovy-developer/SKILL.md +++ b/.agents/skills/groovy-developer/SKILL.md @@ -1,29 +1,13 @@ - --- name: groovy-developer description: Expert guide for Groovy 4 development, covering concise syntax, closures, DSLs, metaprogramming, static compilation, and integration with Java 17 and Grails license: Apache-2.0 -compatibility: opencode, claude, grok, gemini, copilot, cursor, windsurf -metadata: - audience: developers - languages: groovy, java - versions: 4.0 - paradigms: dynamic, static, functional, object-oriented, DSL-oriented --- + ## What I Do diff --git a/.agents/skills/java-developer/SKILL.md b/.agents/skills/java-developer/SKILL.md index 0f8a9d163ac..94d7dc5b932 100644 --- a/.agents/skills/java-developer/SKILL.md +++ b/.agents/skills/java-developer/SKILL.md @@ -1,28 +1,13 @@ - --- name: java-developer description: Guide for developing in Java 17 LTS, including modern features, best practices, and integration with Groovy/Grails projects license: Apache-2.0 -compatibility: opencode, claude, grok, gemini, copilot, cursor, windsurf -metadata: - audience: developers - languages: java - versions: 17 --- + ## What I Do diff --git a/.agents/skills/test-fixer/SKILL.md b/.agents/skills/test-fixer/SKILL.md new file mode 100644 index 00000000000..a34ca8ccb71 --- /dev/null +++ b/.agents/skills/test-fixer/SKILL.md @@ -0,0 +1,142 @@ +--- +name: test-fixer +description: Guide for running, reviewing, and fixing test failures across grails-core modules using Gradle test reports +license: Apache-2.0 +--- + + +## What I Do + +- Guide targeted and full test runs across grails-core modules. +- Help interpret Gradle HTML and XML test reports. +- Help triage failing specs, static state pollution, and module-specific regressions. + +## When to Use Me + +Activate this skill when: + +- Running a failing module or specific spec. +- Preparing a commit and verifying affected module tests. +- Triaging regressions after a dependency upgrade or refactor. +- Reviewing aggregate test results from `:grails-test-report`. + +--- + +## Key Tasks + +### Targeted Testing Recommended + +To save time, run only related tests: + +```bash +./gradlew :grails-data-hibernate7-core:test --tests "grails.gorm.tests.BasicCollection*" +``` + +### Full Run + +```bash +./gradlew test --continue +``` + +Use `--continue` when you need later modules to run after an earlier module fails. + +--- + +## Aggregate Test Reports + +The `grails-test-report` project owns repository test aggregation. + +```bash +./gradlew :grails-test-report:check --continue +``` + +This generates: + +- Unit HTML: `grails-test-report/build/reports/tests/test/index.html` +- Unit Markdown: `grails-test-report/build/reports/tests/test.md` +- Integration HTML: `grails-test-report/build/reports/tests/integrationTest/index.html` +- Integration Markdown: `grails-test-report/build/reports/tests/integrationTest.md` +- Combined HTML: `grails-test-report/build/reports/tests/combined/index.html` +- Combined Markdown: `grails-test-report/build/reports/tests/combined.md` + +The aggregate report includes root subprojects that define matching `test` or `integrationTest` tasks. + +The collected unit and integration `Test` tasks are finalized by their matching aggregate report tasks. Reports are attempted after failures and after targeted module test runs, but they summarize the XML results currently available on disk. Use `--continue` for full-suite runs so Gradle keeps scheduling later test tasks after an earlier failure; without it, reports can be partial. Run `clean` first when stale XML results should be excluded. + +--- + +## Running Tests for a Specific Module + +```bash +# All tests in a module +./gradlew :grails-data-hibernate7-dbmigration:test + +# A specific spec +./gradlew :grails-data-hibernate7-dbmigration:test \ + --tests "org.grails.plugins.databasemigration.command.DbmGenerateGormChangelogCommandSpec" + +# A specific feature method +./gradlew :grails-data-hibernate7-core:test \ + --tests "org.grails.orm.hibernate.FooSpec.my feature name" + +# Force rerun even if Gradle thinks it is up-to-date +./gradlew :grails-data-hibernate7-core:test --rerun-tasks +``` + +--- + +## Test Source Layout + +| Source set | Directory | Task | +|------------|-----------|------| +| Unit tests | `src/test/groovy/` | `test` | +| Integration tests | `src/integration-test/groovy/` | `integrationTest` | + +Most specs in grails-core are unit tests (`src/test/groovy/`) run by the `test` task. A small number of modules use `integrationTest` for full Spring context tests. + +--- + +## Parallel Test Execution + +Tests run in parallel (`maxParallelForks` defaults to `4` on CI and to `availableProcessors * 3/4` otherwise; override with `-PmaxTestParallel`). This can cause: + +- Static state pollution: one test mutating a static field that another test reads. +- Port conflicts: multiple test JVMs binding the same port. +- `@Shared` field contamination: shared state not properly cleaned up between feature methods. + +To diagnose flaky failures, rerun with forced serial execution: + +```bash +./gradlew :module:test -PmaxTestParallel=1 --rerun-tasks +``` + +--- + +## Test Configuration Flags + +| Property | Effect | +|----------|--------| +| `skipTests` | Skips all `Test` tasks (build only) | +| `maxTestParallel=N` | Override parallel fork count | +| `onlyFunctionalTests` | Run only functional test suites | +| `skipHibernate7Tests` | Skip H7-specific test suites | +| `onlyMongodbTests` | Run only MongoDB test suites | +| `onlyCoreTests` | Run only core module tests | + +--- + +## XML Report Location + +Gradle writes JUnit XML test results to: + +```text +/build/test-results/ +├── test/ +│ └── TEST-org.grails.SomeSpec.xml +└── integrationTest/ + └── TEST-org.grails.SomeIntegrationSpec.xml +``` diff --git a/.editorconfig b/.editorconfig index 4c509b592c4..fc99647e201 100644 --- a/.editorconfig +++ b/.editorconfig @@ -23,4 +23,5 @@ indent_size = 4 indent_style = space insert_final_newline = true spaces_around_operators = true -wildcard_import_limit = 999 \ No newline at end of file +wildcard_import_limit = 999 +imports_layout = java.**, |, javax.**, |, groovy.**, org.apache.groovy.**, org.codehaus.groovy.**, |, jakarta.**, |, *, |, io.spring.**, org.springframework.**, |, grails.**, org.apache.grails.**, org.grails.**, |, $* \ No newline at end of file diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index a26d1566221..27d51e349f3 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -30,10 +30,12 @@ on: push: branches: - '[4-9]+.[0-9]+.x' + - '8.0.x-hibernate7.*' pull_request: # The branches below must be a subset of the branches above branches: - '[4-9]+.[0-9]+.x' + - '8.0.x-hibernate7.*' # queue jobs and only allow 1 run per branch due to the likelihood of hitting GitHub resource limits concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index b5e85454e5b..b13790bf310 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -18,6 +18,7 @@ on: push: branches: - '[0-9]+.[0-9]+.x' + - '8.0.x-hibernate7.*' pull_request: workflow_dispatch: # Queue jobs - cancel in-progress PR runs when new commits pushed, but allow branch builds to complete @@ -273,6 +274,7 @@ jobs: -PonlyFunctionalTests -PskipCodeStyle -PskipHibernate5Tests + -PskipHibernate7Tests -PskipMongodbTests mongodbFunctional: if: ${{ !contains(github.event.head_commit.message, '[skip tests]') }} @@ -353,6 +355,44 @@ jobs: -PgrailsIndy=${{ matrix.indy }} -PonlyHibernate5Tests -PskipCodeStyle + hibernate7Functional: + if: ${{ !contains(github.event.head_commit.message, '[skip tests]') }} + name: "Hibernate7 Functional Tests (Java ${{ matrix.java }}, indy=${{ matrix.indy }})" + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + java: [ 21, 25 ] + indy: [ false ] + include: + - java: 21 + indy: true + steps: + - name: "Output Agent IP" # in the event RAO blocks this agent, this can be used to debug it + run: curl -s https://api.ipify.org + - name: "📥 Checkout the repository" + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: "☕️ Setup JDK" + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 + with: + distribution: liberica + java-version: ${{ matrix.java }} + - name: "🐘 Setup Gradle" + uses: gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0 + with: + cache-provider: basic # 'basic' uses the MIT-licensed, open-source cache provider; the default 'enhanced' provider (v6+) is proprietary (Gradle commercial Terms of Use) + develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + - name: "🏃 Run Functional Tests" + env: + GITHUB_MAVEN_PASSWORD: ${{ secrets.GITHUB_TOKEN }} + run: > + ./gradlew bootJar check + --continue + --rerun-tasks + --stacktrace + -PgrailsIndy=${{ matrix.indy }} + -PonlyHibernate7Tests + -PskipCodeStyle publishGradle: if: github.repository_owner == 'apache' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') needs: [ buildGradle ] diff --git a/.github/workflows/groovy-joint-workflow.yml b/.github/workflows/groovy-joint-workflow.yml index 1b4f0cc430a..2da4597bde3 100644 --- a/.github/workflows/groovy-joint-workflow.yml +++ b/.github/workflows/groovy-joint-workflow.yml @@ -17,10 +17,12 @@ name: "CI - Groovy Joint Validation Build" on: push: branches: - - '[4-9]+.[0-9]+.x' + - '[0-9]+.[0-9]+.x' + - '8.0.x-hibernate7.*' pull_request: branches: - - '[4-9]+.[0-9]+.x' + - '[0-9]+.[0-9]+.x' + - '8.0.x-hibernate7.*' workflow_dispatch: # queue jobs and only allow 1 run per branch due to the likelihood of hitting GitHub resource limits concurrency: @@ -124,7 +126,6 @@ jobs: run: | cd groovy ./gradlew pTML -x groovydoc -x javadoc -x javadocAll -x groovydocAll -x asciidoc -x docGDK - build_grails: needs: [build_groovy] runs-on: ubuntu-latest diff --git a/.github/workflows/rat.yml b/.github/workflows/rat.yml index 14b2a98bc9f..9e9df4f0c71 100644 --- a/.github/workflows/rat.yml +++ b/.github/workflows/rat.yml @@ -17,14 +17,12 @@ name: "Licensing - RAT Report" on: push: branches: - - '[4-9]+.[0-9]+.x' - - '[3-9]+.[3-9]+.x' - - license-audit + - '[0-9]+.[0-9]+.x' + - '8.0.x-hibernate7.*' pull_request: branches: - - '[4-9]+.[0-9]+.x' - - '[3-9]+.[3-9]+.x' - - license-audit + - '[0-9]+.[0-9]+.x' + - '8.0.x-hibernate7.*' workflow_dispatch: # queue jobs and only allow 1 run per branch due to the likelihood of hitting GitHub resource limits concurrency: diff --git a/.gitignore b/.gitignore index ca770d0c557..46293f4418c 100644 --- a/.gitignore +++ b/.gitignore @@ -54,7 +54,10 @@ testWatchedFile.properties _alternativeTable.gsp **/src/en/ref/Versions/Grails BOM.adoc **/src/en/ref/Versions/Grails BOM Hibernate5.adoc +**/src/en/ref/Versions/Grails BOM Hibernate7.adoc **/src/en/ref/Versions/Grails BOM Micronaut.adoc +**/src/en/ref/Versions/Grails BOM Hibernate5 Micronaut.adoc +**/src/en/ref/Versions/Grails BOM Hibernate7 Micronaut.adoc **/src/en/ref/Configuration/Application Properties.adoc stacktrace.log target diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index ab13aa909ae..ce4b40f7953 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -54,6 +54,7 @@ +