Maven: How to avoid building a module during a release? - maven

I know how to avoid deploying a module during the release process. What is not clear is how to avoid building the module to begin with. For example, my project contains an "examples" module. This takes a very long time to build and is never deployed to Maven Central so I'd like to avoid building it altogether (but only during a deploy). Any ideas?

If you're using the Maven Release Plugin, you will need to take care of both the prepare and the release steps, since projects are usually built in both steps.
For the prepare step, I would try the preparationGoals parameter, which by default uses clean verify, which includes a build of the project. Maybe you can try setting it to clean only to avoid the build.
http://maven.apache.org/plugins/maven-release-plugin/perform-mojo.html
For the perform step, take a look at the goals parameter, which by default is set to deploy. You can override this by specifying clean only.
http://maven.apache.org/plugins/maven-release-plugin/perform-mojo.html
I haven't tried this exact combination, so I don't know whether this will have any side-effects on the rest of the build.

Best thing in this case is to use a profile and put the example into a separate module which can be activated by a profile. This prevents building during release but can be build during usual development etc. via activating profile.

Related

Teamcity Snapshot Dependency without shared sources

I have a number of builds that creates a package that is published to a package manager (for example NPM, Nuget and Maven).
I have subsequent builds that trigger on the completion of this build, they get the artifact from this repository. The problem is they show a warning:
I'm considering adding a Snapshot dependency, however, Teamcity's UI describes snapshot dependencies as builds using the same sources:
There is no source dependency between these projects and in fact, they may have completely different VCS roots.
What is the appropriate way to link these projects? Reading the documentation on Snapshot Dependencies, it sounds like things might not work as expected if I add a dependency without shared sources.
There is no requirement to link these projects, other than by the trigger you already have I don't think.
If the triggered build always gets the latest version from the package manager, then you'll get the behaviour that you want.
Snapshot dependency simply ensures that a build which depends on another build gets the same version of the source code when it builds, and doesn't end up being built using some changes that someone else checked in between the first build starting and the second build starting. This doesn't look like its going to be an issue in your situation (and indeed the builds may use completely different repositories), so I think your finished build trigger is an appropriate solution.

Maven module dependency source instead of repository jars

I have a multi-module project, i.e.
parent
module1
module2
In one dev cycle, I added a class mod1.A to module1. Class mod2.B in module2 depends on it.
I do not have the artifacts in my local .m2/repository. Running this:
$ cd prj/module2
$ mvn -o exec:java -Dexec.mainClass=mod2.B
results in an error along the lines of:
The following artifacts could not be resolved: com.example:module1:jar:1.0-SNAPSHOT
After I install the artifacts via mvn install while in the prj folder, it all works as expected.
However, this presents an issue in at least two ways:
I have to go through the slower install phase instead of the faster compile phase
I have two versions of the same project and conflicting modifications in these. I cannot run the same Java class with their respective modifications, only the currently installed modifications, considering they are both the same SNAPSHOT version
There are workaround for both (skip parts of the build for the first, different snapshot versions for the second), but they are far from usable in practice.
Is there a way to make maven use the local modules, instead of using artifacts from local maven repository?
If I understand your question correctly, it seems like you are living a bit outside the norm here: you have two local "copies" of the project with different modifications, that you want to work with alternately when running "exec:java". And Maven is getting in your way: it expects your local .m2 repository area to be in play, but the version strings in each copy are the same, so you end up with the changes interfering among the copies.
To me, it sounds like what you are trying to do is to test your changes. I suggest you just write an actual JUnit or TestNG test in module2 that tests what you want (it can just call mod2.B Main if you want). Then, from your chosen project directory, you can run mvn test -Dtest=MyTestName. It won't "install" anything and it will find the dependencies the way you want it to.
Otherwise, I can see three options.
Change the version string locally in one of the copies (mvn versions:set -DnewVersion=B-SNAPSHOT can do this for you). That way any "installed" jars from your work on that copy will not be considered by the other copy, and vice-versa. You refer to this as being "far from usable" ... I think it should be fine? These are different versions of the project! They should have different version strings! I strongly recommend this option out of the three. (You can do mvn versions:revert when done if you used :set, or you can rely on version control to undo the change.)
Select a different local repository used by Maven when working on one of the projects, with a command-line flag as per https://stackoverflow.com/a/7071791/58549. I don't really think this is a good solution, since you would have to be very careful about using the right flags every time with both projects. Also you'd end up having to re-download Maven plugins and any other dependencies into your new local repository anyway, which is kind of a waste of time.
Try to avoid using any local repository at all. You seem to be trying to make this option work. I don't think this is a great approach either; you're fighting against Maven's expectations, and it limits your flexibility a lot. Maven will indeed find dependencies from the "reactor" (i.e., the executing mvn process) first, but this means all of the required modules must be available in the reactor to be found, which means you can only run mvn at the top level. So if instead you want to just do "mvn exec:java" inside a single module, mvn needs to find that module's dependencies somewhere ... and that's what the local repo is generally used for.
If you're dead set on going with option 3 (instead of option 1), then I suggest you follow the comments on your question and create a profile that runs your exec selectively against module2 and binds it to a lifecycle phase. But this is in practice very close to just wrapping it with a test.
For IntelliJ users:
I solved this problem using IntelliJ's Run configuration. It has the options Resolve workspace artifacts and Add before launch task -> Build. See this picture for clarification:
Run configuration example
The whole point of modules in Maven is to create decoupling between them. You either build each module independently, so that you can work on one module without touching the other, or include both modules as sub-modules in the parent pom and build the parent, which will resolve dependencies between its sub-modules and trigger their builds.
It looks like you have two options here:
Review the structure of your project. Do you really need to split it into two separate modules, if you change code in both of them simultaneously?
Import the project into a Maven-aware IDE (IntelliJ IDEA is very good at working with Maven), and let the IDE handle the compilation. Once finished and stabilized the code-base, build normally with Maven.

