Skip to content

fix(docker): resolve toolchain versions at build time instead of pinning#125

Merged
GordonBeeming merged 3 commits into
mainfrom
gb/toolchain-latest-at-build
Jun 29, 2026
Merged

fix(docker): resolve toolchain versions at build time instead of pinning#125
GordonBeeming merged 3 commits into
mainfrom
gb/toolchain-latest-at-build

Conversation

@GordonBeeming

Copy link
Copy Markdown
Owner

Problem

The post-merge Build and Publish run on main failed on Build java (run 28349443241): the Eclipse JDT language server download 404'd. It was pinned to a milestone URL (JDTLS_VERSION=1.43.0), and Eclipse deletes old milestones, so the pin was guaranteed to rot.

The same hard-pinned pattern was used for Go, Maven, Gradle, and PlantUML. Those don't 404 (their hosts keep archives), but they silently go stale and need manual bump PRs.

Fix

.NET already avoids this — dotnet{8,9,10}.Dockerfile resolve the latest SDK at build time via dotnet-install.sh --channel. This applies the same build-time-latest, optionally-pinnable pattern to the remaining toolchains, so generated Dockerfiles no longer carry version numbers and the rot can't recur.

Tool Resolve mechanism (verified live)
JDTLS stable snapshots/jdt-language-server-latest.tar.gz symlink
Go go.dev/VERSION?m=text
Gradle services.gradle.org/versions/current
PlantUML GitHub latest-release unversioned asset
Maven latest stable 3.9.x from the dlcdn.apache.org listing — not maven-metadata <release>, which is currently 4.0.0-rc-5 (a release candidate)

Each tool keeps an optional pin ARG (GOLANG_VERSION, MAVEN_VERSION, GRADLE_VERSION, JDTLS_URL, PLANTUML_URL) defaulting to "resolve latest", mirroring DOTNET_SDK_N_VERSION. Every resolve step guards against an empty result (test -n) so a failed lookup fails the build loudly instead of producing a broken image.

Notes

  • Gradle jumps 8.12 → 9.x on first build. These are dev/agent images and Gradle is backward-tolerant; pin via GRADLE_VERSION build-arg if any image needs to stay on 8.x.
  • Maven stays on stable 3.9.x by design; the listing filter excludes the Maven 4 RCs. Widen it deliberately when Maven 4 GAs.
  • Reproducibility tradeoff is accepted: builds days apart can pull different tool versions; the pin ARGs are the escape hatch.

Test plan

  • pwsh docker/generate-dockerfiles.ps1 regenerates clean; only Dockerfile.java + Dockerfile.golang change among main-tracked generated files (the snippets feed only those two images on main).
  • Every resolve URL confirmed live (200 / valid JSON); Maven filter yields 3.9.16, not the 4.0.0-rc-5 RC.
  • Real proof is the Build * image jobs in this PR's publish pipeline — each snippet ends with a RUN … --version smoke check (go version; java --version && mvn --version && gradle --version && plantuml -version), so a bad resolve fails the image build. Green Build java + Build golang is the signal.

🤖 Generated with Claude Code

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request updates the Dockerfiles and snippets for Go and Java to dynamically resolve the latest stable versions of Go, Maven, Gradle, PlantUML, and Eclipse JDTLS at image-build time, while still allowing version pinning via build arguments. The review feedback suggests several improvements to make the build process more robust and consistent: using the Apache archive URL instead of the CDN mirror for Maven downloads to prevent 404 errors when pinning older versions, stripping the leading 'go' prefix from the Go version for better backward compatibility, and simplifying the Gradle version resolution logic using shell parameter expansion instead of an if/then/fi block.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread docker/snippets/java.Dockerfile Outdated
Comment thread docker/generated/Dockerfile.java Outdated
Comment thread docker/snippets/golang.Dockerfile Outdated
Comment thread docker/generated/Dockerfile.golang Outdated
Comment thread docker/snippets/java.Dockerfile Outdated
Comment thread docker/generated/Dockerfile.java Outdated
@GordonBeeming GordonBeeming marked this pull request as ready for review June 29, 2026 07:43
Copilot AI review requested due to automatic review settings June 29, 2026 07:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates Docker build snippets (and regenerated Dockerfiles) to resolve several toolchain versions at build time rather than hard-pinning versions that can go stale (notably Eclipse JDTLS milestone URLs).

