Repository navigation
Fix the two causes of the intermittent Neo4j functional test failures - #16436
Merged
Merged
Conversation
The Neo4j CI jobs failed on random JDKs of the matrix for two unrelated
reasons, found by surveying every gradle.yml run since 2026-09-16:
1. Dependency resolution died on repo.grails.org ("Remote host terminated
the handshake") before any test ran. GrailsRepoSettingsPlugin declared
repo.grails.org/grails/restricted as the only release repository, and
Gradle never falls through to another repository on a transport
failure. The jobs using setup-gradle's basic cache provider all shared
one ~300 MB entry written by the fast validate job, so every Neo4j run
re-downloaded the GORM dependency set through that host.
2. MultiTenancySpec and HasManyInheritanceSpec both started an embedded
Neo4j on the pinned port 7687. grails-data-neo4j-core runs its tests
across parallel forks, so whenever the two specs ran concurrently the
second one failed with PortBindException.
Maven Central is now the first release repository, with repo.grails.org
kept as the fallback for anything Central does not host; a TestKit spec
pins the repository order. The eight basic-provider CI jobs use the same
branch-keyed dependency jar cache as the other jobs instead of per-job
entries, because the repository is already at its 10 GB cache limit and
every test family needs roughly the same ~1 GB working set. The two specs
drop the pinned URL so the embedded server binds a random free port like
the TCK manager already does.
sbglasius
approved these changes
Sep 30, 2026
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 8.0.x #16436 +/- ##
===================================================
+ Coverage 32.7604% 58.6142% +25.8538%
- Complexity 563 24309 +23746
===================================================
Files 84 2174 +2090
Lines 4945 107346 +102401
Branches 865 19566 +18701
===================================================
+ Hits 1620 62920 +61300
- Misses 3065 35571 +32506
- Partials 260 8855 +8595 🚀 New features to boost your workflow:
|
✅ All tests passed ✅🏷️ Commit: d03fbba Learn more about TestLens at testlens.app/docs. |
jamesfredley
approved these changes
Sep 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The Neo4j functional test jobs fail intermittently on 8.0.x, on whichever JDK of the matrix happens to be unlucky (#16435 is a recent example). A survey of every
gradle.ymlrun since 2026-09-16 showed that all of the Neo4j failures not caused by the PR under test fall into two shapes.1. Dependency resolution dies on repo.grails.org before any test runs
Seen on #16435 (Java 25, 2026-09-30) and, on
maven-resolver-api, on the 2026-09-23 run for #16385. Three things combine here:GrailsRepoSettingsPlugindeclaredrepo.grails.org/grails/restrictedas the only release repository for project dependencies, so every POM and jar of the build went through that one host. Gradle disables a repository for the rest of the build on a transport failure and fails resolution; it never falls through to the next repository.setup-gradlewithcache-provider: basic. That provider keys its entry assetup-java-<os>-<arch>-gradle-<hash of **/*.gradle*>, has no restore keys, and shares the one entry between every job that uses it. Whichever job finishes first on an 8.0.x push writes it; that is the validate job, so the entry is ~290-350 MB and holds none of the GORM test dependencies.actions/cachestep from 6daf2d1. A PR that touches any Gradle file started fully cold.2.
initializationErrorending inorg.neo4j.helpers.PortBindExceptionMultiTenancySpeclost on 2026-09-23 (#16385) andHasManyInheritanceSpecon 2026-09-27 (#16415). Both specs configured their embedded Neo4j withbolt://localhost:7687, andNeo4jConnectionSourceFactorybinds that literal port when a URL is given.grails-data-neo4j-core:testruns withmaxParallelForks = 4andforkEvery = 10on CI, so whenever the two specs are dispatched to different forks at the same time the second one cannot bind. The forks and the pinned port arrived together in 413d19f (#15972). The TCK manager already lets the harness pick a free port.Changes
.github/workflows/gradle.yml: the eight jobs oncache-provider: basicnow use the same branch-keyedactions/cachestep as the rest of the workflow (gradle-deps-<os>-<branch>-<hash of dependencies.gradle and the wrapper>, currently ~1.1 GB and complete), withcache-disabled: trueonsetup-gradle. Per-job entries were considered and rejected: the repository sits at 10.5 GB of its 10 GB Actions cache limit, and every test family's working set is roughly the same ~1 GB, so six per-job entries per active branch would evict everything and make every job cold.GrailsRepoSettingsPlugin: Maven Central is now the first release repository for project dependencies;repo.grails.org/grails/restrictedstays behind it as the fallback for anything Central does not host.pluginManagementalready had Central first. A newGrailsRepoSettingsPluginSpec(TestKit) pins the repository order for both blocks,FAIL_ON_PROJECT_REPOS, and theGRAILS_INCLUDE_MAVEN_LOCALbehaviour.MultiTenancySpec/HasManyInheritanceSpec: drop the pinned URL so the embedded server binds a random free port, the same way the TCK manager does.SingleTenancySpecandMultipleConnectionsSpecalso mention 7687 but use the defaultremoteconnection type, so they never bind it and are unchanged.Not in this PR: the other workflows that still use
cache-provider: basic(codestyle, coverage, rat, sitemesh2, benchmark, codeanalysis, release) keep sharing the smallsetup-java-*entry. They no longer influencegradle.ymland can move to the branch-keyed cache separately. The 9.0.x Neo4j job timing out after 90 minutes on 2026-09-26 is a different problem on that branch.Verification
build-logic:./gradlew :build-logic:test --tests org.apache.grails.buildsrc.GrailsRepoSettingsPluginSpec(4 tests, 0 failures)./gradlew :grails-data-neo4j-core:test :grails-data-neo4j-core:codeStyle validateRepositoryConventions(596 tests, 98 skipped, 0 failures; Checkstyle and CodeNarc clean; no repository convention violations)Contributor Checklist
Issue and Scope
Code Quality
./gradlew build --rerun-tasks../gradlew codeStyleand resolved any violations.Licensing and Attribution
Documentation