feat: Add maven jib build support#596
Conversation
Signed-off-by: Qi Hu <qi.hu@broadcom.com>
Signed-off-by: Qi Hu <qi.hu@broadcom.com>
Signed-off-by: Qi Hu <qi.hu@broadcom.com>
- Add missing copyright header to jib.go - Update errcheck exclude for PrefixWriter - Handle returned errors in git_test.go Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Qi Hu <qi.hu@broadcom.com> Co-authored-by: Cursor <cursoragent@cursor.com>
- Fix line length limits (under 80 characters) across docker, jib, and built images. - Add package-level comment and document exported fields/functions in jib and config. - Fix redundant import aliases and import shadowing of package name maven. - Remove unused global regexp variable ImageID. Signed-off-by: Qi Hu <qi.hu@broadcom.com> Co-authored-by: Cursor <cursoragent@cursor.com>
- Remove extra empty lines at the start of blocks in jib.go and built.go - Replace unnecessary fmt.Errorf with errors.New in jib.go - Add missing exported comment to NewBuiltImage in built.go Signed-off-by: Qi Hu <qi.hu@broadcom.com> Co-authored-by: Cursor <cursoragent@cursor.com>
- Create a `BuildersOpts` struct to group the builder dependencies. - Update `NewBuiltImage` in built.go to accept `BuildersOpts` instead of 10 individual parameters, resolving the argument-limit (max 8) linter error. - Update `Factory.New` in factory.go to construct and pass `BuildersOpts`. Signed-off-by: Qi Hu <qi.hu@broadcom.com> Co-authored-by: Cursor <cursoragent@cursor.com>
- Wrap the function signature for `Jib.Run` to keep the line length below the 80 characters limit enforced by the revive linter. Signed-off-by: Qi Hu <qi.hu@broadcom.com> Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Pull request overview
Adds first-class Maven/Jib build support to kbld so images can be built from Maven projects (via Jib) similarly to existing builders (Docker, Bazel, Pack, Ko, etc.).
Changes:
- Introduces a Maven/Jib builder and wires it into the image build selection flow.
- Extends config to allow
sources[].maven.runoptions. - Adds a Maven “helloworld” sample under e2e assets and a new example manifest for local Maven builds.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| test/e2e/assets/simple-app/helloworld/src/main/java/example/HelloWorld.java | Adds a minimal Java entrypoint for the Maven/Jib sample app. |
| test/e2e/assets/simple-app/helloworld/pom.xml | Adds a Maven project configured with the Jib Maven plugin. |
| pkg/kbld/image/git_test.go | Adjusts env var and Close handling to satisfy errcheck expectations. |
| pkg/kbld/image/factory.go | Wires the Maven/Jib builder into the image factory construction. |
| pkg/kbld/image/built.go | Adds Maven/Jib as a build source option and routes builds through the new builder. |
| pkg/kbld/config/config.go | Extends Source with a Maven field for Jib configuration. |
| pkg/kbld/config/config_jib.go | Defines config structs for Jib run options. |
| pkg/kbld/builder/maven/jib.go | Implements the Maven/Jib builder execution and Docker retagging. |
| pkg/kbld/builder/docker/docker.go | Adds command logging for docker inspect. |
| hack/errcheck_excludes.txt | Updates errcheck excludes for the logger writer type rename. |
| examples/simple-app-build-local-mvn/build.yml | Adds a new example manifest for building a local Maven/Jib-backed image. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| cmdArgs := []string{ | ||
| "compile", | ||
| "jib:dockerBuild", | ||
| "-Dimage=" + targetImage, | ||
| "-Djib.allowInsecureRegistries=true", | ||
| } |
There was a problem hiding this comment.
Our downstream launch tool currently relies on this being enabled by default. We can look into making this configurable in a follow-up coordinated change.
| // Run executes the Maven Jib build. | ||
| func (b *Jib) Run(image, directory string, | ||
| opts config.SourceJibRunOpts) (ctlbdk.TmpRef, error) { | ||
| prefixedLogger := b.logger.NewPrefixedWriter(image + " | ") |
There was a problem hiding this comment.
This e2e test will require mvn available in the CI runner, I will need more information, we can skip this I believe.
There was a problem hiding this comment.
The file that needs to be changed to install mvn is https://github.com/carvel-dev/kbld/blob/develop/hack/Dockerfile.dev. Give it a look and see if there is an easy way to add the Java and Maven environment.
There was a problem hiding this comment.
Done! Added default-jdk-headless and maven to hack/Dockerfile.dev. I also added a full E2E test suite in test/e2e/build_maven_jib_test.go and verified that Jib image building compiles and works successfully inside this environment. To completely resolve the race condition, I also updated the builder to build to a unique random temporary tag first before retagging.
joaopapereira
left a comment
There was a problem hiding this comment.
The code as a whole looks good, but I would like to see some e2e tests. Take a look at https://github.com/carvel-dev/kbld/blob/develop/test/e2e/build_pack_test.go to make sure we have some assurance that this feature does not break in the future.
Made some form suggestions, mainly around imports and naming, with a NIT that I do not have a strong opinion about; I leave that to you.
My main concern is the fact that we build it and then ask the registry what the SHA is; this can cause race conditions or even malicious behavior.
| if err := cmd.Run(); err != nil { | ||
| _, _ = prefixedLogger.Write([]byte(fmt.Sprintf( | ||
| "error: %s\n", err))) | ||
| return ctlbdk.TmpRef{}, err | ||
| } | ||
|
|
||
| inspectData, err := b.docker.Inspect(targetImage) |
There was a problem hiding this comment.
This is somewhat a race condition where if 2 builds are happening at the same time for the same image and no tags are provided, we do not know what image SHA we will get back. This might be a bit of a corner case, but I am not 100% sure I like this approach.
In other builders, we read the logs of the building tool and parse it. It may be more brittle if the verbiage changes between versions, but at least we know we tag the correct SHA.
Does maven output from jib provide the SHA in the logs?
There was a problem hiding this comment.
The race only hits the latest fallback path — when a tag is set (our consumer always passes a unique one) the inspect can't collide. Ok to leave for now and revisit parsing the SHA from logs as a follow-up?
There was a problem hiding this comment.
Today, your consumer does, but if for some reason they stop doing it, we are relying on other people to keep consistency in our tools, which is concerning. In a world where we have multiple teams or eventually multiple agents doing work on a code base at any given time will only increase the possibility of this becoming an issue.
Another option we can use is the same technique we have for docker images building where we generate a temporary tag inside kbld code and then we use that tag, check https://github.com/carvel-dev/kbld/blob/develop/pkg/kbld/builder/docker/docker.go#L63, afterwards we also do the inspect and ensure that the image is tagged with the tag the user asks for.
There was a problem hiding this comment.
where if 2 builds are happening at the same time for the same image and no tags are provided
Is this considered a poor build practice, or is this a common industry standard and we should handle that case? @joaopapereira
There was a problem hiding this comment.
This is an issue with the current design. We cannot predict what people will do with kbld, also this can also happen if someone is pushing the same tag to the repository.
What I want to make sure is that we cross our T's and dot our I's, the build already fail for a number of different reasons unrelated to kbld so we should make sure that kbld does behave well. Also this is not such a big change in the current code that we can do to ensure no randomess happens when building
There was a problem hiding this comment.
I went ahead and implemented the robust solution for this to completely eliminate any possible race condition: we now generate a unique, random temporary tag (via ctlb.TagBuilder{}) to run the maven build against, inspect that specific temporary tag, and then retag it to the desired user tag and stable/digest references.
- Update copyright headers to 2026 in jib.go and config_jib.go - Group imports (stdlib first) and use ctlbmvn alias for the maven builder package in jib.go, built.go, and factory.go - Use value instead of pointer when resolving the image tag in jib.go - Fix simple-app-build-local-mvn example: rename bazel-derived resource names/labels to mvn and drop the unsupported maven.run.name field Signed-off-by: Qi Hu <qi.hu@broadcom.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Thanks @joaopapereira , could you help me confirm that CI env have maven setup ahead so I could add some tests for these changes. |
- Refactor Jib builder to build to a unique, random temporary tag first, then inspect and tag back to the target/stable tags, eliminating any potential tag/SHA race conditions with concurrent builds. - Update hack/Dockerfile.dev to use default-jdk-headless to ensure reliable Java environment installation across different Debian versions. - Document the optional tag property inside simple-app-build-local-mvn example. - Add and integrate the new Maven Jib E2E test suite. Signed-off-by: Qi Hu <qi.hu@broadcom.com> Co-authored-by: Cursor <cursoragent@cursor.com>
- Wrap lines exceeding the 80-character boundary enforced by revive under the 'e2e' build tag config. Signed-off-by: Qi Hu <qi.hu@broadcom.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Qi Hu <qi.hu@broadcom.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Qi Hu <qi.hu@broadcom.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Qi Hu <qi.hu@broadcom.com> Co-authored-by: Cursor <cursoragent@cursor.com>
|
@joaopapereira Update on the recent CI failures in the By placing the I've just pushed a commit that moves the Java app into its own dedicated directory at |
Signed-off-by: Qi Hu <qi.hu@broadcom.com> Co-authored-by: Cursor <cursoragent@cursor.com>
|
I was looking at cnb in docker hub and the latest sha is sha256:17ea21162ba8c7717d3ead3ee3836a368aced7f02f2e59658e52029bd6d149e7 not sure if that will be enough but they did not update the image for 3 years. can you check with that image |
Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Qi Hu <qi.hu@broadcom.com> Co-authored-by: Cursor <cursoragent@cursor.com>
|
@joaopapereira I've updated the pack builder image to the one you suggested ( |
Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Qi Hu <qi.hu@broadcom.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Qi Hu <qi.hu@broadcom.com> Co-authored-by: Cursor <cursoragent@cursor.com>
|
@joaopapereira The suggested builder image ( Because we've already fixed the root cause of the previous 404 error (by moving I've reverted the image SHA back to the original in the test. The CI should hopefully pass cleanly now. |
|
@BulldromeQ, thanks for the long feedback loop here. I am happy that we got to the current point. |
Summary
This pull request introduces support for Maven Jib builds, upstreaming the changes developed in the
vishrantgupta/kbldfork.The changes include:
pkg/kbld/builder/maven/jib.go).simple-app-build-local-mvn.