How to Deploy Continuously, part 2

Strider CI logo

In previous article Continuous Integration with Strider, part 1 I demonstrated how to set up continuous Integration, that means how to test the code automatically and find out if it the newest changes to code broke it or not. Now that you are automatically testing your commits, the next logical step in automation process would be to release our tested code to live website. We would want it to happen automatically, when all tests pass. We also want it to happen in short cycles, so no huge deployments will happen. If the code breaks, we will know it soon and exactly in which commit did it break. It is easier to spot one bug in one commit than investigate bunch of bugs in twenty commits. This process is called continuous deployment. But wait, there is one more term called Continuous delivery. Let's first look on the difference between them two.

What is the difference between Continuous Delivery and Continuous Deployment?

  1. In Continuous Delivery, when all tests pass, the build will be made and will wait in CI, ready to be deployed. The last step: to deploy code out to wild will have to be done manually by some person.

  2. In Continuous Deployment the whole process from commit, through testing to deployment is automated. The Continuous Integration system will automatically deploy the code and switch to it, only after all tests pass and build is ready. This is fully automated cycle.

It's hard to tell which one is better. Probably the best answer is: it depends on needs of your company/project. There might be companies which needs to wait until certain time to deploy new feature. While continuous deployment may not be right for every company, continuous delivery is an absolute requirement of DevOps practices. When you continuously deliver your code, you have confidence that your changes were tested and built properly and ready to deliver to your customers within seconds of pushing the "deploy" button. Actually once the Continuous Integration tool is set up, anyone with access to Continuous Integration tool can press deploy button when the business is ready for it.

Continuous delivery vs Continuous deployment

Steps to Continuous deployment with Strider

Let's say that our application skey.uk has a brand new api and we want to deploy it to http://api.skey.uk/. That url will be our production api. We will set up this api such way, that it will be easy to setup another api (staging or testing). I split the process into the following six steps:

  1. Configure environment variables
  2. Create deployment script
  3. Start Api first time
  4. Setting up different branches
  5. Turn on continuous deployment
  6. Setup proxy for Apache Virtual Host

1. Configure environment variables

Sometimes you work with different environments: let's say develop, test, staging and production. Each of them connects to different database with different credentials. Some of them may run on different hostnames or different ports. In the past, I used to have many if conditionals through my code, where I was checking IP address of server and based on it, I decided what environment it is. Or I was checking location of root folder of project or their combination. Trust me, that approach doesn't work well and usually ends up as total mess. There are also other options like exporting system variables, to which the server usually has access. That too didn't work for me, mainly on shared hostings where I couldn't set these up. Finally I started to use dotenv files. It is simple text file and looks like this:

NODE_ENV=develop
    
PROTOCOL=http:
HOSTNAME=localhost
PORT=3000
    
DB_USER=username
DB_PASS=password
DB_HOST=localhost
DB_NAME=thedbname
DB_PORT=27017

It is the combination of keys and values, empty lines ignored, string values inside double quotes. Using dotenv package mentioned above, you can easily access these values as variables in your node application. I usually add to git repository only .env.example file for referencem which is like placeholder with correct keys. The file with real passwords is not part of git code. Thanks to this reference file i know, what values I need to fill in. The only condition in code repository checks if the .env file is present, otherwise shows error page.

We will need to prepare such dotenv file for our production api. Let's call it .env.production. We need to fill correct values in this file and we will store the file in safe place. It doesn't matter where we save it, unless it is not accessible by unauthorized people. I placed it into /root/.strider/dotenv folder as this is default build directory for our CI. You probably see the larger picture, that in case of setting up other servers, like staging one, you would place here .env.staging.

    stefan@webserver:/stefan/.strider/dotenv stefan$ ls -la
    total 16
    drwxr-xr-x 2 root root 4096 Apr  1 16:31 .
    drwxr-xr-x 5 root root 4096 Apr  1 16:31 ..
    -rw-r--r-- 1 root root  188 Apr  1 16:30 .env.production

2. Create deployment script

You may have seen in Strider in last post that when I was defining Custom tasks, I left shell input field for Deploy empty. Commands in that field are run only when we are deploying code. We could write all commands straight in that field, but instead we will save those steps into shell file and store it in our code repository. Therefore type in Deploy field:

# put your shell code here
bash ./bin/production-deploy.sh

As you can see, we are going to create production-deploy.sh file in folder bin in our code repository . Again, the file name and folder name can be named to whatever. The .sh file extension means, that we are going to write shell commands. Open the IDE of our choice, create that file in your code repository and add these lines into file:

#!/bin/bash

NOW=$(date +"%F_%H%M%S")

cp -r $PWD /var/www/api.skey.uk/build-$NOW

cp /var/www/api.skey.uk/dotenv/.env.production /var/www/api.skey.uk/build-$NOW/.env
cd /var/www/api.skey.uk/build-$NOW && npm run mongo-migrate

rm -r /var/www/api.skey.uk/current
ln -s /var/www/api.skey.uk/build-$NOW /var/www/api.skey.uk/current

pm2 restart my-api

The line 1 says that the following will be bash shell commands. The line 3 will set the current date and time into shell variable NOW. We will use this date to create folder name for current build. The line 5 will copy the content of Present Working Directory ($PWD) to our deploy location. PWD will return us the directory where the strider builds the code and if you didn't specify it different in .striderrc file, then it will be /root/.strider/data/.

The line 7 will copy our dotenv file with production configuration from our safe place directly into our new build and will also rename it from .env.production to .env. The line 8 will in my case run all new migrations and seeds. You may not have to have this, but I do have to run it for my project.

The line 10 will remove current folder/symlink and line 11 will create a new symlink from new build directory to point to current directory. These two commands will happen in a few miliseconds. Effectively it's atomic operation as nothing is copied, you just switch pointing from one directory to another.

Finally the line 13 will restart the my-api node process, which will load node from new current files.

3. Start Api First time

First time is always a bit different, your youth self may remember

Skey

There are some steps which needs to be done before automatic deployment script can be run. - We will have to create deployment folder manually, otherwise the automatic deploy will fail to copy build:

 stefan@webserver:~$ cd /var/www
 stefan@webserver:/var/www$ mkdir api.skey.uk
 stefan@webserver:/var/www$ cd api.skey.uk
 stefan@webserver:/var/www/api.skey.uk$ mkdir current
 stefan@webserver:/var/www/api.skey.uk$ ls -la
 total 28
 drwxr-xr-x  7 root root 4096 Apr  1 15:25 ./
 drwxrwxrwx 28 root root 4096 Apr  1 15:25 ../
 lrwxrwxrwx  1 root root   45 Apr  1 15:25 current
  • Next, we will make first build and start the pm2 service, otherwise our command pm2 restart my-api in deployment script will not work. As you can see below, the first deploy steps are very similar to our deployment script. Your project may have a slightly different steps. What I'm doing here is cloning my git repository into current folder, then copying dotenv file, then running npm install and migrations and lastly starting pm2 server with name my-api:
stefan@webserver:/var/www/api.skey.uk$ NOW=$(date +"%F_%H%M%S")
stefan@webserver:/var/www/api.skey.uk$ git clone https://skecskes@bitbucket.org/skey/api.skey.uk.git ./current
stefan@webserver:/var/www/api.skey.uk$ cd current
stefan@webserver:/var/www/api.skey.uk/current$ cp /stefan/.strider/dotenv/.env.production /var/www/api.skey.uk/build-$NOW/.env
stefan@webserver:/var/www/api.skey.uk/current$ npm install
stefan@webserver:/var/www/api.skey.uk/current$ npm run mongo-migrate
stefan@webserver:/var/www/api.skey.uk/current$ pm2 start ./bin/www --name my-api
┌───────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────────────┬──────────┐
│ App name  │ id │ mode │ pid   │ status │ restart │ uptime │ memory      │ watching │
├───────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────────────┼──────────┤
│ strider   │ 0  │ fork │ 679   │ online │ 1       │ 24D    │ 31.770 MB   │ disabled │
│ my-api    │ 1  │ fork │ 22730 │ online │ 0       │ 1s     │ 04.699 MB   │ disabled │
└───────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────────────┴──────────┘

