Geoff Garbers

Husband. Programmer. Tinkerer.

Code folding and timing in Travis CI

Nov 01, 2017

The utility functions detailed below are incredibly useful for implementing code folding and timing in your Travis CI builds. Using them will output something similar to the following image in the Travis CI interface (you can view a “live” example of this in an existing build):

After a bit of digging, the utility functions that Travis CI provides to be able to implement this code folding and timing have been found.

These functions are undocumented; this probably means that Travis CI intended for them to be for internal use. Be careful when using them - they could change without any warning.

Exporting bash functions for access

The bash functions required for this to work need to be exported and available to all sub-shells. This is as easy as adding the following four lines to your before_script section:

- export -f travis_nanoseconds
- export -f travis_fold
- export -f travis_time_start
- export -f travis_time_finish

Due to these being bash functions that are exported, they will not work in any other shell other than bash. All your scripts that should have a shebang that looks something like #!/usr/bin/env bash.

travis_nanoseconds

If you’d like to time something manually, a utility function is provided to retrieve the UNIX time in nanoseconds:

ns=$(travis_nanoseconds)
echo $ns

travis_fold

Code folding is very useful in that verbose text output can be folded into an expandable “tag”. Folding commands is as simple as the following:

travis_fold start "name.of.fold"
# execute commands here
travis_fold end "name.of.fold"

The name.of.fold portion of the example will be the title of the code fold (which cannot contain spaces). Unlike the timers described in the next section, code folds can be nested.

travis_time_*

It can be useful to time certain sections of your code (as an example, it’s useful to know how long a deployment to Google Cloud Storage takes). This is where the travis_time_* utility functions come in.

travis_time_start
# Execute some command that takes a while (like `sleep 10`)
travis_time_finish

Note: Timers cannot be nested. A previous timer will need to be finished before starting another one. This is due to a global variable being used to keep track of the timer ID.

Combining travis_fold and travis_time_*

Both of these utility functions can be combined to create a timed code fold. I’ve found it works best to specify the fold first, followed by the timer:

travis_fold start "deploy.part1"
    travis_time_start
        # Run deployment
    travis_time_finish
travis_fold end "deploy.part1"