Is it possible to use the maven-release-plugin with a specific revision? - maven

I am thinking about a deployment pipeline using SVN, Jenkins and Maven. At the moment I'm stuck at the point where I usually would call mvn release:perform on a working copy.
When thinking in deployment pipelines, I want to create a pipeline where every commit could be used to release a software to test/production. Let's say I have 5 builds, and I decide to release build 3 (with revision 3) to production. There will already be 2 new commits to trunk (which is now at revision 5).
Is it possible to use the maven-release-plugin to checkout/build/tag/commit a release at revision 3? When the maven-release-plugin finishes the release it usually commits the modified POMs to trunk.
I'm happy about any kind of information or advice here, so feel free to point me to books (like http://www.amazon.com/Continuous-Delivery-Deployment-Automation-Addison-Wesley/dp/0321601912), blog posts, Jenkins documentation... Maybe I'm completely on the wrong track.

By default, the release plugin creates the release based on the contents of your working copy, it just ensures that you don't have any uncommitted content before doing so. AFAIK it doesn't force an update of the sources, as that's usually the job of the Continuous Integration system (Jenkins in your case). So whatever is checked out by Jenkins will be released.
What you're trying to do sounds more like a configuration change on the Jenkins side, pointing it to the right revision.
On the other hand, if the POM files are modified as part of the release, but have been changed in SVN in the meantime, you will run into a conflict when Maven wants to check in the modified POM files. That's a situation that might happen, depending on how for back you want to go with the release.
Based on this, it might make more sense to always create a branch before doing a release. So you would create a branch based on revision 3 and then create your release in that branch. This way, you wouldn't run into issues with committing resources that have changed in more recent revisions.
Creating the branch and checking it out could probably be automated through Jenkins and Maven as well.

As far as I tested it, it is not possible.
More explicitely, as nwinler said, when you release, maven try to commit the modified pom. But, if it's an older revision than the current one, SVN will complain that your sources are not up to date. So it won't work. ... as far as I know.
You may read docs about promotion build. I don't find any one clear enough to be pointed out (in th few minutes of the writing of this message).

Related

maven-release-plugin release:branch - Avoid commit to original branch

I have just hit a roadblock and would really need some insight from someone who knows the maven-release-plugin. I am trying to use the plugin for operating with my pom file, but without having it touching/committing to the main branch, but to a separate branch so that I can later on PR from there and get the review+approval required by the branch protection policy in my repos.
Context
We use github, and the company is enforcing a new branch protection policy in our main branches for security reasons mainly.
I have been using a jenkins pipeline for releasing and delivering my code which in turn, uses the maven-release-plugin for tagging the repo, and switching the version in the pom.xml, etc.
When using github's branch protection, the release plugin cannot do the usual operations, because it cannot push straight to the main branch.
My research
I found out that the plugin supports creating a branch in the process of releasing, that would be exactly what I am looking for. So, I built the environment for trying this out:
GitHub repository
Maven project
and started running some tests. The closest to being successful, was this line (version number is not important):
mvn --batch-mode release:branch '-DbranchName=release-v1.2.1' -DupdateBranchVersions=true -DupdateWorkingCopyVersions=false
I started with the version in the pom set to the value of the version I am releasing (it is not great, but I am willing to make that commit myself). I have checked the release:prepare docs but found nothing that would help me achieving my goal.
My question
Is there any way of telling the plugin, not to make any commits to the original branch, so that it does not get rejected by the branch protection?
I always get at least a commit to the main branch like this one:
* 934af86 2020-04-27 | [maven-release-plugin] prepare branch release-v1.2.1 (HEAD -> master) [Commiter Name]
I know it's late to answer this but I just had the same issue and maybe someone else will search for this as well.
My configuration:
Jenkins
SCM Manager (Sonia)
Git master repo restricted for PRs only
What I end up doing was checking out to new branch and do the release from there. In my SCM-Manager I removed all priviledges for this branch from other users except for jenkis to protect it from being written directly.
So in jenkins project configuration I have set "Branches to build" to "*/Master". Then I added "Check out to specific local branch" in "Additional Behaviours". In branch name I have put "master_release". Your branch should be shown when you do release for the first time.
Since this was first release I will update this answer if I encounter any issues on next iteration but from my perspective it should work.

Teamcity trigger build on new branch without a new commit

I'm using TeamCity 2017.1.4 along with GitVersion.
The teamcity project itself consists of many build configurations the first of which is to run GitVersion and then all subsequent steps take a snapshot dependency on this step and pull the version from its parameters.
In most scenarios this works great, however if we create a new branch eg. /release-foo and push this, teamcity will not trigger a build because its already previously built the commit sha, unfortunately we need it to trigger again as even though the commit hasn't changed being in a new branch means it will get a different GitVersion number.
I've tried forcing the snapshot dependencies on the GitVersion build configuration to always be rebuilt but this seems kind of ugly as kind of breaks all other scenarios where this isn't a problem. I also know I could manually trigger the build telling it to rebuild all dependencies and it would work, however I'm curious if there's a nicer way to get teamcity to automatically trigger a build for a commit on a branch if that branch didn't previously exist, or indeed any other way I could approach this.
You could try configuring TeamCity to include different/more GitVersion version variables in the build, including the branch name and possibly version tags. This would provide a way for your build process to differentiate between the same commit on different branches.
See steps 1-5 of this CD post, as well as this detailed blog post on using GitVersionTask for some examples on how to use the additional info in TeamCity.
You can achieve this by triggering the build from a git hook.
As explained here, you can use a the update hook to identify pushed branches (even when several are pushed in a single operation) and for each branch (assuming it passes your triggering rules) trigger a TeamCity build using the REST API.
If you simply amend the commit on the new branch without modifying anything, it will get a new hash because of timestamp changes. I wouldn't consider this a nice solution, but imho it's better than triggering manually.

