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

Jenkins 在项目之间共享gitlab-ci.yml,jenkins,shared-libraries,jenkins-pipeline,pipeline,gitlab-ci,Jenkins,Shared Libraries,Jenkins Pipeline,Pipeline,Gitlab Ci,我们正在考虑将ci从jenkins转移到gitlab。我们有几个项目具有相同的构建工作流。现在我们使用一个共享库,其中定义了管道,项目中的jenkinsfile只调用在定义实际管道的共享库中定义的方法。因此,只需在影响多个项目的单个点进行更改 我想知道gitlab ci是否也可以这样做?据我所知,不可能在存储库之外定义gitlab-ci.yml。是否有其他方法可以定义管道并与多个项目共享此配置以简化维护?首先,让我说:谢谢您提出这个问题!这促使我(再次)寻找解决方案,因为我经常想知道这是否可能。

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


我想知道gitlab ci是否也可以这样做?据我所知,不可能在存储库之外定义gitlab-ci.yml。是否有其他方法可以定义管道并与多个项目共享此配置以简化维护?

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

因此我找到了一个有效的解决方案:

受Gitlab本身创建的启发,在加载脚本之前,他们使用一个模板作业和每个
,我提出了以下设置

  • 需要一组共享CI作业/功能的多个项目回购(,)
  • 在单独的回购协议中包含所有共享功能
文件

因此,使用

一个通用的
.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
您可以将文件从复制粘贴到,它将使用相同的共享Gitlab CI函数

这些示例非常详细。出于示例目的,请以任何方式优化它们

经验教训

因此,在大规模(40多个项目)应用上述结构后,我想分享一些经验教训,这样您就不必找出困难的方法:

  • 版本(标记/发布)共享ci函数脚本。改变一件事现在可以使所有管道失效
  • 使用不同的Docker映像可能会导致bash加载函数的要求出现问题(例如,对于默认情况下具有
    sh
    的基于CLI工具的作业,我使用一些基于Alpine的映像)
  • 使用基于项目的CI/CD秘密变量对项目的生成作业进行个性化设置。比如环境URL等

使用
包含
功能(可从GitLab 10.6获得):

GitLab
11.7
引入了新的
include
方法,例如
include:file


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

,因此,我一直想发布我现在想到的内容:

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

我创建了一个名为
ci\u shared\u library
的存储库,其中包含

  • 每个构建作业的shell脚本,包含步骤的执行逻辑
  • 包含整个管道配置的
    pipeline.yml
    文件。在before脚本中,我们将
    ci_shared_库
    加载到
    /tmp/shared
    ,以便能够执行脚本
  • 每个想要使用此管道配置的项目都必须有一个
    .gitlab ci.yml
    。在这个文件中,唯一要做的就是从
    ci_shared_库
    repo导入共享的
    pipeline.yml
    文件

    # .gitlab-ci.yml
    
    include:
      - project: 'ci_shared_library'
        ref: master
        file: 'pipeline.yml'
    
    使用这种方法,与管道相关的所有内容实际上都位于一个存储库中,并且是可重用的。我们将整个管道模板放在一个文件中,但我认为甚至可以将其拆分为一个yml文件中的每个作业。通过这种方式,它将更加灵活,可以为具有类似作业但并非每个项目都需要所有作业的项目创建可以不同方式合并在一起的默认作业…

    自gitlab以来,可以定义外部
    .gitlab-cy.yml
    文件

    要自定义路径,请执行以下操作:

  • 转到项目的设置>CI/CD
  • 展开“常规管道”部分
  • 在自定义CI配置路径字段中提供值
  • 单击保存更改。 ... 如果CI配置将托管在外部站点上,则URL链接必须以.yml结尾:

    如果CI配置将托管在中的其他项目中 GitLab中,路径必须相对于另一个目录中的根目录 项目,并在末尾添加组和项目名称:

    .gitlab ci。yml@mygroup/另一个项目

    my/path/.my自定义文件。yml@mygroup/另一个项目


    您可以研究的概念

    它的演变包括:

    使用Jsonnet动态生成子管道配置 我们发布了,它允许您在运行时生成整个
    .gitlab ci.yml
    文件。
    例如,当您希望运行时行为更加动态时,这是monorepos的一个很好的解决方案

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

    请参见和。

    对于(2020年10月),包含的
    功能更加有用:

    使用API验证扩展的GitLab CI/CD配置 编写和调试复杂的管道不是一项简单的任务。您可以使用关键字来帮助减少管道配置文件的长度

    但是,如果您想验证整个管道
    include:
      - project: 'my-group/my-project'
        ref: master
        file: '/templates/.gitlab-ci-template.yml'
    
    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
    
    include:
      - project: 'ci_shared_library'
        ref: master
        file: 'pipeline.yml'