极狐GitLab

从复制粘贴到可复用组件:极狐GitLab CI/CD 组件目录实战

极狐GitLab
2026年9月7日
18600
分享:

从复制粘贴到可复用组件:极狐GitLab CI/CD 组件目录实战

在企业级 DevOps 实践中,流水线配置的重复编写是一个长期存在的效率瓶颈。不同项目之间相似的构建、测试、安全扫描步骤,往往通过「复制粘贴 + 局部修改」的方式传递,导致版本碎片化、维护成本居高不下。极狐GitLab 从 16.0 开始引入的 CI/CD 组件(Components)组件目录(Catalog),正是为了解决这一问题:把流水线中的通用能力封装为可版本化、可参数化的复用单元,让团队从「复制粘贴」走向「引用组件」。

本文基于极狐GitLab 官方文档,系统梳理 CI/CD 组件的核心概念、目录化发布流程与落地实践,并给出可直接使用的 .gitlab-ci.yml 示例。


一、为什么需要 CI/CD 组件

在引入组件之前,极狐GitLab 已经支持 include:templateinclude:projectinclude:remote 等方式复用流水线配置。但这些方式各有局限:

  • include:template 只能引用极狐GitLab 内置模板,无法承载团队自定义逻辑;

  • include:project 可以引用其他项目的文件,但缺乏版本语义,引用分支意味着随时可能引入破坏性变更;

  • include:remote 依赖外部 URL,版本控制与审计追踪都不理想。

CI/CD 组件在以上基础上做了三个关键增强:

  1. 目录化:组件可以发布到 CI/CD 组件目录,团队内可搜索、可发现;

  2. 版本化:组件支持语义版本(Semantic Versioning),调用方可以精确锁定到 1.0.0,也可以使用 1~latest 自动获取兼容的最新版本;

  3. 参数化:通过 spec:inputs 定义输入参数,调用方通过 inputs 传参,避免硬编码带来的耦合。

版本要求:CI/CD 组件在极狐GitLab 17.0 成为 GA(正式发布),组件目录在 16.7 进入 Beta、17.0 GA。当前每个项目最多支持 100 个组件(18.5 起)。


二、组件的核心语法:include:component

引用一个组件的标准格式如下:

include:
  - component: $CI_SERVER_FQDN/my-group/my-project/secret-detection@1.0.0
    inputs:
      stage: test

各段含义:

  • $CI_SERVER_FQDN:极狐GitLab 实例的预定义变量,避免硬编码域名;

  • my-group/my-project:组件所在项目的完整路径;

  • secret-detection:组件名称,对应 templates/secret-detection.ymltemplates/secret-detection/template.yml

  • 1.0.0:组件版本,可以是标签、提交 SHA、分支名,或 ~latest

版本解析优先级

组件版本按以下优先级解析(从高到低):

优先级

类型

示例

1

提交 SHA

e3262fdd0914fa823210cdb79a8c421e2cef79d8

2

标签

1.0.0(推荐)

3

分支名

main

4

部分语义版本 / ~latest

11.2~latest

使用部分版本时,系统会自动选择匹配范围内的最新稳定版本,不会选中预发布版本(如 1.0.1-rc)。


三、如何创建一个组件

一个合格的组件项目需要满足以下目录结构:

├── templates/
│   └── secret-detection.yml          # 单文件组件
│   └── build-image/
│       ├── template.yml              # 多文件组件(仅 template.yml 对外暴露)
│       ├── Dockerfile
│       └── test.sh
├── README.md                          # 必须:记录所有组件的说明
├── LICENSE.md
└── .gitlab-ci.yml

单文件组件示例

以下是一个用于密钥检测的组件定义:

# templates/secret-detection.yml
spec:
  inputs:
    stage:
      default: test
      description: "密钥检测作业所在的阶段"
---
gitleaks-scan:
  stage: $[[ inputs.stage ]]
  image:
    name: zricethezav/gitleaks:latest
    entrypoint: [""]
  script:
    - gitleaks detect --source . --verbose --redact
  artifacts:
    reports:
      secret_detection: gl-secret-detection-report.json
    when: always

关键说明:

  • spec:inputs 定义了调用方可传入的参数,未传则使用 default 默认值;

  • $[[ inputs.stage ]] 是 CI/CD 表达式语法,用于在组件内部引用输入值;

  • --- 分隔符将 spec 头部与实际的作业定义分开。

多文件组件示例

当组件需要附带辅助文件(如脚本、配置模板)时,使用目录形式:

# templates/build-image/template.yml
spec:
  inputs:
    image_name:
      description: "输出的镜像名称"
    image_tag:
      default: latest
    dockerfile:
      default: Dockerfile
---
build-container:
  stage: build
  image: gcr.io/kaniko-project/executor:debug
  script:
    - /kaniko/executor
      --context "$CI_PROJECT_DIR"
      --dockerfile "$CI_PROJECT_DIR/$[[ inputs.dockerfile ]]"
      --destination "$CI_REGISTRY_IMAGE/$[[ inputs.image_name ]]:$[[ inputs.image_tag ]]"

