Skip to content

Credit Spine Compiler codegen execution to coverage#727

Merged
alexander-yevsyukov merged 4 commits into
masterfrom
port-compiler-coverage
Jul 7, 2026
Merged

Credit Spine Compiler codegen execution to coverage#727
alexander-yevsyukov merged 4 commits into
masterfrom
port-compiler-coverage

Conversation

@alexander-yevsyukov

Copy link
Copy Markdown
Contributor

What & why

Ports the buildSrc coverage helpers from
validation#317
into config, so every consumer repo receives them via ./config/pull.

The Spine Compiler runs plugin code — renderers, option generators, and
other codegen plugins — in a forked launch*SpineCompiler JVM during the
build, which Kover/JaCoCo do not instrument. That out-of-process execution is
otherwise reported at ~0% line coverage even though each repo's .proto
fixtures exercise it on every build. In validation, wiring this in took the
root report from 12% → 86%. This change distributes the mechanism; each
consumer opts in with a single subprojects { enableSpineCompilerCoverage() }
line in its own root build script (that wiring stays consumer-owned and is
not part of this PR).

How

  • enableSpineCompilerCoverage() (new
    buildSrc/.../gradle/testing/SpineCompilerCoverage.kt) attaches
    -javaagent:<JaCoCo agent>=destfile=…/<task>.exec,append=false to every
    launch*SpineCompiler JavaExec task, one exec file per launch variant.
  • The .exec is declared as a task output, so the launch tasks stay
    cacheable: a JavaExec blocks until the fork exits and the agent flushes
    on exit, so the file is on disk when the action returns. Coverage survives
    both an UP-TO-DATE skip and a FROM-CACHE hit — unlike the TestKit worker
    daemon, which is why enableTestKitCoverage() must instead disable caching.
  • KoverConfig feeds the exec files into the root report's
    additionalBinaryReports (the report Codecov ingests) and orders the
    kover*Report/kover*Verify tasks after the launch tasks.
  • The JaCoCo agent coordinate is centralized as Jacoco.agent, shared with
    enableTestKitCoverage() (which previously inlined the same literal).

