Maven repository setup for different environment - maven

I am setting up an internal maven repo feed for our team. I dont know how to deal with different environments.
I want to have 3 different feeds e.g. dev, ppe and prod. How can I parameterized my pom.xml so that the build/install command can talk to either of these three feeds based on some parameter?
for example
mvn clean deploy -dev : will install and deploy to dev feed
mvn clean deploy - ppe : will install and deploy to ppe feed
Can it be done by profiles? if yes, how?
or is there any other way to achieve this?

This answer might be closed as too broad, but ...
If you have three stages for new software and the artifacts should move to the next stage when tests are successful, you usually don't build the artifact again, but move or tag it somehow to distinguish stages. The reason for this is simple: When you rebuild an artifact, you end up with a slightly different artifact than the one you tested before. So strictly speaking, you need to repeat the tests.
Practically, sometimes people do rebuild the artifact for some reason or the other, but you should have such a good reason to do it.
Furthermore, there is often a "stage before the first stage" where you build SNAPSHOT artifacts and play around with them without intending to ever put them productive (in the preliminary state they are in).
Having said all that: You can deploy to different Maven repositories depending on Maven profiles. You just need to put the <distributionManagement> into a profile and activate/deactivate it on the command line (or some other profile activation mechanism). You just need to be sure you really need this.

Related

Can the maven updatePolicy be set to never from the command line?

I would like repeatable results when running maven commands locally, even if somebody else is pushing updates to a snapshot dependency.
To achieve this, I would like to use the updatePolicy of never.
This will allow any dependencies that aren't available locally to be downloaded, while any I have installed locally will be used.
The offline flag won't work in this situation, as there may be dependencies that I haven't installed locally which will need to be downloaded from the remote repo.
I don't want to have to modify the pom, as doing this locally with every checkout will be error prone, and I don't want to commit these changes as it will have adverse effects on other developers.
Ideally I'd like to specify this from the command line. The opposite of the -U flag.
I've searched the docs, and so far have not found out how to do this.
If you want repeatable builds you can create a Docker image that can run Maven. Then load all you project files and run Maven build.
This will provide a clean environment for your build every time.
About the changing dependencies, if you work using SNAPSHOT dependencies, you must expect this different results. That is what SNAPSHOT means: "this is under development".
If you (or your team) control the SNAPSHOT dependency and there is an error in the build that's a "good" sign, the tests found something to be fixed.
If you (or your team) don't control the SNAPSHOT dependency, you would prefer to the last stable release.

clean before every build (package)

Regardless of build tool, I have seen people doing a clean task/phase before every time they do package/compile or ... is it really necessary?
Dose build tools use reuse artifacts of previous builds?
Most of the time you see clean install as the default command, but I would encourage everybody to use verify instead.
When executing clean the target-folder is removed which makes it impossible to do incremental builds. Plugins have enough information to detect if they should do their action. For instance: the maven-compiler-plugin compares the java sourcesfiles and the compiled classfiles (and other things) to see if files needs to be (re)compiled. If you think that a plugin is not working correctly with incremental builds, please file an issue for that plugin.
The install was often required with multimodules in Maven2, but Maven3 is capable to resolve these inner module dependency references. The only thing 'install' does is copying artifacts to the local repository (=IO=expensive). And it'll make your local repo look different compared to your coworkers, which might give different results during builds. Better to let a buildserver push those artifacts to the shared remote repositories and let every pull those SNAPSHOTs from there. Only in rare cases calling install is valid (experienced Maven users know when :) ), so instead please use verify.

Does maven support concurrent execution of different projects

I have a query regarding maven.
Does maven support concurrent execution of different projects which are not related.
To elaborate it more;I have 4 different projects and i want to run "mvn site" command on all of them on 4 different terminals.
So the question is,Does maven support this feature.
Thanks
#Raj Jain,
By "different projects which are not related" I take you to mean each one has a different pom file sitting in a different directory. If so, then the answer is yes, but.
Yes, in theory, you can build all of them concurrently, for instance running 4 xterms concurrently, cd to each one's respective dir, and run mvn clean install in rapid succession.
And yes, each of the builds will run in its own directory in a self-contained manner, creating a local subdir called target/ to store all the build artifacts.
But there is a slight risk of builds interfering with one another as they write to what's called the local repo. Especially if they depend on the same jars, they might write the same file to the same folder simultaneously, causing the build to get corrupted. This doesn't happen often, especially after the first time the build runs since the local repo is now fully populated.
However, if you want extra insurance against this kind of collision, then have each of the builds write to their own repo using mvn -Dmaven.repo.local=/tmp/repository1/
Hope that helps.
Add all the artifacts to a pom.xml as modules, so when you run mvn site on the pom.xml, all modules should be called.

