Skip to content

fix: use maven-metadata.xml to look up latest test framework version#1868

Merged
wenytang-ms merged 4 commits into
mainfrom
fix/use-maven-metadata-for-version
Jun 3, 2026
Merged

fix: use maven-metadata.xml to look up latest test framework version#1868
wenytang-ms merged 4 commits into
mainfrom
fix/use-maven-metadata-for-version

Conversation

@wenytang-ms
Copy link
Copy Markdown
Contributor

@wenytang-ms wenytang-ms commented Jun 2, 2026

Problem

search.maven.org's Solr index was frozen as part of Sonatype's migration
to the new Central Portal — migration.json returns {"successful":[], "failed":[]} for every artifact we ship, so the legacy endpoint silently
stopped returning new releases.

For junit-platform-console-standalone that left the extension picking
the milestone build 1.13.0-M3 (last entry in the stale index) instead
of a real stable release, breaking "Enable Java Tests" on unmanaged
folders. See #1866 for the full report.

Change

UI - User select Test Framework

image

Switch the data source (fix)

Replace the search.maven.org Solr lookup with
repo1.maven.org/.../maven-metadata.xml, the Maven 2 metadata file that
every artifact on Maven Central is required to publish and that is always
in sync with what Central actually serves. This removes the dependence on
a deprecated, frozen index.

Split JUnit Jupiter 5 and JUnit Jupiter 6 by version line

junit-platform-console-standalone now publishes two coexisting release
lines under the same GAV — 1.x for Jupiter 5 and 6.x for Jupiter 6 —
and <release> tracks the globally newest stable (currently 6.1.0).
Without a per-line constraint, picking JUnit Jupiter 5 would still
resolve to a 6.x jar.

The QuickPick now exposes two entries:

Menu label Platform line Default fallback
JUnit Jupiter 5 1.x 1.14.4
JUnit Jupiter 6 6.x 6.1.0

To support this, IArtifactMetadata gains an optional versionLine
field. When set, getLatestVersion() / parseLatestStableVersion()
skip the <release> shortcut and scan <versions> for the newest
stable version whose leading segment matches the requested line
('1' matches 1.14.4 but not 10.x or 11.x).

Add regression coverage

Layer File Catches
Integration test/unmanaged-folder-suite/enableTests.test.ts Production code path: tightened to require a stable 1.x junit-platform-console-standalone-*.jar after enableTests(JUnit5), so any silent re-introduction of -M3 / -RC1 builds or accidental drift back to the 6.x line fails CI.
Unit test/suite/testDependenciesCommands.test.ts XML parser invariants: <release> happy path, fallback to <versions> when <release> is a pre-release (mirrors slf4j-api shape), and the new per-line cases — selecting newest stable in the requested line, ignoring an out-of-line <release>, skipping pre-releases inside the line, returning undefined when the line has nothing stable, and using leading-segment match (not prefix).
Health check scripts/checkVersionSources.js + .github/workflows/health-check.yml Future Sonatype breakage: weekly cron + PR/push runs that HEAD every artifact we ship (now probes both the 1.x and 6.x console-standalone lines independently) and opens / updates a tracking issue on scheduled failure.

Known follow-up: JUnit Jupiter 5 + current vscode-java

There is a separate upstream JDT-LS dispatch bug that routes every
junit-platform-console-standalone jar through the new "JUnit 6" runner,
which reflectively requires APIs only present in Platform 6+. So on a
vscode-java build that still bundles the affected JDT-LS, picking
JUnit Jupiter 5 (1.x) will fail with NoClassDefFoundError: .../CancellationToken.