automatic, implicit, easy and reliable source revision indicator for maven+jenkins multi-module SNAPSHOT builds?

I currently have a set of maven modules whose versions are set to 1.0-SNAPSHOT designating the current trunk. Those modules get built inside jenkins separately, share the same SVN repo, but do not share a single checkout, so I cannot just take the svn revision of the build's checkout revision -- and that poses my main problem: I usually wait until all activity in Jenkins stops and everything is green (or blue), then I know that everything is ok and that the final build product's svn revision is consistent with all trunk-based modules' source revisions.
If you cannot follow me up to this point, please tell.
Is there any way to improve that, ie. make it more automatic? Two potential pitfalls I can see with that solution: first, Jenkins dependency resolution may be broken, out of date etc. That would lead to an inconsistent mapping between final product revision and possible outdated dependency revisions (because their build was not triggered). Second, there may be some race between final product build and a new source svn commit.
Question: how do you go about that? Yes, I know, it would be cleaner to use explicit release management, but because the builds won't leave some inner circle, it seems to be unnecessary overhead. Is there any way to propagate each and every module's svn revision and dump all dependencies' svn revision in the final product build using something similar to "mvn dependency:tree"? Is it possible to assign snapshot versions a source code revision without having to change the snapshot version references upon changing it?
Update:
here is some solution to store http://www.jayway.com/2012/04/07/continuous-deployment-versioning-and-git/ svn revision inside the MANIFEST etc., however it has a drawback: how do I make sure that these revisions get included into the final build?
Ideally, the svn revision would be appended to the "1.0-SNAPSHOT" revision identifier, ie. "1.0-SNAPSHOT-4783", however, that breaks the ability to reference the latest SNAPSHOT build by simply using "1.0-SNAPSHOT" in dependent modules... I could use [1.0-SNAPSHOT,) in dependent modules to reference SNAPSHOT builds, but it seems that such SNAPSHOT identifiers are not treated as SNAPSHOT by Nexus (I cannot deploy them to a snapshot repo).

How to pick up release version from maven release plugin using GMaven?

I have the feeling I'm doing something wrong here as I have been digging around the net for a while (stackoverflow included of course) and yet that rendered no results!
In brief, I have a maven project set up with maven release plugin which works fine, increments the version correctly, checks in code in SVN, tags and deploys with no problem.
However, the need has arrived to also generate a script with each release which has to reference the jar generated. This means 2 things:
for the release version, change the script to contain the release version, commit it back in SVN (so it gets tagged etc)
following the release, the script has to be updated to contain the (next) SNAPSHOT version and committed back into SVN
For example, let's assume my current working version of the pom is 1.1.1-SNAPSHOT. As such my script.sh contains a reference to project-1.1.1-SNAPSHOT.jar.
When I perform a mvn release:prepare (assuming I will stick with the versions suggested by maven-release-plugin) the release version will become 1.1.1. At this stage, my script.sh should be changed to reference project-1.1.1.jar and committed back in.
Upon mvn release:perform all the 1.1.1 the tagging occurs, deployment to maven repo etc. And following that, my pom will be changed to 1.1.2-SNAPSHOT and committed back in SVN. At this point my script needs to be changed to reference project-1.1.2-SNAPSHOT.jar.
I figured out I can alter the script easily by using something like GMaven plugin -- and I have got the script in fact to kick in during prepare-resources phase (though maybe I need to look at another one?) however the biggest problem I see is retrieving the versions that maven-release-plugin has decided to use: in other words, how do I find out:
release version that maven-release-plugin has decided to use
next dev/SNAPSHOT version that maven-release-plugin will use
Once I get access to these I think I can get GMaven to execute the required code to change my script accordingly. (Though, if looking at the above scenario you can recommend a better way of doing this I would be more than glad to hear it!) Are there any properties like ${project.releaseVersion} (that doesn't work by the way) which could give me these 2 version numbers?
Thanks in advance!
Liv

Branching then tagging with the Release plugin

I'm learning how to use the Maven Release Plugin and I have a question with the process of tagging/branching. I'm working on a project called "test" version 1.0-SNAPSHOT. I'm ready for the release. I can prepare the release and perform the release but Maven only creates a tag and I also want a branch for maintenance (bug fixes). I know that there is a possibility to branch with the Release plugin, but the branch goal doesn't create a tag also. I understand that when you want to branch, you don't want to tag. But, generally when you create a tag from the trunk (because release 1.0 in this case), you would want to branch for future maintenance.
Is there a way to configure the prepare/perform goal(s) to also branch the project before or after creating the tag?
Thanks
AFAIK no. But simply copy the /tag/test-root-1.0 to /branches/test-root-1.0. Then you need to update the versions in the pom. For this you can simply use the "mvn versions:set" goal and set the version to "1.0.1-SNAPSHOT". You are probably up to scripting these two commands in bash script if you need to make it look as one :-)
You might want to consider integrating the maven-scm-plugin into the mix. Either scm:tag or scm:branch before or after your release goals should do the trick.

Resources