Skip to content

Build and run the examples from a fresh clone on the runner's own JDK - #137

Merged
jwrosewell merged 5 commits into
rcfrom
ci/examples-fresh-clone
Nov 15, 2026
Merged

jwrosewell merged 5 commits into
rcfrom
ci/examples-fresh-clone

Conversation

@jwrosewell

@jwrosewell jwrosewell commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Two gaps against the examples rule, that every example builds and runs both from a fresh clone and against the published packages, found in the audit of the examples on 13 November.

  1. CI never ran an example from a fresh clone. ci/fetch-assets.ps1 puts every data file in place before any test, so no run ever took the path where an example finds only the .link for its free data file and downloads it, and nothing ran the examples the way AGENTS.md tells a person to.
  2. CI never built the examples against the packages on Maven Central. A pull request build uses the reactor with the dev profile (ci/run-integration-tests.ps1 lines 29 to 33), and Publish tests them against the versions it has just built.

Building the examples the way AGENTS.md says, on the JDK the runner has, showed a third gap.

  1. The examples did not build on Java 25. In the runs below ubuntu-latest ran the ubuntu-26.04 image, whose default JDK is 25.0.5. The examples' resource check runs PMD 7.7.0, through maven-pmd-plugin 3.26.0, which cannot read Java 25 class files ("Unsupported class file major version 69") and fails the build with a StackOverflowError, so mvn -pl console -am package -DskipTests stops before it makes a jar. Java 25 is the current long-term release, so anyone who clones the repository with it today cannot build an example.

