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

问题描述 投票:4回答:4

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

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

jenkins shared-libraries jenkins-pipeline pipeline gitlab-ci
4个回答
11
投票

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

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

受到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加载函数的要求出现问题(例如,我使用一些基于Alpine的图像用于基于CLI工具的默认情况下具有sh的作业)
  • 使用基于项目的CI / CD秘密变量来个性化项目的构建作业。像环境URL等。

4
投票

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实例上创建新项目。


3
投票

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


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 repo导入共享的ci_shared_library文件。

# .gitlab-ci.yml

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

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

© www.soinside.com 2019 - 2024. All rights reserved.