2015-11-04 10 views
14

Sto usando Gitlab CI 8.0 con gitlab-ci-multi-runner 0.6.0. Ho un file .gitlab-ci.yml simile al seguente:Come evitare di reinstallare le dipendenze per ogni lavoro in Gitlab CI

before_script: 
    - npm install 

server_tests: 
    script: mocha 

client_tests: 
    script: karma start karma.conf.js 

Questo funziona ma significa le dipendenze sono installati in modo indipendente prima di ogni lavoro di prova. Per un grande progetto con molte dipendenze si aggiunge un notevole sovraccarico.

In Jenkins userei un lavoro per installare le dipendenze, quindi TAR su e creare un artefatto di costruzione che viene poi copiato in processi a valle. Qualcosa di simile funzionerebbe con Gitlab CI? C'è un approccio raccomandato?

+0

Ho personalizzato la mia immagine di finestra mobile con quello che mi serve. Funziona per te? –

risposta

10

un approccio migliore in questi giorni è di fare uso di artifacts.

Nell'esempio seguente, la directory node_modules/ è immediatamente disponibile per il lavoro lint una volta completata la fase build.

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 
+0

Gli artefatti mostrano le opzioni di download nella pagina della pipeline. Possiamo evitarlo? – xiang

+0

Non ci credo, anche se questo problema potrebbe valerne la pena, https://gitlab.com/gitlab-org/gitlab-ce/issues/29757 – brendo

0

Penso che non sia raccomandato perché tutti i lavori dello stesso stadio potrebbero essere eseguiti in parallelo.

  1. Prima tutti i lavori di compilazione vengono eseguiti in parallelo.
  2. Se tutti i lavori di compilazione hanno esito positivo, i processi di test vengono eseguiti in parallelo.
  3. Se tutti i lavori di test hanno esito positivo, i lavori di distribuzione vengono eseguiti in parallelo.
  4. Se tutti i lavori di distribuzione hanno esito positivo, il commit è contrassegnato come riuscito.
  5. Se uno dei processi precedenti non riesce, il commit viene contrassegnato come non riuscito e non vengono eseguiti lavori di ulteriore livello.

Ho letto che qui:

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

+2

Sì, ma non potreste avere un lavoro stage 'build' che installa le dipendenze allora un numero qualsiasi di lavori in fase' test' che usano quegli stessi file? – Tamlyn

+0

In questo caso, suppongo che tu possa farlo, ma non so se prima troverai qualche problema con le dipendenze installate. Un'opzione potrebbe essere quella di definire uno script bash ed eseguire questa bash nel test (- sh script.sh) e quindi è possibile gestire le installazioni all'interno di bash. –

10

Aggiornamento: ora mi consiglia di utilizzare artifacts con una breve expire_in. Questo è superiore a cache perché deve scrivere l'artefatto solo una volta per pipeline mentre la cache viene aggiornata dopo ogni lavoro. Anche la cache è per runner, quindi se esegui i tuoi lavori in parallelo su più corridori non è garantito che vengano popolati, a differenza degli artefatti che vengono memorizzati centralmente.


Gitlab CI 8.2 aggiunge runner caching che consente di riutilizzare i file tra costruisce. Tuttavia ho trovato che questo è molto lento.

Invece ho implementato il mio sistema di caching utilizzando un po 'di scripting di 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 

Questo verrà eseguito prima di ogni lavoro nel vostro .gitlab-ci.yml e installare solo le dipendenze se package.json è cambiato oppure il file di cache è mancante (ad es. prima corsa o file cancellato manualmente). Si noti che se si dispone di più corridori su server diversi, ognuno avrà il proprio file di cache.

È possibile eliminare regolarmente il file di cache per ottenere le ultime dipendenze. Lo facciamo con la seguente voce di cron:

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

Sto utilizzando un approccio diverso, con un comando ln -s nella directory di backup before_script a node_modules e un rm node_modules in after_script. Questo è molto più veloce di un artefatto gitlab o di un zip. + usando l'ambiente gitlab su_stop è ora possibile eliminare la directory di backup quando si elimina il ramo. – BlouBlou

+0

Sembra buono. Perché non aggiungere questo come risposta? – Tamlyn

+0

Come funziona se si esegue il bump della versione del nodo da 6 a 8, ad esempio? Immagino che questo fallirà. Se hai impostato i motori di conseguenza in package.json, funzionerà comunque. –