As developers, every second we save in our development process, adds up to make us that much more efficient. The faster we test our code and deploy, the faster our end users get a better product.
The concept of continuous delivery helps us keep an optimized and quick build process. Here's a top down view of what continuous delivery consists of:
- Push code to your Git repo
- Run automated tests
- Code is deployed to a hosting environment
All of the above happens automatically after you push to your repository. Having a continuous delivery system makes all the major tasks that you have to do simple and easy. A fully automated system can help save an incredible amount of time. This is where Codeship comes in.
What is Codeship?
Codeship will do all of the above for you and provides a powerful service with an extremely easy to use dashboard. Their free plan provides:
- 1 concurrent build
- 1 testing pipeline
- 100 private builds/month
- 5 private projects
- Unlimited team members
- Unlimited for open source
To setup a project on Codeship that will automatically run tests and deploy to your chosen host, we will have three steps to complete:
- Setup Git repository
- Create tests
- Create deployment
Let's look at how we can deploy an actual project in practice using GitHub, Codeship, and Heroku.
Testing and Deploying a Node Appplication
For this example, we will be using the meanjs.org MEAN stack starter kit. This project gives us a great foundation for a simple application that we can test and deploy.
The starter kit provides a Node application that comes with tests that are run using the task runner Grunt to run Mocha tests for the Node back-end code and Karma tests for the Angular front-end code.
Related Reading: For information on deploying Node applications to Heroku (without the automated and continous delivery), read: How to Deploy a Node.js App to Heroku.
Setting Up the Project
Go ahead and fork the meanjs.org GitHub repo so that we can use our newly created Git repo as the basis for our continuous delivery experiment.
Once we have that repository forked over to our GitHub account, go ahead and clone your project locally if you'd like to test. In my case, I use the following git command:
Clone the Newly Forked Repo
$ git clone firstname.lastname@example.org:sevilayha/mean
Make sure you have a local instance of MongoDB installed and running using:
Install npm Dependencies
Install the dependencies for the project using the npm command:
$ npm install
Now that we have setup our project, let's run it by starting up the project with Node:
$ node server.js
We'll be able to see our project in browser at: http://localhost:3000.
Great! We got a MEAN stack app up pretty quickly. Now let's see how tests are implemented because we'll want Codeship to run our tests every time we push to our repository.
If we look into the
Gruntfile.js, we can see that there are three tasks built for testing on lines 181-183:
grunt.registerTask('test', ['test:server', 'test:client']); grunt.registerTask('test:server', ['env:test', 'mochaTest']); grunt.registerTask('test:client', ['env:test', 'karma:unit']);
grunt test task will run both the server testing task and the client testing task. Just to be sure that everything works perfectly, let's test out the well... tests. Go ahead and type:
$ grunt test
Important Note: We can run the back-end and front-end tests with separate commands using
grunt test:server and
We'll be able to see the tests run and hopefully we'll see everything passing! Now this would take up a lot of our time if we wanted to keep running tests on our code manually. What happens when we have multiple people on a team all pushing code to the same repository? We wouldn't want to have someone test all the new incoming code. That would not be the most fun job in that development team.
We now have a Node and Angular stack application with working tests. Let's get this integrated into Codeship so that our tests are run automatically on every push. After we've got that configured, we'll set up deployment to Heroku automatically!
Hooking Up Codeship to Our GitHub Repo
This is probably going to be the simplest of all the steps. Just login to Codeship, link your GitHub account, and select your repo. We are going to start our first project.
And link our GitHub repository.
We'll be given a list of our repositories that we can choose from:
Once your repository is selected, the next step is to setup your tests.
Test Driven Development and Behavior Driven Development have become very popular recently and rightly so. Implementing testing into our projects helps keep quality high and our development process efficient.
Codeship provides a simple interface (two textareas) to input two things:
- Setup commands
- Test commands
Just like we did locally, our setup commands will be:
And our test commands will be:
It's that simple to setup Codeship with our tests! Now whenever we push to our repository, Codeship will grab the new code, create a new virtual machine, install Node dependencies, and run our tests. We can also setup notifications for build errors or successes.
If we change something in our repo, git commit and push, we can see that Codeship will recognize the change and trigger a build.
If we click into that build, we can see exactly what commands are being run and how long they take. This build ran successfully and took 1 min 30 sec.
This entire system is now automated and our tests will run when our code is pushed to the repository. Much simpler than running tests and checking the repo manually.
Codeship will also conveniently provides a multitude of notification options for build errors or if you want to be notified of certain events.
Codeship comes with a lot of integrations for build notifications. You can integrate with email, GitHub, Hipchat, Campfire, Grove, Flowdock, and Slack. There is also a free Chrome extension for Codeship build notifications called Shipscope.
By default, you will receive email notifications if a build has failed:
There are also badges that can be placed on your site or GitHub repo so that users can see that all builds are green!
Now that we've gotten our setup and first round of tests ready, let's look at a neat new feature that will speed up our workflow even more. This new feature that Codeship recently released makes builds even faster than they already are.
While this build only took 1 min 30 seconds, when this application gets larger and has more tests, this time could go up much further. When you have multiple developers pushing and deploying their code, the more automated and faster this process is, the better. Etsy is a prime example of a company that deploys a whopping 30+ times per day.
Codeship's new feature, ParallelCI, allows you to create multiple testing pipelines to greatly increase the speed of your builds. Earlier, we noted that the MEAN stack starter kit had two sets of tests (back-end and front-end).
Let's split those two test tasks into parallel testing pipelines and see how that improves our build times. When we create testing pipelines, they will run parallel to each other, which means that one doesn't have to finish before the other starts; they both run at the same time and don't interfere with each other.
How is this done? Codeship will create separate VMs for each testing pipeline. Each VM will run your setup commands and then do its set of testing.
Let's setup another testing pipeline and name this Test Frontend.
Now we'll change the testing commands for each pipeline to:
# first testing pipeline grunt test:server # second testing pipeline grunt test:client
ParallelCI Build Speed Increase
Now when we push to our repository and trigger a build, we can see the next build happening with ParallelCI.
We can see both testing pipelines are running:
You'll notice your tests run quicker than the original build. This is because of the ParallelCI testing pipelines. We can see the comparison of the two builds.
Original Build: 1 min 30 sec ParallelCI Build: 27 sec
Even for a simple application like this with some quick tests, the speed improvements are apparent.
Now that we've got testing configured and optimized, let's look at deploying our application to Heroku.
Codeship lets us configure deployment pipelines to have our applications pushed out to hosting environments as soon as the tests are run successfully.
We can create deployment pipelines as complex or as simple as we want. If you want to include a staging server and QA server in the mix, then by all means. For our purposes, we'll create a very simple deploy to Heroku pipeline.
Codeship provides many options for supported hosts including:
- Google App Engine
- Cloud Foundry
If the above hosts aren't where you deploy to, then you are able to configure custom script deployments very easily. In our case, we will set the master branch to go to Heroku.
All we need are our Heroku app name and API key. You will need an already created Heroku application ready for this integration. Create one from the Heroku dashboard by clicking the plus sign.
Related Reading: Learn how to create an app on Heroku. Deploy a Node.js App to Heroku.
Getting Heroku Ready
There are a few steps we'll need to get our app ready for Heroku. We have been using a local instance of MongoDB, but we don't have that luxury on Heroku. We will need to add the free MongoLab addon.
From the command line, make sure you have the Heroku toolbelt, and type:
$ heroku addons:add mongolab
Once that is installed, you'll be able to see the MongoLab addon in your Heroku dashboard.
We will now need to grab the MongoDB URI so we can connect to our database. To find out our MongoDB URI, type the following into your command line:
$ heroku config | grep MONGOLAB_URI
That will spit out your URI including username and password. We'll have to go into our MEAN app and change the database URI for production since that's the environment that will connect to this MongoLab instance.
config/env/production.js, add this URI to the
Commit and push this new change and Codeship will handle the rest!
We can see the build, the tests, and the deployment all happen.
Then we can see our application in browser!
Hopefully this gives you a good overview of how Codeship and continuous delivery can help increase the speed and efficiency of our code.
Be sure to check out Codeship and the great features that they offer. Go forth and implement your own continuous deployment/integration/development system!