Repository navigation
Stop the integration-test build from recompiling the root modules - #94
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`tests/settings.gradle.kts` made the `tests` build a composite of the root one. `integrationTest` runs it after every root `test` task and, usually, before `koverXmlReport`, so Gradle reran `:api:launchSpineCompiler`, `compileKotlin`, and `jar` of the root build in its own `api/build`. The Validation plugin keeps `launchSpineCompiler` out of date (it adds its settings file to the task's inputs in `doFirst`), and its generated code uses random identifiers. The recompiled classes got new JaCoCo class IDs, and the root report dropped their coverage at random. The `tests` build now consumes what `localPublish` puts into Maven Local, resolving the Compiler plugin and the `compiler-*` artifacts from there first, so it no longer touches the root project directories. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The `tests` root script adds the standard repositories to its subprojects before their own scripts run, so the Maven Local repository appended in `beforeProject` came last for the project dependencies. An exclusive content filter, scoped to the version under development, does not depend on the repository order, and it fails the build if `localPublish` did not run instead of falling back to a remote copy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Re-bump for a version collision: PR #90 now claims `2.0.0-SNAPSHOT.076`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
🔵 Needs a closer look
Nested Gradle resolution and repeatable coverage uploads still need CI confirmation and final human review.
No open issues 🎉
What changed in this PR
Isolates integration tests from the root build to prevent recompilation from invalidating coverage data.
Changes:
- Replaces composite-build resolution with locally published Compiler artifacts.
- Documents standalone integration-test execution.
- Updates the development version and dependency reports to
.077.
| File | Description |
|---|---|
version.gradle.kts |
Bumps the Compiler version to .077. |
tests/settings.gradle.kts |
Removes the root composite build and configures Maven Local resolution. |
tests/README.md |
Documents publication prerequisites and build isolation. |
docs/dependencies/pom.xml |
Updates the project version. |
docs/dependencies/dependencies.md |
Refreshes report versions and timestamps. |
.agents/tasks/deterministic-coverage.md |
Records diagnosis, verification, and remaining CI confirmation. |
Review effort: Balanced
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3aa5bd4446
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
# Conflicts: # docs/dependencies/dependencies.md # docs/dependencies/pom.xml # version.gradle.kts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #94 +/- ##
=========================================
Coverage 76.99% 76.99%
Complexity 692 692
=========================================
Files 205 205
Lines 4021 4021
Branches 402 402
=========================================
Hits 3096 3096
Misses 796 796
Partials 129 129 🚀 New features to boost your workflow:
|
`2.0.0-SNAPSHOT.077` is taken by #94 on `master`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Problem
codecov/project(threshold 0.05%) failed pull requests at random. Between CI runs ofthe same tree, Codecov credited some
apifiles with full coverage or with none:FieldTypeExts.kt,FilePatterns.kt,TypeExts.kt,DescriptorExts.kt,value/Options.kt,MessageTypeDependencies.kt,ValueConverter.kt— up to 182 hits.api's ownFilePatternsSpecandOptionsSpeclost their hits too, so this was notabout cross-module attribution.
Root cause
tests/settings.gradle.ktsmade the integration-test build a composite of the root one(
includeBuild("..")). So:integrationTestruns thetestsbuild after every roottesttask and, in practice,before
koverXmlReport. Gradle substitutes thecompiler-*artifacts with the rootprojects and runs
:compiler:api:launchSpineCompiler,kspKotlin,compileKotlin,and
jarfrom there, in the root'sapi/build.JavaValidationRenderer.pb.jsoninto thesettingsDirectoryinput of everyLaunchSpineCompilerin adoFirstaction, after Gradle has fingerprinted the inputs.(The same is why CI's
dokkaGeneratestep recompiles:api.)compiled regular expressions with
SecureRandomString, so the sources really differ(
TypeUrlPrefixPattern_C0Kx…vsTypeUrlPrefixPattern_YxGa…). Kotlin's incrementalcompiler then recompiles the hand-written files that use them. The class files differ
only in their constant-pool layout, but that changes their JaCoCo class IDs.
koverXmlReportanalyzes the rewritten class files, finds no execution data withmatching IDs, and reports those classes as uncovered.
Reproduced locally with a
clean buildof this branch before the fix. The exec files ofall test tasks matched 249/249 executed
apiclasses as compiled beforeintegrationTest, but 5 of them (FieldTypes,FilePatterns,Types,DescriptorExtsKt,OptionValue) mismatched the classes the report read. The report hadFieldTypeExts.ktat 0/73 lines andFilePatterns.ktat 0/9.Fix
The
testsbuild no longer includes the root build. It consumes whatlocalPublish(already a dependency of
integrationTest) puts into Maven Local:pluginManagementresolves theio.spine.compilerplugin from Maven Local at theversion under development (
in-place-consumerapplies it viaplugins {}).beforeProjecthook declares Maven Local the exclusive source ofio.spine.tools:compiler-*at the version under development, in both the build-scriptand project repositories. Repository order would not do it:
standardToSpineSdk()listsMaven Local last, and the
testsroot script adds the repositories to the subprojectsbefore their own scripts run. With the rule, a remote repository that already has the
same version never serves it. If
localPublishdid not run, the build fails instead.Verified: with the version under test absent from Maven Local but present in the
registry, resolution fails; other
compiler-*versions still resolve remotely.tests/README.mdexplains this and how to run thetestsbuild on its own.After the fix, both a cached and an uncached (
--no-build-cache)clean build:apiclass files and generated sources unchanged acrossintegrationTest;apiclasses;FieldTypeExts.kt73/73,FilePatterns.kt7/9,
TypeExts.kt17/19,DescriptorExts.kt45/46,value/Options.kt42/42,MessageTypeDependencies.kt30/30,ValueConverter.kt11/15.The uncached run had freshly randomized generated sources (8 files differed from the cached
run), yet the coverage was the same.
Follow-ups (in
validation)SecureRandomString(it also defeats thebuild cache for every consumer).
LaunchSpineCompilerare fingerprinted.Version:
2.0.0-SNAPSHOT.077(first.076; re-bumped because #90 now claims.076).🤖 Generated with Claude Code