Python GitLab CI 的 include + extends 优化

1次阅读

gitlab ci 的 include 是静态 yaml 合并而非 python 式导入,路径错误会静默跳过导致 job 消失;include 路径须以项目根目录为基准,extends 仅限单文件内生效,变量合并规则复杂,需谨慎使用 before_script、cache 和 variables。

Python GitLab CI 的 include + extends 优化

include 路径写错导致 job 找不到

gitlab CI 的 include 不是“导入 Python 模块”,它只做 YAML 合并,路径错误时不会报错,而是静默跳过——job 就凭空消失了。最常见的是相对路径没对准 .gitlab-ci.yml 所在位置。

实操建议:

立即学习Python免费学习笔记(深入)”;

  • include 中的 local 路径始终以项目根目录为基准,不是以当前文件所在目录为基准
  • include: local: '/ci/templates/deploy.yml',别写成 './templates/deploy.yml'(点开头会被忽略)
  • CI 配置里加个 dummy job 测试 include 是否生效:test-include: + script: echo "loaded",放在被 include 的文件里
  • GitLab 15.0+ 支持 include: template,但仅限官方模板;自定义模板必须用 localfile + project

extends 不能跨文件直接引用

extends 只在单个 YAML 文件内有效。很多人把基础 job 定义在 /ci/base.yml,然后在主文件里写 extends: .base-job,结果报错 Could not find anchor .base-job

实操建议:

立即学习Python免费学习笔记(深入)”;

  • 必须先 include 含有 anchor 的文件,再在**同一层级或下游文件**中 extends
  • anchor 名称要带点前缀避免冲突,比如统一用 .template-job.retry-strategy
  • 如果多个子文件都要复用同一组 anchor,把它们全收进一个 /ci/common.yml,主文件 include 它一次就够了
  • 注意 YAML 解析顺序:GitLab 先合并所有 include,再解析 extends,所以不能在 include 之前就用 extends

include + extends 组合后变量覆盖混乱

当 base job 定义了 variables:,而 extending job 也写了同名变量,实际行为是“深层合并”而非“覆盖”——比如 PATH 会拼接,但 ENV 这种标量会被后写的完全替换。容易误以为没生效。

实操建议:

立即学习Python免费学习笔记(深入)”;

  • !reference 替代部分 extends 场景,它支持跨文件引用 job 内容(GitLab 14.6+),且变量行为更可预测
  • 避免在 base 中设全局 variables,改用 default:variables 或显式传参:variables: { APP_ENV: $APP_ENV }
  • 调试时加 script: env | grep -E '^(APP|CI)_' 看最终变量值
  • before_scriptafter_script 是浅合并(后声明覆盖前),和 variables 行为不一致,别混着依赖

Python 项目里 include 复用 pytest 配置的坑

想把 pytest 相关 job 抽到 /ci/python-test.yml,但发现 cache: 路径不对、artifacts: 没上传、甚至 poetry install 报错找不到 pyproject.toml——问题出在工作目录和上下文丢失。

实操建议:

立即学习Python免费学习笔记(深入)”;

  • 所有被 include 的 job 必须显式声明 before_script 切工作目录:- cd $CI_PROJECT_DIR
  • cache:key 别用 $CI_COMMIT_REF_SLUG,改用 $CI_PROJECT_ID-$CI_COMMIT_TAG 避免跨分支污染
  • Python 依赖缓存建议用 pip + requirements.txt 方式,比 poetry 更稳定;若必须用 poetry,确保 POETRY_HOMEcache:paths 对齐
  • 不要在 base job 里写 script: pytest ...,改用 script: $TEST_CMD,让 extending job 通过 variables: { TEST_CMD: "pytest tests/" } 注入,更灵活

GitLab CI 的 include 和 extends 看似简单,但 YAML 合并规则、解析时机、作用域边界这些细节,一旦组合起来就很容易漏掉一层上下文。最常被忽略的是:include 不等于 import,extends 不等于 inherit,它们没有运行时概念,只有静态合并逻辑。

text=ZqhQzanResources