Git, Gitlab & Gitlab CI

La CI avec Gitlab

Introduction

$ Whois

Contenu

    Kevin Gautreau
    Développeur Back freelance
    Clermont-Ferrand (depuis Septembre 2015)
    Spécialisé Drupal
    Twitter / Github : @Kgaut
    Mail : contact@kgaut.net

 

 

Et vous ?

Contenu
  • Profil
  • Experience
  • CMS
  • Attentes sur la formation

Objectifs de la formation

Contenu
  • Revoir les fondamentaux de GIT
  • Utiliser un serveur gitlab
  • Comprendre le principe de la CI
  • Appliquer la CI avec Gitlab
  • Expérimenter les possibilités

Autre chose ?

À noter

Contenu
  • Je ne suis pas un expert mais un expérimenteur
  • Domaine en constante évolution
  • => Avoir les clés pour être autonome pour la suite

Cette présentation

Git

« Versionner »

Contenu

Mettre sous gestionnaire de version

  • Effectuer des "sauvegarde" de son code à un instant T.
  • Revenir à une version précédente
  • Travailler à plusieurs, fusionner des développements

Wut ?

Contenu

Système de gestion de version à la mode.

Développé à l'origine par Linus Torvalds.

Démocratisé par Github.

Principe simple

Contenu

Création d'un dépo : git init

** Code **

Création d'une version :



git commit

** Code **

Création d'une nouvelle version :



git commit

...

Les « remotes »

Contenu

Copies locale ou distante du dépot, permettant de travailler à plusieurs



git remote add origin chemin/vers/remote

récupération d'un dépot distant



git clone chemin/vers/remote

Remotes possible : github, gitlab, dossier local / réseau...

Le fichier .gitignore

Contenu

Fichier à placer à la racine du dépot ou dans un sous-dossier



Contenant les dossiers / fichiers à ne pas versionner (images, fichiers de config, css...)

