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

pyr*_*d3r 6 pipeline shared-libraries jenkins gitlab-ci jenkins-pipeline

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

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

Ste*_*tel 11

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

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

灵感来自Auto DevOps .gitlab-ci.yml模板 Gitlab本身创建,并且他们使用一个模板作业定义所有使用的函数调用每个before_script加载它们,我想出了以下设置.

所以使用共享的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"
}
Run Code Online (Sandbox Code Playgroud)

常见和通用.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
Run Code Online (Sandbox Code Playgroud)

您可以将文件从project-1复制粘贴到project-2,它将使用相同的共享Gitlab CI函数.

这些示例非常冗长,例如,以您喜欢的方式优化它们.

得到教训

因此,在大规模应用上述建设(40多个项目)后,我想分享一些经验教训,所以你不必找出困难的方法:

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


miq*_*miq 7

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'
Run Code Online (Sandbox Code Playgroud)

这将允许您在包含共享的GitLab实例上创建一个新项目.gitlab-ci.yml


Joa*_*ino 7

从 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


小智 6

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


pyr*_*d3r 6

所以,我一直想发布,以及我现在想到的:

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

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

  1. 每个构建作业的 shell 脚本,包含该步骤的执行逻辑。
  2. pipeline.yml包含整个管道配置的文件。在之前的脚本中,我们加载ci_shared_libraryto/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\/.*/
Run Code Online (Sandbox Code Playgroud)

每个想要使用此管道配置的项目都必须有一个.gitlab-ci.yml. 在这个文件中,唯一要做的就是pipeline.ymlci_shared_libraryrepo导入共享文件。

# .gitlab-ci.yml

include:
  - project: 'ci_shared_library'
    ref: master
    file: 'pipeline.yml'
Run Code Online (Sandbox Code Playgroud)

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