The upstream fix is merged (eclipse.jdt.ui#2910 / 17f8fa5d9f) and is
waiting on the eclipse.jdt.ls bump + the next redhat.java release.
Until then, affected users should pick JUnit Jupiter 6 or roll back
to an older redhat.java. #4396 tracks the rollout.

Closes

The previous implementation queried search.maven.org's Solr endpoint and
returned the `latestVersion` field. That index has been frozen since
around May 2025 (a side effect of the Sonatype migration to
central.sonatype.com), so the endpoint now serves stale data. For
example, the latest version it reports for
`junit-platform-console-standalone` is `1.13.0-M3` (a JUnit 5 milestone),
while the actual current stable on Maven Central is `6.1.0`. As a
result, `Enable Java Tests` ends up downloading either that milestone
or, after falling back, the hard-coded `1.9.3`.

Switch the lookup to the artifact's own `maven-metadata.xml` on
repo1.maven.org, which is the authoritative metadata maintained
alongside the artifact:

* Prefer the `<release>` tag (Maven's pointer to the latest non-snapshot
  version).
* Fall back to scanning `<version>` entries from newest to oldest for
  the first stable build.
* Pre-release qualifiers (`-M*`, `-RC*`, `-beta`, `-SNAPSHOT`, etc.) are
  rejected via `isStableVersion`.

Also bump the JUnit Jupiter `defaultVersion` from `1.9.3` to `6.1.0` so
the offline fallback matches a currently published stable.

Related to #1866

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread src/commands/testDependenciesCommands.ts
Add three layers of regression coverage so that a silent upstream change
to the Maven Central data sources used by the "Enable Java Tests" flow
cannot reappear unnoticed for a year (cf. #1866, where the legacy
search.maven.org Solr index was frozen and kept returning
1.13.0-M3 as the "latest" junit-platform-console-standalone).

1. Tighten the existing integration test in
   test/unmanaged-folder-suite/enableTests.test.ts so it only accepts
   a stable release jar (junit-platform-console-standalone-X.Y.Z.jar)
   instead of any filename containing "junit-platform-console-standalone".

2. Add a focused unit test for the XML parser
   (test/suite/testDependenciesCommands.test.ts) covering:
     - <release> being a stable version,
     - <release> being a milestone (fallback to <versions>),
     - <release> missing entirely,
     - newest <version> being a pre-release,
     - all entries being pre-releases (returns undefined),
     - malformed input.
   Exposed parseLatestStableVersion / isStableVersion via the existing
   exportedForTesting convention.

3. Add a CI health check (scripts/checkVersionSources.js +
   .github/workflows/health-check.yml) that, for every artifact the
   extension fetches from Maven Central, downloads maven-metadata.xml,
   parses what production would pick, and HEADs the resolved .jar URL.
   Runs on every PR/push and weekly via cron; the scheduled run opens
   (or comments on) a tracking issue labelled ci-health on failure.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the “Enable Java Tests” dependency download flow to determine the latest stable test framework versions from each artifact’s maven-metadata.xml (instead of the stale search.maven.org Solr index), and adds automated checks to prevent regressions/upstream drift.

Changes:

  • Switch latest-version resolution to repo1.maven.org/.../maven-metadata.xml, preferring <release> and falling back to scanning <version> entries for the newest stable version.
  • Bump the JUnit Platform Console Standalone offline fallback version to 6.1.0, and strengthen the unmanaged-folder E2E test to reject pre-release jars.
  • Add unit tests for the metadata parsing logic, plus a CI “health check” workflow + script to validate upstream metadata/jar availability.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/commands/testDependenciesCommands.ts Implements maven-metadata.xml-based latest stable version lookup and updates the JUnit fallback version.
test/unmanaged-folder-suite/enableTests.test.ts Tightens the E2E assertion to require a stable junit-platform-console-standalone-<digits>.jar.
test/suite/testDependenciesCommands.test.ts Adds unit tests for stable-version detection and metadata parsing behavior.
scripts/checkVersionSources.js Introduces a Node script to validate Maven Central metadata + jar URL health for required artifacts.
.github/workflows/health-check.yml Adds a PR/push/weekly workflow that runs the Maven Central health check and files an issue on scheduled failures.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/commands/testDependenciesCommands.ts Outdated
Comment thread src/commands/testDependenciesCommands.ts
Comment thread .github/workflows/health-check.yml
- getHttpsAsText: handle ClientRequest 'error' events (DNS / TLS /
  socket failures before a response) so the promise no longer hangs
  forever, and drain the response body on non-2xx instead of leaving
  the socket open. Accept any 2xx status, not just 200.
- getLatestVersion: include the underlying error message in the
  Error reported to telemetry so transient failures are diagnosable.
- health-check workflow: idempotently create the 'ci-health' label
  before opening / commenting on the tracking issue so that the
  scheduled-failure branch does not 422 when the label is missing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@wenytang-ms wenytang-ms requested a review from chagong June 3, 2026 02:42
Comment thread src/commands/testDependenciesCommands.ts
@wenytang-ms wenytang-ms force-pushed the fix/use-maven-metadata-for-version branch from db488a2 to 58fd772 Compare June 3, 2026 06:02
JUnit Platform now publishes two coexisting release lines under the same
GAV (1.x for Jupiter 5, 6.x for Jupiter 6), and <release> tracks the
globally newest stable, which is currently 6.1.0. Without a per-line
constraint, picking 'JUnit Jupiter 5' would still resolve to a 6.x jar.

This change splits the two menu entries to download what they advertise:

- Add an optional 'versionLine' field to IArtifactMetadata that asks
  getLatestVersion() to find the newest stable version whose leading
  segment matches a given string (with leading-segment match, so '1'
  does not accidentally match '10.x').
- parseLatestStableVersion() now skips the <release> shortcut when a
  versionLine is provided, since <release> may point outside the
  requested line.
- TestKind.JUnit5 -> versionLine '1' (defaultVersion '1.14.4').
- TestKind.JUnit6 -> versionLine '6' (defaultVersion '6.1.0').
- Unit tests cover: matching line, ignoring out-of-line <release>,
  skipping pre-releases inside the line, no-stable-in-line returns
  undefined, leading-segment vs prefix match.
- Tighten the unmanaged-folder integration test to require a 1.x jar
  for TestKind.JUnit5.
- Health check probes both the 1.x and 6.x lines independently.

Pairing with the upstream JDT-LS dispatch fix (eclipse.jdt.ui#2910 /
17f8fa5d9f), this restores the architecturally correct behaviour: each
menu entry installs the line it advertises. Users on a vscode-java build
that ships the buggy JDT-LS dispatch should pick 'JUnit Jupiter 6'
until that fix is released; #4396 tracks the upstream rollout.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@wenytang-ms wenytang-ms force-pushed the fix/use-maven-metadata-for-version branch from 58fd772 to 5763d0e Compare June 3, 2026 07:24
@wenytang-ms wenytang-ms merged commit 04d1702 into main Jun 3, 2026
5 checks passed
@wenytang-ms wenytang-ms deleted the fix/use-maven-metadata-for-version branch June 3, 2026 07:32
wenytang-ms added a commit that referenced this pull request Jun 4, 2026
Add a "JUnit Jupiter 6" entry to the framework picker and rename the
existing entry to "JUnit Jupiter 5". `TestKind.JUnit6` already exists
in the API and `getJarIds` already routes JUnit5 to the 1.x line and
JUnit6 to the 6.x line (PR #1868) — this PR is just the UI side of
that split so users can actually pick JUnit 6 from the QuickPick.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
wenytang-ms added a commit that referenced this pull request Jun 4, 2026
Add a "JUnit Jupiter 6" entry to the framework picker and rename the
existing entry to "JUnit Jupiter 5". `TestKind.JUnit6` already exists
in the API and `getJarIds` already routes JUnit5 to the 1.x line and
JUnit6 to the 6.x line (PR #1868) — this PR is just the UI side of
that split so users can actually pick JUnit 6 from the QuickPick.
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.

3 participants