目录中的 Dockerfiletest.sh 等文件仅用于组件自身的构建或测试,不会被调用方直接引用


四、组件上下文:让组件知道自己是谁

从极狐GitLab 18.6(Beta)/ 18.7(GA)起,组件可以通过 组件上下文 访问自身的元数据:

spec:
  component: [name, version, reference]
  inputs:
    stage:
      default: build
---
build-image:
  stage: $[[ inputs.stage ]]
  image: registry.example.com/$[[ component.name ]]:$[[ component.version ]]
  script:
    - echo "Building with component $[[ component.name ]]@$[[ component.version ]]"
    - echo "Reference: $[[ component.reference ]]"

支持的上下文字段:

  • name:组件名称;

  • version:被解析后的实际版本;

  • reference:调用方原始引用的版本字符串;

  • sha:组件的提交 SHA。

这在需要把组件版本信息注入产物元数据或日志追踪时非常有用。


五、发布到 CI/CD 组件目录

组件目录是极狐GitLab 实例内的「组件市场」。发布流程如下:

  1. 确保项目结构合规:包含 README.mdtemplates/ 目录;

  2. 创建语义版本标签:如 git tag -a v1.0.0 -m "Initial release" && git push origin v1.0.0

  3. 发布到目录:在项目的 设置 > CI/CD > 组件目录 中,选择要发布的组件并确认;

  4. 验证发布:在实例的 探索 > CI/CD 组件目录 中搜索组件名称,确认可见。

注意:发布到目录的组件必须使用语义版本标签(如 1.0.01.1.0),v1.0.0 前缀的 Git 标签也会被正确解析。


六、在项目中引用组件:完整示例

假设团队已经发布了以下组件:

  • my-group/ci-components/secret-detection@1.0.0

  • my-group/ci-components/build-image@2.1.0

项目中的 .gitlab-ci.yml 可以这样组合使用:

stages:
  - build
  - test
  - deploy

include:
  - component: $CI_SERVER_FQDN/my-group/ci-components/build-image@2.1
    inputs:
      image_name: my-app
      image_tag: $CI_COMMIT_SHORT_SHA
      dockerfile: Dockerfile.prod

  - component: $CI_SERVER_FQDN/my-group/ci-components/secret-detection@1.0.0
    inputs:
      stage: test

  - component: $CI_SERVER_FQDN/my-group/ci-components/unit-test@~latest
    inputs:
      stage: test
      coverage_threshold: 80

deploy-staging:
  stage: deploy
  image: bitnami/kubectl:latest
  script:
    - kubectl set image deployment/my-app
      my-app=$CI_REGISTRY_IMAGE/my-app:$CI_COMMIT_SHORT_SHA
      --namespace=staging
  environment:
    name: staging
    url: https://staging.example.com
  only:
    - main

这个示例展示了三个关键实践:

  1. 精确版本锁定secret-detection@1.0.0 确保安全扫描行为稳定不变;

  2. 部分版本自动升级build-image@2.1 自动获取 2.1.x 的最新补丁版本,兼顾稳定性与缺陷修复;

  3. ~latest 快速迭代unit-test@~latest 适合仍在快速演进的内部工具,但需谨慎用于生产关键路径。


七、组件与 include 其他方式的对比

特性

include:component

include:template

include:project

版本控制

语义版本 / SHA / 分支

无(跟随实例版本)

分支 / 标签(非语义化)

参数化

支持 spec:inputs

不支持

不支持

目录化发现

支持(CI/CD Catalog)

不支持

不支持

适用场景

团队自定义复用组件

极狐GitLab 官方模板

跨项目文件引用


八、安全与维护建议

对于组件使用者

  • 审计组件源码:在引入第三方组件前,审查其 templates/ 下的实际逻辑;

  • 固定版本:优先使用提交 SHA 或精确标签,避免 ~latest 引入意外变更;

  • 最小权限:为组件项目配置范围最小的访问令牌,避免过度授权。

对于组件维护者

  • 启用分支保护:要求所有变更通过合并请求进入默认分支;

  • 签署提交:确保组件仓库的提交可追溯、可验证;

  • 使用受保护标签:为发布标签配置保护规则,防止误删或篡改。


九、总结

CI/CD 组件与组件目录的引入,让极狐GitLab 的流水线配置从「文件级复用」跃迁到「组件级复用」。通过语义版本、参数化输入和目录化发现,团队可以把最佳实践固化为可共享、可演进的流水线资产,显著降低多项目维护成本。

对于已经运行在极狐GitLab 17.0+ 的团队,建议从以下路径开始落地:

  1. 识别团队内重复率最高的流水线片段(如镜像构建、安全扫描、单元测试);

  2. 将其提取为组件项目,定义清晰的 spec:inputs

  3. 发布到 CI/CD 组件目录,并在 2-3 个试点项目中引用验证;

  4. 逐步推广至全团队,建立组件的维护与版本治理规范。


参考来源