Alexander Shishenko
Alexander Shishenko

Reputation: 960

Multi-branch configuration with externally-defined Jenkinsfile

I have an open-source project, that resides in GitHub and is built using a build farm, controlled by Jenkins.

I want to build it branch-wise using a pipeline, but I don't want to store Jenkinsfile inside the code. Is there a way to accomplish this?

Upvotes: 3

Views: 1715

Answers (2)

Colin D Bennett
Colin D Bennett

Reputation: 12084

I have encountered the same issue as you. While the idea of having the build process as part of the code is good, there is information that the Jenkinsfile would include that are not intrinsic to the project build itself, but rather are specific to the build environment instance, which may change.

The way I accomplished this is:

  1. Encapsulate the core build process in a single script (build.py or build.sh). This may call specific build tools like Make, CMake, Ant, etc.

  2. Tell Jenkins via the Jenkinsfile to call a function defined in a single global library

  3. Define the global Jenkins build function to call the build script (e.g. build.py) with appropriate environment settings. For example, using custom tools and setting up the PATH.

So for step 2, create a Jenkinsfile in your project containing just the line

build_PROJECTNAME()

where PROJECTNAME is based on the name of your project.

Then use the Pipeline Shared Groovy Libraries Plugin and create a Groovy script in the shared library repository called vars/build_PROJECTNAME.groovy containing the code that sets up the environment and calls the project build script (e.g. build.py):

def call() {
    node('linux') {
        stage("checkout") {
            checkout scm
        }
        stage("build") {
            withEnv([
                "PATH+CMAKE=${tool 'CMake'}/bin",
                "PATH+PYTHON=${tool 'Python-3'}",
                "PATH+NINJA=${tool 'Ninja'}",
            ]) {
                execute 'python build.py'
            }
        }
    }
}

Upvotes: 1

Joost van der Griendt
Joost van der Griendt

Reputation: 323

First of all, why do you not want a Jenkinsfile in your code? The pipeline is just as much part of the code as would be your build file.

Other then that, you can load groovy files to be evaluated as a pipeline script. You can do this either from a different location with the from SCM option and then checkout the actual code. But this will force you to manually take care of the branch builds.

Another option would be to have a very basic Jenkinsfile that merely checkouts an external pipeline.

You would get something like this:

node{
    deleteDir()

    git env.flowScm
    def flow = load 'pipeline.groovy'
    stash includes: '**', name: 'flowFiles'

    stage 'Checkout'
    checkout scm // short hand for checking out the "from scm repository"

    flow.runFlow()
}

Where the pipeline.groovy file would contain the actual pipeline would look like this:

def runFlow() {
    // your pipeline code

} 

// Has to exit with 'return this;' in order to be used as library
return this;

Upvotes: 0

Related Questions