Continuous Integration
Before working on open source projects, I was unfamiliar with the practice of continuous integration and it’s role in the development process. Continuous integration platforms, such as Travis CI, allow for small code changes to be merged into a project after passing a series of automated testing performed in a virtual environment. Not only does this reduce the risk of introducing a bug into a program but it allows for the development of cleaner more stable code.Many bugs can be deep rooted into a project only to surface during specific edge cases. Continuous integration can pin point these potential failures and return descriptive feedback to the user. If one or more of the build tasks fail the build is considered broken and returns a descriptive message to where it went wrong. This drastically reduces time spent manually testing how new code changes affect the rest of the project.
Travis CI allows developers to define a virtual environment where their application will run along side a series of user defined tests. These tests could be performed to check code styling, function validations, and overall stability. The options are truly limitless.
As we continue developing our file function library https://github.com/marcobeltempo/fileside, our next goal was to implement the Travis CI service to perform automated tests on our code.
Below you will find the steps I took to setting up my project with continuous integration.
NOTE these instructions apply to NodeJS applications. To find the setup instructions for your project checkout: Specifying Runtime Versions
Travis CI with NodeJS
- To get started you must authorize Travis CI to access your repositories by logging in with your GitHub account Travis-CI.org
- Once you’ve logged in you’ll see a list of repositories connected to your profile.
Beside each project is a toggle you can turn on to activate the Travis CI service. - Now that you’ve activated Travis CI it’s time to create a file named
.travis.yml
in the root of your project..travis.yml
acts as a list of guidelines on how you want your build to be executed. - I configured my
fileside/.travis.yml
file with the following settings:language: node_js // this tells Travis the type of program you’re running
node_js: // build must operate in node
-“node”
– “8” // with a minimum version requirement of 8
sudo: false // Travis CI runs each build in a container on a shared host via Docker
cache: // to speed up the build Travis can cache directories that are modified too often such as our node modules
directories:
– node_modules
For a full list of customization options checkout customizing-the-build - In order to trigger the Travis CI build you must commit and push the newly created
.travis.yml
file to your repository. - Switch back to your TravisCI dashboard and you will see the status of your build.
Build Scripts
Now that we’ve successfully setup Travis CI with our project it’s time to write some build tests. The great thing about continuous integration is tests can be created as new features are added.
The package.json
file supports the “scripts” property which contains various instructions that can be executed at different stages of your build process. In this case we want to create scripts which can be executed with the npm run script_name
command and with Travis CI.
I figured the best place to start would be by implementing a script to test the styling and formatting of the code. Linting tools like eslint allow developers to discover problems with their JavaScript code without executing it. Along side eslint
we will be installing the prettier
code formatter. prettier
enforces a consistent style by parsing your code and re-printing it with its own rules.
The next steps will install eslint
+ prettier
and configure executable test scripts:
npm install eslint --save-dev //the --save-dev flag will only install the module in development environments for testing
eslint --init
//creates.eslintrc
configuration file in the current directory-
- The initializaton process will ask you a series of setup questions best suited for your project
.eslintrc
can be configured with the following eslint rules.eslintignore
contains a list of files/folders you don’t want to test
npm install --save-dev prettier eslint-plugin-prettier
In.eslintrc.json
add the following
{
<span class="pl-s"><span class="pl-pds">“</span></span><span class="pl-s">plugins</span><span class="pl-s"><span class="pl-pds">“</span></span>: [
<span class="pl-s"><span class="pl-pds">“</span></span><span class="pl-s">prettier</span><span class="pl-s"><span class="pl-pds">“</span></span> ],
<span class="pl-s"><span class="pl-pds">“</span></span><span class="pl-s">rules</span><span class="pl-s"><span class="pl-pds">“</span></span>: {
<span class="pl-s"><span class="pl-pds">“</span></span><span class="pl-s">prettier/prettier</span><span class="pl-s"><span class="pl-pds">“</span></span>: <span class="pl-s"><span class="pl-pds">“</span></span><span class="pl-s">error</span><span class="pl-s"><span class="pl-pds">“</span></span> }
}- Next we are going to create an executable script under the scripts property.
-
- Add the scripts property if it doesn’t already exist
</li>
</ol>
</li>
</ol>
<pre>"scripts": {</pre>
<pre> }</pre>
<ol>
<li>
<ol>
<li> - The first script will execute
eslint
on the entire project.
</li>
</ol>
</li>
</ol>
<pre>"scripts": {</pre>
<pre>"test": "eslint ."</pre>
<pre>}</pre>
<ol>
<li>
<ol>
<li> - The “test” script can be executed in the command line by running
The second script will be called to automatically fix any errors raised by the “test” script.npm test
</li>
</ol>
</li>
</ol>
<pre>"scripts": {</pre>
<pre>"test": "eslint .",</pre>
<pre>"test:lint:fix": "eslint . --fix"</pre>
<pre>}</pre>
<ol>
<li>
<ol>
<li>- The “test:lint:fix” script can be executed in the command line by running
npm run test:lint:fix
Now that we’ve setup some simple linting and formatting scripts Travis CI will automatically run these tests every time a pull request is made to the master branch.
- Add the scripts property if it doesn’t already exist
Reflection
Learning the concepts of continuous delivery and implementing it into my personal project has been a valuable learning experience. Development practices aren’t exactly taught in school. We’re taught the fundamentals of a new programming language and build small practice applications. But never how to properly test and implement these projects in the real world. This practice not only simplifies the testing process, but I found as a new programmer this opened my mind to reading and writing code from a different perspective.