What changed and why

  • .github/workflows/examples-fresh-clone.yml checks the repository out with its submodules, as git clone --recurse-submodules does, prints the runner's own Java and Maven, and for each product builds the console examples in its examples folder with mvn -pl console -am package -DskipTests, exactly as AGENTS.md says. Without the dev profile the examples use the packages published on Maven Central (device-detection.version and ip-intelligence.version are 4.5.130 in the examples' poms). It then runs GettingStartedOnPrem from the repository root with no arguments or settings, and fails unless it exits 0, logs that its free data file "is missing, so it is being downloaded", and prints Results:. It runs on Ubuntu, Windows and macOS on each push to main and rc, daily at 04:30 UTC and by hand, and on Ubuntu and Windows for a pull request that changes examples, cxx or the workflow, because the organisation's macOS runners are shared. It sets up no JDK, so it builds with whatever the runner has, as the 13 November policy on toolchains asks.
  • maven-pmd-plugin 3.28.0 in the two examples poms (examples/device-detection/pom.xml and examples/ip-intelligence/pom.xml), which runs PMD 7.17.0 (its pom's pmdVersion), so the resource check reads Java 25 classes. The examples are not published packages, so nothing is released for it.
  • Each free data file is downloaded once a run (d8ffbf40), under the rule of 22:23 UTC on 14 November that in CI the free data files are fetched once and a test of the download itself is the one place that still downloads. Before, every job let its example download its file, so a run fetched the 455 MB IP Intelligence Lite file two or three times. Now an Ubuntu job for each product tests the download as before and keeps the file in the Actions cache, keyed by the file's link, and the Windows and macOS jobs restore it, with fail-on-cache-miss, and fail if their example downloads it again (examples-fresh-clone.yml). The run step moves to ci/run-fresh-clone-example.ps1, which both jobs share, with -ExpectDownload saying which of the two each job checks, and ci/README.md and AGENTS.md say so.
  • AGENTS.md (118b2d39 and c2de14e6). Its pitfall "What CI does not test", which said CI never runs the console example jars, becomes "What CI tests" and says that the workflow does what "Run the examples" says, and the prerequisites say CI also builds and runs the examples on the JDK each runner has.

Tests

The new workflow is the test. It ran first on a throwaway branch holding rc and the workflow alone, then on one holding both commits, each with the branch added to the workflow's push trigger so it ran with the full matrix.

Run Commit Ubuntu 26.04 (JDK 25.0.5) Windows (JDK 17.0.21) macOS 26 arm64 (JDK 21.0.13)
Red, 43584327980 6c36acd, the workflow alone both products fail to build, pmd:3.26.0:check both pass both pass
Green, 43584351849 7964dcd, with maven-pmd-plugin 3.28.0 both pass both pass both pass

In the red run the Ubuntu builds stopped with StackOverflowError and "Unsupported class file major version 69" in the first module's resource check, and on Windows and macOS each example logged its free file as "is missing, so it is being downloaded", saved it (51Degrees-LiteV4.1.hash, and 51Degrees-LiteV41.ipi at 455 MB) and printed its results. In the green run all six did the same, and on Ubuntu the resource check ran as pmd:3.28.0:check on JDK 25.0.5. The pushes ran macOS on macos-latest, which was the macOS 26 arm64 image, so the Intel image was not tried.

The pull request's own run of the workflow on 118b2d3, 43586613934, passed on Ubuntu and Windows.

The download once a run, d8ffbf4. Red 43666775032 ran the head with the cache restore taken out of the Windows job, on a throwaway branch, for Device Detection. The Ubuntu job downloaded its file and passed, and the Windows job's example logged "'51Degrees-LiteV4.1.hash' is missing, so it is being downloaded", and the step failed with "The example downloaded its data file, which should have come from the cache." Green is the pull request's own run of the workflow on d8ffbf4, 43666745115, where both Ubuntu jobs downloaded and passed and both Windows jobs took the file from the cache and passed.

Before that, two throwaway runs built the examples on ubuntu-latest with its default JDK 25.0.5, with no other change. Run 43583839259 on rc failed both products in pmd:3.26.0:check (StackOverflowError, "Unsupported class file major version 69"), and run 43583848187 with maven-pmd-plugin 3.28.0 built both.

Full build

Run 43586620228 built 118b2d3 merged with rc (1c99b72) on nine configurations, Ubuntu x64 with Java 8, 11, 17 and 21, Ubuntu arm64 with Java 17, and Windows with Java 8, 11, 17 and 21, and every job passed. In each of the nine the examples' resource check ran as pmd:3.28.0:check and passed, so maven-pmd-plugin 3.28.0 also runs on Java 8. Each of its ten Setting 'PullRequestSha' lines names 118b2d3, and its Configure job printed "Left out 6 macOS entries". macOS was left out of this draft's full build under the 9 November decision. The rc head is built with macOS before it merges into main, and this workflow runs on macOS on each push to rc.

The head, d8ffbf4, adds two commits to 118b2d3. c2de14e6 changes wording in AGENTS.md, and d8ffbf4 changes this workflow, the script it runs, ci/README.md and AGENTS.md. Neither changes package or example code, so this build stands, under James Rosewell's decision of 11:35 UTC on 12 November that a change to CI scripts and their notes needs no full build of its own. Every quick check on d8ffbf4 passed, being the fresh clone workflow's four jobs, the CI script tests on Ubuntu and Windows, the environment variable names check, the UTM link lint and the rc into main check.

Base branch

rc at ceab088. The full build merged 118b2d3 with rc at 1c99b72, and a trial merge of the head with rc at 2eebbff is clean.

What remains

  • The library trees (pipeline, device-detection, ip-intelligence and location) also use maven-pmd-plugin 3.26.0, so they do not build on Java 25 either. The test jobs choose Java 8, 11, 17 and 21, but the nightly's package build uses the runner's default JDK, so main's nightly stops there. #140 moves the four trees to 3.28.0 and fixes the two other places a Java 25 build stops. It changes different files from this draft, so the two merge in either order.
  • The workflow runs only the two getting started examples. The others run with no settings in ExamplesWithoutSettingsTest, against the data files CI provides.

A workflow clones the repository with its submodules, builds each
product's console examples against the packages on Maven Central as
AGENTS.md says, with the JDK and Maven the runner has, and runs the
getting started example from the repository root with no settings. It
checks the example exits 0, downloads its free data file, and prints
results.
…classes

PMD 7.7.0, which maven-pmd-plugin 3.26.0 runs, cannot read the class
files of Java 25, so building the examples on a JDK 25 runner failed in
the resource check. maven-pmd-plugin 3.28.0 runs PMD 7.17.0.
The pitfall said CI never runs the console example jars, which the new
workflow now does on the runner's own JDK against the published
packages.
The pitfall sits under Pitfalls, so 'this section' read as the pitfalls.
It now links Run the examples.
Every job of the workflow let its example download the free data file, so
a run fetched the 455 MB IP Intelligence Lite file two or three times. The
Ubuntu job now tests the download and saves the file in the cache, keyed
by the file's link, and the Windows and macOS jobs restore it and fail if
their example downloads it again. The run step moves to
ci/run-fresh-clone-example.ps1 so both jobs share it.
@jwrosewell
jwrosewell marked this pull request as ready for review November 15, 2026 04:32
@jwrosewell
jwrosewell merged commit 30e8df6 into rc Nov 15, 2026
9 checks passed
@jwrosewell
jwrosewell deleted the ci/examples-fresh-clone branch November 15, 2026 04:32
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