Outils supportant le DEVeloppement, le déploiement et la maintenance collaborative des Applications
https://github.com/seblucas/odeva
- Un accès au projet Platine sur Gitlab
- Document court (1 page) :
- Répartition des tâches
- Statégie sur la CI / CD
- Les problèmes rencontrés
- Les solutions apportées
L'art de travailler ensemble.
- Analyse
- Développement
- Livraison / Recette
- Mise en production
- Maintenance
- Livraison par bloc
- Travail en équipe (offshore)
- Maintenance (plusieurs années)
- Plusieurs clients
- Stress
- Qualité
"Un chef de projet est la seule personne au monde à croire que 9 femmes peuvent faire 1 bébé en 1 mois"
"7 projets informatiques sur 10 ne réussissent pas dans les temps ou pire encore jamais" Codendi
Une projet se reussit en agissant sur les faits et en travaillant en vérité avec le client, sa hiérarchie et ses collaborateurs.
- Seule source 100% fiable
- Ouvert à l'extérieur
- Construit au fur et à mesure
- Aide mémoire.
- Jenkins, Teamcity, Bamboo, Travis, ...
- Compilation automatique et immutable
- Test unitaires
- Test d'intégration
- Génération artefacts
- C'est une réalité
- Déploiement simplifié.
- Github, Facebook, Google, Amazon
- Même des PME de 12 personnes
- SCM (Source Code Management)
- VCS (Version Control System)
- SCV (Systême de Contrôle de Version)
- SCCS: 1972, Bell Labs, Marc J. Rochkind
- diff: 1974, AT&T, Hunt-McIlroy algorithm
- RCS: 1982, GNU, Walter F. Tichy
- patch: 1985, Larry Wall
- CVS: 1986, Dick Grune
- Subversion: 2000, CollabNet, Apache
- Git: 2005, Linus Torvalds
Toutes les sociétés n’utilisent pas encore de SCM !
- Plusieurs développeurs travaillent ensemble sur le même projet
- Chacun dispose de sa copie locale
- Chacun met à disposition des autres les dernières modifications
- Co-développement, contrôle de distributions, maintenance.
- Évolution des changements subis par un ensemble de fichiers
- Liste de choses à faire !
- Ne pas oublier les petites tâches.
- Les relire constamment.
- Aide mémoire.
- Qui, Quand, Quoi, Pourquoi, Comment, Ou ?
- Catégorie : Bug, Evolution, ...
- Étiquettes (Tag).
- Jalon (Milestone).
- Propriétaire.
- Ordonnancement.
- Phrases à bannir !
- Historique d'un client.
- Qu'est ce qui a été livré ?
- Comment a-t-on clôturé un ticket ?
- Statistiques.
- Un service REST en PHP
- Un contrôleur AngularJS en Javascript
- Une vue HTML
- Des dépendances externes (librairies AngularJS, framework CSS, framework PHP, ...)
user@home:~/src/projet1# ls
Modele.php
Controleur.js
Vue.html
vendor
- L'évolution d'un projet informatique n'est pas linéaire (beaucoup de retours en arrière).
- Besoin de sauvegarde.
- Envie de garder à disposition la dernière version fonctionnelle.
user@home:~/src/projet1# ls
Modele.bak
Modele.php
Controleur.bak
Controleur.js
Vue.bak
Vue.html
vendor
- Besoin de sauvegardes plus anciennes
- Besoin de trouver des ensembles cohérents
user@home:~/src/projet1# ls
Modele.php.20140302
Modele.php.20140407
Modele.php
Controleur.js.20140302
Controleur.js
Vue.html.20140407
Vue.html
vendor
Cela commence à être complexe
- Sauvegarde historisée (mail, dropbox, ...).
- Un fichier texte est ajouté sur chaque répertoire pour préciser ce qui est fait et ce qui reste à faire (aide mémoire).
- Utilisation régulière de la commande
diff
pour se souvenir des différences de code.
user@home:~/src# ls
projet1_20140502
projet1_20140503
projet1_20140504
projet1
- Besoin d'un historique.
- Besoin de sauvegarde.
- Besoin de cohérence.
- Besoin d'un aide mémoire (texte,
diff
)
cd /home/user/svn
svnadmin create monProjet
mkdir /tmp/Projet
mkdir /tmp/Projet/branches
mkdir /tmp/Projet/tags
mkdir /tmp/Projet/trunk
svn import /tmp/Projet file:///home/user/svn/monProjet -m "Import initial"
cd /home/user/src
svn co file:///home/user/svn/monProjet/trunk maCopieLocale
cd maCopieLocale
vi /home/user/svn/monProjet/conf/svnserve.conf
# anon-access = read -> anon-access = write
svnserve -d -r /home/user/svn --listen-port 45001 --foreground
svn co svn://ip:45001/monProjet/trunk distance
touch list.txt
svn add list.txt
(Modifier le fichier)
svn status
svn ci list.txt -m "Ajout de XXX dans la liste"
svn co http://path/to/trunk
svn up
svn revert list.txt
svn log list.txt
svn diff -r3:4 list.txt
svn copy http://path/to/revision http://path/to/tag
svn copy http://path/to/trunk http://path/to/branch
svn merge -r5:6 http://path/to/branch
Gestion manuelle la plupart du temps.
- L'historique des versions est toujours disponible
- Les commits sont toujours possibles (même offline)
- Beaucoup plus rapide
- Facilité de création de branches
- Moins de maintenance
- La manière de collaborer n'est pas forcée par le système
- Impossible de savoir où est la dernière version
- Besoin de cadrer l'organisation.
- Les numéros de version sont des GUID
- Les contributeurs font des PR
- Le mainteneur les accepte, les refuse ou demande des modifications
- Notion de
rebase
pour réécrire l'histoire. - Git flow
Nouveau rôle : Intégrateur.
- Une seule personne partage son dépôt
- Ajouter un utilisateur à un dépôt
- A vous
- Peu de mauvaises solutions
- Besoin d'expliquer le fonctionnement
- Gestion des bugfixes claire
La meilleure source à mon avis
git log
git diff (--cached)
git status
git config --global core.editor nano
cd /home/user/src
git init testGit
git clone testGit testGitLocal
cd testGitLocal/
touch a.txt && git add a.txt
git commit -am "Ajout de a.txt"
git checkout -b modif
git branch
touch b.txt && git add b.txt
git commit -am "Ajout de b.txt"
git checkout master
touch c.txt && git add c.txt
git commit -am "Ajout de C.txt"
git merge modif
cd ../testGit
git config --bool core.bare true
cd ../testGitLocal
git remote -v
git push origin master
cd ../testGitLocal
nano .gitignore
git add .gitignore
git commit -am "Ajout de la liste des ignorés"
git push origin master
cd /home/user/src
git clone testGit testGitDeux
cd testGitDeux
touch z.txt && git add z.txt
git commit -am "Add z"
git push origin master
cd ../testGitLocal
touch y.txt && git add y.txt
git commit -am "Add y"
git pull --rebase origin master
git push origin master
cd ../testGitDeux
echo "Modification A" >> a.txt
git commit -am "Modification a.txt"
git push origin master
cd ../testGitLocal
echo "Modification B" >> a.txt
git commit -am "Modification a.txt"
git pull --rebase origin master
git push origin master
git push -u origin mabranche
- Avoir le droit de changer d’avis
- Tester des idées sans conséquence
- Collaborer avec d’autres personnes
- Faciliter la maintenance ou le déboggage
- Générer des statistiques
- Gagner du temps
- Garder sa santé mentale
- Log
- Blame / Annotate
- Bisect
Pas de revue de code sans gestionnaire de source.
Excellent moyen d'apprendre !
TortoiseSVN, TortoiseHG, Github, Bitbucket, SourceTree, Github Desktop, GitKraken, ...
- Un SCM mal utilisé sera certainement plus pénalisant que de ne pas en utiliser.
- Ce n'est pas le SCM qui va permettre de gérer la communication autour du projet.
- Un SCM se sauvegarde !
- Ne jamais toucher aux fichiers internes (.svn, .git, ...)
- Aucun résultat de compilation (dll, jar, ...)
- Aucun fichier spécifique à un ordinateur (préférences, lien d'accès à une base de données, ...)
- Les fichiers à exclure doivent être ignorés (svn:ignore, .hgignore, .gitignore)
- Aucun executable ou limiter les fichiers binaires.
- Limiter les librairies externes (privilégier si possible les outils comme composer, gradle, bower, maven, ...)
- Avant un commit, il faut rafraichir sa copie locale (récupérer les modifications des collaborateurs).
- Avant de faire un commit, les modifications doivent être testées (par le développeur et via des tests unitaires le cas échéant).
- Un commit doit avoir un message explicite en bon français.
- Un commit ne mélange pas le fond et la forme.
- Un commit = Un objectif.
- La suppression ou le renommage se font avec le SCM
- Les commits doivent être fréquents.
- Un commit doit être relu.
- Un commit doit se suffire à lui même.
- A vous ...
- Some shit.
- It works!
- fix some fucking errors
- fix
- Fixed a little bug...
- Updated
- typo
- Revision 1024!!
- Semantic commit messages
- Prévoir la recherche future
- Regarder les commits du noyau Linux
- Ne pas se lancer la patate chaude.
- Etre adulte.
- Un conflit n'est pas à cause de l'autre.
- Avoir des conflits est normal dans un projet.
- Règles définies = Moins de conflits.
- Résoudre un conflit nécessite une reflexion.
- Si votre SCM détecte un conflit, alors sans SCM, il y aurait eu de la perte de code.
Créer un fichier .travis.yml
à la racine du projet
language: java
Dans certains cas cela peut suffire
- Se connecter avec son compte Github à Travis
- Activer le dépôt concerné
- Faire un commit
- Créer le dépôt Github
- Ajouter les sources à la racine (pom.xml à la racine)
- Activer le dépôt dans Travis
- Créer et pousser le
.travis.yml
- Attendre le "vert"
language: java
jdk:
- openjdk8
- openjdk9
language: node_js
matrix:
include:
- node_js: "5"
- node_js: "4.2"
before_install:
- npm install -g bower
- bower install
script:
- gulp ci
- 'if [ "${TRAVIS_NODE_VERSION}" = "4.2" ]; then gulp protractor ; fi'
- https://github.com/seblucas/sqlite-enhanced-icu/blob/master/.travis.yml
- https://github.com/seblucas/firebase-sensor/blob/master/.travis.yml
- https://github.com/seblucas/cops-html-ui/blob/master/.travis.yml
- https://github.com/seblucas/cops/blob/master/.travis.yml
- Reprendre un projet passé (Web)
- Créer un projet Github, l'importer
- Le lier à Travis
- utiliser les outils de lint (csslint, jslint, bootlint)
- Selenium / Appium : Saucelabs, Browserstack, Cypress, ...
- Analyse statique de code : Codeclimate, Scrutinizer, ...
- Couverture de code : Coveralls, la liste précédente
- Vérification de dépendances : Versioneye, David, Snyk, ...
- Documentation : ReadTheDocs, Apiary, ...
- Déploiement : AWS, Azure, Heroku, Play Store, ...
- Créer ou reprendre un dépôt Github avec un projet Java
- Suivre la doc pour intégrer SonarQube
- Comparez les résultats entre vous
sonar.projectKey=XXX
sonar.projectName=Test
sonar.projectVersion=1.0-SNAPSHOT
# SQ standard properties
sonar.sources=src/
sonar.language=java
sonar.java.binaries=output/
git rm --cached <fichier> # annule un add
git checkout -f # Annule toutes les modifications
git reset --hard # Supprime aussi les nouveaux fichiers non suivis
git add -i / -p # commit que d'une partie d'un fichier
git diff --ignore-all-space
git commit --amend (--no-edit)
Permet d'écraser le message mais aussi d'ajouter un fichier manquant. Attention ne le faire que si aucun push n'a été fait.
git checkout -b new-feature
# Faites plusieurs modifications et plusieurs commits
git commit -a -m "Début"
git commit -a -m "Modification du précédent"
git checkout master
# 1 commit sur la master
git commit -a -m "Correction pb sécurité"
git checkout new-feature
git rebase -i master
- pick : conserver un commit
- squash/fixup : fusionner deux commits
- edit : découper un commit
- reword : renommage de message
- suppression
- réordonner
Notion de cherry picking et commit squashing.
git log
git log --graph --decorate --pretty=oneline --abbrev-commit
git rebase -i HEAD~[NUMBER OF COMMITS]
ou
git rebase -i [SHA]
git rebase -p --onto SHA^ SHA
git log --abbrev-commit master..
Ne jamais utiliser le rebase
sur des commits qui ne sont pas strictement locaux.
nano b.txt # Faire des changements
git stash push -m "Sauvegarde des modifications sur b.txt"
git stash list
git stash show -p stash@{0}
git stash pop
git stash list && git status
git stash push -u -m "Sauvegarde des modifications y compris les ajouts"
git stash clear # Attention irrémédiable
git stash branch <branchname> <stashname>
A ajouter dans le .bashrc
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
export PS1="\u@\h \[\e[32m\]\w \[\e[91m\]\$(parse_git_branch)\[\e[00m\]$ "
- Créer le dépôt Git
- Définir les règles
- Créer l'intégration continue (et vérifier les règles)
- Créer la livraison continue
- Ecrire les tickets (avec priorités)
- Valider l'architecture
- Commencer le code
- Mettre à jour les tickets
- Revue de code
- Formation interne éventuellement
- Remettre à jour les règles
- Modifier l'intégration continue
- Valider que la livraison continue est fiable
- Mettre à jour les tickets
- Faire des choix
- Tester, Tester, Tester
- Valider que la livraison continue est fiable
- Faire un bilan / rétrospective
- A supprimer
- A améliorer
- A conserver
- Soyez fainéant
- Ne faites que ce qui est nécessaire
- Soustraitez le maximum aux machines
- Automatisez
- Communiquez
- Lancer Virtualbox
- Récupérez l'image disque : ici
- La dezipper
- Créer une VM de type Linux / Ubuntu 64bits
- Ne pas créer de nouveau disque mais pointer sur le disque téléchargé
sudo apt install docker.io
sudo systemctl enable --now docker
sudo usermod -aG docker SOMEUSERNAME
- Docker == conteneur != machine virtuelle
- Moins sécurisé (partage le noyau)
- Plus léger
- Source de vos images de base
- ubuntu / alpine / etc
docker run --rm hello-world
docker run -d -p 8080:80 nginx
# -d : detached // arrière plan
# -p : transfert de port
wget http://localhost:8080
docker ps -a # liste les conteneurs
docker exec -it ID_RETOURNÉ_LORS_DU_PS bash
wget http://localhost:80 # dans le conteneur
## CTRL + D pour sortir ##
docker ps -a # liste les conteneurs
docker stop ID_RETOURNÉ_LORS_DU_PS
docker rm ID_RETOURNÉ_LORS_DU_PS
FROM alpine:3.12
RUN apk --no-cache --update add python3 && \
rm -rf /tmp/* /var/tmp/* /var/cache/apk/*
WORKDIR /app
COPY hello.py .
CMD ["python3", "hello.py"]
print("Hello, World!")
docker build -t testmaster:latest .
docker run -it --rm testmaster:latest
echo -e "\nprint(\"Very new world\")" >> hello.py
docker build . -t testmaster:latest
# Seules les couches modifiées sont reconstruites
docker run -it --rm testmaster:latest
- docker-compose
- push / pull
- Lien avec VS Code pour développer dans un conteneur
- Kubernetes