The following is an idea of how our deploy folder could look like after several deployments. That each build is in a separate directory. There is only one current folder and that points to last build. The pm2 process with name my-api was and is always called from current folder, so it loads correct configuration variables.

 stefan@webserver:/var/www/api.skey.uk$ ls -la
 total 28
 drwxr-xr-x  7 root root 4096 Apr  1 23:36 ./
 drwxrwxrwx 28 root root 4096 Apr  1 23:35 ../
 drwxr-xr-x 14 root root 4096 Apr  2 09:12 build-2016-04-02_091230/
 drwxr-xr-x 14 root root 4096 Apr  3 10:48 build-2016-04-03_104813/
 drwxr-xr-x 14 root root 4096 Apr  4 14:33 build-2016-04-04_143320/
 drwxr-xr-x 14 root root 4096 Apr  4 23:36 build-2016-04-04_233646/
 lrwxrwxrwx  1 root root   45 Apr  4 23:36 current -> /var/www/api.skey.uk/build-2016-04-04_233646/

In case of some bug we can switch to previous build by creating symlink to previous build. We may also add some script which will check and delete old builds to save so some hardisk space. We could also add some command to do database backup before deploy and upload the backup into AWS S3 storage. Basically you can shell script any functionality to this deployment script. This article shows you only basic steps to deploy.

4. Setting up different branches

Now you are ready with scripting and we can come back to Strider's backend. We have to specify when will the deployment happen. I assume that your git flow has some branches like master, develop or feature/make-this-work. Let's also say that master branch should always mirror what is in the live server, develop branch should be always on staging server and you just work on branch feature/make-this-work on your latest changes. The strider will currently run tests and deploy after each commit.

Therefore we have to specify what should happen after you push commits to individual branches. Open you project and click on branches menu item. You should see the page like on image below. Each of the branches can have separate steps on preparing build, testing or deploying. We will specify master, develop and *. Star is a wildcard for all other branch names.

Branch management in Strider

Now you can switch to different branches in menu from dropdown.

Selecting branch in Strider

As you are switching from one to another, you will probably see the notice on screenshot below. Click on each Customize Branch button. We will customize each branch as we want Strider to do a slightly different thing with each of them.

Customize each branch in Strider

5. Turn on continuous deployment

Now we can select each branch from the dropdown and set settings and plugins for it. Let's select master branch first and go deeper into settings.

Setting options offered here are:

  1. Active - when ticked tests and deploys will happen automatically. We want to have this ticked on master branch and develop branch. Both branches should be stable to run tests and/or deploy to production/staging server. We probably don't want it active on * as our /feature/make-this-work may be in development and may fail tests, we don't want the whole team to receive email always when you commit to your feature branches. However, if you wish to run tests, you can do so manually. Each developer should be able to run his tests on his own environment even without Continuous Integration tool.

  2. Deploy on green - means that it will deploy the code, when all tests pass. We will not tick it on * branches, just because we don't want to deploy after commit to branch /feature/make-that-work. If we are deploying develop branch to some staging server, we may click it. If we are doing Continuous Deployment on production site, then we will definitively keep it ticket. But if we are doing Continuous Delivery then we will untick it, because we don't want automatic deploy.

  3. Deploy on Pull Request - In case you don't have any tests, you can use this option to deploy the code after each commit. I wouldn't ever do that without tests, but here you are the option in case you need it. We will not tick this in our examples.

Deploy switches

From left menu select Custom Scripts and check that Deploy shell area contains the bash ./bin/production-deploy.sh command on master branch. Other branches shouldn't have this and deploy field should stay empty. In case you want to deploy to staging server, you will have to write another shell file which will be very similar to this one, but will deploy to different folder and use different dotenv file.

Now you are in stage where you could see your first fruit from work so far. You can make your first deploy from Strider. You can do so by clicking on blue Deploy button or by pushing commit to master branch. If everything goes right, your tests turn green, you should see your new server deployed, up and running. Go to browser and type the url of your node project. In my case, I specified in dotenv file my project to run on localhost on port 3000, so I should type in browser http://localhost:3000 and the api index page should be there. If you specified different hostname or port, go ahead there.

Of course, if you are running it on your remote server or cloud, you will be not able to see it through localhost url. On my server I have running apache server which controls all connections to port 80. Therefore I see theese options here, on how to set it up: - I can set hostname and port in dotenv file and use it (for example: api.skey.uk:3000/) - I can set webserver like apache or nginx to proxy my node server to different url and port

