Skip to content

Disable the OpenRewrite recipes that keep Scheduled Cleanup red - #3026

Merged
nedtwigg merged 1 commit into
mainfrom
chore/openrewrite-green
Aug 20, 2026
Merged

Disable the OpenRewrite recipes that keep Scheduled Cleanup red#3026
nedtwigg merged 1 commit into
mainfrom
chore/openrewrite-green

Conversation

@nedtwigg

Copy link
Copy Markdown
Member

Scheduled Cleanup 🧹 has failed every weekly run since at least 2026-06-03. The failing step is rewriteDryRun, which fails by design when recipes would make changes.

It was never an unattended backlog. Running rewriteRun does not fix it, and applying its output is actively unsafe.

Why not just run rewriteRun

I did, then compiled and tested the result. Three problems:

1. Two recipes emit code that does not compile.

GoogleJavaFormatStep.java:126: incompatible types: Support<Object> cannot be converted to Support<String>
CleanthatJavaStep.java:52:    incompatible types: Support<Object> cannot be converted to Support<String>
RdfFormatterStep.java:36:     incompatible types: Support<Object> cannot be converted to Support<String>
IdeaStep.java:261:            incompatible types: OutputStream cannot be converted to FileOutputStream

UnnecessaryExplicitTypeArguments strips the witness from Jvm.<String>support(NAME). Since support is static <V> Support<V> support(String), V can't be inferred from the argument, and the chained .add(..) blocks target typing — the witness is required. FileRulesRecipes causes the fourth by rewriting new FileOutputStream(..) into Files.newOutputStream(..) where the variable is declared FileOutputStream.

CI never caught these because rewriteDryRun only reports — it never compiles what it proposes.

2. JavaUtilAPIs breaks the Gradle configuration cache.

Its MigrateCollectionsEmpty* rules swap Collections.emptyMap()/emptyList() for Map.of()/List.of(). Where those land in Gradle extension state, they no longer survive the round-trip:

Could not load the value of field `stepsInternalRoundtrip` of task `:spotlessKotlin`
> java.lang.reflect.InvocationTargetException

Bisected to one line in BaseKotlinExtension#ktlint; reverting that single file turns IsolatedProjectTest green again. The same rewrite appears 46× across the tree — the Kotlin path just happens to be the only one with a test covering it.

3. OrderImports permanently fights Spotless.

spotless.importorder puts catch-all imports last (5=); OpenRewrite puts them before com.diffplug:

 import javax.annotation.Nullable;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
 import com.diffplug.spotless.ForeignExe;
-
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

rewriteRun moves it, spotlessApply moves it back, forever. It fired 32× in the 2026-08-12 run too.

Both offenders in (1) and (3) are nested inside composite recipes, so they can't be disabled individually — the parent has to go.

This PR

Disables the 7 recipes needed to reach zero findings, each annotated inline with its reason. 44 recipes stay active.

No source changes: rewriteDryRun now exits 0 against an unmodified tree, so the job goes green on content already on main.

Verification

All three steps of the workflow pass locally:

Step Result
assemble -Derror-prone=true pass
rewriteDryRun pass — 0 files flagged (was 85)
:lib-extra:verifyEclipseJdtLockfiles pass

I also confirmed the prune is minimal — re-enabling EqualsAvoidsNull and UnnecessaryExplicitTypeArguments individually puts the job straight back to red, so all 7 are load-bearing.

Unrelated finding

gradle/error-prone.gradle reads getenv('error-prone') (an environment variable), but the workflow passes -Derror-prone=true (a system property). That step has never actually enabled Error Prone. Left alone here — fixing it likely surfaces a fresh pile of findings and deserves its own PR.

🤖 Generated with Claude Code

`Scheduled Cleanup` has failed every weekly run since at least 2026-06-03.
The failing step is `rewriteDryRun`, which fails by design when recipes
would make changes. It was never an unattended backlog -- running
`rewriteRun` does not fix it, and applying its output is not safe.

Three findings, all verified locally:

1. Two recipes emit code that does not compile.
   - UnnecessaryExplicitTypeArguments strips the witness from
     Jvm.<String>support(NAME). `support` is `static <V> Support<V>
     support(String)`, so V cannot be inferred from the argument and the
     chained .add(..) blocks target typing -- the witness is required.
     3 files, "Support<Object> cannot be converted to Support<String>".
   - FileRulesRecipes rewrites `new FileOutputStream(..)` into
     `Files.newOutputStream(..)` where the variable is declared
     FileOutputStream. 1 file.
   CI never caught either, because rewriteDryRun only reports; it never
   compiles the result.

2. JavaUtilAPIs breaks the Gradle configuration cache. Its
   MigrateCollectionsEmpty* rules swap Collections.emptyMap()/emptyList()
   for Map.of()/List.of(). Where those values land in Gradle extension
   state they no longer survive the configuration-cache round-trip:

     Could not load the value of field `stepsInternalRoundtrip`
     of task `:spotlessKotlin`
     > java.lang.reflect.InvocationTargetException

   Bisected to BaseKotlinExtension#ktlint; reverting that one file turns
   IsolatedProjectTest green again. The same rewrite appears 46x across
   the tree, only the Kotlin path has a test covering it.

3. CommonStaticAnalysis bundles OrderImports, which permanently disagrees
   with gradle/spotless.importorder about where catch-all imports go
   (spotless puts `5=` last, OpenRewrite puts them before com.diffplug).
   rewriteRun moves them, spotlessApply moves them back, forever. It
   fired 32x in the 2026-08-12 run too.

Both offenders in 1 and 3 are nested inside composite recipes, so they
cannot be disabled individually -- the parent has to go.

Disables the 7 recipes needed to reach zero findings, each with the
reason inline. 44 recipes stay active. No source changes: `rewriteDryRun`
now exits 0 against an unmodified tree, so the job goes green on content
that is already on main.

Verified: all three steps of the workflow pass locally -- `assemble
-Derror-prone=true`, `rewriteDryRun` (0 files flagged), and
`:lib-extra:verifyEclipseJdtLockfiles`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@nedtwigg
nedtwigg merged commit 526b575 into main Aug 20, 2026
36 checks passed
@nedtwigg
nedtwigg deleted the chore/openrewrite-green branch August 20, 2026 17:55
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