Nous concevons et développons des applications web.
(parmi d'autres activités)
Nous aidons des startups à proposer de la valeur à leurs marchés : la qualité des applications est importante.
On veut éviter un facteur bus trop faible.
Le développement, la qualité et le déploiement d'un projet ne doivent pas reposer sur une seule personne !
Il faut documenter et automatiser un maximum de choses pour pouvoir travailler collaborativement.
... quand il n'y avait qu'un seul développeur.
La source de vérité du projet est sur le poste du dev.
Le dev gère tout manuellement :
On prend l'exemple d'un site développé avec Jekyll.
Transform your plain text into static websites and blogs.
Le dev est seul. Il n'a pas besoin de partager son code ou d'y incorporer des modifications faites par d'autres.
.
├── _config.yml
├── _drafts
| ├── begin-with-the-crazy-ideas.md
| └── on-simplicity-in-technology.md
├── _includes
| ├── footer.html
| └── header.html
├── _layouts
| ├── default.html
| └── post.html
├── _posts
| ├── 2007-10-29-why-every-programmer-should-play-nethack.md
| └── 2009-04-26-barcamp-boston-4-roundup.md
├── _data
| └── members.yml
├── _site
├── .jekyll-metadata
└── index.html
Le projet a besoin de jQuery pour fonctionner.
Le dev va donc :
jquery-3.1.1.min.js
depuis le site officielS'il veut mettre à jour jQuery, il supprime l'ancienne version et recommence.
Le dev a installé sur son système :
Il lance une commande pour produire le site final : bundle exec jekyll build
Le dossier _site/
contient maintenant une version déployable de l'application.
Le dev envoie le contenu du dossier _site/
vers son hébergement.
Il peut utiliser (notamment) :
Plus de projets → plus de devs
Les devs doivent collaborer sur les projets, ce qui pose des problèmes.
Quelques exemples :
Ou VCS, logiciel de gestion de versions.
Permet de stocker un ensemble de fichiers en conservant la chronologie de toutes les modifications qui ont été effectuées dessus.
On code normalement, et on utilise le VCS pour organiser la journalisation de nos modifications.
Aujourd'hui, on ne va parler que de Git.
(mais il y en a d'autres)
On peut :
Apprenez Git. Utilisez Git.
Utilisez une interface graphique pour débuter.
Exemple : GitHub Desktop (Windows/Mac OS)
GitLab unifies chat, issues, code review,
CI and CD into a single UI
✓ La source de vérité est le dépôt Git dans GitLab.
✓ Git permet ça, et GitLab ajoute du confort !
Inclure jQuery dans la base de code rend :
jQuery est une dépendance externe : on n'a pas envie de la gérer comme le reste du code qu'on écrit !
npm est le gestionnaire de paquets officiel de Node.js.
On synchronise dans Git un manifeste qui contient des références vers les dépendances.
Sur chaque poste de dev, on lance npm install
pour récupérer ces dépendances et les placer dans le dossier node_modules/
.
package.json
:
{
"name": "my-awesome-project",
"version": "1.0.0",
"dependencies": {
"jquery": "3.1.1"
}
}
.gitignore
:
/node_modules/
✓ On ne synchronise que des références, et on a un outil pour les résoudre et récupérer le contenu des dépendances.
Grunt est un outil permettant de définir et lancer des tâches automatisées.
On définit les tâches dans le fichier Gruntfile.js
et on utilise la commande grunt [tâche]
pour les lancer.
Exemple : on veut minifier le JavaScript de notre application.
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
build: {
src: 'src/app.js',
dest: 'build/app.min.js'
}
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('default', ['uglify']);
};
src/app.js
+ Grunt → build/app.min.js
Si on synchronise build/app.min.js
:
src/app.js
)Si on ne le synchronise pas :
src/app.js
est modifiéOn ajoute /build/app.min.js
dans .gitignore
.
On n'est pas des animaux, on ajoute un fichier README
qui documente :
/build/app.min.js
package.json
Continuous Integration & Continuous Delivery
CI = vérifier à chaque modification de code source que le résultat des modifications ne produit pas de régression.
Usages courants :
.gitlab-ci.yml
au projetlint:
stage: test
script:
- npm install --quiet
- npm run lint
Docker est un outil qui peut empaqueter une application et ses dépendances dans un conteneur isolé, qui pourra être exécuté sur n'importe quel serveur Linux.
On peut facilement créer une image Docker qui contient tous nos outils préférés.
FROM debian:jessie
RUN curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
RUN apt-get update \
&& apt-get install --no-install-recommends -y \
nodejs
Chaque tâche de GitLab CI peut être lancée dans une image Docker : on maitrise l'environnement d'exécution.
lint:
stage: test
image: myorg/myimage:latest
script:
- npm install --quiet
- npm run lint
tags:
- docker
Une fois que c'est terminé, on récupère le résultat et on jette le container à la poubelle !
Autres avantages :
✓ On utilise GitLab CI pour lancer la construction et les tests dans une image Docker.
On peut choisir d'exécuter certaines tâches uniquement dans certains cas :
deploy_prod:
stage: deploy
image: myorg/myimage:latest
script:
- npm install --quiet
- npm run lint
- # deploy command
tags:
- docker
only:
- tags
some_task:
script:
- echo "$TEST"
Transférer en une commande un dossier local vers un serveur distant.
Exemple (non-optimal) :
rsync -r ./ "$USER:$PASSWORD@$HOST:/var/www/$CI_PROJECT_NAME"
Problème : le site en production peut être entre 2 états (ancienne version et nouvelle version).
Deployer permet des déploiements atomiques.
/your/project/path
|--releases
| |--20150513120631
|--shared
| |--config.php
| |--...
|--current -> /your/project/path/releases/20150513120631
On définit les tâches de déploiement dans le fichier deploy.php
et on utilise la commande php deployer.phar [tâche]
pour les lancer.
deploy.php
:
<?php
require 'recipe/common.php';
task('deploy:upload_code', function () {
upload('build', '{{release_path}}/');
})->desc('Uploading code');
task('deploy', [
'deploy:prepare',
'deploy:release',
'deploy:upload_code',
'deploy:symlink',
'cleanup',
])->desc('Deploy your project');
server('prod', getenv('PROD_HOST'))
->user(getenv('PROD_USERNAME'))
->password(getenv('PROD_PASSWORD'))
->env('deploy_path', '~')
->stage('production');
set('default_stage', 'production');
compile:
stage: build
dependencies:
- im_build
script:
- ...
artifacts:
name: "$CI_BUILD_NAME-$CI_BUILD_REF"
paths:
- target/
expire_in: 1 day
tags:
- docker
✓ On utilise GitLab CI + Deployer pour déployer automatiquement lorsqu'on crée un tag.
The Purely Functional Linux Distribution
https://dsferruzza.github.io/conf-immutable-infrastructure-with-nixos
Utilisez Git !
Et mettez en place un CI/CD sur votre projet :)
Twitter : @d_sferruzza
Slides sur GitHub :