mvn --resume-from downloads snapshots

I have a multi-module maven project with 5 modules. The modules are tiered such that a few depend on the first that builds (it's my model classes) and some depend on the second ones that build (those are core application classes). The final one that builds is a Spring WebMVC app which depends on all the other modules.
The problem I'm having is in Maven's --resume-from flag. It apparently doesn't do what I want. I must me misunderstanding what the word "resume" means in this context as I would expect it to, well, resume something.
If I run mvn verify and it fails at the rest-api sub-module, it tells me I can resume by running mvn --resume-from :rest-api verify. When I do that though, it downloads snapshots of the other modules from my project which rest-api depends on. That is so incredibly not what I want that it's comical. I wanted it to re-use the in-place jars it just built like 5 seconds ago inside this local checkout of the project!
Does anyone know what the nature of my misunderstanding is here? Am I misusing inter-module dependencies? Am I totally misunderstanding what --resume-from means? Is there some other argument to do what I want?
Use mvn install instead of mvn verify, as only after the install phase, Maven will be able to pull it from your local repo.
You probably also want the --also-make-dependents option.
See this blog for the full story.

How to change additional projects with maven release plugin?

We create releases and upgrade the versions of our multi module project with the maven release plugin, which is usually triggered with a Jenkins release build. The problem is that we have a couple of modules whose versions should be updated as well, but which should not be built on the server - only the version upgrade should be performed. (These are just testing stuff only used occasionally by developers.) Any good ideas how to do that?
I believe the accepted policy is that every module should be built that forms part of a project. That includes those modules intended to test others.
If internally you have a situation in which a module is intended to test another but should definitely not form part of the build you may wish to extract that module into another project and adjust the module to depend on the artefacts of the older project's module.
You may still find that your CI server (such as Jenkins) recognises this dependency and builds your test project because it detects a changed dependency. In that case disable the automatic building of this test project.
You may find it less "smelly" to correct the testing procedure to ensure your test modules are designed to be run upon each build. Having a set of tests that should not be automatically run seems contrary to modern software engineering approaches.

Quick question regarding TeamCity dependencies

Ok, this may be a silly question, maybe my English knowledge, or "just" my comprehesnion level, is fooling me, but what is the difference between snapshot dependencies and dependency triggers?
I guess the first means that when you build a project, TC makes sure the dependency is up to date, if it isn't it is rebuilt, and then it builds the original project, plus it won't allow builds in parallel. And the later means that if a new build of the dependency is built, it triggers a build of the project.
Also, if this is the case, I guess any "recursion" problem is already handled, like, eg: you force a build of a project with both features enabled, it checks the dependency and sees it needs to be rebuilt, and when it does so, the trigger isn't fired.
Are my assumptions right?
For the first part of your question, you answered it yourself.
Snapshot dependencies, force the dependent Build Configuration to build (if it's not up to date) before building the current Build Configuration.
Dependency triggers, make the current Build Configuration build after a successful build of the dependent project.
On the second part of your question, I think you are asking if Build Configuration A will run twice when it has both a Snapshot Dependency and a Dependency trigger to Build configuration B and you Run the Build Configuration A.
I tried this myself with Teamcity 5.1.2 and I saw that it only ran once.

Resources