Continuous integration and continuous delivery with Serverless Framework

Earlier, we set up continuous deployment using IBM Bluemix tools. Here, we will be using open source tools to set up continuous integration and continuous delivery for OpenWhisk functions. I will be setting up a Jenkins container with Serverless Framework installed on it. I have created a Dockerfile that does the heavy lifting for us by creating a Jenkins container with Node.js, Serverless Framework, and an OpenWhisk plugin installed. I have added this Dockerfile to the Git repository. We will be using the weather reporting OpenWhisk application, and we will code it, commit it on GitHub, and then deploy it on the Bluemix cloud through Serverless Framework. We will unit test the application and run a smoke test by invoking the function (see https://github.com/shzshi/OpenWhisk-weather-report-serverless.git). Let's look at these steps in more detail:

  1. Git clone the repository:
$ git clone https://github.com/shzshi/OpenWhisk-weather-report-serverless.git
  1. Once it is successfully cloned, we need to build the OpenWhisk image using the following code: 
$ docker build --rm -f OpenWhisk-weather-report-serverless/Dockerfile -t OpenWhisk-weather-report-serverless:latest OpenWhisk-weather-report-serverless
  1. Once the Docker image is built, we will create a container for the OpenWhisk-weather-report-serverless:latest image, using the following code: 
$ docker run --rm -it -p 50000:50000 -p 8080:8080 -v /Users/HOST_PATH/OpenWhisk-weather-report-serverless/jenkins:/var/jenkins_home OpenWhisk-weather-report-serverless:latest
  1. Now we will go to the browser, navigate to the Jenkins application, and create a job. As my Docker container is running on the localhost, my URL would be http://localhost:8080/.
  1. Open the Chrome/IE browser, paste the preceding localhost URL, and open Jenkins. At the first page, we will be asked for the administrator password. We can get this password from the logs of container run. It should look something like the following:
Jenkins initial setup is required. An admin user has been created and a password generated.

Please use the following password to proceed to installation: 7d4a4a91efb24f369bac95122686bd45
  1. Once we enter the password, we will be asked to install a suggested plugin. Go ahead and do this. It will be a one-time activity, as we are saving the plugin on the Docker host, and once the plugin is added, we will be asked to create an admin user. Go ahead and create the user, and make sure that you remember the password. Then, once the user is created, go ahead and start using Jenkins.
  2. Now let's create a job called Serverless-OpenWhisk. Click on New Item; it will open a new page. Type in Serverless-OpenWhisk in the text box, select Freestyle project, and click OK.
  3. Now select Git in the Source Management tab and add https://github.com/shzshi/OpenWhisk-weather-report-serverless.git in Repositories URL. We won't feed in the credentials as this is a public repository. If we use the private GitHub repository, then we add can credentials for Jenkins to clone the repository.
  4. Next, in the Build tab in the Add build step dropdown, select Execute shell. A Command text box will open up. Let's add the following code in the Execute shell field. You need to replace the OW_AUTH and OW_APIHOST keys that are highlighted with one that we have created previously, or we can log into the OpenWhisk portal and get the details: 
npm config set prefix '~/.npm-global'
export PATH=~/.npm-global/bin:$PATH
npm install
./node_modules/mocha/bin/mocha test/test.js
export OW_AUTH=00700a7f-2b1a-4831-bf32-3a566263ed44:4TBcM7f8g0gj5UPgSVHXwNmMkfpbX36OdWximngOwqZYAJrDSkZwPjeSPjQ45Wm1
export OW_APIHOST=OpenWhisk.eu-gb.bluemix.net
serverless deploy -v
serverless invoke --function main -d '{"location":"Paris"}'
  1. Once that is done, save the job and then click on the Build Now link. The job will then run. It will download and install the npm dependencies mentioned in package.json, then run the mocha unit test, deploy the action to the OpenWhisk cloud, and then invoke the function/action with a parameter to make sure that the deployment was successful. The output will look something like the following:
Building in workspace /var/jenkins_home/workspace/Serverless-OpenWhisk
Cloning the remote Git repository
Cloning repository https://github.com/shzshi/OpenWhisk-weather-report-serverless.git
 > git init /var/jenkins_home/workspace/Serverless-OpenWhisk # timeout=10
Fetching upstream changes from https://github.com/shzshi/OpenWhisk-weather-report-serverless.git
 > git --version # timeout=10
 > git fetch --tags --progress https://github.com/shzshi/OpenWhisk-weather-report-serverless.git +refs/heads/*:refs/remotes/origin/*
 > git config remote.origin.url https://github.com/shzshi/OpenWhisk-weather-report-serverless.git # timeout=10
 > git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
 > git config remote.origin.url https://github.com/shzshi/OpenWhisk-weather-report-serverless.git # timeout=10
Fetching upstream changes from https://github.com/shzshi/OpenWhisk-weather-report-serverless.git
 > git fetch --tags --progress https://github.com/shzshi/OpenWhisk-weather-report-serverless.git +refs/heads/*:refs/remotes/origin/*
 > git rev-parse refs/remotes/origin/master^{commit} # timeout=10
 > git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
Checking out Revision af9511727c7610915701372a7d617e73a03825f5 (refs/remotes/origin/master)
 > git config core.sparsecheckout # timeout=10
 > git checkout -f af9511727c7610915701372a7d617e73a03825f5
Commit message: "updated jenkin host"
First time build. Skipping changelog.
[Serverless-OpenWhisk] $ /bin/sh -xe /tmp/jenkins660311873862513550.sh
+ npm config set prefix ~/.npm-global
+ export PATH=~/.npm-global/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
+ npm install
---
--- Finished: SUCCESS

This aim of this exercise was to show how we can set up continuous integration through Jenkins, Mocha, and Serverless Framework. In the next section, we will see how make it more robust, and learn how to set up a continuous delivery pipeline with the same set of tools. We will also set up automated deployment across the different environments using gates.