最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

gitlab - Is there a way to save build artifacts produced by Maven that can be passed to a later Maven execution? - Stack Overflo

programmeradmin1浏览0评论

I'm working on creating GitLab CI/CD pipeline components to provide the following processes:

  1. build an Java jar file (mvn compile)
  2. run tests (mvn test)
  3. deploy jar file to a registry (mvn deploy)

I want these to be separate jobs, so that a build failure is separate from a test failure. Also, there may be situations where there are no tests, so that job could be optional.

Based on my experience with Maven, even if I run mvn test by itself, it is still essentially running a compile before invoking any tests. I was hoping there was the capability to "save" the build artifacts from the build stage and make them available to the test stage, without having Maven basically recompiling everything. Similarly, I think it's also recompiling the code at the deploy stage (not 100% sure of that, though).

Does anyone know if this is possible with Maven?

My Rationale

GitLab CI/CD pipelines are arranged as a set of stages that run in order. There can be multiple jobs within a stage, or only one as the pipeline needs dictate. My idea is that I would have build, test, package and deploy stages where the following would happen.

build - run mvn clean compile. The job (and pipeline) fails if the job script (running Maven) fails. This would give developers the opportunity to fix the problems and re-commit.

test - run mvn test. Run tests and fail the job and pipeline if there are any test failures. Developers can address any issues and commit changes again. It would save time if it didn't compile the source code a second time and instead could be preserved from the build stage and used in this stage.

We also wanted to be able to "soft fail" the test stage if no tests were found (-DfailIfNoTests). The pipeline would not fail, however the pipeline highlights the test stage with a warning to alert developers that no tests were found and that they should consider creating some.

package - run mvn package. Package the compiled code into a Jar file, suitable for "deployment" to a GitLab package registry.

deploy - run mvn deploy. Push (via mvn deploy) the Jar file to a GitLab package registry. This is not a Maven repository.

Perhaps it makes more sense to combine the package and deploy stages together as one. Again, it would save time if either of these stages did not need to compile the code, but could utilize the artifacts created from the build stage.

I'm working on creating GitLab CI/CD pipeline components to provide the following processes:

  1. build an Java jar file (mvn compile)
  2. run tests (mvn test)
  3. deploy jar file to a registry (mvn deploy)

I want these to be separate jobs, so that a build failure is separate from a test failure. Also, there may be situations where there are no tests, so that job could be optional.

Based on my experience with Maven, even if I run mvn test by itself, it is still essentially running a compile before invoking any tests. I was hoping there was the capability to "save" the build artifacts from the build stage and make them available to the test stage, without having Maven basically recompiling everything. Similarly, I think it's also recompiling the code at the deploy stage (not 100% sure of that, though).

Does anyone know if this is possible with Maven?

My Rationale

GitLab CI/CD pipelines are arranged as a set of stages that run in order. There can be multiple jobs within a stage, or only one as the pipeline needs dictate. My idea is that I would have build, test, package and deploy stages where the following would happen.

build - run mvn clean compile. The job (and pipeline) fails if the job script (running Maven) fails. This would give developers the opportunity to fix the problems and re-commit.

test - run mvn test. Run tests and fail the job and pipeline if there are any test failures. Developers can address any issues and commit changes again. It would save time if it didn't compile the source code a second time and instead could be preserved from the build stage and used in this stage.

We also wanted to be able to "soft fail" the test stage if no tests were found (-DfailIfNoTests). The pipeline would not fail, however the pipeline highlights the test stage with a warning to alert developers that no tests were found and that they should consider creating some.

package - run mvn package. Package the compiled code into a Jar file, suitable for "deployment" to a GitLab package registry.

deploy - run mvn deploy. Push (via mvn deploy) the Jar file to a GitLab package registry. This is not a Maven repository.

Perhaps it makes more sense to combine the package and deploy stages together as one. Again, it would save time if either of these stages did not need to compile the code, but could utilize the artifacts created from the build stage.

Share Improve this question edited Feb 3 at 13:49 Joseph Gagnon asked Jan 31 at 17:21 Joseph GagnonJoseph Gagnon 2,1356 gold badges48 silver badges90 bronze badges 3
  • 1 First the life cycle phases up to compile will not create a jar file or any kind of packaging... that will be done later in the life cycle. The life cycle phase test is intended to run the unit tests... and using deploy life cycle will include previous cycle package will will produce the resulting jar files... If you just use test life cycle phase this will include previous life cycle phases including compile (check maven.apache./guides/introduction/…) – khmarbaise Commented Jan 31 at 20:28
  • 1 Furthermore to separate life cycle phases as you described does not make sense just call mvn deploy and everything will run as required in the order needed (see docs)... If tests fail the build will not continue to the next phases... if everything is recompiling everything there is something wrong... – khmarbaise Commented Jan 31 at 20:29
  • 1 "I want these to be separate jobs, so that a build failure is separate from a test failure." What is the advantage? If you put them all into one job, you also see in the log what the error is. – J Fabian Meier Commented Feb 1 at 10:05
Add a comment  | 

1 Answer 1

Reset to default 2

To simplify the things (@khmarbaise gave you the right direction) - it's probably (and likely) not what you would want to do, unless your delivery relies on direct deployment of artifacts to the runtime environments skipping the binary management system.

First, mvn test will indeed compile the code, but it will not produce the jar files. mvn package will do - but it will not run the integration tests (if any) which would be run by mvn verify.

Then, if there's no tests, there is no need to avoid the tests or verify phases - they will not fail, they will just report that no test classes were found.

So, at this point we're ending up with mvn verify as the minimum, and then thinking about optimizations:

I was hoping there was the capability to "save" the build artifacts from the build stage and make them available to the test stage, without having Maven basically recompiling everything.

Too early - because you typically need to make sure that your application could be successfully built from scratch. Moreover, it's not necessarily true that your application will be built on a same build runner that already has all the dependencies downloaded. So it makes perfect sense to recompile everything in a CI environment, adding clean phase to clean up the target directories, resulting in mvn clean verify. Also, for advanced scenarios, three is an option to experiment with incremental builds, but they are typically supported by the external systems (TeamCity, IntelliJ IDEA etc.) or Maven extensions, as it goes a bit against the Maven lifecycle design.

Only after this you can make a decision on how to proceed with the build artifacts.

Further steps depend on your deployment process. But in a CI/CD environment it usually doesn't make much sense to store the artifacts in the Maven local repository (which is being done by mvn install that would be implicitly invoked by mvn deploy, so instead of using deploy you might want to consider uploading the artifacts by an external tool or another Maven plugin.

Also (and probably this is what you wanted to hear in the first place), you can try to make use of separate plugin goals instead of phases that aggregate them - for example, mvn deploy:deploy.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论