13

I am using Jenkins Declarative Pipeline to automate my build process. We want to publish our artifacts to a remote JFrog repository only if certain conditions (Sonar,Checkmarx) pass.

After a bit of research, I found that Artifactory plugin is useful for this. But I am unable to find any document on how to integrate in declarative pipeline. Below is the code snippet from Jenkinsfile

stages{

    stage('Pre-Build'){
        steps{

             script{
                def server = Artifactory.server 'LocalJfrog'
                def rtGradle = Artifactory.newGradleBuild()
                rtGradle.resolver server: server, repo: 'gradle-dev-local'
                rtGradle.deployer server: server, repo: 'gradle-release-local'
                rtGradle.useWrapper = true
            }

        }   
    }
}

The conditional publish is not possible with above code as I cannot reuse the server variable even if I disable auto publish.

3

You can have conditionals in your declarative pipeline by using the when-block inside a stage. There is a plugin called "environment injector" which lets you set variables outside of the pipeline-script which is nice. Also if you put the step below the other steps, it won't execute if they fail.

 when {
    environment name: 'pushArtifact', value: 'true'
  }
  steps{
     //push artifact  
  }
  • Thanks for the hint. If i understood it right a variable has to be set after conditions have been met and then check that variable in Pre-Build step – Dharanidhar Jul 6 '17 at 8:02
2

I think your issue is rooted in the server variable not being reusable outside the pre-build stage block.

In Jenkins declarative, you can define variables like that using the script { ... } block, but once you leave the stage those variables are inaccessible to other to stages.

With the previous suggestions, I'd recommend this:

House the artifactory deploy code to a shared library.

gradle_artifactory.groovy

    def call (Map parameters = [:]) {  //optional parameters mapping

        def server = Artifactory.server 'LocalJfrog'
        def rtGradle = Artifactory.newGradleBuild()
        rtGradle.resolver server: server, repo: 'gradle-dev-local'
        rtGradle.deployer server: server, repo: 'gradle-release-local'
        rtGradle.useWrapper = true
        def buildInfo = rtGradle.run rootDir: "projectDir/", buildFile: 
            'build.gradle', tasks: 'clean artifactoryPublish'

    }

Then to keep your declarative pipelines D.R.Y

@Library('my-shared-lib') 
...
stage('Artifactory Upload') {
    when { <some expression with sonarqube/checkmarx> }
    steps {
        script {
            gradle_artifactory()
        }
    }
}

refs:

https://jenkins.io/doc/book/pipeline/syntax/#when

https://jenkins.io/doc/book/pipeline/shared-libraries/

1

If you want to embed logic in the Jenkinsfile, the declarative syntax may not be the best method as it is not always easy to reflect it in the code.

If you switched to the Jenkinsfile scripted pipeline, you would be able to define and use conditions in an easier way.

  • 1
    Thanks for the reply. I am aware of scripted pipeline but since, this is a basic necessity for any project thought it would be included in declarative pipeline. Will switch back to Scripted or external groovy script then – Dharanidhar May 11 '17 at 12:38
0

One could use the declarative syntax as long as you define the methods outside the pipeline block:

def server = Artifactory.server 'LocalJfrog'
def rtGradle = Artifactory.newGradleBuild()

pipeline {
stages{
    stage('Pre-Build'){
        steps{
             script{
                rtGradle.resolver server: server, repo: 'gradle-dev-local'
                rtGradle.deployer server: server, repo: 'gradle-release-local'
                rtGradle.useWrapper = true
            }
        }   
    }
}
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.