Showing posts with label Travis-CI. Show all posts
Showing posts with label Travis-CI. Show all posts

Tuesday, October 30, 2018

Travis-CI - Continuous deployment to staging but production deployment only on tag commit

Background

Travis-CI is a hosted Continuous Integration & Continuous Delivery tool. Based on configurations, users can have their application deployed to production. They provide free service to open source projects. The CI&CD environment currently using Linux.

Aim

  • Have the CI & CD pipeline trigger for each and every commit going into GitHub. Deploy only to staging or testing area.
  • Testing / staging area is GitHub pages hosted in the same repo. Deploy to staging should not trigger another build which ends up as infinite loop. Not into gh-pages branch but to \docs folder.
  • When there is tagged commit deploy to production.

How its done

Avoid build on commit from Travis-CI bot

The word bot is used to indicate the CI&CD account used by Travis-CI. We can see that account on the commits from Travis-CI. When the bot commits, it uses message as follows.

""Deploy <github userid>/<project> to github.com/<github userid>/<project>.git:master""

One such example given below.

"Deploy joymon/prayerbook to github.com/joymon/prayerbook.git:master"

We need to write build conditions at the top of .travis.yml file to bye pass the build if the commit message is matching.

Build and deploy on commit tag

This is another condition we need to put into condition. If we don't put this Travis-CI will not build on tag commit. Below is one example.

if: tag IS present OR commit_message != "Deploy joymon/prayerbook to github.com/joymon/prayerbook.git:master" OR tag = true

If we use tag = true alone it may not work. Needs more analysis on the Travis-CI yml schema.

A sample travis.yml file can be found below which works based on the above conditions.

https://github.com/joymon/prayerbook/blob/master/.travis.yml

References

https://stackoverflow.com/questions/18216991/create-a-tag-in-github-repository
https://docs.travis-ci.com/user/conditions-v1
https://github.com/travis-ci/travis-ci/issues/8518

Disclaimer

The author is not working for Travis-CI or any of their subsidiaries or partners. There is no guarantee that the technique mentioned in this post will work forever. Travis-CI may change their system the way they want it to be. 
This is not at a sponsored post.

Tuesday, September 25, 2018

Travis-CI v/s Windows development environment

We are in the world of DevOps where we do CI & CD activities automatically for even individual code commits. Don't think DevOps means just doing CI & CD. One of the practice in DevOps is CI&CD. Though there are so many CI&CD tools, the leading 'free for open source hosted SaaS' tools are AppVeyor & Travis-CI. Azure Pipeline is new player in the market giving free service.

AppVeyor is my default choice. But in order to get a feel of another CI&CD mechanism, but I used Travis-CI in one of my personal projects.

Problem

It was going good till the builds started failing recently. After inspecting logs, I could understand that there are new NPM module versions available and conflicting. They were used because I used ^ in versions which is mentioned in packages.json. So decided to fix.

It started working fine in my local machine but when I pushed into GitHub, the CI&CD pipeline again failed.

This time its was on the tests. Some files were not served during tests. The http error code is 404-Not found. Initially I thought, since the file names have unicode characters in it, Webpack dev server is not able to serve the files. But it worked in my machine. The classic case of 'it works in my machine'.  But here it is my personal project and I am the only one to fix.

Cause

After hours of debugging via log statements, I was able to figure the silly issue. It is the difference in Linux v/s Windows. Windows is not case sensitive for file paths but Linux is. The files are accessible in Windows but due to case sensitivity the files are not accessible in Linux. Travis-CI uses Linux in their build environment.

Seems others too faced the same issue and asked Travis-CI to add documentation.
https://github.com/travis-ci/docs-travis-ci-com/issues/209

But Travis-CI is smart and had the documentation already. It was I who is now into the lazy to read group.
https://docs.travis-ci.com/user/multi-os/#operating-system-differences

Moral of the story

Better be consistent with Dev, QA, Stg and Prod environments. 10th item in the 12-Factor App methodology.
https://12factor.net/dev-prod-parity

Updates

15Oct2018

More best practices on TravisCI - https://eng.localytics.com/best-practices-and-common-mistakes-with-travis-ci/

Tuesday, February 16, 2016

CI & CD for pure HTML+JS browser apps using Travis-CI

When its said pure HTML+JS browser app, it really mean. There is no web services or server side HTML generation involved. Its simple HTML+JS site running inside browser. People may wonder why such an browser app needs continuous integration where there is no compilation involved.

That's true that it doesn't need compilation. But it always can have tests and those tests can be run after each git push and deploy to staging or production. Many of the enterprise people will not have such a scenario of pure client app. However lets look how can we setup Continuous Integration & Continuous Delivery for such an pure HTML+JS SPA.

Objectives

  • Upon git push the integration process should start
  • It should unit test the tests written using Jasmine framework.
  • If the tests are working, deploy to a FTP location in a web site.

Tools & Frameworks used

The app uses HTML5,JS and jQuery. Below is the list used for CI & CD activities.
  • Github - where the code is stored
  • Travis-CI - which provides machine to run the CI & CD activities
  • Jasmine - Test Framework API
  • Karma - Test runner
  • PhantonJS - The headless browser where Karma can run the tests
  • NodeJS
  • NPM Modules other than required by above
    • ftp-deploy

Node.JS

Do not confuse with the usage of Node.JS. We are not going to run anything in server, its pure HTML+JS SPA. NodeJS is just to do npm package management and to upload to FTP for deployment. The test runner Karma which we are going to use comes as npm package. Also this is the language type supported in Travis-CI for pure HTML+CSS+JavaScript projects.

Prerequisites

