web-dev-qa-db-ja.com

Gitlab CIの各ジョブの依存関係の再インストールを回避する方法

Gitlab CI 8.0と gitlab-ci-multi-runner 0.6.0を使用しています。 .gitlab-ci.ymlファイルは次のようになります。

before_script:
  - npm install

server_tests:
  script: mocha

client_tests:
  script: karma start karma.conf.js

これは機能しますが、依存関係は各テストジョブの前に個別にインストールされます。多くの依存関係を持つ大規模なプロジェクトの場合、これはかなりのオーバーヘッドを追加します。

Jenkinsでは、1つのジョブを使用して依存関係をインストールし、TARを実行してビルドアーティファクトを作成し、それをダウンストリームジョブにコピーします。同様のものがGitlab CIでも機能しますか?推奨されるアプローチはありますか?

20
Tamlyn

最近のより良いアプローチは artifacts を利用することです。

次の例では、node_modules/ディレクトリは、lintステージが正常に完了するとすぐに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
9
brendo

更新artifactsと短いexpire_inを併用することをお勧めします。これはcacheより優れています。これは、アーティファクトをパイプラインごとに1回書き込むだけでよく、キャッシュはすべてのジョブの後に更新されるためです。また、キャッシュはランナーごとにあるため、複数のランナーでジョブを並行して実行した場合、中央に保存されているアーティファクトとは異なり、データが入力されるとは限りません。


Gitlab CI 8.2は、ビルド間でファイルを再利用できるようにする ランナーキャッシング を追加します。しかし、これは非常に遅いことがわかりました。

代わりに、シェルスクリプトを少し使用して、独自のキャッシュシステムを実装しました。

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

これは、.gitlab-ci.ymlのすべてのジョブの前に実行され、package.jsonが変更された場合、またはキャッシュファイルが見つからない場合(最初の実行、またはファイルが手動で削除された場合など)にのみ依存関係をインストールします。異なるサーバー上に複数のランナーがある場合、それぞれに独自のキャッシュファイルがあることに注意してください。

最新の依存関係を取得するために、定期的にキャッシュファイルをクリアすることをお勧めします。これを行うには、次のcronエントリを使用します。

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

docs から:

  • cacheプロジェクトの依存関係の一時ストレージに使用します。jarapkファイルなどの中間ビルド結果を保持するのには役立ちません。キャッシュは、依存関係(npmパッケージ、Goベンダーパッケージなど)などを維持することにより、特定のジョブの後続の実行の呼び出しを高速化するために使用されるように設計されているため、パブリックから再フェッチする必要はありません。インターネット。ステージ間で中間ビルド結果を渡すためにキャッシュが悪用される可能性がありますが、アーティファクトの方が適している場合もあります。

  • artifactsステージ間で渡されるステージ結果に使用します。アーティファクトは、ビルドのコンパイル/生成されたビットをアップロードするように設計されており、任意の数の同時ランナーによってフェッチできます。 。それらは利用可能であることが保証されており、ジョブ間でデータを受け渡すために存在します。また、UIからダウンロードするために公開されます。 アーティファクトはビルドディレクトリに相対的なディレクトリにしか存在できず、このルールに準拠していないパスを指定すると、直感的で非論理的なエラーメッセージがトリガーされます(拡張機能については https://gitlab.com/gitlab-org/gitlab-ce/issues/155 )。次のステージジョブを開始する前に、アーティファクトをGitLabインスタンス(GitLabランナーだけでなく)にアップロードする必要があるため、時間を費やす前に、帯域幅がステージとの共有によるアーティファクトから利益を得ることができるかどうかを慎重に評価する必要があります。セットアップの変更。

したがって、cacheを使用します。キャッシュを更新する必要がない場合(例:テストジョブのビルドフォルダー)、policy: pullを使用します( here を参照)。

3
Alisson Nunes

パイプラインの終了時にfilesを削除するため、私はキャッシュを使用することを好みます。

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
3
Alex Montoya

同じステージのすべてのジョブを並行して実行できるため、お勧めしません。

  1. まず、ビルドのすべてのジョブが並行して実行されます。
  2. ビルドのすべてのジョブが成功すると、テストジョブが並行して実行されます。
  3. テストのすべてのジョブが成功すると、デプロイジョブが並行して実行されます。
  4. デプロイのすべてのジョブが成功した場合、コミットは成功としてマークされます。
  5. 以前のジョブのいずれかが失敗した場合、コミットは失敗としてマークされ、それ以降のステージのジョブは実行されません。

私はそれをここで読んだ:

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

0