maven Best Practices: Version Management
Blog Category:MAVEN MAVEN Configuration Management project management SVN Subversion
What is version management
First, versioning (version management) does not refer to versioning (version control), but this article assumes that you have basic knowledge of versioning and understand the basic uses of subversion. Version management refers to the version of the component (artifact), but not the source version (such as the common rxxx in subversion, or git in a commit has a SHA1 commit number).
For example I have a project whose artifactid is MyApp, along with the progress of the project, We will generate some jar:myapp-1.0-snapshot.jar,myapp-1.0.jar,myapp-1.1-snapshot.jar,myapp-1.0.1.jar and so on. You may say, this is very simple, I change a version,mvn in the pom clean install is not finished. But this is just the surface, this article I will tell the difference between the snapshot and release versions, how to automate release releases (if your project has dozens of module, you will feel the manual modification of POM to upgrade the version is very painful), combined with the automated release process, Maven-release-plugin will also be introduced here. In addition, some SCM concepts will be involved, such as tag and branch.
premise: Version control
Anyway, we all need to build a project and submit it to the SCM, and here I take subversion for example. You have to have a well-configured Subversion repository, where I built an empty SVN repository with the address: https://192.168.1.100:8443/svn/myapp/now, there are only three empty typical subdirectories in this directory:/ trunk/, branches/, tags/. They are used to store trunk, branch, and label respectively.
Then import the project into the SVN repository, to the project root directory, and run the following command:
SVN import-m ' project initialization ' Https://192.168.1.100:8443/svn/myapp/trunk
(Note that you will import all the files in the directory into the SVN repository, but some of these directories and files should not be imported, such as the/target directory, and the Eclipse-related project files)
Currently, we set the version of the project to 1.0-snapshot.
why use Snapshot.
Let me start by talking about what it would be like if there were no snapshot. Let's say your project has 2 modules, A, B, where a depends on B. These three modules were developed by A and b two individuals. In the development process, because a is dependent on B, so B each time a change will affect a, so, B submitted some changes, need to let a see. This time, how to do it. B to a said, "You check out my code, build it OK", a a bit reluctant, but still do, check out the code, SVN clean install, and then, found that the build error, there is a test without pass. A depressed, said to B, "Your code can not be used, I do not want to build, you build good to me", B looked at the actual code build but then went back to solve, and then hit a jar package, throw to a, a pair of Groupid,artifactid, Put it in your own. m2/repository/directory, OK, it can be used.
So b every update to do so, packaging, copying, and then a paste, use ... Gradually, we found that this is a very stupid way, this is purely manual labor, programmers most BS is the repetition of labor. One day, A to B said, "Do you know the Nexus?" You put your jar on the nexus and I'm going to download it automatically, which is awesome. "B said," Oh. With this good thing, I went to see "so B discovered the nexus of this new continent and successfully released the B-to-nexus." (See, Nexus Starter Guide, (text)).
However, please note that all of us here assume that there is no snapshot, so if B does not change the version, a download once like B-1.0.jar, Maven thinks it has the correct version of B, it will not be re-downloaded. A found this problem, said to B "Your update I do not see, you updated it." "B said" impossible. I looked, so I checked a download of the C-1.0.jar, and found that it was a few days ago. B A PAT head, said "This simple, I update my version is good, I released a B-1.1.jar up, you update the dependent version", a photo done, it seems to do is feasible.
Here is a problem, one commit to update a version, which is obviously not the right management method, in addition, B to constantly notify a update on the B dependent version, tired not tired. 1.0, or said 1.1,2.0, all represent the stability, so casually change version, can stabilize it.
So Maven has the concept of the snapshot version, which corresponds to the release version, which refers to the stable release version of 1.0,1.1,2.0.
B can now be set to a version of 1.0-snapshot, each change, mvn deploy to the Nexus, each time Deploy,maven will SNAPSHOT into a current time timestamp, For example, when B-1.0-snapshot.jar into a nexus, it will look like this: B-1.0-20081017-020325-13.jar. When Maven is dealing with the snapshot dependency of B in a, the latest jar is downloaded based on such timestamp, and the default maven is updated daily , so if you want Maven to force updates, you can use the-u parameter, such as:MVN Clean Install-u .
Now things are simplified like this: B makes the change, then mvn deploy, and the most recent B can be obtained with the simplest MAVEN command.
from 1.0-snapshot to 1.0 to 1.1-snapshot
Snapshot is the meaning of the snapshot, and after the project has reached a stage, it is necessary to publish a formal version (release version). A formal release requires some work: in the trunk, update the POM version from 1.0-snapshot to 1.0 to 1.0 dozen an SVN tag for mvn deploy for tag, release the official version of the update trunk from 1.0 to 1.1-snapshot
You can do these things by hand, just a few SVN operations, some pom edits, and some mvn operations. But you should understand that doing these things by hand is tedious and error-prone. So here I introduce the use of Maven plugins to automate this series of actions. SCM
First we need to add SCM information to the POM so that maven can do the SVN operation for you, here my configuration is as follows: XML code <scm> <connection>scm:svn:http:// 192.168.1.100:8443/svn/myapp/trunk/</connection> <developerconnection>scm:svn:https:// 192.168.1.100:8443/svn/myapp/trunk/</developerconnection> </scm>
It is important to note that many Windows use the TORTOISESVN client without the SVN command line client, which causes MAVEN all SVN-related work to fail, so you first make sure that SVN--version is able to run. Distribution Warehouse
To get Maven to help us automate the release, first we need to configure the distribution repository. In this regard, see MAVEN Best practices: Maven repositories-distributing artifacts to remote warehouses. Maven-release-plugin
Next, we need to configure the Maven-release-plugin, this plugin will help us to upgrade the POM version, submit, tag, then upgrade the version, then submit, and so on. The basic configuration is as follows: XML code <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactid>maven-rel ease-plugin</artifactid> <version>2.0-beta-7</version> <configuration> <TAGBASE&G T;https://192.168.1.100:8443/svn/myapp/tags/</tagbase> </configuration> </plugin>
Gav I don't explain much, here we need to note is the configuration element under the Tagbase element, which represents our svn in the tag directory, that is, Maven-release-plugin help us to hit the tag when the base directory is what. Here, I filled out the standard tags directory in the SVN repository. Submit Code
Next, make sure that all your code is submitted, if you have uncommitted code, the release plugin will report an error, since you want to release the version, it means that the code is stable, so either the code is submitted, or the local changes are discarded. Start Working
Now, hold your breath and perform:
mvn release:prepare
During the execution, you will encounter such a hint:
What's the release version for "Unnamed-org.myorg:myapp:jar:1.0-snapshot"? (Org.myorg:myapp) 1.0::
--"Why do you want to release 1.0-snapshot?" The default is 1.0. "All I want is 1.0, go straight to the car."
What is the SCM release tag or label for "Unnamed-org.myorg:myapp:jar:1.0-snapshot"? (Org.myorg:myapp) myapp-1.0::
--"What is the tag tag name of the publication?" The default is myapp-1.0. "I still want the default value, direct carriage.
What's the new development version for "Unnamed-org.myorg:myapp:jar:1.0-snapshot"? (Org.myorg:myapp) 1.1-snapshot::
-"What is the new version on the trunk?" The default is 1.1-snapshot. "Ha, release plugin will automatically help me update the version to 1.1-snapshot, very good, direct carriage."
Then the screen brushes a brush, MAVEN builds our project, and carries out some SVN operations, you can carefully review the next log.
So what's the result? You can browse the next SVN repository: We have one more tag:https://192.168.1.100:8443/svn/myapp/tags/myapp-1.0/, which is the version 1.0 that needs to be released. Then look at the Pom in the trunk and its version is automatically upgraded to 1.1-snapshot.
That's not what we want. Wait, there seems to be something missing, right, 1.0 hasn't been released into the warehouse yet.
Hold your breath again, perform:
mvn release:perform
Maven-release-plugin will automatically check out the tag we just hit, and then package it, distribute it to the remote Maven repository, so that the entire version of the upgrade, labeling, publishing and other work completed. We can see the officially released version 1.0 in the remote Maven repository.
This is an automated , formal release.
version rules for maven
Before we mention the difference between the snapshot and release versions, now look at why there is a version of 1.0,1.1,1.1.1, and what the rules are here.
Maven basically defines the version rules as follows:
< major version >.< minor version >.< incremental version >
For example 1.2.3, the main version is 1, the minor version is 2, and the incremental version is 3.
The main version typically represents major architectural changes to the project, such as Maven 1 and Maven 2, which are both architecturally different, and the future of Maven 3 and Maven 2 will vary greatly. Minor versions typically represent additions or changes to some features, but no architectural changes, such as the Nexus 1.3, which adds a new or improved set of features (warehouse mirroring support, improved warehouse management interface, and so on) compared to Nexus 1.2来, but from a large architecture, 1.3 and 1.2 are no different. As for the incremental version, it is generally a small bug fix that will not have significant functional changes.
In general, after we publish an important version, we will develop a new version, for example, after myapp-1.1 is released, we begin to develop the myapp-1.2. Since myapp-1.2 has new major functionality additions and changes, it becomes unstable before releasing the test, and myapp-1.1 is a relatively stable version, now the problem is that we found some bugs in the myapp-1.1 (which of course exist in 1.2), in order to be able to fix the bug and still publish it in a time period. Stable version, we will use the branch (branch), we open a branch based on 1.1 1.1.1, in this branch to fix the bug, and quickly released. This ensures a stable version, as well as a quick fix for bugs, and a different stop to 1.2 development. It's just that every time you fix a bug in a branch 1.1.1, you need the merge code to 1.2 (trunk).
The above is why we need to use the incremental version.
Combat Branch
The current version of our trunk is 1.1-snapshot, in fact, according to the previous version of the rules explained, should be 1.1.0-snapshot.
Now we want to publish the 1.1.0 and then upgrade the trunk to 1.2.0-snapshot, while opening a 1.1.x branch to fix bugs in the 1.1.0.
First, before releasing 1.1.0, we create a 1.1.x branch and run the following command:
mvn release:branch-dbranchname=1.1.x-dupdatebranchversions=true-dupdateworkingcopyversions=false
This is Maven-release-plugin's branch goal, we specify branch name is 1.1.x, there will be version 1.1.1, 1.1.2 and so on. Updatebranchversions=true means that the version is updated in the branch, while Updateworkingcopyversions=false is the version of the current working directory (this is the trunk) that is not changed.
After running the command, we will encounter such a prompt:
What's the branch version for "Unnamed-org.myorg:myapp:jar:1.1-snapshot"? (Org.myorg:myapp) 1.1-snapshot::
--"What is the version number in the branch?" The default is 1.1-snapshot "At this point we want the version is 1.1.1-snapshot, so input 1.1.1-snapshot, enter, MAVEN continues execution until the end.
Next, we browse the SVN repository and see a directory like this: https://192.168.1.100:8443/svn/myapp/branches/1.1.x/, which opens the Pom file whose version is already 1.1.1-snapshot.
Once the branch is created, you can use Release:prepare and release:perform to label the 1.1.0, upgrade the trunk to 1.2.0-snapshot, and then distribute the 1.1.0.
At this point, everything OK.
Summary
This article describes how to use MAVEN in conjunction with SVN for version management. Explains the origins of the snapshot version in Maven, as well as the rules for the MAVEN managed version. Combined with the SCM's tag and branch concepts, it shows how to use the Maven-release-plugin release version and create a branch. This article involves a lot of content, and a little more complex, but mastering the skills of version management is very important for the regularization management of the project. MAVEN has provided us with a set of more mature mechanisms that deserve to be mastered.