With the somewhat recent addition of pipelines to Jenkins, we can achieve pretty much anything we want, as part of our build.

I recently set out to implement what I see as a quite common pattern. That is, when someone merges to a certain branch, deployment to a certain environment is triggered.

I was quite inspired by CircleCIs syntax, where I can declare the following:

...
deployment:
  production:
    branch: master
    commands:
      - bash ./deploy.sh prod

  test:
    branch: develop
    commands:
      - bash ./deploy.sh test
...

This is super elegant in my opinion, easy to read and understand.
I am keeping things simple here, and simply saying that our deployment procedure relies on calling a shell script (deploy.sh), but his could obviously be anything.

All of my build jobs are multibranch builds. That is, Jenkins picks up and builds any branch in the configured repository, if it includes a file named Jenkinsfile in the root. This way, all feature branches gets built whenever there is pushed to it, and test failures, drops in code coverage, etc., will trigger a notification in slack immediately (more on slack notifications in a later post).
However, we don’t want builds of every feature branch to trigger a deployment, we will only want to deploy whenever there is merged to, in this case, one of develop or master branches.

So in order to achieve the same thing as above in our Jenkinsfile, which as you may know is plain old Groovy, we will first of all need to know what branch we are currently building. Fortunately, we can simply get this information from the environment variable $BRANCH_NAME, which in Groovy translates into env.BRANCH_NAME. So now, we can express the following:

switch (env.BRANCH_NAME) {
  case 'master': env.DEPLOYMENT_ENVIRONMENT = 'prod'; break;
  case 'develop': env.DEPLOYMENT_ENVIRONMENT = 'test'; break;
  default: env.DEPLOYMENT_ENVIRONMENT = 'no_deploy';
}
if (env.DEPLOYMENT_ENVIRONMENT != 'no_deploy') {
  sh './deploy.sh'
}

This may not be as elegant as CircleCIs syntax, but still very readable, and on the other hand, we may have won a bit of flexibility. Those env. variables, are proper environment variables, and can be read from subsequent shell scripts, like deploy.sh in this example.
We could even add more environment specific variables to each case block, or specify other environment specific pre- or post-deployment tasks.

From here our deployment procedure can take over, knowing exactly what it needs, based on good old environment variables.

Take a look at this gist, for a full example of a Jenkinsfile, building, testing and deploying a node.js project.

/Christian

Save

Save

Save