Deviations from the source PR (behavior identical)

  • KDoc generalized — validation-specific references (java/context
    modules, JavaValidationPlugin) removed, since these files land in ~40 repos.
  • detekt-driven dedupconfig runs detekt over buildSrc (consumers
    don't); the verbatim port tripped TooManyFunctions. The twin
    testKitExecFiles/compilerExecFiles helpers are now one
    execFiles(project, dirName), and the Kover-task predicate reuses the
    pre-existing consumesCoverageBinaryReports() from SiblingCoverage.kt
    (promoted privateinternal) rather than duplicating it.
  • Idempotency guard — an early return makes enableSpineCompilerCoverage()
    safe to call more than once per project; without it a second call would
    append a second -javaagent: and double-load the agent in the fork.

Verification

  • JAVA_HOME=17 ./gradlew :buildSrc:build detekt — green (tests included).
    config's root has no build lifecycle task and does not register
    dokkaGenerate, so this is the applicable command.
  • No root version.gradle.kts in config, so the version-bump gate is not
    applicable.
  • Reviewers on the final diff — spine-code-review, kotlin-engineer,
    review-docs, dependency-audit — all APPROVE.

🤖 Generated with Claude Code

alexander-yevsyukov and others added 2 commits July 6, 2026 20:19
Port the `buildSrc` helpers from SpineEventEngine/validation#317:

- `enableSpineCompilerCoverage()` attaches the standalone JaCoCo agent
  to the forked `launch*SpineCompiler` JVMs and declares each per-task
  `.exec` as a cacheable task output.
- `KoverConfig` feeds those exec files into the root report's
  `additionalBinaryReports`, so out-of-process codegen execution is
  credited to the coverage Codecov ingests.
- The JaCoCo agent coordinate is centralized as `Jacoco.agent`, shared
  with `enableTestKitCoverage()`.

Deviations from the source PR: KDoc generalized (no validation-specific
module names), duplicate helpers merged (`execFiles`, and the Kover
task predicate now reuses `consumesCoverageBinaryReports()` from
`SiblingCoverage.kt`), and an early-return guard makes
`enableSpineCompilerCoverage()` idempotent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Extend the `porting-buildsrc-from-consumer-repos` memory with the two
adaptations this port surfaced: `config`-only detekt coverage of
`buildSrc`, and generalizing consumer-specific KDoc.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 6, 2026 19:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Ports Spine Compiler out-of-process coverage wiring into config’s buildSrc so consumer repositories can optionally attribute codegen/plugin execution in forked launch*SpineCompiler JVMs to their root Kover/JaCoCo coverage reports.

Changes:

  • Add enableSpineCompilerCoverage() to attach the JaCoCo agent to launch*SpineCompiler JavaExec tasks and publish per-task .exec outputs.
  • Extend KoverConfig to include compiler-produced .exec files in the root aggregated report, and deduplicate exec-file discovery logic.
  • Centralize JaCoCo agent coordinates as Jacoco.agent and reuse it from existing TestKit coverage helper.

Reviewed changes

Copilot reviewed 5 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
buildSrc/src/main/kotlin/io/spine/gradle/testing/TestKitCoverage.kt Switches TestKit agent dependency to the new centralized Jacoco.agent coordinate.
buildSrc/src/main/kotlin/io/spine/gradle/testing/SpineCompilerCoverage.kt Introduces the new helper that instruments forked Spine Compiler JavaExec launch tasks and wires root Kover tasks to depend on them.
buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/SiblingCoverage.kt Promotes consumesCoverageBinaryReports() for reuse and updates KDoc to include compiler-produced binary data.
buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/KoverConfig.kt Adds compiler .exec files to root additionalBinaryReports and consolidates exec-file listing logic.
buildSrc/src/main/kotlin/io/spine/dependency/test/Jacoco.kt Adds Jacoco.agent Maven coordinate constant for the standalone runtime agent JAR.
.agents/tasks/port-compiler-coverage.md Adds an agent task log documenting the port rationale and verification steps.
.agents/memory/project/porting-buildsrc-from-consumer-repos.md Documents recurring porting adaptations (detekt and KDoc generalization) for future ports.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 82e0c5bb2a

ℹ️ 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".

Comment thread buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/KoverConfig.kt Outdated
alexander-yevsyukov and others added 2 commits July 6, 2026 20:27
Address Copilot review feedback on PR #727: the `-javaagent` argument is
added in `doFirst`, so the agent coordinate was not part of the
`launch*SpineCompiler` task fingerprint. A JaCoCo version bump would then
leave the cacheable launch tasks UP-TO-DATE/FROM-CACHE, serving a stale
`.exec` written by the previous agent.

Declare the agent *coordinate* (`Jacoco.agent`) as an `inputs.property`
so a version bump invalidates the tasks and regenerates the exec. The
coordinate string — not the resolved absolute JAR path — is tracked, so
the cache key stays machine-independent, preserving the cross-machine
cache reuse the `doFirst` attachment was designed to protect. This also
brings the helper to parity with `enableTestKitCoverage()`, which already
declares its agent as a task input.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Address Codex review feedback (P2) on PR #727: the root report gathered
Spine Compiler coverage by scanning every subproject's
`build/jacoco-compiler/` directory. In an un-`clean`ed workspace a stale
`.exec` from a removed `launch*SpineCompiler` task — or from a module that
stopped enabling the helper — lingered and was still credited, inflating
the root coverage.

Collect the `.exec` files from the declared outputs of each subproject's
currently configured launch tasks instead of scanning the directory. A
removed task is no longer in the collection, and a task whose module
disabled the helper no longer declares an exec output, so neither stale
file is credited. This mirrors the existing `SiblingCoverage.execFilesOf`
pattern (map current tasks, not a directory) while preserving the
launch tasks' cacheability — unlike `enableTestKitCoverage()`, which wipes
its directory and must therefore disable caching.

`isSpineCompilerLaunchTask()` is promoted to `internal` for reuse by
`KoverConfig`; `COMPILER_COVERAGE_DIR` is no longer needed there.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 6, 2026 19:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 7 changed files in this pull request and generated no new comments.

@alexander-yevsyukov alexander-yevsyukov self-assigned this Jul 6, 2026
@alexander-yevsyukov alexander-yevsyukov moved this to 🏗 In progress in v2.0 Jul 6, 2026
@alexander-yevsyukov alexander-yevsyukov moved this from 🏗 In progress to In Review in v2.0 Jul 6, 2026
@armiol

armiol commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

@alexander-yevsyukov this is going to be a long wait :(
image

@alexander-yevsyukov

Copy link
Copy Markdown
Contributor Author

@alexander-yevsyukov this is going to be a long wait :( image

Here's what we have in the ruleset for this repo:

image

I think we're having a GitHub issue here.

@alexander-yevsyukov alexander-yevsyukov enabled auto-merge (rebase) July 7, 2026 13:00
@alexander-yevsyukov

Copy link
Copy Markdown
Contributor Author

@armiol

this is going to be a long wait :(

This was a org-wide ruleset which applied after we upgraded our org to Team. I've turned it off.

@alexander-yevsyukov alexander-yevsyukov merged commit 0c0ef6e into master Jul 7, 2026
4 checks passed
@github-project-automation github-project-automation Bot moved this from In Review to ✅ Done in v2.0 Jul 7, 2026
@alexander-yevsyukov alexander-yevsyukov deleted the port-compiler-coverage branch July 7, 2026 13:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

3 participants