db/*.sql
web/uploads
web/sites/default/settings.php

Les workflows Git

Contenu

Comment organiser son dépot pour gérer les cas ?

  • Déploiement sur prod ?
  • Développement de hotfix ?
  • Développement de fonctionnalités plus longues ?
  • Validation en preprod ?

Git flow à la rescousse

Contenu
  • Branche master => Prod
  • Branche preprod => environnement de preprod, validation des développements en cours
  • Pour chaque hotfix / fonctionnalité, une branche spécifique (basée sur master)
    • ex : fix-541-email-not-sent
    • ex : feature-542-new-homepage

N'est pas une vérité absolue, à adapter en fonction du fonctionnement de l'entreprise et de l’environnement du projet

https://nvie.com/posts/a-successful-git-branching-model/

Gitlab ❤️

Gitlab ?

Contenu

Solution SASS

  • Pas de serveur à configurer
  • Moins la main sur la configuration

Solution auto-hébergée

  • Configuration au "petits" oignons
  • Possibilité d'héberger où l'on veut
  • Backups facilités

 

Concurents SAAS

Contenu

Concurents SAAS

Contenu
  • Github
  • Bitbucket
  • ...

Repo publics gratuits, privés payants.

Concurents auto-hébergés

Contenu

Avantages de gitlab auto-hébergé

Contenu
  • Solution robuste et éprouvée
  • Beaucoup d'intégrations
  • Intégration de Mattermost
  • CI incluse

One more thing

Contenu

L'intégration continue

Principe

Contenu

Automatiser la construction d'une "build"

  • Génération des assets
  • « Compilation »
  • Tests unitaires
  • ...

Solutions SAAS

Contenu

Github + Travis CI (https://travis-ci.org/)

Quand push sur "master" -> lancement de tests

Les hooks git

Contenu
  • Script exécuté lors d'une action
  • Local (pre commit) distant (post receive)
  • scripts dans le .git/hooks d'un dépot

Attention : Gitlab utilise déjà ces hooks pour fonctionner, ne pas les modifier ! utiliser les "custom_hooks"

Exemple.

 

Gitlab CI

Contenu
  • Solution type "travis"
  • Intégrable facilement à côté d'un gitlab
  • n gitlab <=> n gitlab CI (même sur des serveurs différents)
  • Principe de "Runner"

Prise en main de gitlab CI

Premiers tests

Contenu
  1. Création d'un dépot
  2. Création du fichier .gitlab-ci.yml
  3. Tests

.gitlab-ci.yml

Contenu

Défini le comportement.


stages:
  - deploy

prod-deployment:
  stage: deploy
  script:
    -  ssh slides_kgaut_net@slides.kgaut.net 'bash -s' < scripts/prod-deployment.sh
  only:
    - master

Proof of concept

Contenu


mail:
  script: "echo 'coucou' | mail -s 'test email' contact@kgaut.net"

Les variables

Contenu
variables:
  DESTINATAIRE: 'contact@kgaut.net'

mail:
  script: "echo 'coucou' | mail -s 'test email' $DESTINATAIRE"

Variables sur gitlab

Contenu

Settings > CI / CD / Variables

Exemples d'utilisation de variables

Contenu

variables:
  PROJECT_NAME: 'MonSite.com'
  PROJECT_SHORTNAME: 'monsite'
  DB_PATH: 'db'
  DRUSH_EXEC: 'drush'
  DIFFS_PATH: 'files/diffs'

  PREPROD_URL: 'preprod.monsite.com'
  PREPROD_DRUSH_ALIAS: '--uri="preprod.monsite.com"'
  PREPROD_DRUSH_ROOT_ARG: '--root="/var/www/html/preprod.monsite.com" --uri="preprod.monsite.com"'
  PREPROD_EMAIL_ALERT: 'contact+montsite-preprod@kgaut.net'
  PREPROD_USER: 'admin'
  PREPROD_IP: 'preprod.monsite.com'
  PREPROD_SSH: 'ssh admin@preprod.monsite.com'
  PREPROD_PROJECT_ROOT: '/var/www/html/preprod.monsite.com'

Définition de plusieurs «jobs»

Contenu


mail:
  script: "echo 'coucou' | mail -s 'test email' contact@kgaut.net"
mail2:
  script: "echo 'coucou' | mail -s 'test email 2' contact+test@kgaut.net"

Ajout condition de branche

Contenu


mail:
  script: "echo 'push sur master' | mail -s 'push sur master' contact@kgaut.net"
  only:
    - master
mail2:
  script: "echo 'coucou' | mail -s 'push une branche' contact+test@kgaut.net"

Les «stages»

Contenu

Groupement de jobs qui seront exécutés en parallèle.

Si plusieurs étapes, alors l'étape N+1 ne sera lancée que si l'étape N s'est correctement exécutée.

NB : la clé allow_failure : true permet de ne pas impacter la suite au niveau d'un job

Exemple «stages»

Contenu


stages:
  - etape_1
  - etape_2

mail_admin:
  script: "echo 'push sur master' | mail -s 'push sur master' contact@kgaut.net"
  stage: etape_1
  only:
    - master
fail:
  script: "lorem"
  stage: etape_1

mail_2:
  script: "echo 'coucou' | mail -s 'push une branche' contact+test@kgaut.net"
  stage: etape_2

Plus d'exemples

Connexion distante via Gitlab CI

Principe

Contenu

Au push :

  1. Le runner va se connecter à notre serveur distant
  2. Il va exécuter une ou plusieurs commande commande
  3. Nous en retournera le résultat

Autoriser le runner à se connecter

Contenu

Genérer une clé SSH :


sudo -u gitlab-runner -H ssh-keygen -t rsa -C "contact@kgaut.net"

Ajouter la clé au trousseau du serveur distant


sudo -u gitlab-runner -H ssh-copy-id user@serveur

Note : Il peut être pratique d'ajouter cette clé dans /etc/skel/.ssh/authorized_keys.

Tester


sudo -u gitlab-runner -H ssh user@serveur

Authoriser notre serveur à se connecter à gitlab

Contenu

Génération d'une clée :


ssh-keygen -t rsa -C "contact@kgaut.net"

cat .ssh/id_rsa.pub

Ajout de cette clé aux clés de déploiements du dépôt.

Ou par des variables

Contenu

Clée SSH ou password.

settings / CI CD / Variables

Plus d'informations sur les variables : https://gitlab.com/help/ci/variables/README#variables

Connexion via variables

Contenu

before_script:
  - 'which ssh-agent || ( apt-get install -qq openssh-client )'
  - eval $(ssh-agent -s)
  - ssh-add <(echo "$SSH_PRIVATE_KEY")
  - mkdir -p ~/.ssh
  - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'

deploy_prod:
  type: deploy
  script: ssh $SSH_USER@$SSH_HOST "ls -al"

 

Script de déploiement

Contenu

Script bash qui sera executé sur le serveur distant :


ssh user@serveur 'bash -s' < scripts/prod-deployment.sh
  • Le script sera versionné.
  • Langage "bash"

Exemple script de déploiement D8

Contenu


#!/bin/bash
set -e
cd /home/slides_kgaut_net
~/vendor/bin/drush @sli sql-dump --gzip > db/`date +%Y-%m-%d_%H-%M-%S`-slides.kgaut.net-drush.sql.gz
git pull
composer install
composer install
cd web
~/vendor/bin/drush @sli updb -y
~/vendor/bin/drush @sli cr
~/vendor/bin/drush @sli config-import

Livre de recettes

Utiliser une image docker spécifique

Contenu

generate_assets:
  stage: postdeploy
  image: node:10.15.2
  script:
    - node -v
    - npm install -g gulp
    - npm install --silent
    - gulp build
  except:
    refs:
      - schedules

Déclencher une tache sur certains type de fichiers

Contenu
generate_assets:
  stage: postdeploy
  image: node:10.15.2
  script:
    - node -v
    - npm install -g gulp
    - npm install --silent
    - gulp build
  only:
    refs:
      - master
    changes:
      - web/themes/custom/cb_back/assets/**/*.scss
  except:
    refs:
      - schedules

