Skip to content

feat/v2.2-adoption-feedback: polish the operator experience surfaced by the service pilot#37

Merged
vedanthvdev merged 1 commit intomasterfrom
feat/v2.2-adoption-feedback
Apr 24, 2026
Merged

feat/v2.2-adoption-feedback: polish the operator experience surfaced by the service pilot#37
vedanthvdev merged 1 commit intomasterfrom
feat/v2.2-adoption-feedback

Conversation

@vedanthvdev
Copy link
Copy Markdown
Owner

Why

The v2.1 pilot against Modulr's security-service (CAR-5190) surfaced five non-breaking rough edges that an adopter hits in their first hour with the plugin. This PR sharpens each one while keeping every DSL knob, default, and resolved behaviour from v2.1 bit-for-bit identical — v2.1 users can bump to v2.2 without touching build.gradle.

What (the five fixes)

Bug A — --explain no longer forces a full compile

The unconditional testClasses dependency turned a 3-second diagnostic run into a multi-minute compile on the real repo. v2.2 wraps the dependency in a Callable that re-evaluates after CLI parsing: when --explain is set the Callable returns an empty list and testClasses is pruned from the task graph; when --explain is absent the dependency behaves exactly as before.

Bug B — situation-specific Hint: lines in the --explain trace

Pre-v2.2 every mapper-touching situation printed the same "outOfScopeTestDirs is configured" hint — misleading on runs where OOS wasn't the cause. v2.2 splits the hint into three targeted branches:

  • DISCOVERY_EMPTY → "discovery mapped 0 test classes" + testSuffixes / testDirs / no-coverage-yet causes
  • DISCOVERY_INCOMPLETE → names the parse-failure risk + points at onDiscoveryIncomplete = "full_suite"
  • DISCOVERY_SUCCESS with OOS configured-but-unmatched keeps the v2.1 wording

Risk C — LOCAL + DISCOVERY_INCOMPLETE now emits a loud WARN

LOCAL keeps onDiscoveryIncomplete = SELECTED on purpose, but without a visible signal a parse failure silently understates what ran. v2.2 emits a lifecycle WARN with marker affectedTest: LOCAL mode accepted a partial selection — grep-friendly, visible at Gradle's default log level, gated so it never fires in CI/STRICT (which already escalate to FULL_SUITE on DISCOVERY_INCOMPLETE).

Feature D — -PaffectedTestsMode runtime override

Mirrors -PaffectedTestsBaseRef: set -PaffectedTestsMode=local|ci|strict|auto to flip the plugin's mode without editing build.gradle. Implemented as a convention() so DSL-declared mode = '...' keeps precedence — a repo pinning its CI mode cannot be silently overridden by a stray -P.

Polish E — :module:test dispatch breakdown in --explain

A SELECTED --explain run now prints the exact dispatch grouping a non-explain run would use:

Modules:         2 modules, 3 test classes to dispatch
  :application:test (2 test classes)
    com.example.FooTest
    com.example.BarTest
  :api:test (1 test class)
    com.example.BazTest

Non-SELECTED runs suppress the block entirely.

Verification

  • ./gradlew test functionalTest green locally (73 unit tests + 54 Cucumber scenarios, +2 new unit tests and +10 new e2e scenarios from this PR).
  • New e2e file 06-v2.2-adoption-feedback.feature pins each user-facing behaviour above, so a regression on any of the five surfaces as a named scenario failure rather than silent UX drift.
  • Unit tests pin the Callable prune shape (Bug A), the mode-precedence contract (Feature D), the three hint variants (Bug B), and the Modules-block empty/multi-module/root-project/preview-truncation edges (Polish E).

Release plan

  • CHANGELOG.md has a full v2.2.0 entry describing each fix and its scope.
  • .release-version pins 2.2.0 so the next merge-to-master release workflow tags and publishes v2.2.0, then auto-deletes the pin in a [skip ci] follow-up (matches the v2.1.0 release flow).

Test plan

  • ./gradlew test — green
  • ./gradlew functionalTest — green (all 6 feature files, including new 06-v2.2-adoption-feedback.feature)
  • CI pipeline green on this branch before merge

@vedanthvdev vedanthvdev force-pushed the feat/v2.2-adoption-feedback branch from e767f48 to 5816f43 Compare April 24, 2026 14:36
…by the security-service pilot

