The GitHub Actions job "CI" on 
grails-core.git/fix/bom-cli-afterEvaluate-ordering has succeeded.
Run started by GitHub user codeconsole (triggered by codeconsole).

Head commit for run:
9f751d16be6cc332c3e21d86cd68ca8b29880520 / Scott Murphy Heiberg 
<[email protected]>
Fix review feedback: preserve plugin identity/idempotency, add regression test

The previous commit fixed the afterEvaluate ordering race by having
GrailsGradlePlugin call BomPropertyOverridesPlugin's static applyOverrides()
directly instead of project.plugins.apply(BomPropertyOverridesPlugin). That
broke the plugin's public identity/idempotency contract:

- project.plugins.findPlugin('org.apache.grails.gradle.bom-property-overrides')
  returned null even when the override machinery was active (breaks all 4
  cases in BomPlatformFunctionalSpec).
- Manually recreating the bomPropertyOverrides extension collides with
  BomPropertyOverridesPlugin's own extension creation if a build explicitly
  applies org.apache.grails.gradle.bom-property-overrides alongside a Grails
  app/plugin (previously safe, since project.plugins.apply(Class) is
  idempotent).
- No automated test reproduced the actual multi-project race the original
  commit fixed - the existing suite is entirely single-project fixtures, so
  none of it exercises resolving one project's grailsCliDetect probe forcing
  another project to finish configuring mid-resolution.

Also investigated and discarded two alternative fixes before landing here:
deferring GrailsCliGradlePlugin's classpath probe to
project.gradle.projectsEvaluated (throws IllegalResolutionException -
resolving a configuration there is unsafe, no exclusive lock is held), and
switching BomManagedVersions.applyTo() to register its constraints via
Configuration.withDependencies() instead of eagerly (passes the whole
existing suite but does NOT fix the real race - registering
withDependencies() on an already-observed configuration is rejected exactly
like the eager mutation was, just later, confirmed against the actual
multi-project reproduction case, not just the unit suite).

This commit instead keeps project.plugins.apply(BomPropertyOverridesPlugin)
(restoring identity + idempotency) but un-nests the call so it's a top-level
statement in applyGrailsBom rather than nested inside its own afterEvaluate -
avoiding the same queue-ordering race without bypassing the plugin API.
Because the grails.bom-null opt-out can only be determined once afterEvaluate
runs (too late to conditionally gate this call without reintroducing the
race), the plugin is now applied unconditionally; BomOptOutFunctionalSpec is
updated to assert the functional outcome (zero override constraints added)
rather than plugin identity, with the tradeoff documented in both the code
and the test.

Adds BomCliMultiprojectRaceFunctionalSpec: a two-project fixture (consumer
depending on producer via project(), producer carrying an active
property-based BOM override) that reproduces the original crash exactly.
Verified it fails against the pre-fix code with the same
"Cannot mutate the dependencies of configuration ... after ... was resolved"
error, and passes with this fix.

Full :grails-gradle-plugins:test suite (75 tests) passes. Re-verified against
the real multi-project reproduction case (a Grails 8 app with a
project(...) dependency chain and a grailsVersion property override) by
publishing to mavenLocal and rebuilding - previously failed, now succeeds.

Report URL: https://github.com/apache/grails-core/actions/runs/29670484204

With regards,
GitHub Actions via GitBox

Reply via email to