Mon projet d'apprentissage de Rust avance doucement et c'est volontaire. Je prends le temps d'améliorer ma centaine de lignes de code, d'écrire des tests unitaires et je continue à lire sur Rust : la newsletter hebdomadaire et des liens sur Reddit (https://www.reddit.com/r/rust/). Suite à la découverte de Clippy, l'utilitaire de détection d'erreurs de programmation, j'ai revu un code qui fonctionnait mais avait des failles potentielles et abusait du type String alors que des littéraux faisaient l'affaire. J'avais peu à peu mis des String partout pour ~~simplifier~~ contourner le borrowing (un classique du débutant en Rust semble-t-il) et par manque de vision sur la manière dont ma fonction serait utilisée.
Finalement, j'ai un petit bout de mon projet (un seul module) avec ses tests unitaires, suffisamment complet pour mettre en place une intégration continue. Késako ? Il s'agit de s'assurer de la qualité du code au fur et à mesure de son écriture pour garantir une bonne qualité en fin de développement en incitant le développeur à améliorer son code tout au long du cycle. On peut aller plus ou moins loin dans les attentes d'une intégration continue :
A une autre époque, j'aurais mis en place un Gitlab et une chaîne d'intégration de A à Z, j'aurais tâté du système, fait du scripting, déployé des containers, appris plein de trucs... Aujourd'hui je dois faire rapide et efficace donc j'ai tablé sur les fournisseurs de CI en ligne (Cloud CI providers pour les anglos) qui peuvent s'interfacer avec mon projet sur GitHub. J'ai testé Circle CI et Travis CI et c'est ce dernier qui m'a semblé le mieux gérer les projets Rust.
Techniquement, c'est très simple : on ajoute un fichier de configuration .travis.yml à son projet GitHub qui définit le pipeline d'intégration, on se connecte à Travis avec son identifiant GitHub et on configure son projet, et hop. A chaque commit Git, Travis déroule pipeline d'intégration.
Ma configuration pour Rust a quelques particularités :
Mon fichier de configuration .travis.yml :
language: rust
sudo: required
rust:
- stable
- beta
before_script:
- rustup component add clippy
script:
- cargo clippy
- cargo test
jobs:
fast_finish: true
cache: cargo
addons:
apt:
packages:
- libcurl4-openssl-dev
- libelf-dev
- libdw-dev
- cmake
- gcc
- binutils-dev
- libiberty-dev
after_success: |
wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
tar xzf master.tar.gz &&
cd kcov-master &&
mkdir build &&
cd build &&
cmake .. &&
make &&
make install DESTDIR=../../kcov-build &&
cd ../.. &&
rm -rf kcov-master &&
for file in target/debug/stacorust-*; do [ -x "${file}" ] || continue; mkdir -p "target/cov/$(basename $file)"; ./kcov-build/usr/local/bin/kcov --exclude-pattern=/.cargo,/usr/lib --verify "target/cov/$(basename $file)" "$file"; done &&
bash <(curl -s https://codecov.io/bash) &&
echo "Uploaded code coverage"
Les résultats de build avec moult détails son publiés sur le site de Travis CI : https://travis-ci.org/kianby/stacorust et ceux de la couverture de code sur le site CodeCov : https://codecov.io/gh/kianby/stacorust
Cerise sur le gateau, on peut intégrer les badges sur la page README du projet pour avoir une vue synthétique de l'intégration continue.