'Run maven deploy without re-running the entire build

I'm working on a multi-branch pipeline for a maven project. I'm trying to follow what the Jenkins docs keep referring to as the standard CI steps, Build, Test, Deploy. But maven doesn't seem to work very well with treating these as discreet steps.

I have this so far:

stages {
    stage('Test') {
        steps {
            sh "mvn -B clean verify"
        }
    }
    stage('Deploy') {
        when {
            branch 'master'
        }
        steps {
            sh "mvn -B deploy"
        }
    }
}

With this, the full build is going to run twice, once in the Test stage and again in the Deploy stage. That isn't great as it's a time consuming build thanks to Google Web Toolkit, but that's a separate issue.

Is there a way to gracefully skip the earlier maven lifecycle steps in the Deploy stage and skip to the deploy goal?

The only other alternative I can think of is

stages {
    stage('Test') {
        when {
            // Some expression that states "not master"
        }
        steps {
            sh "mvn -B clean verify"
        }
    }
    stage('Test-and-Deploy') {
        when {
            branch 'master'
        }
        steps {
            sh "mvn -B deploy"
        }
    }
}

I'm not happy with that either due to how this is rendered in the Jenkins UI, and it feels odd to compress what the Jenkins documentation implies should be 3 stages into a single stage. I figure it's the lesser evil though, so I'll probably go with that unless I can find something better.



Solution 1:[1]

Here's a partial answer.

Usually, the most time-consuming part of a build is running the tests. For many projects, skipping that part is already enough to reduce the build time to something acceptable.

In Maven, you can skip the execution of your unit tests (which is done by the Surefire Plugin) like this:

mvn deploy -B -DskipTests

If your project has interation tests (executed by the Failsafe Plugin), you can skip those as well:

mvn deploy -B -DskipTests -DskipITs

Solution 2:[2]

Consider using Maven Cache. By default Maven cache in ~/.m2 directory. It depends how you setup your Jenkins Agent/Slave. It is possible to have Maven cache inside Jenkins Agent and reuse the cache when Maven run deploy and it can save significant amount of build time.

Solution 3:[3]

Maven lifecycle runs all steps that are preconditions to what you execute. Lifecycle looks like this:

process-resources
compile
process-test-resources
test-compile
test
package
install
deploy

So compile will run process-resources and so on.

If you want to execute a single goal, you need to specify it using the plugin:goal syntax, like this:

compile:compile

In your case, to execute only deploy, you need to do mvn deploy:deploy.

For detailed description of maven lifecycle and goals, please see the official docs.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 rolve
Solution 2 Dharman
Solution 3 Moro