Continuous Integration with TravisCI
Goals
By the end of this lesson, you will:
- Understand what continuous integration is and why it’s important
- Be familiar with a typical deployment flow for agile teams
- Be able to implement TravisCI for continuous integration and automatic deployments for front end applications that use Jest
What is Continuous Integration
Continuous Integration is a jargony buzzword that means “releasing changes fast and often”. The goal of CI is to ensure stability by releasing smaller changesets at a time that are each fully tested. Many projects these days will rely on some sort of automated service to handle testing these changesets and facilitating frequent releases.
Some of the most common CI services you’ll hear about are TravisCI, CircleCI and Jenkins. They all behave in a similar manner, though the setup and configuration process for each tool is slightly different. Focus on integrating TravisCI to perform a full build of an application, test it using our test suite, and once that is finished, automatically deploy our changes to Heroku.
Why Use a CI Tool?
Being able to run and test a full build of your application before you release it to production is important. Think of how easy it was to deploy new changes to your production apps on Heroku. You would make a commit, and it would immediately be reflected on production after running git push heroku master
. What if that commit introduced breaking changes? There is no safeguard or filter against pushing up bad code. With a CI tool like TravisCI, we can still take advantage of automatic deployments, but we also get an extra layer of assurance that our app is in good condition before any changes are pushed live.
TravisCI will also help you catch errors that you might not find locally. By more closely mimicking a production environment, we can recognize any differences that might be causing inconsistent behavior between environments. For example, if I am developing an app locally and I did an npm install
(JavaScript apps) or bundle install
(Ruby apps) months ago, and I did not explicitly lock down the version numbers for each of my dependencies in my package.json
or Gemfile
, I might not notice that my production environment received more updated packages during the npm install
/bundle install
phase. Some of these packages may have included breaking changes that would only be exposed in production, and impossible to reproduce locally until another npm install
/bundle install
was run.
Getting Started with TravisCI
-
Sign up for a TravisCI account here and login with your GitHub account.
-
Authorize TravisCI to access information about your GitHub repos (it’s ok)
-
Click the
+
button next to “My Repositories” on the left pane -
Search for the name of the repository using the
Filter repositories
box (you might have to click theSync account
button on the top right) -
Flip the switch!
-
Go back to your TravisCI dashboard (Click on the
Travis CI
icon on the top left of the page)
That’s it! Easy, right? Just kidding.
Now, any time you push new commits to your remote repository, TravisCI will automatically kick off a new build so you can keep an eye on the overall health and stability of your application.
Note: If you don’t see your repo after you’ve flipped the switch, try refreshing the page.
Configuring TravisCI
As you may have noticed, front-end repos are made up of 90% config files and 10% actual code. In order for TravisCI to be able to run our code and run our tests, we need to add a .travis.yml
file to the root of our repository.
Any time TravisCI runs a build, it will look for this .yml
file (pronounced “Yam-El”) and follow any instructions we provide.
What is a Build?
Think of all the steps you have to take if you want to collaborate on a classmate’s project. You have to fork their repo, clone it down locally, make sure you have an up-to-date version of Node (or some other platform) on your machine, install any dependencies, start up a server and maybe run a file watcher.
Sometimes more complex projects require additional steps. This setup process is called a build. It’s all the things you need to do to get your app up and running. CI tools will run through all of these steps (and then some!) to make sure the application is in a stable, working state before it goes to production.
Phases of the Build Process
The .yml
file can define settings for various phases of the build lifecycle. In TravisCI, there are two main phases of the build lifecycle, three if you add on automatic deployment:
- install: install any dependencies required (configure the virtual machine (VM) to be able to run your code)
- script: run the build script (run your code and tests)
- deploy: deploy your code to your web servers (such as deploying to Heroku)
Getting Setup w/ Travis CI for FE Apps
The following instructions for getting setup with Travis CI are specific to React applications. We will start by creating a new .yml
file!
Adding a .yml
File
- Add a
.travis.yml
file to the root of your project.- Yes, there is a dot in front of the filename because it is a hidden file, which are typically used for configuration files.
</section>
Test
Before we get started configuring the TravisCI installation, script, and deployment phases, let’s make sure we have our test script set up.
By default, in our Node projects the TravisCI test section will simply try to run npm test
. If you don’t currently have a command in here for your test script in your package.json
file, update it to reflect the command you’ve been using to run your tests. That might look something like this:
"scripts": {
"start": "react-scripts start",
"test" : "jest --forceExit",
"test:watch": "jest --watchAll"
}
If you don’t have any updated scripts for testing, the scripts that come packaged with any create-react-app
are as follows:
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
Run npm test
to make sure your tests are passing locally. If they are, you’re ready to move on to the next steps. If not, then fix or skip the tests temporarily to get a passing test suite.
Begin TravisCI Configuration
Let’s push up our .travis.yml
file to the master branch on GitHub, look at the TravisCI build, and squash those errors!
If we look at our repository on TravisCI, we see that it starts a new build automatically! The build starts, but it soon fails because it looks like it is trying to build a Ruby project! If we are using React, Vue, etc. we are working in JavaScript, so we need to implement a Node project to get CI setup correctly!
Specify Node Build
We can look at this documentation page to see how to set the build as a Node build instead.
In the .travis.yml
file, add the node configuration:
language: node_js
node_js:
- "node"
If you need to use a specific version of Node, instead of - "node"
, you could specify a version like - "7"
for version 7 of Node.
Dismiss Email Notifications
You might have noticed that TravisCI emails you every time a build takes place. This can get annoying, but this documentation page tells you how to dismiss the emails. Here is what we need to add to our .travis.yml
file:
language: node_js
node_js:
- "node"
notifications:
email: false
Now we won’t have to deal with those pesky emails!
Configure Automatic Deployments to Heroku
If a build passes on TravisCI, then that means the code is good enough to go to production. We can make TravisCI automatically deploy to Heroku for us after a build passes.
A few things to note here:
- If you are working in React, Svelte, Vue, etc. you will want to utilize Travis CI to check that your build is stable AND deploy to Heroku (or other hosting site)
- If you are working in React Native, you are only going to utilize Travis CI for running your test suite. You will NOT deploy to Heroku since React Native is a true mobile app and you cannot run it (or host it) on a website
Review Documentation
This documentation page goes over the configuration needed to add automatic Heroku deployments to your TravisCI build. Take some time to review before continuing on!
Deploying to Heroku
We need the TravisCI command line tool to generate a Heroku API key. You can install the tool using the command:
gem install travis -v 1.8.10 --no-document
If your terminal gives you a response along the lines of permissions needed
, then you might need to use the sudo
command to install the gem. In that case, use the command sudo gem install travis -v 1.8.10 --no-document
where you’ll have to enter your system password.
Next we need to generate the deployment API key. To do so, use the command:
travis encrypt $(heroku auth:token) --add deploy.api_key --org
Once you run this command (there might not be any feedback in the terminal that it was successful), look back in the .travis.yml
file. You should see a new section added called deploy
with the api_key
and secure
added as children to the deploy
section.
Note: Your api_key
is unique to your application and Heroku account. You must generate your own API key using the command above.
We also need to add information about where we are deploying, specifically the provider
and Heroku app
name.
So our .travis.yml
file will look like:
language: node_js
node_js:
- node
notifications:
email: false
deploy:
provider: heroku
api_key:
secure: THISWILLBEUNIQUETOYOURHEROKUAPP
app: cool-app-name
skip_cleanup: true
The app
name is the name of your Heroku app. For instance, this app’s Heroku address is https://cool-app-name.herokuapp.com/
. So the app
name is cool-app-name
.
Commit and push up the new changes. Watch the new build, and we have automatically deployed to Heroku!
Checking Pull Requests
After we have configured pushes to our master branch to successfully build, what about checking pull requests before they are merged?
Take a look at this documentation to review how TravisCI handles reviewing pull requests!
Badges
What about those cool badges you see in GitHub repositories that show if the latest build has passed all of the tests in TravisCI? How do we add this?
This documentation page will give you an idea of how to add the badge to your GitHub repository.
Note
- FE since you now use Cypress for end to end testing, you will need to do a little bit of research. (Hint: You might find value using the “start-server-and-test” module here!
-
The goal of CI is to run all of your tests. In your CI Platform’s Dashboard you should see the tests running in your build logs. Just because you get a green “successful build” output doesn’t mean that your tests ran, so double check!</li>