https://kgaut.net/snippets/2019/gitlab-ci-ne-lancer-une-tache-que-lorsq…


 

Déployer sur un tag

Contenu

prod_deploy:
  script:
  - $PROD_SSH 'bash -s' < scripts/deploy/deploy.sh $PROD_PROJECT_ROOT $CI_ENVIRONMENT_NAME $PROD_DRUSH_ALIAS $DRUSH_EXEC
  only:
  - tags
  except:
  - schedules
  stage : deploy
  environment:
    name: prod

#!/bin/bash
set -e

PROJECT_ROOT="$1"
CI_ENVIRONMENT_NAME="$2"
PROJECT_DRUSH_ALIAS="$3"
DRUSH_EXEC="$4"

cd $PROJECT_ROOT

if [ $CI_ENVIRONMENT_NAME = "prod" ]
then
    git fetch --tags
    latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
    git checkout $latestTag
else
    git pull
fi

composer install --no-dev
$DRUSH_EXEC "$PROJECT_DRUSH_ALIAS" cr
$DRUSH_EXEC "$PROJECT_DRUSH_ALIAS" updb -y
$DRUSH_EXEC "$PROJECT_DRUSH_ALIAS" config-import sync -y
$DRUSH_EXEC "$PROJECT_DRUSH_ALIAS" scr ../scripts/deploy/post-import-script.php



 

Sauvegarder son gitlab

Contenu

Crontab :


05      0       *       *       *       gitlab-rake gitlab:backup:create BACKUP=dump GZIP_RSYNCABLE=yes

Dossiers à sauvegarder :

/etc/gitlab

/opt/gitlab

/var/opt/gitlab