Changes:

  • Switch JDTLS install to use the stable jdt-language-server-latest.tar.gz snapshots symlink (with an optional JDTLS_URL pin).
  • Resolve Maven (stable 3.9.x), Gradle (current release), PlantUML (GitHub latest asset), and Go (go.dev current) at image build time, with optional pin build args.
  • Regenerate docker/generated/* to reflect updated snippets.

Reviewed changes

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

Show a summary per file
File Description
docker/snippets/lsp-java.Dockerfile Moves JDTLS download from pinned milestone tarball to the snapshots “latest” symlink with optional URL pin.
docker/snippets/java.Dockerfile Resolves Maven/Gradle/PlantUML at build time and updates install logic accordingly.
docker/snippets/golang.Dockerfile Resolves Go version at build time via go.dev/VERSION?m=text with optional pin arg.
docker/generated/Dockerfile.java Regenerated output reflecting updated Java snippet resolution logic and JDTLS URL arg.
docker/generated/Dockerfile.golang Regenerated output reflecting updated Go snippet resolution logic.

Comment thread docker/snippets/java.Dockerfile Outdated
Comment thread docker/snippets/golang.Dockerfile

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d94390e755

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread docker/snippets/golang.Dockerfile
Comment thread docker/snippets/java.Dockerfile Outdated
GordonBeeming and others added 3 commits June 29, 2026 18:01
The Build java job 404'd because the Eclipse JDT language server was pinned to
a milestone URL, and Eclipse deletes old milestones. The same pinned-version
pattern applied to Go, Maven, Gradle, and PlantUML — they don't 404 but go
stale and need manual bumps.

Mirror the .NET snippets (which resolve latest-in-channel at build time): each
tool now resolves its current version during docker build, with an optional ARG
to pin. Generated Dockerfiles no longer carry version numbers, so the version
rot can't recur.

- JDTLS: download the stable snapshots/jdt-language-server-latest.tar.gz symlink
- Go: resolve from go.dev/VERSION
- Gradle: resolve from services.gradle.org/versions/current
- PlantUML: GitHub latest-release unversioned asset
- Maven: latest stable 3.9.x from the dlcdn listing (maven-metadata <release> is
  a Maven 4 RC, which we don't want)

Each resolve step guards against an empty result so the build fails loudly
rather than producing a broken image.

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: GitButler <gitbutler@gitbutler.com>
- Maven: download from archive.apache.org (keeps all releases) while still
  resolving the latest from the dlcdn listing, so a pinned older MAVEN_VERSION
  doesn't 404 on dlcdn (which prunes old versions).
- Go: strip a leading 'go' from the resolved/pinned version and re-prepend it,
  so GOLANG_VERSION accepts either '1.26.3' or 'go1.26.3'.
- Gradle: use ${GRADLE_VERSION:-...} parameter expansion for consistency with
  the Go and Maven snippets.

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: GitButler <gitbutler@gitbutler.com>
…-args

Resolving the version inside the image RUN doesn't survive the registry layer
cache: the instruction text is static, so BuildKit reuses the cached layer and
never re-runs the curl — images would freeze at whatever version was first
cached (caught in review by chatgpt-codex-connector).

Resolve go/maven/gradle/jdtls/plantuml in the prepare-versions job (same place
the dotnet SDK versions are resolved) and pass them as build-args on the golang
and java image matrix entries. The resolved value is now part of the layer cache
key, so a new version busts the cache and rebuilds — exactly how the dotnet
images already stay current. The in-Dockerfile resolution stays as the fallback
for local dev-build.sh, which passes no build-args.

Also convert the matrix build_args to multi-line YAML block scalars for
readability (the Prepare build args step's echo -e handles them unchanged).

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: GitButler <gitbutler@gitbutler.com>
@GordonBeeming GordonBeeming force-pushed the gb/toolchain-latest-at-build branch from de142e9 to dbdb3a3 Compare June 29, 2026 08:26
@GordonBeeming GordonBeeming merged commit d59cd5e into main Jun 29, 2026
33 checks passed
@GordonBeeming GordonBeeming deleted the gb/toolchain-latest-at-build branch June 29, 2026 08:33
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.

2 participants