web-dev-qa-db-fra.com

Comment éviter de réinstaller des dépendances pour chaque travail dans Gitlab CI

J'utilise Gitlab CI 8.0 avec gitlab-ci-multi-runner 0.6.0. J'ai un fichier .gitlab-ci.yml semblable au suivant:

before_script:
  - npm install

server_tests:
  script: mocha

client_tests:
  script: karma start karma.conf.js

Cela fonctionne, mais cela signifie que les dépendances sont installées indépendamment avant chaque travail de test. Pour un grand projet avec de nombreuses dépendances, cela ajoute un surcoût considérable. 

Dans Jenkins, j'utilisais un travail pour installer des dépendances, puis les TAR et créer un artefact de construction qui est ensuite copié dans les travaux en aval. Est-ce que quelque chose de similaire fonctionnerait avec Gitlab CI? Y a-t-il une approche recommandée?

17
Tamlyn

De nos jours, une meilleure approche consiste à utiliser les artefacts .

Dans l'exemple suivant, le répertoire node_modules/ est immédiatement disponible pour le travail lint une fois que l'étape build s'est terminée avec succès.

build:
  stage: build
  script:
    - npm install -q
    - npm run build
  artifacts:
    paths:
      - node_modules/
  expire_in: 1 week

lint:
  stage: test
  script:
    - npm run lint
9
brendo

Update: Je recommande maintenant d'utiliser artifacts avec un expire_in court. Ceci est supérieur à cache car il ne doit écrire que l’artefact une fois par pipeline, alors que le cache est mis à jour après chaque travail. De plus, le cache est par coureur. Ainsi, si vous exécutez vos travaux en parallèle sur plusieurs coureurs, son remplissage n’est pas garanti, contrairement aux artefacts stockés de manière centralisée.


Gitlab CI 8.2 ajoute runner caching qui vous permet de réutiliser des fichiers entre les générations. Cependant, j'ai trouvé que c'était très lent. 

Au lieu de cela, j'ai implémenté mon propre système de mise en cache en utilisant un peu de script Shell:

before_script:
  # unique hash of required dependencies
  - PACKAGE_HASH=($(md5sum package.json))
  # path to cache file
  - DEPS_CACHE=/tmp/dependencies_${PACKAGE_HASH}.tar.gz
  # Check if cache file exists and if not, create it
  - if [ -f $DEPS_CACHE ];
    then
      tar zxf $DEPS_CACHE;
    else
      npm install --quiet;
      tar zcf - ./node_modules > $DEPS_CACHE;
    fi

Cela sera exécuté avant chaque travail de votre .gitlab-ci.yml et n'installera vos dépendances que si package.json a changé ou si le fichier de cache est manquant (par exemple, première exécution, ou le fichier a été supprimé manuellement). Notez que si vous avez plusieurs coureurs sur différents serveurs, ils auront chacun leur propre fichier de cache. 

Vous voudrez peut-être vider le fichier de cache régulièrement pour obtenir les dernières dépendances. Nous faisons cela avec l'entrée cron suivante:

@daily               find /tmp/dependencies_* -mtime +1 -type f -delete
11
Tamlyn

Je pense que ce n’est pas recommandé car tous les travaux de la même étape peuvent être exécutés en parallèle.

  1. Tous les travaux de construction sont d'abord exécutés en parallèle.
  2. Si tous les travaux de construction réussissent, les travaux de test sont exécutés en parallèle.
  3. Si tous les travaux de test réussissent, les travaux de déploiement sont exécutés en parallèle.
  4. Si tous les travaux de déploiement réussissent, la validation est marquée comme réussie.
  5. Si l'un des travaux précédents échoue, la validation est marquée comme ayant échoué et aucun travail de l'étape suivante n'est exécuté.

J'ai lu ça ici:

http://doc.gitlab.com/ci/yaml/README.html

0

Je préfère utiliser le cache car supprime files lorsque le pipeline est terminé.

Exemple

image: node

stages:
 - install
 - test
 - compile

cache:
 key: modules
 paths:
  - node_modules/

install:modules:
 stage: install
 cache:
  key: modules
  paths:
    - node_modules/
  after_script:
   - node -v && npm -v
  script:
  - npm i

test:
 stage: test
 cache:
   key: modules
   paths:
     - node_modules/
   policy: pull
 before_script:
  - node -v && npm -v
 script:
- npm run test

compile:
 stage: compile
 cache:
 key: modules
 paths:
   - node_modules/
 policy: pull
 script:
  - npm run build
0
Alex Montoya