6. Setup proxy for Apache Virtual Host

As you see I didn't like the port and want a nice clean endpoint for my new API: http://api.skey.uk/ . If you want the same, don't worry, because the solution is very simple. We will have to ssh into our server, go into apache configuration folder for virtual hosts and open the skey.uk.conf:


stefan@webserver:~# cd /etc/apache2/sites-available/
stefan@webserver:/etc/apache2/sites-available# nano skey.uk.conf

and add some lines, best on the top of the file:


<VirtualHost *:80>
    ServerName api.skey.uk
    ServerAdmin info@skey.uk
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/
</VirtualHost>

The above code will tell to apache webserver to listen on port 80 and if the requested server is api.skey.uk, then it will proxy it to localhost:3000, which is our new node api. Don't forget to restart the apache web server to activate this new virtual host.

Ta-daaaa, open browser and type in http://api.skey.uk :-) Well done.

Conclusion

We have setup Strider CD to make automatic Continuous Deployment. We also showed how to store passwords in dotenv file so the environment specific configuration details are not stored in code repository. We created script which will deploy our code. The script can do other tasks too, like backing up database, running some cron, or deleting old assets. Finally we looked into Strider and set it up to use our deployment script and configured branches, so that each branch can do something else.

Happy Continuous Deploying!

Tags: ci, strider, nodejs


Continuous Integration with Strider, part 1

Strider CI logo

We, developers, are producing websites or applications for many years now. What kinds of tasks needs to be done, before we see the changes live on web. This was a big unknown to me for a very long time. Is my process of deploying the code the best practice? Should I do it other way? When I started creating websites, there was only one task and it was to deliver updated files to web server. I usually used the FTP client with nice GUI (graphical user interface). I logged in to IP address using login and password and copied files from left to right. :) Then I went to website, refreshed the page and checked that the changes are live. Simple, or not?

We used this approach in my very first job. I still remember the day, when I took down the website of my employer for first time. I made some new feature to the code. Marketing manager already sent out newsletter emails to customers and she was pushing me to deliver that feature that morning. It worked on my machine, so I decided to upload it to the live server with FTP client and I went straight for a brew to ease the stress. I have spent around 10 minutes drinking coffee in kitchen, looking outside the window (it was one of those nice sunny mornings in England). I was contemplating myself about my cool addition to the code and the genial way how I fixed the issue. I was also expecting thanking email from manager for delivering the feauture on time. When I went back to office, the reality was "a bit" different. My colleague was on phone explaining to CEO, that we are aware of that issue and that the whole web dev team is looking into the issue as highest priority task. I sat to my computer and I realised it. The website was down! You know it, the error was typical white blank 500 page. In that time we didn't even used version control system and my colleagues didn't know that I have uploaded some updated files. They where wondering why has suddenly website gone down out from the blue. I have soon realised, that the problem was in my shiny new code. I fixed it fast and the website was up again. It was down altogether about 25 minutes. I've checked my emails only then. They were from managers, not even one was thanking me for the new feature. Also my capability went down in eyes of my colleagues. That was the time before we used versioning systems or tests. The times I call 'wild west', where each cowboy shot first and asked questions later, where you didn't have best practices and everybody made changes his own way. The times where chaos and uncertainty about code stability was a normal way of life.

Later I started to work for larger company on a bigger project where the release process was more complicated than just uploading few files with FTP. The release was complex thing and it had to be done each time the same way, without any error. Otherwise the website would be down altogether with hundreds of clients surfing it at any time. I would again expect a not joyful call from my boss. The code consisted from several repositories which had to be cloned into certain folders and symlinked together in subfolders, there were unit tests for each repository which had to pass in order to get to build stage. Even though in that time we weren't using any package managers like composer or npm and we weren't processing assets with gulp or similar tool and we weren't making DB update migrations, seeds or preprocessing images. It was still very complicated and I could see at least 10 places where it could go wrong.

What we want to achieve?

