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.
- 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
- NPM Modules other than required by above
PrerequisitesThis 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
Running tests using SpecRunner.html
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
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
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.
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_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
If there are any steps missing and difficult to follow just fork / download the sample. There is no good documentation than the code itself.