具有复杂子文件夹的 Gitlab CI 父/子管道

Posted

技术标签:

【中文标题】具有复杂子文件夹的 Gitlab CI 父/子管道【英文标题】:Gitlab CI parent/child pipelines with complex subfolders 【发布时间】:2021-10-10 21:49:23 【问题描述】:

我的 gitlab(社区版,版本 14.1.2)CI 在我的 monorepo 上存在复杂管道的问题。

我的结构是客户端/服务器:

根/ ---- 服务器/ -------- 库/ ------------ libA/ ------------ libB/ ------------ libC/ -------- 应用程序/ ------------ appA/ ------------ appB/ ------------ appC/ ---- 客户/ -------- 应用程序/ ------------- appA/ ------------- appB/ ...

每个文件夹(根目录、服务器、lib、libA、libB、libC 等)都有自己的“.gitlab-ci.yml”

“.gitlab-ci.yml”是:

stages:
  - build
  - test

build-server:
  stage: build
  trigger:
      include:
          - local: 'server/.gitlab-ci.yml'
  rules:
      - changes:
          - server/**/*
        
build-client:
  stage: build
  trigger:
      include:
          - local: 'client/.gitlab-ci.yml'
  rules:
      - changes:
          - client/**/*

服务器“.gitlab-ci.yml”是:

stages:
  - build
  - test

build-lib:
  stage: build
  trigger:
      include:
          - local: 'lib/.gitlab-ci.yml'
  rules:
      - changes:
          - lib/**/*
        
build-applications:
  stage: build
  trigger:
      include:
          - local: 'applications/.gitlab-ci.yml'
  rules:
      - changes:
          - applications/**/*

lib“.gitlab-ci.yml”是:

stages:
  - build
  - test

build-libA:
  stage: build
  script:
     - echo "Execute libA build!" 
  rules:
      - changes:
          - libA/**/*
        
build-libB:
  stage: build
  script:
     - echo "Execute libB build!" 
  rules:
      - changes:
          - libB/**/*

如果我更改 libA 中的文件,仅触发根文件夹的“.gitlab-ci.yml”,其他子文件夹不会检测到文件更改并且不会触发构建。 此配置的目的是,例如,当我更改 libA 中的文件时,管道会检测到更改并构建 libA。 有人可以帮我解决吗?我希望结构和问题是清楚的。谢谢。

更新

我正在使用 gitlab 14.1.0

感谢 DavidC 的回答,但使用您的解决方案我没有解决我的问题,尤其是触发器 $CI_PROJECT_PATH 似乎不起作用。

一段时间后,我终于找到了一个解决方案(可以用变量进化)

“.gitlab-ci.yml”是:

stages:
  - build
  - test

build-server:
  stage: build
  trigger:
      include:
          - local: '/server/.gitlab-ci.yml'
  rules:
      - changes:
          - server/**/*
        
build-client:
  stage: build
  trigger:
      include:
          - local: '/client/.gitlab-ci.yml'
  rules:
      - changes:
          - client/**/*

服务器“.gitlab-ci.yml”是:

stages:
  - build
  - test

build-lib:
  stage: build
  trigger:
      include:
          - local: '/server/lib/.gitlab-ci.yml'
  rules:
      - changes:
          - server/lib/**/*
        
build-applications:
  stage: build
  trigger:
      include:
          - local: '/server/applications/.gitlab-ci.yml'
  rules:
      - changes:
          - server/applications/**/*

lib“.gitlab-ci.yml”是:

stages:
  - build
  - test

build-libA:
  stage: build
  script:
     - echo "Execute libA build!" 
  rules:
      - changes:
          - server/lib/libA/**/*
        
build-libB:
  stage: build
  script:
     - echo "Execute libB build!" 
  rules:
      - changes:
          - server/lib/libB/**/*

注意gitlab文档中的这一行:“父子管道被引入,最大深度为一个子管道级别,随后增加到两个。一个父管道可以激活许多子管道,这些子管道可以激活自己的子管道。无法激活其他级别的子管道。”参考:https://docs.gitlab.com/ee/ci/pipelines/parent_child_pipelines.html#nested-child-pipelines

感谢您的帮助!

【问题讨论】:

【参考方案1】:

似乎 GitLab 子管道上下文执行路径与您的存储库的根目录相同,并且与子管道 gitlab-ci.yml 文件的路径无关。

到目前为止,唯一的解决方案似乎是将您想要的目录的路径作为变量提供给您的子管道,或者直接在 .gitlab-ci.yml 中定义它。

例子:

根“.gitlab-ci.yml”是:

stages:
  - build
  - test

build-server:
  stage: build
  variables:
    CI_ROOT_DIR: server # you don't need to provide it, if you define it in the server/.gitlab-ci.yml file
  trigger:
      include:
          - local: '$CI_ROOT_DIR/.gitlab-ci.yml'
  rules:
      - changes:
          - $CI_ROOT_DIR/**/*
        
build-client:
  stage: build
  variables:
    CI_ROOT_DIR: client
  trigger:
      include:
          - local: '$CI_ROOT_DIR/.gitlab-ci.yml'
  rules:
      - changes:
          - $CI_ROOT_DIR/**/*

服务器“.gitlab-ci.yml”是:

stages:
  - build
  - test

variables:
  CI_ROOT_DIR: $CI_PROJECT_PATH/server # default

build-lib:
  stage: build
  variables:
    CI_ROOT_DIR: $CI_ROOT_DIR/lib # you don't need to provide it, if you define it in the server/lib/.gitlab-ci.yml file
  trigger:
      include:
          - local: '$CI_ROOT_DIR/.gitlab-ci.yml'
  rules:
      - changes:
          - $CI_ROOT_DIR/**/*
        
build-applications:
  stage: build
  variables:
    CI_ROOT_DIR: $CI_ROOT_DIR/applications # you don't need to provide it, if you define it in the server/applications/.gitlab-ci.yml file
  trigger:
      include:
          - local: '$CI_ROOT_DIR/.gitlab-ci.yml'
  rules:
      - changes:
          - $CI_ROOT_DIR/**/*

lib ".gitlab-ci.yml" 是:

stages:
  - build
  - test

variables:
  CI_ROOT_DIR: $CI_PROJECT_PATH/server/lib # default

build-libA:
  stage: build
  script:
     - echo "Execute libA build!" 
  rules:
      - changes:
          - $CI_ROOT_DIR/libA/**/*
        
build-libB:
  stage: build
  script:
     - echo "Execute libB build!" 
  rules:
      - changes:
          - $CI_ROOT_DIR/libB/**/*

如果可以在父管道触发时选择管道执行的上下文,或者 Gitlab 预定义的环境变量可以使用 CI_CHILD_PIPELINE_DIR 变量,那就更好了

【讨论】:

以上是关于具有复杂子文件夹的 Gitlab CI 父/子管道的主要内容,如果未能解决你的问题,请参考以下文章

问:Gitlab CI 谁重试旧管道

gitlab ci 管道部署 ftp 失败

gitlab CI 管道检查代码格式

为合并请求触发的管道运行应用 GitLab CI/CD 管道更改

使用管道在父进程和子进程之间进行通信的问题

如何从 GitLab CI 管道的工作发送电子邮件?