This is the last article in a series: “How I develop Meteor apps”. You can jump to the other articles:
- part 1. Package for everything
- part 2. Testing Meteor packages (for humans)
- part 3. Continuous integration and delivery of your Meteor “package for everything” project <- you are here
In the last article in this series I will present you a step by step tutorial of how to add Continuous Integration and Continuous Delivery processes to your “package for everything” MeteorJS app.
What are Continuous Integration (aka CI) and Continuous Delivery (aka CD) ?
CI and CD combined together create a process in which an external server:
- clones your code each time you make a push to the repo
- tests the code against automated tests (usually)
- deploys your code when tests pass.
As simple as that - let’s do it!
I assumed the following:
- your “package for everything” app has tests and those tests pass,
- your code is hosted either on Github or Bitbucket,
- you have a Codeship account,
- you have the basic knowledge of “Meteor up”,
- you have a digitalocean account,
- your app uses the latest version of Meteor (22.214.171.124 in the time of writing)
If you meet all of those criteria, move forward to the first step.
Step 1. Run tests locally
First we have to ensure that tests can be run in the terminal. To do this, instead of
Meteor test-packages --driver-package respondly:test-reporter package:name`
run the following command:
Meteor test-packages --velocity
(you can add
--settings settings.json when your packages depend on it).
When you see in the terminal “TESTS RAN SUCCESSFULLY” and the test runner stopped execution - move forward to the next step.
But if the process is still running:
- make sure you use the latest version of Meteor
- check if in all of your packages you defined mike:mocha-package in the latest version (mike:email@example.com in the time of writing)
Step 2. Setup Codeship for continuous integration
Now it’s time to run tests on continuous integration server for the first time. To do this:
Create a new project
In the first stage Codeship tells you to pick a repository from which the code will be cloned. Pick the right repo and in the next screen set up configuration.
Codeship.io doesn’t have MeteorJS preinstalled, so you have to set up Codeship to download it and install before each test run. There are 2 ways of doing this:
- clone latest Meteor repo from github
- use MeteorJS install script, but before you run it make sure you change the settings so that it can be run by a “normal user” (sudo not required)
Long story short - execution time of the second approach is shorter, so we will use it in our configuration. Paste the following script to “Setup Commands” section (from this discussion ):
curl -o Meteor_install_script.sh https://install.Meteor.com/ chmod +x Meteor_install_script.sh sed -i "s/type sudo >\/dev\/null 2>&1/\ false /g" Meteor_install_script.sh ./Meteor_install_script.sh export PATH=$PATH:~/.Meteor/
What it does:
- downloads MeteorJS install script,
- allows for file execution
- allows it to run by a “normal” user
- installs Meteor
- adds Meteor executable to Codeship.io PATH
And now paste the following:
Meteor test-packages --velocity
(or with --settings part)
This is the same command we use in step 1. Save the project and after the next push Codeship will run your tests automatically.
Step 3. Run deploy locally
Similarly as before, let’s start with setup process to run locally and then move it to Codeship. In the beginning of this article I mentioned that we will use digitalocean along with Meteor up deployment script.
Let’s start with digitalocean.
After logging in create your Bucket with the following setup
- name: pick suitable name,
- for bucket size - let’s go with default version for 10$
- region doesn’t matter here - pick the one closest to you
- image should be latest ubuntu 14.04
Before clicking “save” let’s add 2 SSH keys:
- key on your dev machine - it should be located in ~/.ssh/id_rsa.pub. When in ~/.ssh there are no keys just create one
- key from codeship. You can find it “general settings” of your project
And now you can click “save”.
After about 1 minute the bucket will be created - remember its IP address and move to the next step.
Setup Meteor up (aka mup)
Setting Meteor up is quite straightforward:
- install package: npm install -g mup
- in your project root run
mkdir -p .deploy/staging(let’s say this will be your staging environment) and cd to it
cd .deploy/staging(we use “.deploy” with “dot” as a name for main configuration folder - this way Meteor won’t compile it as other files on run).
- initialize Meteor up configuration: mup init
You can read more details about setting up Meteor up on projects github page.
Meteor up creates 2 files: one with settings.json which will be copied to the server and available under Meteor.settings. Change it according to your project.
The other file is an actual mup configuration. In mup.json change:
- in servers section set up hostname with IP of your newly created Bucket
- remove password key, since we won’t use it. That’s also why you have to uncomment "pem": "~/.ssh/id_rsa". - When you run mup on your local machine it will point to your local key, where on codeship - it will point to codeship’s key.
- change location to "app": "../../" (two folders “above” mup.json)
- and finally in env section set root_url to “http://your_bucket_ip”.
Now add the created files to the repo and push it.
Important info: adding mup configuration files to the repo is a bad thing in general, because suddenly all your secret credentials placed in settings.json will be available to all folks who have access to the git repo. I have proposed this way of set up to demonstrate the process on a simple example - feel free to change anyhow you like.
Run mup locally
first set up created bucket - run:
and after it is done deploy your app with the following command:
If everything went fine you should be seeing your app online under bucket IP address. If not, check logs:
mup logs -f
Step 4. Run deploy by Codeship
Let’s go back to your Codeship project. Under “project settings/deployment” click tab: “add new deployment pipeline”. Basically, pipelines are scripts which will be triggered for different branches.
Choose master as a branch name (it means that it will be run whenever you push something to the master branch and tests pass).
On the next screen choose “custom script” (last option) and under the deployment command write:
npm install -g mup cd .deploy/staging mup deploy
It’s as simple as that (but please note that before this happens you had to add ssh key to your bitbucket to make it work).
Of course, all kinds of things can go wrong. You can verify each command by debugging the build in Codeship. You can read more about it here
Along with CI
After configuring CI/CD you can also set up Codeship to send notifications to your Slack, Hipchat, whatever. This way you will have an immediate feedback on what happens in the code.
Continuous Integration and Delivery are a bless when working with startups, where multiple developers work on the same codebase and 10 deploys per day is a standard.