We can now see that the process of releasing the code to server can be more complex, than just simple FTP upload. We want to keep all changes in code repository - prefererably GIT. We will automate the build, which means that we will run all tasks required in order to have working code and testing DB. Then we will run the self-testing, unit tests, behavioural tests or whatever tests we have. We will force developers to commit often, which reduce the number of conflicting changes to code and also is much easier to find errors in small commits. We will run CI after each commit. We need to run CI on develop branch too. That way we never merge failing branch to master branch. The testing environment should be very same to production environment (same version of OS, same version of DB server, same web server, same firewall settings, etc). Everyone should be able to see the results of builds - when it fails, what was broken and by whom. We will also receive an email when the status of repository changes to fail or when the failed build is fixed.

Selecting Strider CI

In this post I will be using an API code I'm currently working on. API is built in express framework on Node.js server and using mongoDB. There are many tools for Continuous Integration and I selected to use Strider, mainly because it: - allows me to install it on my own testing server, which copies the production environment. - it is open source software, check it out on github - it is written in javascript, same as my code and running javascript code from it should be easy - it runs on node.js, same as my code - it is also Continuous Deployment platform - you can code your own plugins and extend the functionality of Strider CI

Requirements

I assume you have the following:

  • access to terminal on Unix server
  • node.js
  • mongoDB
  • GIT

Installing and configuring Strider CI

  1. Install Strider
  2. Set up mongoDB
  3. Create initial admin user
  4. Running Strider
  5. Setting SMTP credentials
  6. Login and adding repository
  7. Selecting plugins
  8. Adding repository
  9. Setting up CI

1. Install Strider

Installation of Strider is quite straightforward, thanks to instructions on github. Install the Strider globally with:


    npm install -g strider

alternatively you could get the code by cloning from git and installing all dependencies. I prefer this aproach as I have more control of how it runs.


    cd /var/www/
    git clone https://github.com/Strider-CD/strider.git .
    cd strider
    npm install

2. Set up mongoDB

Setting up mongoDB in mLab

The CI uses mongoDB for storing users, invitations, repository information and so on. You can use locally installed mongoDB or use a remote one. The default values are set to use the local one and if you decide to use this, you don't need to make changes in this step.

I decided to use remote mongoDB, so I can show you how to set it up. I have found mLab have sandbox plan, which offers a mongoDB with 500MB capacity for free. This is much more than our CI will ever need and therefore we will use it. Create an account and create a database as shown in screenshot. Select the free option and confirm that you agree to terms and conditions. mLab will create a mognoDB with name you want, I typed strider-foss.

Now that you have database, check the url of db. We will need it to set up the Strider. You will also have to create a user and password to connect to this mongoDB and it should be different from your mLab username and password.

Details about created mongoDB

Guys behind Strider prepared for us to use file called .striderrc, which is basically a json configuration file. It is used by Strider when the node.js server is starting and these configuration values can not be changed later at runtime. Lets create that file inside the Striders main folder:


    nano .striderrc

now add our details of mongoDB in it. Your url will be slightly different from mine. Use the mongoDB user and password you created in mLab before.


    {
        "db_uri": "mongodb://dbuser:dbpassword@ds035985.mlab.com:35985/strider-foss"
    }

3. Create initial admin user

You will have to create the initial admin user to be able to log in into the Strider. Luckily guys behind Strider thought about this and they have created a simple script which guides you through steps and creates new user for you by simply typing:


    node bin/strider addUser

Example:


    $ node bin/strider addUser
    Enter email []: strider@example.com
    Is admin? (y/n) [n]: y
    Enter password []: *******
    
    Email:    strider@example.com
    Password: ****
    isAdmin:  true
    OK? (y/n) [y]:
    22 Oct 21:21:01 - info: Connecting to MongoDB URL: mongodb://ds035985.mlab.com:35985/strider-foss
    22 Oct 21:21:01 - info: User added successfully! Enjoy.

You can see that Strider will use database strider-foss in mongoDB. That is the name of DB we have created in mLab.

4. Running Strider

Now you are ready to simply run the Strider with:


    NODE_ENV=production npm start

If you open browser now and type in http://localhost:3000 or http://0.0.0.0:3000 you should see the strider login page, where you can login with your new Strider admin credentials. That hostname and port are default for Strider.

However, the CI server I use is not located on my localhost. In fact, it is virtual machine in AWS cloud and therefore I couldn't see it in browser as it is set up now. I need to pass some parameters to node when starting strider. I can do these by exporting environment variables, something like the below before running strider:


    export SERVER_NAME=strider.skey.uk:3000

The other option is to send the parameter altogether when starting the node.js:


    NODE_ENV=production SERVER_NAME=strider.skey.uk:3000 npm start

Both options are not very optimal. We may forget to add variable when we strat the Strider few days later and we may end up investigating few hours what is wrong. I think the optimal solution is to store this configuration into .striderrc file. So again, go to Striders main folder and open/create .striderrc with:


    nano .striderrc

Now add server name and port on the end of json:


    {
        ...
        "server_name": "http://strider.skey.uk:3000",
        "port": "3000",
    }

Please note: In order to create subdomain with node.js, the DNS record for that domain must point to IP address of your server. If you don't have domain name, you can use ip address as well.

Tip: I used for my Strider CI port 3000 or I could use any other free port. On the same server I have running Apache webserver, which controls port 80. Therefore I could not set port 80. What I could do in this situation is to set up virtual host in apache with subdomain strider.skey.uk and port 80. In vhost setting I would set it to proxy to the port 3000 which is our node.js server running Strider CI. Then I could simply type in browser http://strider.skey.uk . I don't know your server configuration and so I don't want to confuse you with unnecessary setting.

Tip: AWS EC2 instances are usually preset with closed ports as it is the recommended practice. Because it is also our case, I had to log in to AWS console and open the outgoing TCP port 3000 for this instance to be able to use Strider on that port.

So now we can run the Strider with a simple node command and it's loading the correct configuration, but when we end the command and close the ssh connection, the Strider CI stops too. Therefore we want to run the Strider as service. We could use Upstart job on Ubuntu and create script that would daemonize Strider. That would be solution specific to one OS only. Instead we want some more generic solution. We want be able to run on any operating system. The solution is pm2. Pm2 is advanced node process manager which allows us to run node instances as services, list them, monitor them and restart or stop easily. Firstly we will install it globally using npm


    npm install pm2 -g

That's it. Now that we have fully configured Strider, we can run it with pm2:


    $ pm2 start bin/strider
    
    [PM2] Starting bin/strider in fork_mode (1 instance)
    [PM2] Done.
    ┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────────────┬──────────┐
    │ App name │ id │ mode │ pid   │ status │ restart │ uptime │ memory      │ watching │
    ├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────────────┼──────────┤
    │ strider  │ 0  │ fork │ 57541 │ online │ 0       │ 0s     │ 7.711 MB    │ disabled │
    └──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────────────┴──────────┘
     Use `pm2 show ` to get more details about an app

As you see, pm2 created an instance and tracks its status. You can list all running instances with pm2 list or you can restart any node instance in case of configuration change with pm2 restart strider. You can also start more node.js instances and pm2 will keep track of all of them.

5. Setting SMTP credentials

We will need to setup SMTP credentials to be able to send emails when CI tests pass or fail. Again, the choice is up to you: - you may host your own smtp server - use the SES from AWS - use some other free service, such as Mandrill

In my case, I use SES from AWS. I had to validate email used for sending through SES and I created ticket requesting 300 emails per month. The customer service sorted out my ticket within hour, giving me free 50000 emails per day at rate 14emails per second. That's much more than Strider will ever use. To set up SMTP credentials you will have to open .striderrc configuration file again and add your details at the end:


    {
        ... 
        "smtp_host": "email-smtp.eu-west-1.amazonaws.com",
        "smtp_port": "587",
        "smtp_user": "",
        "smtp_pass": "",
        "smtp_from": "Strider CI noreply@skey.uk"
    }

SES will provide you with username and password. After saving your settings, you have to restart the node.js running Strider to activate the changes. This time we use pm2 command:


    pm2 restart strider

6. Login and adding repository

Now that we had setup everything required, we should open browser to your Strider instance http://strider.skey.uk:3000. You should see a login form with email and password. Use the admin account which we created before using striders script.

Login page to Strider

7. Selecting plugins

Go to plugins area in Admin menu and install or update the plugins which you want. The ones we will use is Custom Scripts and Email Notifier. You can add more plugins anytime to add more functionality.

Installing and updating plugins in Strider is easy

8. Adding repository

Strider supports oAuth for github and bitbucket to connect it easily with your repository. However, if you have all the details, you can connect to any server with GIT repository. In my example, I connected Strider to bitbucket through oAuth. I also created a special user in bitbucket for Strider, towns-deployer, who has privileges to read repositories and create webhooks. Creating special bitbucket user for Strider is not necessary, but I have learned from past that managing special users for this type of task is better than changing permissions on your own bitbucket account. Strider has access to all repositories of deployer user account. This is thanks to oAuth authentication. You can see on screenshot, that Strider loaded list of all repositories, the user has access to and we can set up CI for each of those repositories.

You can set up CI for all repositories of bitbucket user

9. Setting up CI

Select the repository you want to configure for CI. I don't want to go into deep details on all options, because the interface is quite straightforward.

Service hook is simple record in git repository to make some HTTP request to url. This can be before commit, after commit, after merge, etc. The URL of service hook is usually some API, which will trigger some action. In our case the service hook will be triggered after commit and will call the Strider CI API, which will trigger the test. You will want to setup service hook which is in last menu item Provider: Bitbucket. It will authorise bitbucket to touch url in Striders API and that will automatically trigger CI for you. That means, that Striders CI will be triggered on each commit or merge in bitbucket repository.

Setting up Service Hooks

You can also set up branches on which you want to run CI. You can set different CI plugins and steps for each branch or you can have same setting as on master branch. I prefer having develop and master customized. Other branches doesn't need to be tested for me, but you might be using different branching strategy. I want tests to be run on develop branch always, before I merge changes to live master branch.

Customize branch or leave it same as master

You can select plugins and their order on each customized branch. Therefore develop and master branch might have different test and deploy scenarios. Some of the plugins have some extra settings or fields to fill n and some of them don't need any setup. As you can see on screenshot I added two plugins to runner and are displayed in left menu: - The Custom Scripts - The Email Notifier

Selected plugins

Email Notifier will send us emails about results of the tests. The Custom Scripts is the most interesting and basically makes all the hard work. It is split into few parts, which are run in given order.

Custom Scripts plugin is divided into 5 sections

Environmnet

Environment is a space where you can run some commands which prepares the server. You can here also install node or git or maybe just copy configuration file from some AWS S3 bucket. It's up to you what you need to prepare, but in my case everything is ready for CI. The git repository is cloned out after Environment and before Prepare stages.

Prepare

Prepare is the stage where you are preparing the build, the git repository is already cloned out and we can install npm dependencies, migrate DB entries into our DB and finally start node server with API from repository.


    npm install
    npm run mongo-remigrate
    pm2 start bin/www

Test

Test is the most important part of CI. You can define here all commands which will run the tests. In my case I had simple javascript linter run through gulp. The second one is Mocha.js behavioural testing run by npm. You can add as many tests as you want. Just remember one rule: if any of these tests throws error, the next stage Deploy will not be run, and the build will be marked as failed. Also please remember, that the code quality is only as good as is the quality of tests.


    gulp test
    npm test

Deploy

Deploy commands are run only when automatic tests pass or when you manually click "Deploy the build" button.

Deploy Button

Cleanup

Cleanup will be run in any case at the end of testing or deploy. In my case, I'm just stopping the API node server to clean up resources and delete it from the pm2 list of instances.


    pm2 stop www
    pm2 delete www

After the test you will receive email about results of test. Therefore you don't have to log in to Strider each time you commit to check the results.

Email report about passed tests for commit to develop branch

Conclusion

At this point, you may want to create snapshot of your AWS instance, in case you would like to deploy more CI instances later. You now have a GUI tool set up to make CI. You can invite your coworkers, so that they will also see the state of current project and will be notified by email when anything goes wrong. You can also begin to explore other Strider's features and plugins.

Strider is quite new tool and is still heavily developed as you can see on github. To update your Strider CI with new fixes of bugs, simply log into terminal and run as root:


    npm update -g strider

In case you didn't install Strider globally, you have to go to the folder with Strider and run:


    npm update

PS: Using this setup few years ago I would know that my hotfix will break the code and take down the website. I would also know it even before the changes would be merged to master branch. I would also be appreciated by my manager and my future would be much brighter. Please, do use CI for the brighter futures!

Tags: ci, strider, nodejs