gitlab ci跨项目模板复用依赖include+extends组合:通过专用ci-templates仓库分目录管理基础、语言、部署等模板,业务项目用include引入指定版本文件后,以extends继承其中以.开头的template job,实现逻辑复用与定制化。

GitLab CI 的 extends 本身不跨项目,它只在单个 .gitlab-ci.yml 文件内生效。真正实现跨项目模板复用和版本控制,靠的是 include + extends 的组合——把通用 job 定义在独立仓库中,再通过 include 引入,最后用 extends 继承和定制。
统一模板仓库的结构设计
新建一个专用 GitLab 项目(如 ci-templates),作为所有团队共享的 CI 模板源。推荐目录结构如下:
-
base/:存放基础模板,如.job-base(定义通用镜像、缓存、超时) -
language/:按语言分组,如python-test.yml、node-build.yml -
deploy/:环境相关模板,如k8s-deploy.yml、serverless-deploy.yml -
versioned/:为每个大版本建子目录(如v1.2/),确保下游项目可锁定模板版本
每个 YAML 文件只定义 template jobs(以 . 开头),不声明 stage 或触发条件,保持纯粹可复用性。
在业务项目中引入并继承模板
业务项目根目录的 .gitlab-ci.yml 不写具体逻辑,只做两件事:引入 + 扩展。
例如,某 Python 服务想复用测试模板并适配自身路径:
include:
- project: "group/ci-templates"
ref: "v1.2" # 锁定模板版本,避免上游变更影响
file: "language/python-test.yml"
<p>test:unit:
extends: .python-test-unit
variables:
TEST_PATH: "src/tests/"
artifacts:</p>
- "coverage.xml"
关键点:
Convert Github Repository下载适用于以下场景:(1)用户提供 GitHub 仓库 URL 或本地仓库路径,并请求将其转换为其他格式;(2)用户请求导出 GitHub 仓库……
-
ref必须指定分支或 tag,不能用main这类浮动引用,否则失去版本控制意义 -
extends后接的是被引入文件里定义的 template job 名(如.python-test-unit),不是文件名 - 本地 job 可覆盖变量、添加
artifacts、修改rules等,但不建议重写script—— 那会破坏统一性
-
支持多环境与差异化配置
模板仓库内部也可分层设计。比如在 ci-templates/deploy/ 下提供:
-
base-deploy.yml:含通用部署脚本、权限检查、镜像拉取逻辑 -
staging-deploy.yml:extends: .base-deploy,追加灰度发布参数 -
prod-deploy.yml:extends: .base-deploy,增加人工审批、备份步骤
业务项目按需引入:
include:
- project: "group/ci-templates"
ref: "v1.2"
file: "deploy/prod-deploy.yml"
<p>deploy-to-prod:
extends: .prod-deploy
variables:
TARGET_CLUSTER: "prod-us-east"</p>
这样既保证核心逻辑集中维护,又保留各项目对目标环境的控制权。
版本升级与向后兼容策略
模板升级不是直接改 main 分支,而是:
- 在
ci-templates仓库打新 tag(如v1.3),包含文档更新、变更日志、废弃说明 - 新增模板用新名字(如
.python-test-v2),旧模板保留在v1.2目录下继续服务老项目 - 提供自动化迁移脚本(如扫描所有业务项目
.gitlab-ci.yml,批量替换ref和extends引用)
GitLab 自身不校验跨项目引用的语义正确性,所以每次发布前务必在模板仓库跑一次「集成验证流水线」,用多个模拟业务项目配置触发实际构建,确保所有 include + extends 组合能正常解析和执行。