The v2.1 pilot against Modulr's security-service (CAR-5190) surfaced
five non-breaking rough edges that an adopter hits in their first hour
with the plugin. v2.2 sharpens each one while keeping every DSL knob,
default, and resolved behaviour from v2.1 bit-for-bit identical.

Bug A: `--explain` no longer forces a full compile. The unconditional
`testClasses` dependency turned a 3-second diagnostic run into a
multi-minute compile on a real-world repo. The dependency is now
wrapped in a `Callable` that re-evaluates after command-line parsing
and returns an empty list when `--explain` is set, pruning
`testClasses` from the task graph entirely. Dispatch runs keep the
dependency as before.

Bug B: situation-specific `Hint:` lines in the `--explain` trace.
Pre-v2.2 every mapper-touching situation printed the same
"outOfScopeTestDirs is configured" hint — correct for a subset of
DISCOVERY_SUCCESS runs, actively misleading everywhere else. v2.2
splits the hint into three targeted branches: DISCOVERY_EMPTY names
the realistic causes (testSuffixes, testDirs, no coverage yet),
DISCOVERY_INCOMPLETE names the actual risk (parse failure → partial
selection) plus the `onDiscoveryIncomplete` escalation knob, and
DISCOVERY_SUCCESS keeps the v2.1 OOS wording in the one situation it
was right for. The DISCOVERY_INCOMPLETE hint is action-aware: only
the SELECTED branch claims the selection is partial; the FULL_SUITE
branch (CI/STRICT default, or explicit override) drops that wording
and the circular "escalate to what we already did" advice.

Risk C: LOCAL mode + DISCOVERY_INCOMPLETE now emits a lifecycle WARN
when it accepts a partial selection. LOCAL keeps
`onDiscoveryIncomplete = SELECTED` on purpose (devs iterating on WIP
want fast feedback), but without a visible signal a parse failure
silently understates what actually ran. The new `WARN` marker
"affectedTest: LOCAL mode accepted a partial selection" is
grep-friendly, visible at Gradle's default log level, and gated so it
never fires in CI/STRICT modes (which already escalate to FULL_SUITE
on DISCOVERY_INCOMPLETE). The gate also short-circuits on
`skipped=true` / empty FQN lists so an operator never sees a
"0 test classes accepted" WARN immediately before a skipped run. The
wording cross-references the engine's own parse-failure WARN rather
than restating it.

Feature D: `-PaffectedTestsMode=local|ci|strict|auto` runtime override.
Mirrors the existing `-PaffectedTestsBaseRef` pattern so adopters can
A/B modes without editing `build.gradle`. Implemented as a
`convention()` on the mode Property so DSL-declared `mode = '...'`
keeps precedence — a repo pinning its CI mode in the build script
cannot be silently overridden by a stray `-P`.

Polish E: `--explain` now shows the `:module:test` dispatch breakdown
on a SELECTED run. Same grouping helper the dispatch path uses, same
preview-truncation cap — so an operator comparing `--explain` against
a real dispatch sees the exact same shape. Non-SELECTED runs suppress
the block entirely rather than print a noisy "0 modules" line. The
task-path normalisation is shared between explain and dispatch via a
`testTaskPath` helper so the two operator-facing strings cannot drift.

Every user-facing behaviour above is pinned by a Cucumber e2e scenario
in `06-v2.2-adoption-feedback.feature`, plus unit tests on the
Callable prune shape, the mode-precedence contract, the three hint
variants (including the action-aware DISCOVERY_INCOMPLETE split), the
Risk C WARN four-way gate (mode, situation, action, skipped/empty),
and the Modules-block empty/multi-module/root/truncation edges. The
two-module Bug A e2e scenario pins that `--explain` prunes
`compileJava` on every subproject, not just the root. CHANGELOG bumped
with the adoption-feedback narrative plus a follow-up Unreleased
section capturing the v2.2 code-review polish; the release-version
pin is set to 2.2.0 so the next merge to master tags and publishes
v2.2.0.
@vedanthvdev vedanthvdev force-pushed the feat/v2.2-adoption-feedback branch from 5816f43 to 758da15 Compare April 24, 2026 15:29
@vedanthvdev vedanthvdev changed the title feat/v2.2-adoption-feedback: polish the operator experience surfaced by the security-service pilot feat/v2.2-adoption-feedback: polish the operator experience surfaced by the service pilot Apr 24, 2026
@vedanthvdev vedanthvdev merged commit f9299ce into master Apr 24, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant