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

Archived in project

Development

Successfully merging this pull request may close these issues.

3 participants