POST
Use Travis CI to build and deploy project automatically on Github
This article will introduce how to use Travis CI to build, test and deploy the Github project automatically. I will take my blog project on Github as an example to explain.
Why do I use Travis CI ?
If you’ve looked at my previous article, you may know my blog was deployed on Github Pages and was built by Jekyll static site generator.
Github Pages are a great approach to build websites. Using a Github repository and with the Jekyll static site generator, we can build static websites easily. It is suitable for building a personal blog.
Although Github Pages can automatically generate a website from a repository containing a Jekyll project, it has some limitations.
To deploy the blog on Github Pages, you just need to commit your website's source code to the Github Repo and don't pay any effort on the building and deployment.
Github Pages will do it for you!
One of them is
- we can’t use Jekyll plugins
I need to use plugins to extend the functionality of my website, e.g. for implementation of toc and markdown function enrichment.
Understandably,Github Pages doesn’t allow the plugin for security reasons.
Github Pages Generator uses the Jekyll --safe flag.
The workaround is to generate the site locally and then to push the generated HTML to Github (I’ve interpreted how to do in my previous article). However, I usually use different branches for source code and output static HTML. The dev
branch accommodates the source code and the gh-pages
branch, which is as a window of website visiting, stores the static website files.
So my current workflow is
- modify the source code at the dev branch and use Jekyll build locally.
- commit the change to the dev branch.
- copy the output static website files which are in the
_site
folder to \tmp folder. - switch to the local gh-pages branch.
- add copied static website file in
_site
folder to the gh_pages branch. - git add & commit.
- push to the remote gh-pages branch.
or I can push the files in _site
to the remote gh-pages branch forcibly from the dev branch although it is not an ideal way of routine operation.
You see it! ☹️ Really tedious, isn’t it?
I think it is a poor efficiency and should be improved.
The main motivation for me is to be able to get a tool that helps me do the above works automatically. What I want to do is just committing the code to the remote dev branch (this is the necessary work) and others leave to the tool.
The basic idea is to use the Travis CI continuous integration (CI) service. The function of Travis CI service fully meets my expectation. And the most important point is that it is FREE for open-source projects in Github.
Prerequisites
To start using Travis CI, make sure you have:
- Github account
-
Adding authentication methods to your Github account. You can do it by creating a personal access token (PATs) or connecting to GitHub with SSH Key. If you don’t know how to do, please refer to
- Travis CI account and sign up, you can use your Github account ID to log in directly.
-
Authorize the Travis CI (you will be requested to do it when you sign in to Travis CI for the first time), active your Github repositories that you want to use Travis CI service. Please refer to
- One local git repository for your project.
Workflow
The workflow of Travis CI building and deployment is as follows:
- git push to the Github repo triggers Travis CI
- Travis CI starts up a virtual machine and installs all required software (mostly Ruby gems)
- I use a custom rake task to tell Travis CI how to build the Jekyll site and push the updated content back to Github
- Travis CI clones a different branch (either dev or master, depending on the kind of Github repo) that holds the website’s source code.
- Travis CI runs Jekyll build with the destination in the other branch (gh-pages)
- Travis CI does a git push of the other branch (gh-pages)
- Github Pages starts serving the updates site
Depending on the required software that needs to be installed, the whole process takes anywhere between 1 and 5 min and is fully automated.
.travis.yml
Travis CI uses the .travis.yml file to describes the build process. Create a .travis.yml into your project’s repo and edit it.
Don’t forget to commit it and push it to the remote repo once you finished editing!
Lifecycle
The whole job’s life cycle can be divided into several phases.
The main phases are:
install
- install any dependencies requiredscript
- run the build script
You can complete basic work with the above minimal life cycle. Besides, Travis CI affords some phases that allow users to insert custom commands.
To get to know the details and learn how to write .travis.yml file, please read
Sensitive Data
Travis CI will inevitably use the sensitive data (for example, SSH private key or Github personal access token) to access the Github. Of course, we cannot expose the data without any protection. Travis CI provides encryption scheme to protect your secret information.
Travis CI offers commands that can encrypt the private key or any files. You can also save your sensitive data to environment variables, where the data is invisible and can be accessed from any stage in your build process.
For my project, I’ve tried two methods as below:
- use SSH scheme access Github with RSA key pairs
- access with encrypted Github PATs (personal access tokens)
SSH
For SSH access, I assume you have created SSH key pairs and it is workable for your Github. If you don’t have, do it by following
you can test the connection status by inputting the command.
If you get a message like this, you are accessing Github successfully.
Then use the below command that Travis CI provides to encrypt the private key.
Above commands sign in Travis CI (for applying the APIs), encrypt the private key, and generate a code snippet (as below) into your .travis.yml
file to decrypt the private key during the building process.
then add your SSH private key to the ssh-agent.
After generated the encrypted key leave it into your code repo.
Do not forget to remove your PRIVATE KEY before you commit code to Github Repo!
Otherwise, you may potentially disclose your private key.
PATs
If using PATs, you should follow below steps:
-
acquire a PAT, refer to
remember to keep this token’s value carefully since it is only visible for the first time generated.
-
encrypt the PAT by inputting the command
This will output a string looking something like this:
Now you can place it in the .travis.yml
file.
You can also skip the above, and add it automatically by running:
GH_TOKEN
is the environment variable, which can be accessed in the .travis.yml
file.
GH_REF
environment variable can be set to “github.com/user-name
/repo-name
.git”.
Please note that the name of the environment variable and its value are both encoded in the string produced by “travis encrypt.” You must add the entry to your .travis.yml
with key secure
(underneath the env
key). This makes the environment variable GH_TOKEN
with the value of PATs available to your program.
Once you got the personal access token and encrypted, you can access the Github repo by the below method:
With this method, you can avoid being request passphrase when accessing.
Example
I attached my blog project’s .travis.yml file here as an example.
OK, everything is done here!
Let’s see what happens!
I modify code and push to the remote dev branch, open my Travis CI web page to view the building process.
Yes, my commit event to the dev
branch triggers Travis CI to work for the building.
Booting virtual machine …
Setting environment variable…
Continue waiting…, oh! start to decryption and install toolchain…
Installation completed, building now…
Building succeed! The last step, deploy…
It’s done! Looks like the whole process was completed successfully! 👍
Let me go to the Github gh-pages repo to check the result.
GREAT! 😄
The repo was updated successfully with the new contents.
The Travis CI works well, which means I can get back to the normal workflow to develop my blog without extra git operation between different branches.
The workflow is not only valid for blog projects deployed on Github Pages but any open source projects on Github.
The last thing is don’t forget to add a Travis CI logo/link to your README.
Troubleshooting
Building Errors:
- Error:
iv undefined
when executingopenssl
command.
Possible Reason:- check the Travis CI website address, it should be
https://travis-ci.com
rather thanhttps://travis-ci.org
. - run
travis login --com
instead oftravis login --org
to log in Travis CI. - check the configuration file
~/.travis/config.yml
, the value of endpoint should behttps://api.travis-ci.com/
.
- check the Travis CI website address, it should be
-
Error: Being asked for entering passphrase for key
/root/.ssh/id_rsa
when executingopenssl
command to do decryption of the SSH private key.
It is because you set the passphrase when generating the SSH key, usessh-keygen -p
command to reset the passphrase tonone
. Then replace the private key with the new one and re-encrypt the private key. -
Error: report
the encrypted_xxx file size is incorrect
when decryption.
Probably you are using the wrong format encryption file, the Travis CI host is running on Ubuntu OS. So the file format should be UNIX, if you generate an encryption file with DOS format, you will encounter this issue.
The solution is to usedos2unix
orfromdos
command to convert the format to UNIX. -
Error: you got repository not known to https://api.travis-ci.org/: user-name/repo-name when you execute the command
It is because your current repo is not in the repo’s list in the config.yml, add your repo’s name into the config.yml and indicate the endpoint to https://api.travis-ci.com/
manually.