5

I have multiple projects with similar build steps and I am looking into reusing a Jenkinsfile pipeline across these projects. I am having a hard time to find documentation on how to implement such an standard (to my opinion) setup.

Here are my requirements :

1) a Jenkinsfile is stored in repo, shared across multiple projects

2) Each project has its own parameter : the project location in the repo.

3) Each project should be independent in Jenkins from a user perspective at least, meaning for example the executions and logs are available in each project's entry in Jenkins

How can I achieve this? based on How do pipeline parameters and jenkins GUI parameters work together? I understand that I can use freestyle jobs however the logs are not available directly with this option. I was suggested also to use Jenkinsfile in each of these independent jobs but to my opinion that sounds like too much unnecessary configuration.

I initially thought about replicating my pipeline job (meaning copy the job including parameters definition, Repository and credential & jenkinfile location definition), the problem I am having with this idea is that every single time I run the job, the pipeline is erasing the parameters default values

e.g. defining a projectSvnPath property in the Jenkinsfile with NO default value will erase my job parameter projectSvnPath value in Jenkins. For that reason I was not able to use this option.

properties([
  parameters([
    string(name: 'projectSvnPath',      description: '*', )
   ])
])
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
NicolasW
  • 1,519
  • 5
  • 22
  • 34
  • Possible duplicate of [How to configure a Jenkins 2 Pipeline so that Jenkinsfile uses a predefined variable](https://stackoverflow.com/questions/43278124/how-to-configure-a-jenkins-2-pipeline-so-that-jenkinsfile-uses-a-predefined-vari) – herm Jun 15 '17 at 09:26
  • I am something new in the subject of jenkins pipelines and until recently I was able to maintain a single jenkinsfile that several of the projects that we develop in the company share as they all have a standard way of building, however I think that the problem with this form of working the shared pipelines is that the variables that are filled with the project data (branch, tag, MG) are interpreted at the time of the pipeline's execution, this causes that if it is required to restart a pipline from a specific stage, manually these data is no longer there and therefore the expected results are – Komodo Jul 22 '20 at 17:12

3 Answers3

2

I am working on the same pb : Sharing a pipeline across many projects

I am using jenkinsFile.properties (each project has its own) where I put my specific data :

apiName=test
host.Dev=localhost

Then I access my data in the jenkinsFile with

props = readProperties  file: 'jenkinsFile.properties'
targetHost = props["host.${devHost}"]
apiName = props["apiName"]

Then I can use them and work in a very crude way :

    sh '''
        git clone ...
        mvn -X clean install
    '''
terrasson marc
  • 97
  • 1
  • 10
1

Jenkins has the shared libraries concept to allow multiple builds to share common pipeline instructions without replicating code. details at https://jenkins.io/doc/book/pipeline/shared-libraries/.

At this point what remains unclear is how to allow parameters overrides to persist each time the Jenkinsfile is reloaded. Seems like a weird design choice.

Update 07/13/17 All my parameters are defined in my pipelines to avoid the issue with parameters. I prefer to have parameters defined in my code repository but I can foresee cases where this won't be practical.

Update 04/18 I gave up using shared libraries - the reason for it is that it cannot be tested. It won't run on dev environments (say your PC), so any development needs to be pushed to your repo basically to perform any testing. This is not a sustainable approach for any kind of software development. At the moment my jenkinsfiles are duplicated because I found no workaround for this using jenkins.

NicolasW
  • 1,519
  • 5
  • 22
  • 34
  • Could you explain what you mean by "parameters overrides to persist"? – herm Jun 15 '17 at 14:14
  • Item 2 in my requirements : " Each project has its own parameter : the project location in the repo." this would be setup in Jenkins (and value will be passed to pipeline to override whatever is defined there). I have not found a way to do this yet so I can only assume it is not possible (per design) – NicolasW Jun 15 '17 at 14:23
  • You pass parameters in the jenkinsfile of each project. You can if they are null overwrite them with a default value. Does that not solve your problem? You can also access jenkins environment variables and other things such as the scm object. scm.getUserRemoteConfigs()[0].getUrl() for example return the url of the git repo. Does that help? – herm Jun 15 '17 at 15:07
  • e.g. defining a projectSvnPath property in the Jenkinsfile with NO default value will erase my job parameter projectSvnPath value in Jenkins. For that reason I was not able to use this option. – NicolasW Jun 15 '17 at 15:24
  • If you use a setup as described in my post any values that you pass in the jenkinsfile will be accessible from the library through the config object. You can have a method to initialize default values if nothing is passed. Nothing is overwritten by seting something in the jenkinsfile. – herm Jun 15 '17 at 15:28
  • per my tests, the Jenkinsfiles erases the parameters defined in the job. I am talking about the jenkins job here. If you read the last part of the question it is clearly explained there again. – NicolasW Jun 15 '17 at 16:20
1

I had the same answer to a different thread but the question was another one. It's up to moderators to decide if its a duplicate question and if not this answer is valid as it will be found with search more easily.

You can use the Pipeline Shared Groovy Library plugin to have a library that all your projects share in a git repository. In the documentation you can read about it in detail.

If you have a lot of Pipelines that are mostly similar, the global variable mechanism provides a handy tool to build a higher-level DSL that captures the similarity. For example, all Jenkins plugins are built and tested in the same way, so we might write a step named buildPlugin:

// vars/buildPlugin.groovy
def call(body) {
    // evaluate the body block, and collect configuration into the object
    def config = [:]
    body.resolveStrategy = Closure.DELEGATE_FIRST
    body.delegate = config
    body()

    // now build, based on the configuration provided
    node {
        git url: "https://github.com/jenkinsci/${config.name}-plugin.git"
        sh "mvn install"
        mail to: "...", subject: "${config.name} plugin build", body: "..."
    }
}

Assuming the script has either been loaded as a Global Shared Library or as a Folder-level Shared Library the resulting Jenkinsfile will be dramatically simpler:

Jenkinsfile (Scripted Pipeline)

buildPlugin {
    name = 'git'
}

The example shows how a jenkinsfile passes name = git to the library. I currently use a similar setup and am very happy with it.

herm
  • 14,613
  • 7
  • 41
  • 62
  • Thanks, although I already replied and mentioned the shared libraries. – NicolasW Jun 15 '17 at 12:48
  • Regarding the possible duplicate, It is not obvious that the question from the other thread provides answers on how to share a Jenkinsfile accross multiple projects, it is labeled 'How to configure a Jenkins 2 Pipeline so that Jenkinsfile uses a predefined variable', the question in the current thread is 'Multiple projects sharing a jenkinsfile'. – NicolasW Jun 15 '17 at 13:13