在项目之间共享gitlab-ci.yml

时间:2017-12-13 10:13:08

标签: jenkins shared-libraries jenkins-pipeline pipeline gitlab-ci

我们正在考虑将我们的ci从jenkins转移到gitlab。我们有几个项目具有相同的构建工作流程。现在我们使用一个共享库来定义管道,项目中的jenkinsfile只调用定义实际管道的共享库中定义的方法。因此,只需要在影响多个项目的单个点上进行更改。

我想知道gitlab ci是否可以实现相同的目标?据我所知,无法在存储库外定义gitlab-ci.yml。是否有另一种方法来定义管道并与多个项目共享此配置以简化维护?

7 个答案:

答案 0 :(得分:11)

首先让我先说:感谢您提出这个问题!它引发了我在经常想知道自己是否有可能之后再次寻找解决方案。我们还有20到30个完全相同的项目,并且.gitlab-ci.yml个文件大约有400 - 500个loc,如果有一个变化,每个文件都需要更改。

所以我找到了一个有效的解决方案:

受到Auto DevOps .gitlab-ci.yml template Gitlab本身创建的启发,以及他们使用一个模板作业define all functions usedcall每个before_script来加载它们,我想出了以下内容设置。

<强>文件

所以使用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函数脚本的版本(标记/发布)。改变一件事现在可以使所有管道都失败。
  • 使用不同的Docker镜像可能会导致bash加载函数的要求出现问题(例如,对于默认情况下sh的基于CLI工具的作业,我使用了一些基于Alpine的图像)
  • 使用基于项目的CI / CD秘密变量来个性化项目的构建作业。像环境URL等

答案 1 :(得分:4)

由于gitlab version 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 :(得分:3)

使用include功能(可从GitLab 10.6获得): https://docs.gitlab.com/ee/ci/yaml/#include

答案 3 :(得分:3)

GitLab 11.7引入了新的include方法,例如include:filehttps://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实例上创建一个新项目。

答案 4 :(得分:0)

所以,我一直想发表我现在想出的东西:

现在,我们使用@ stefan-van-gastel的共享ci库和gitlab 11.7的相对较新include功能的混合方法。我们对这种方法非常满意,因为我们现在可以在一个存储库中管理40多个存储库的构建管道。

我创建了一个名为ci_shared_library的存储库,其中包含

  1. 每个单独构建作业的shell脚本,其中包含该步骤的执行逻辑。
  2. 一个pipeline.yml文件,其中包含整个管道配置。在之前的脚本中,我们将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 develop && 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'

使用这种方法,实际上与管道有关的所有内容都驻留在一个单独的存储库中,并且可以重复使用。我们将整个管道模板放在一个文件中,但我认为甚至可以将其拆分为一个文件,每个文件都包含在yml文件中。这样,它将更加灵活,并且可以创建默认作业,这些作业可以针对具有相似作业的项目以不同方式合并在一起,但并非每个需要所有作业的项目...

答案 5 :(得分:0)

您可以研究 Dynamic Child pipeline 的概念。

它随着GitLab 13.2 (July 2020)的发展而发展:

使用Jsonnet动态生成子管道配置

我们发布了Dynamic Child Pipelines back in GitLab 12.9,可让您在运行时生成整个.gitlab-ci.yml文件。
例如,当您希望运行时行为更加动态时,这是Monorepos的绝佳解决方案。

我们现在通过包含一个项目模板来简化在运行时创建CI / CD YAML的过程,该模板演示了如何使用Jsonnet生成YAML。
Jsonnet是一种数据模板语言,它提供允许完全参数化的YAML配置的函数,变量,循环和条件。

https://about.gitlab.com/images/13_2/jsonnet-template.png

请参见documentationissue

答案 6 :(得分:0)

GitLab 13.5(2020年10月)中,include功能更加有用:

使用API​​验证扩展的GitLab CI / CD配置

编写和调试复杂的管道并不是一件容易的事。您可以使用include关键字来帮助减少管道配置文件的长度。

但是,如果您想事先通过API验证整个管道,则必须分别验证每个包含的配置文件,这既复杂又费时。

现在,您可以通过API验证管道的完全扩展版本,其中包括所有include配置。
现在,调试大型配置变得更加容易和高效。

请参见DocumentationIssue

并且:

请参见GitLab 13.6(2020年11月)

以列表形式包含多个CI / CD配置文件

以前,当使用include:file语法将多个文件添加到CI / CD配置时,必须为每个文件指定项目和引用。在此版本中,您现在可以一次指定项目,引用并提供所有文件列表。这样可以避免重复您的操作,并使您的管道配置不那么冗长。

https://about.gitlab.com/images/13_6/list.png -- Include multiple CI/CD configuration files as a list

请参见Documentation)和Issue