Skip to content

Warn when unpinned recipe artifacts resolve from Maven Central - #1181

Open
timtebeek wants to merge 3 commits into
mainfrom
tim/issue-1180-draft-pr
Open

Warn when unpinned recipe artifacts resolve from Maven Central#1181
timtebeek wants to merge 3 commits into
mainfrom
tim/issue-1180-draft-pr

Conversation

@timtebeek

@timtebeek timtebeek commented Jul 28, 2026

Copy link
Copy Markdown
Member

What

When rewrite.recipeArtifactCoordinates asks for an OpenRewrite/Moderne recipe artifact with a dynamic version (LATEST, RELEASE, [6.0,7.0), …) and it is served by the real Maven Central, the plugin logs a warning pointing at the Code Genome Project:

[WARNING] These recipe artifacts resolve from Maven Central, which no longer receives new recipe releases:
[WARNING]     org.openrewrite.recipe:rewrite-testing-frameworks:LATEST resolved to 3.42.1
[WARNING] Newer recipe versions are published to the Code Genome Project; configure it in your repositories to stop resolving stale recipes.
[WARNING] See https://codegenomeproject.org/token for credentials and repository configuration.

Informational only — resolution is untouched and the build still succeeds.

Acceptance criteria

Criterion How it's met
Warn when recipe artifacts resolve from Maven Central and a newer version is expected on CGP A dynamic version actually served by Maven Central is exactly the "silently stale" case
Warning links to the docs page for getting CGP credentials Links to https://codegenomeproject.org/token
No warning through a configured repository, including an internal mirror Only repo.maven.apache.org / repo1.maven.org / repo2.maven.org count as Maven Central. Maven substitutes a mirror's id and URL into the project's repositories before resolution, so a mirror is reported under its own URL
No warning on explicitly pinned versions Only dynamic version selectors are considered

Alignment with the Gradle plugin

Shared with openrewrite/rewrite-gradle-plugin#459: the CodeGenomeProjectWarning class name, the warningFor(..) entry point returning @Nullable String, the CREDENTIALS_DOCS constant, the exact message text, the Maven Central host set, and the org.openrewrite/io.moderne group check. CodeGenomeProjectWarningTest and StaleRecipeArtifactIT mirror the Gradle plugin's CodeGenomeProjectWarningTest and StaleRecipeArtifactTest case for case.

Three deliberate divergences:

  1. Detection uses the repository the artifact actually came from, not the declared repository set. The Gradle PR notes that Gradle's ResolutionResult exposes no repository origin, so it falls back to inspecting declared repositories. Maven's ArtifactResult.getRepository() reports the serving repository — and, thanks to the enhanced local repository manager's _remote.repositories tracking, still does so for artifacts already in the local cache. That's strictly more precise, so I kept it.
  2. No "CGP is configured, therefore stay quiet" suppression. In Gradle that rule exists because a declared CGP repository makes the origin ambiguous. Maven has no such ambiguity, and the case it would suppress — CGP declared but Central still served the artifact, e.g. because Central is checked first or credentials are wrong — is a genuine stale-recipe situation worth reporting.
  3. The listed coordinate carries the version it resolved to (…:LATEST resolved to 3.42.1). Maven knows this at warning time; Gradle does not.

The dynamic-version selectors necessarily differ, since each matches its own build tool's syntax: LATEST/RELEASE/[/( here versus latest.*/+/ranges in Gradle.

Design notes / open questions

  • The issue suggested keying off "the last version published to Maven Central". I didn't hardcode a per-artifact version map — it needs upkeep on every artifact, and "dynamic version + served by Central" already identifies the same population without going stale itself. Same call as the Gradle PR; happy to switch if the known-final-version list is preferable.
  • Scope is rewrite.recipeArtifactCoordinates, which is what this plugin resolves itself. Recipe modules declared as plugin <dependencies> are resolved by Maven core before the mojo runs and are always pinned, so they fall outside both the hook point and the acceptance criteria. This matches the Gradle PR leaving the plugin's own bundled dependencies unchecked.
  • ArtifactResolver's constructor gained a Log parameter. Both call sites are in this repo.
  • Message wording and the docs URL want a review, and should land identically in both PRs.

Testing

  • CodeGenomeProjectWarningTest — 12 cases over the detection rule (dynamic selectors, Moderne groups, pinned versions, unrelated groups, internal mirror, CGP-served, transitive dependencies, non-remote repository).
  • StaleRecipeArtifactIT — itf integration tests asserting the warning appears on rewrite:discover for a LATEST coordinate and stays quiet for a pinned one. Both pass locally (~16s).
  • Also verified by hand against a scratch project with the plugin installed locally, before the ITs existed: the jar was already in the local repository and the origin was still correctly reported as Central, so the warning is not limited to cold caches. Separately confirmed that with a <mirror> of central configured, Maven reports the project's remote repositories as the mirror's id/URL, so the host check cannot match.

Recipe artifacts are now published to the Code Genome Project, so the
releases left behind on Maven Central go stale. Users without a CGP
repository configured still resolve successfully against Maven Central
and silently stop picking up newer recipe versions.

When a `rewrite.recipeArtifactCoordinates` entry with an unpinned version
(`LATEST`, `RELEASE`, or a range) in an `org.openrewrite` or `io.moderne`
group resolves from the real Maven Central, log an informational warning
pointing at the docs for configuring a download token. Resolution is
never blocked, and no warning is emitted for pinned versions or for
artifacts served by a configured repository or internal mirror.

Fixes #1180
Match the Gradle plugin's naming, message text, and credentials link so
both plugins report the same thing:

- CodeGenomeProjectWarning.warningFor(..), CREDENTIALS_DOCS
- the same multi-line message listing every stale recipe artifact
- https://codegenomeproject.org/token instead of the docs quickstart
- the same Maven Central host set and recipe group check

Maven-specific: each line is logged separately, since Maven only prefixes
the first line of a multi-line message with [WARNING]. The listed
coordinate also carries the version it resolved to, which Maven knows and
Gradle does not.

StaleRecipeArtifactIT mirrors the Gradle StaleRecipeArtifactTest.
@timtebeek
timtebeek marked this pull request as ready for review July 29, 2026 10:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

Warn when recipe artifacts resolve from Maven Central

1 participant