Maven publishing artefacts to remote repository and using $release in the artefact version

Wondering how people manage their project artefacts through an environment lifecycle of say DEV - AQA - CQA - RELEASE and if there's some best practices to follow.
I use a Jenkins build server to build my projects (code checkout then maven build). My artefacts all have version 1.0.0-SNAPSHOT and are published to a local .m2 repo on the build server. There are also Jenkins jobs that rebuild the DEV system (on the same server) using those artefacts. The project build is automated whenever someone checks in code. The DEV build is automated on a nightly basis.
At some point, my lead developer determines that our project is fit to go to AQA (the first level of testing environment on a different server).
For this I need to mark the artefacts as version 1.0.0-1 and publish to a remote AQA repository (it's actually a Nexus repo).
The Maven deploy plugin sounds like the right approach, but how do I change the version number to be effectively 1.0.0-$release (where $release is just an incrementing number starting from 1)? Would Maven/Nexus be able to manage the value of $release, or would I need a simple properties file in my project to store/update the last used $release.
Furthermore, someone tests AQA and determines its fit to move on to CQA (second testing env). This is 'promote to AQA'. So my requirement is to copy the artefact from the AQA Nexus repo and publish to the CQA Nexus repo.
Likewise, after CQA, there'd be a 'promote to RELEASE' job too.
I think the version value remains unchanged during the 'promote' phases. I'd expect the AQA repo to see all versions 1-50, but CQA only 25 and 50, then RELEASE only 50, for example.
I can find loads of info about Maven plugins/goals/phases, but very little about a prescriptive method on how or where to use outside of the immediate development environment.
Any suggestions gratefully received.
Staging/promoting is out of scope for Maven. Once deployed/uploaded to a remote repository, that system is responsible for the completion of the release cycle. Read this chapter about staging: http://books.sonatype.com/nexus-book/reference/staging.html if you use Nexus.
Build numbers are just that build numbers. They are not promotion / staging numbers.
You should come up with another means of tracking your promotions, because otherwise one might get confused in "knowing" that build 10.1.4-2 is the same as 10.1.4-6. Certainly, all of the Maven related software will see those two builds as different builds.
In addition, if a person "grabs" the wrong copy of the build, the way you are managing staging within your build number will increase confusion. As if you don't kill all of the 10.1.4-2 builds, then someone might get a copy of that not realizing that the build has been promoted to 10.1.4-6. This means that for the "last" staging number to be the most likely one to be grabbed, you must do two things (which are impossible in combination)
Remove all the old staging numbers, updating them to the new ones.
Ensure that no copy of an old staging number escaped the update.
Since people generally can copy files without being tracked, or said files might not be reachable at time up "update", or timing between reaching all the files cannot be simultaneous, such a system is doomed to fail.
Instead, I recommend (if you must track by file), placing the same file in different "staging directories". This defines release gateways by whether the file exists in a certain directory, and makes it clear that it is the same file that is going through the entire process. In addition, it becomes easy to have various stages of verification poll their respective directories (and you can write Jenkins tasks to promote from one directory to another, if you really wish).

Use artifact outside of maven

Well, this is kind of embarrassing. I am in the process of mavenizing our build processes and just don't know how the access the result of a build. I build, let's say, a jar file and mvn deploy it. So it ends up as some blah-0.1.2.jar in our company maven repository, which is just a webdav share. Now how would you pass that on to someone else to use? Just pry it from target/blah-0.1.2.jar can't be the answer. I found several suggestions to use variants of mvn dependency:get but they were all just close and didn't feel right. There must be a way to use all those nice versions of blah-*.jar that end up in the repository for purposes other than a maven dependency. Preferably from the command line and maybe even without maven. Hm, a webdav client doesn't look too bad except for snapshots. What would you suggest?
Creating a script that makes a dependency:get call is probably going to be closest to your desired outcome. You can specify the destination of your downloaded jar this way.
If you are looking for an easy way to share builds between people in/outside of your company then you can look into setting up some automated build software like Bamboo or something similar. A new build gets triggered any time a commit is made to the section where your project resides in whatever version control system you use. An artifact is then made available for each successful build and are available via Bamboo's web interface. Bamboo can be configured to run with your maven pom's.
While they can bit a bit of pain to set up, going the automated build route will take a lot of the sting out of sharing your builds in the future.

Resources