Travis CI
tl;dr my use of Travis CI has been entirely superseded by GitLab, which has CI and issue tracking built in. In fact, this blog is built and hosted by GitLab.
Create an account with your GitHub login and enable a repo to get started. (Travis Pro appears to enable new repos by default.)
Simple C++11 compilations
If you just want to get something building quickly the default Trusty build has clang 5 pre-installed, no need for complicated matrices.
Travis config
script: clang++ --version
Travis build debug
$ clang++ --version
clang version 5.0.0 (tags/RELEASE_500/final)
Building with recent gcc and clang
These could be run as separate jobs but you then have to handle each build attempting to deploy.
script:
- make CXX=clang++-6.0
- make clean
- make CXX=g++-8
- cppcheck --enable=all .
- sloccount *.cpp
matrix:
include:
- os: linux
addons:
apt:
update: true
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-8.0
packages:
- clang++-8.0
- g++-8
- cppcheck
- sloccount
C++ code coverage
Create a codecov.io account with your GitHub credentials and simply push your coverage files via Travis CI using the generic upload script as a build stage (no need to enable the repo). Build your C++ using the gcc -g --coverage
flags (which invokes gcov). Note: I've only managed to get sensible coverage results when compiling with gcc 6.
script:
- bash <(curl -s https://codecov.io/bash)
Branch merge
An unexpected side-effect of using Travis CI is that your branch is automatically built as part of the merge verification. You're also offered a Codecov report for the merge.
Deploying to GitHub Pages
In the Travis CI repo settings create a private environment variable containing your GitHub API key, this replaces the GitHub token below (note: use hyphens not underscores). All branches are built in Travis CI by default but in this example on the master branch will be deployed. Deploying for the first time will create a "gh-pages" branch and set up the username.github.io/repo static web page. I like to use this to generate "live" READMEs containing recent data.
Create an API key in your GitHub settings, tick "repo" and "admin:public_key". "skip-cleanup" is set to true because you probably want to deploy the things you've generated.
Finally, in your GitHub repo settings ensure the GitHub Pages section "source" is gh-pages branch.
deploy:
provider: pages
github-token: ${github_token}
skip-cleanup: true
on:
branch: master
R with packages
language: R
install:
- R -e "install.packages('csv')"
- R -e "install.packages('rjson')"
- R -e "install.packages('rmarkdown')"
script: make
bash with dot
script: make
install: sudo apt install graphviz
Python with requests
HTTP requests aren't available by default so you must instruct Travis CI to make it so using an additional "requirements" file.
language: python
python: "3.6"
script: make
# This is implicit
# pip install -r requirements.txt
Add requirements.txt
file to the top level of your repo containing a list of dependencies.
requests
Linting and profiling
To use gprof
, compile your code with the -pg
flag, run the exe and then process the results as part of your build script.
script:
- make
- ./spectrum.o
- gprof ./spectrum.o
To run cppcheck
, add it to your apt configuration and simply run as a build stage.
script:
- cppcheck --enable=all .
Also sloccount
can be run to give an insight into the cost of your codebase.
Compiler options
# Standard
--std=c++2a --all-warnings --extra-warnings --pedantic-errors
# Warnings that are not included by hallmark.md parallelism.md and *extra* but sound like a thing we
# want to know about
-Werror -Wshadow -Wfloat-equal -Weffc++ -Wdelete-non-virtual-dtor -Warray-bounds -Wattribute-alias -Wformat-overflow -Wformat-truncation -Wmissing-attributes -Wstringop-truncation -Wdeprecated-copy -Wclass-conversion
# And a whisper of optimisation
-O1
# Profiler
-pg
# Code coverage (gcc only, ignored by clang)
-g --coverage
Triggering builds using the API
You can configure a daily cron job via the Travis settings but for more frequent builds set up your own cron job on a Linux web server and use the Travis API. Note the .org in the API URL, if you use the wrong one (.com) it will simply report "access denied". There's a different API key for the Pro account too. Update TOKEN
, USERNAME
and REPO
in the script below (leave the "%2").
@hourly nice ~/trigger.sh
#!/bin/bash
body=$(cat <<!
{
"request": {
"branch":"master",
"message":"cron $(date)"
}
}
!
)
curl -s -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Travis-API-Version: 3" -H "Authorization: token TOKEN" -d "$body" "https://api.travis-ci.org/repo/USERNAME%2FREPO/requests" >& /dev/null
Clang format on pre-commit
I use a global git configuration that runs clang-format on all C++ files as they are pushed to the server. See githooks. I've changed my mind about coding standards many times over the years, next time I can just create a new format configuration and run it over my code. This also avoids you having to spend time pondering how to format bracket-heavy features like lambdas and initialiser lists.
for file in $(git diff-index --cached --name-only HEAD); do
if [[ $file == *.cpp || $file == *.h ]]; then
clang-format -i "$file"
git add "$file"
fi
done
Uptime monitoring
See uptime robot.