Continuous integration is an important subject, I cannot think of a development world without it. There are a lot of options for CI, but Travis is a nice and simple one. For personal projects it’s free with unlimited repo’s, perfect! However, it requires you to code your own build script. I had some trouble figuring out a good way to do FTP deployments. So, how do you upload files to FTP servers with Travis?
Travis is a Continuous Integration service that integrates with GitHub. You can sign in to Travis with your GitHub account, you can specify which repo’s it should watch. When you push new changes those repo’s, Travis gets the version of your project on their servers. It then executes the .travis.yml build script that should be in your project’s root.
The only way to specify build tasks is in the .travis.yml file. What can we specify? Well, for instance, we can set environment variables and run command line commands. It looks like this:
We set the environment to _nodejs, this is typical for front-end projects as npm and build tools like gulp all run on node. Then the ‘install’ tasks are executed. Tasks are just command line commands, so they can be anything, but here we run the typical npm and bower install commands. Then the ‘script’ tasks are executed, these are the actual build tasks. In this example it is a gulp build.
This Travis build is nice and all, but these tasks are executed in a temporary virtual machine on Travis’ server. What would be the use of this, if the output never leaves that virtual machine? Let’s upload the result to our FTP server, so our website is updated:
This is an example from Travis’ own docs. First define some environment variables with the user name and password for accessing the FTP server. Then use good old curl to upload index.html to the FTP.
Of course, we don’t want our password in plain text on GitHub, Travis can encrypt it for us with a special command line tool. We can then replace the plain variables with the encrypted ones:
This is all fine, but curl is a bit limited in options. You have to add a command for each file, or combine them with the tedious find command. No, as we allready use Gulp in this example project, why not add a gulp task for uploading the files an folders to FTP?
We need three components for this: minimist for passing command line arguments and vinyl-ftp for the ftp uploading functionality and gulp-util for logging,
npm install vinyl-ftp gulp-util minimist --save-dev.
First we initialize minimist to get the user name and password from the command line arguments. This way we can later on pass the encrypted username and password defined in the .travis.yml to the gulp task.
Now that we retrieved these arguments from the command line inside our gulp file. We can define the FTP uploading task:
It’s that simple :). First we create new ftp connection with vinyl-ftp. Because we use gulp, we can now use glob patterns to gather the files to upload with gulp.src. Then, by piping the globs to the ftp connection, vinyl-ftp will automatically uploads all those files and creates missing folders on the server if needed. This task can now be run from the command line like:
gulp deploy --user 'coolUser' --password 'mySecretPassword'.
conn.newer(destination)method searches the destination for newer files, if there are newer files on the server then those files will not be uploaded with
This is the simplest part. The only thing we have to do is replace the curl command with our new gulp ftp command!
That was easy right! Setting up a Travis build can be challenging. But the result is rewarding, no more manual file copying to servers, just push to GitHub and in a few minutes your changes are live!