web-dev-qa-db-ja.com

プロジェクト間でgitlab-ci.ymlを共有する

CIをジェンキンスからgitlabに移動することを考えています。同じビルドワークフローを持つプロジェクトがいくつかあります。現在、パイプラインが定義されている共有ライブラリを使用しています。プロジェクト内のjenkinsfileは、実際のパイプラインを定義する共有ライブラリで定義されているメソッドのみを呼び出します。したがって、変更は1つのポイントでのみ行う必要があり、複数のプロジェクトに影響を与えます。

同じことがgitlab ciでも可能ですか?私が知る限り、リポジトリの外でgitlab-ci.ymlを定義することはできません。パイプラインを定義し、この構成を複数のプロジェクトと共有してメンテナンスを簡略化する別の方法はありますか?

9
pyriand3r

まず、この質問をしていただきありがとうございます。それが自分自身で可能かどうかよく疑問に思った後、解決策を(もう一度)検索するようになりました。また、まったく同じで.gitlab-ci.yml約400〜500の場所にあるファイルで、1つのものが変更された場合に、それぞれを変更する必要があります。

そこで私は実用的な解決策を見つけました:

Auto DevOps .gitlab-ci.yml template に触発され、Gitlab自体が作成され、1つのテンプレートジョブを使用して 使用されるすべての関数を定義する および call =すべてのbefore_scriptそれらをロードするために、次の設定を思いつきました。

  • 複数のプロジェクトリポジトリ( project-1project-2 )には、CIジョブ/関数の共有セットが必要です
  • 関数スクリプト すべての共有関数が個別のリポジトリに含まれています

ファイル

したがって、 shared ci jobs scipt を使用します:

#!/bin/bash

function list_files {
  ls -lah
}

function current_job_info {
  echo "Running job $CI_JOB_ID on runner $CI_RUNNER_ID ($CI_RUNNER_DESCRIPTION) for pipeline $CI_PIPELINE_ID"
}

一般的で一般的な.gitlab-ci.yml

image: ubuntu:latest

before_script:
  # Install curl
  - apt-get update -qqq && apt-get install -qqqy curl
  # Get shared functions script
  - curl -s -o functions.sh https://gitlab.com/giix/demo-shared-ci-functions/raw/master/functions.sh
  # Set permissions
  - chmod +x functions.sh
  # Run script and load functions
  - . ./functions.sh

job1:
  script:
    - current_job_info
    - list_files

project-1 から project-2 にファイルをコピーして貼り付けると、同じ共有Gitlab CI関数が使用されます。

これらの例は、例を示すためにかなり冗長です。好きなように最適化してください。

教訓

上記の構造を大規模に適用した後(40以上のプロジェクト)、学んだ教訓を共有したいので、難しい方法を見つける必要はありません。

  • 共有CI関数スクリプトのバージョン(タグ/リリース)。 1つのものを変更すると、すべてのパイプラインが失敗する可能性があります。
  • 異なるDockerイメージを使用すると、bashが関数をロードするための要件で問題が発生する可能性があります(たとえば、デフォルトでshが指定されているCLIツールベースのジョブに一部のAlpineベースのイメージを使用します)
  • プロジェクトベースのCI/CDシークレット変数を使用して、プロジェクトのビルドジョブをパーソナライズします。環境URLなど.
12

GitLab 11.7は、include:fileなどの新しいincludeメソッドを導入します: https://docs.gitlab.com/ee/ci/yaml/#includefile

include:
  - project: 'my-group/my-project'
    ref: master
    file: '/templates/.gitlab-ci-template.yml'

これにより、共有.gitlab-ci.ymlを含む同じGitLabインスタンスに新しいプロジェクトを作成できます。

8
miq

include機能を使用します(GitLab 10.6から利用可能): https://docs.gitlab.com/ee/ci/yaml/#include

5
Yevhen Lebid

Gitlab バージョン12.6 以降、外部.gitlab-cy.ymlファイルを定義することが可能です。

パスをカスタマイズするには:

  1. プロジェクトの[設定]> [CI/CD]に移動します。
  2. [一般的なパイプライン]セクションを展開します。
  3. 「カスタムCI構成パス」フィールドに値を入力します。
  4. [変更を保存]をクリックします。 ...

CI構成が外部サイトでホストされる場合、URLリンクは.ymlで終わる必要があります。

http://example.com/generate/ci/config.yml

CI構成がGitLab内の別のプロジェクトでホストされる場合、パスは他のプロジェクトのルートディレクトリからの相対パスで、末尾にグループとプロジェクト名が追加されている必要があります。

.gitlab-ci.yml @ mygroup/another-project

my/path/.my-custom-file.yml@mygroup/another-project

2
Joao Vitorino

だから、私はいつも投稿したかった、今私が思いついたもので:

現在、@ stefan-van-gastelによる共有CIライブラリの考え方とgitlab 11.7の比較的新しいinclude機能の混合アプローチを使用しています。 1つのリポジトリで40以上のリポジトリのビルドパイプラインを管理できるようになったため、このアプローチに非常に満足しています。

ci_shared_libraryというリポジトリを作成しました。

  1. ステップの実行ロジックを含むすべてのビルドジョブのシェルスクリプト。
  2. パイプライン構成全体を含むpipeline.ymlファイル。 beforeスクリプトでは、ci_shared_library/tmp/sharedにロードして、スクリプトを実行できるようにします。
stages:
  - test
  - build
  - deploy
  - validate

services:
  - docker:dind

before_script:
  # Clear existing shared library
  - rm -rf /tmp/shared
  # Get shared library
  - git clone https://oauth2:${GITLAB_TOKEN}@${SHARED_LIBRARY} /tmp/shared
  - cd /tmp/shared && git checkout master && cd $CI_PROJECT_DIR
  # Set permissions
  - chmod -R +x /tmp/shared
  # open access to registry
  - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY

test:
  stage: test
  script:
    - /tmp/shared/test.sh

build:
  stage: build
  script:
    - /tmp/shared/build.sh
  artifacts:
    paths:
      - $CI_PROJECT_DIR/target/RPMS/x86_64/*.rpm
    expire_in: 3h
  only:
    - develop
    - /release/.*/

deploy:
  stage: deploy
  script:
    - /tmp/shared/deploy.sh
  artifacts:
    paths:
      - $CI_PROJECT_DIR/tmp/*
    expire_in: 12h
  only:
    - develop
    - /release/.*/

validate:
  stage: validate
  script:
    - /tmp/shared/validate.sh
  only:
    - develop
    - /release\/.*/

このパイプライン構成を使用するすべてのプロジェクトには、.gitlab-ci.ymlが必要です。このファイルでは、共有するpipeline.ymlファイルをci_shared_libraryリポジトリからインポートするだけです。

# .gitlab-ci.yml

include:
  - project: 'ci_shared_library'
    ref: master
    file: 'pipeline.yml'

このアプローチでは、パイプラインに関するすべてのものが単一のリポジトリに存在し、再利用可能です。パイプラインテンプレート全体が1つのファイルにありますが、これを分割してすべてのジョブをymlファイルに含めることも可能だと思います。このようにすると、より柔軟になり、同様のジョブを持つがすべてのジョブを必要とするすべてのプロジェクトではないプロジェクトに対して、異なる方法でマージできるデフォルトジョブを作成できます...

0
pyriand3r