Continuous Integration & Meteor
Whilst it’s true the the Meteor Development Group have moved their focus to GraphQL & Apollo, the Meteor project remains active and has an avid user base. I’ve been using Meteor in production environments for over four years now and I’m still a fan.
One of my goals has always been to reach development nirvana with Meteor’s rapid, flexible stack underpinned by solid testing and bulletproof deployment methodologies. The Meteor CI Starter Kit is my attempt at doing exactly that.
Consider this basic maxim:
- Write clear, consistent code
- Define RITE tests
- Automate deploys, ship early & often
We can achieve each of these three steps using the starter kit:
- ESLint (and lesserly, JSBeautify) help us write clear, consistent code
- Mocha and Chai help us write our unit tests
- Circle CI and Heroku get our code built & and shipped effortlessly
Technologies & platforms
There are many, many ways to achieve what we’ve described here. Some will be easier to configure, but suffer from vendor lock-in. Some will be more flexible, but require you to dig deeper into their configuration. This guide should hopefully give you the confidence to approach your own integrations & architectures, even if you don’t end up using the tech we’re using here.
There are a lot of steps, and quite a few accounts to set up, but most can use your GitHub account and none require credit cards.
Lastly, code linting is highly addictive, maddening and completely subjective. Don’t take the eslint rules in here as gospel, pls.
Guide
With Meteor installed, simply download the starter kit, run & enjoy some great Meteor-flavoured ESLint rules with pre-commit linting hooks to stop you pushing badly-formatted code.
Test your code using meteor npm run test
and watch
Naturally, to hook this into your CI runner of choice and destination production environment, you're going to have to configure a couple of things. Let’s take things from the top, assuming no prior usage of Meteor:
Install & Run
curl https://install.meteor.com/ | sh
- Download the starter kit
https://github.com/chrisquinnr/meteor-ci/archive/master.zip
cd meteor-ci-master && meteor
So far, so good. We have the starter kit running. I’ll delve into to the kit’s configuration in another article, for now, let’s skip straight onto the benefits.
Pre-commit linting with ESLint
4. Pick a file and remove a semi-colon. If you try to commit this ‘broken’ code, the project will stop you, by using a pre-commit hook which runs eslint
before allowing the commit through.
5. Put the semi-colon back and instead make a small edit to the file, like adding a comment. Try committing this ‘correct’ change and you’ll see it goes through as normal.
Unit testing
6. In another terminal, run meteor npm test
7. Check out the output of the Meteor-supplied unit tests on our basic Links collection.
I’ll cover tests in another article, but for now, let’s acknowledge that we’ve got passing tests configured in our project.
Create a Git repo
8. Create a public repo for your starter kit (https://github.com/new)
9. In the starter kit project root: git remote add origin <repository url>
10. Push the project to your new repo: git push -u origin master
Connect to Circle CI
11. Create a Circle CI account: https://circleci.com/signup/
12. Connect it to your Github account
13. Define a CircleCI project with your project by adding it (it will build straight away, don’t worry if it fails)
We covered quite a lot of different steps here, but hopefully nothing too crazy. If all went to plan, CircleCI will immediately build the contents of your new repo and fail. Yes, fail. We need to hook up a couple of extra options before everything will run smoothly.
Circle CI config
In the starter kit, you’ll see a large and intimidating circle.yml
file — don’t worry, I’ve made sure this is pretty bulletproof, as of Meteor 1.8 and CircleCI 2.0. All we need to understand at this point is that the file has two jobs, build and deploy. Notice that in the deploy job, we’ve simply referenced a Heroku origin path, with some environment variables as placeholders.
Deploying with Heroku
You can hook up any particular hosting provider you like to Circle CI, but I’ll use Heroku for demonstration purposes now and potentially add other platform guides at a later date.
14. Sign up for a Heroku account (https://signup.heroku.com/)
15. Connect your Heroku account to your GitHub repo
Usually, this step is as simple as creating a new app in Heroku and then connecting the app to Github:
16. Select your repo — once connected, you’ll be able to select ‘Enable automatic deploys’ and be sure to tick the option to wait for CI to pass.
17. Grab your Heroku API key and app name and add them as environment variables in Circle CI
Setting up the Meteor App in Heroku
18. To build your app, Heroku needs a couple of configurations variables added.
Buildpack
search for meteor-horse
(no, really) and add this buildpack to the Heroku app.
MongoDB
Grab a free Atlas database (https://www.mongodb.com/cloud/atlas) and follow the prompts to spin up a new cluster (takes a few minutes). Find the connection options for your cluster and select the short SRV string.
Paste this SRV string into your Heroku app’s config vars: https://dashboard.heroku.com/apps/<your-app>/settings
), with a key of MONGO_URL
.
Finish & Test
19. Trigger a new build & deploy by pushing a new commit.
19. Profit???
Summary
At this point, we’ve connected our starter kit to Circle CI and Heroku. When we push a commit to master, CircleCi will
- build, lint & run our application
- run our defined tests
- push the build to Heroku, thereby deploy our application
Which, as I bet you’ve noticed, follows our basic maxims defined above quite nicely:
- Write clear, consistent code
- Define RITE tests
- Automate deploys, ship early & often
Next steps
I think this starter kit is a great way for developers to start using CI — the tech is approachable and clear, it’s easy to get from zero to deployed and the tooling we’ve used is more or less interchangeable. Want to swap Circle CI for Jenkins? Maybe your company already has a mandatory .eslintrc
file you need to use, or maybe you’re deploying to AWS rather than Heroku. In all these cases, you can fork or edit the starter kit to meet your needs (or abandon it & create your own).
If you have an interesting fork or flavour of the kit, send a PR on Github or hit me up at chris@saltedbytes.rocks. Feedback on this guide is welcome too.