This assumes the understanding of
  • Basic web development using HTML+JS+CSS (browser side alone)
  • Using Github.
  • Understanding about NodeJS and its package management ecosystem npm.

Setting up source - production & test code

Application

The application which we are going to use is HTML5 based Karel simulator. Instead of creating separate branch inside it's git repository, better we can create another repository named travis-ci-test in Github itself and uploaded the same source there. /Src is the folder which contains source code.

Tests

There is no question that the leader in client side web testing is Jasmine framework. This provides the API to write test code. Since this is not a post to discuss about Jasmine framework, lets go to Jasmine test code directly. The test JavaScript files can reside inside in the /Tests folder.

Running tests using SpecRunner.html

Jasmine is a JavaScript test framework written in JavaScript and run tests inside browser. For that we just need to create a html file and refer Jasmine js files, app/production js files and test scripts. In this case a SpecRunner.html is available in below location. Browsing it will run the tests and show the results.


Make sure the tests are running from SpecRunner.html. It is always recommended to do a big job in small tasks which can be done in less than 1 hour.

Setting up NodeJS & NPM

The above setup will work really great in our machine. But when in CI environment, we need to run the tests from program. Travis-CI doesn't have client side only JavaScript+HTML app support. But it has node_js support which we can leverage here to test our app.

Next step is to add some Node.JS things. Basically we need to convert our folder to Node.JS application. We can create/convert a Node.JS app by simply issuing 'npm init' command, from any command prompt inside our folder. It will ask for some questions and will create package.json file.

Introducing Karma & PhantomJS

Once our folder is npm enabled or in other sense we got a package.json, we can install packages. Karma is a test runner program which can run our Jasmine tests we wrote in previous step. The JavaScript needs a engine to execute the script and Karma is not a js engine. So it needs a js engine. It can either use any browser itself or can use headless browser called PhantomJS. PhantomJS comes as npm package. All the packages mentioned till here can be installed via npm. See the devDependencies section in package.json file for the packages what we need.

In our local machine we can use npm install <package name> --user-dev command to install the packages. But in CI machine, it will do automatically by reading the package.json.

Setting up Karma & PhantomJS

Karma wants to know where are the production & test js files to run tests. For that it needs a config file. In this case, its  karma.config.js


This file can be created using karma init command. It will ask some questions and create the file. This file is self explanatory.

How npm knows Karma is the test runner to be used

Once the setup is done we are going to execute the tests by issuing below command.

npm test

How does npm knows to run the tests using Karma? Its again configuration inside package.json.

There is a section called 'Scripts' and it contains 'test' section inside. Test node expects an executable command. There we can give the command to run Karma along with karma config we created in previous step.

Once this step is proper we should be able to issue 'npm test' command and it should should run the tests and show results. Testing every step is important.

Upload to FTP via ftp-deploy npm module

Now comes to deployment. If all the tests are passed, we can deploy to our staging or production environment. In this case I want to deploy to a FTP location. The hosted CI platform Travis-CI which we are going to use, doesn't have direct support to deploy a folder to FTP. We had to rely on curl command which can transfer one file at a time. One file at a time doesn't work most of the time.

Now there are 2 ways
  • Use tools such as grunt / gulp which can orchestrate the CI activities. They have FTP deploy methods.(Google knowledge. Didn't try myself)
  • We can write some code in shell script or NodeJS and hook it after the tests run successfully.
As there are already enough tools and technologies just for CI & CD than the production code, lets write some custom NodeJS code to upload files to FTP. No to Grunt and Gulp for now.

The written FTP upload code uses ftp-deploy npm package to upload the files. Why should we rewrite code again for reading the folders, reading the files and to upload using FTP protocol. That is something many people already solved and made open source.

The FTP code can be hooked to the integration process after test by editing the package.json file. We can use 'posttest' section for it.

Testing everything in local machine

If the above environment is ready, we should be able to run everything in our machine. The command 'npm test' should run the unit tests and if everything pass, deploy to FTP folder. In our local environment to work we need to give the FTP credentials to ftpupload script via environment variables. We will see why its via environment variables in next section.

Intro to Travis-CI and getting started with it

Travis-CI is a free hosted CI&CD SaaS environment for open source projects. This is similar to AppVeyor. We could have used AppVeyor which is already referred in previous posts and have already used in other .Net projects. But this time lets try something new. Below are the steps to achieve the same.

  • Upload the code to Github.
  • Create account in Travis-CI using Github.
  • Connect to Github project.
  • Setup below environment variables for FTP access.
    • ftp_host
    • ftp_user
    • ftp_password - Do not turn the flag to display in build log. Build log is public
    • ftp_localPath - Path to the folder inside the CI machine. Usually src
    • ftp_remotePath - Path to where the files should be copied. Only relative url
Refer a build log for sample values. Once this is working. Just do a push to Github to start the integration process.

UI testing in Travis-CI

Travis-CI don't support running in chrome out of the box. They are telling we need to give some commands to get it running. To me it didn't work out. It tried 2-3 times and said failed to start Chrome. So decided to use PhantomJS. Anyway in this sample application, the main objective is test the JavaScript. So it works.

If there are any steps missing and difficult to follow just fork / download the sample. There is no good documentation than the code itself.

References

http://orizens.com/wp/topics/first-steps-in-setting-up-travis-ci-to-your-javascript-project/
https://blog.logentries.com/2015/01/unit-testing-with-karma-and-jasmine-for-angularjs/
http://swizec.com/blog/how-to-run-javascript-tests-in-chrome-on-travis/swizec/6647
http://gis.utah.gov/how-to-wire-up-travis-ci-to-your-js-projects/
http://www.sitepoint.com/testing-javascript-jasmine-travis-karma/