.gitlab-ci.yml 文件常用字段

286 阅读6分钟

在 GitLab CI/CD 中,.gitlab-ci.yml 文件是定义 CI/CD 流水线的核心。它使用 YAML 语法,通过一系列关键字和字段来描述流水线的各个阶段、作业(Job)以及它们的行为。

以下是 GitLab CI/CD 中常用的字段及其详细解释


A. 流水线结构与全局配置 (Pipeline Structure & Global Configuration)

这些字段定义了流水线的整体结构和所有作业的默认行为。

  1. stages

    • 作用: 定义流水线中所有阶段(Stage)的执行顺序。作业只能在已定义的阶段中运行。

    • 范围: 顶层。

    • 示例:

      stages:
        - build
        - test
        - deploy
      
    • 说明: 阶段按顺序执行,前一个阶段的所有作业成功后,下一个阶段才会开始。

  2. image

    • 作用: 指定所有作业(或某个特定作业)将使用的 Docker 镜像。这是运行作业命令的环境。

    • 范围: 顶层或作业级别。

    • 示例:

      default:
        image: node:18-alpine
      
      build_job:
        image: docker/compose:1.29.2 # 覆盖默认镜像
        script:
          - docker-compose build
      
    • 说明: 推荐使用官方或可信赖的镜像。

  3. variables

    • 作用: 定义 CI/CD 变量。这些变量可以在作业的脚本中使用。

    • 范围: 顶层或作业级别。

    • 示例:

      variables:
        APP_VERSION: 1.0.0
        BUILD_DIR: dist/
      
      build_app:
        script:
          - echo "Building version $APP_VERSION into $BUILD_DIR"
      
    • 说明: 变量可以被覆盖,优先级:作业变量 > 顶层变量 > 组/项目变量。

  4. default

    • 作用: 定义所有作业的默认配置。这有助于减少重复代码。

    • 范围: 顶层。

    • 示例:

      default:
        image: alpine/git
        before_script:
          - echo "Running default before script"
        tags:
          - my-runner
      
      build_job:
        script:
          - echo "Build"
      
    • 说明: 任何在作业中明确定义的字段都会覆盖 default 中的设置。

  5. workflow

    • 作用: 控制流水线何时运行或不运行。

    • 范围: 顶层。

    • 子字段:

      • rules: 定义何时创建或跳过流水线的规则。
    • 示例:

      workflow:
        rules:
          - if: '$CI_COMMIT_BRANCH == "main"' # 只有主分支的提交才运行流水线
      
    • 说明: 非常强大,可以根据分支、标签、变量等条件灵活控制流水线。

  6. include

    • 作用: 允许将 CI/CD 配置拆分成多个文件,提高可读性和重用性。

    • 范围: 顶层。

    • 子字段:

      • local: 包含当前项目中的本地文件。
      • file: 包含来自其他 GitLab 项目的文件。
      • remote: 包含来自外部 URL 的文件。
      • project: (与 file 结合) 指定包含文件的项目路径。
      • ref: (与 file 结合) 指定包含文件的 Git 引用(分支、标签、提交 SHA)。
    • 示例:

      include:
        - local: '.gitlab-ci-build.yml'
        - project: 'my-group/my-templates'
          file: '/templates/deploy.yml'
          ref: main
        - remote: 'https://example.com/ci/common.yml'
      
    • 说明: 极大地提高了大型项目的 CI/CD 配置管理能力。

B. 作业定义与执行控制 (Job Definition & Execution Control)

这些字段定义了单个作业的行为和执行条件。

  1. <job_name> (例如 build_job, test_frontend)

    • 作用: 定义一个 CI/CD 作业。作业是流水线中最小的执行单元。

    • 范围: 顶层。

    • 示例:

      build_job:
        stage: build
        script:
          - npm install
          - npm run build
      
    • 说明: 作业名称必须唯一。

  2. stage

    • 作用: 将作业分配到特定的阶段。

    • 范围: 作业级别。

    • 示例:

      my_job:
        stage: test
        script: echo "Running tests"
      
    • 说明: 必须是 stages 列表中已定义的阶段。

  3. script

    • 作用: 定义作业要执行的 shell 命令。

    • 范围: 作业级别。

    • 示例:

      my_job:
        script:
          - echo "Hello CI/CD"
          - npm test
      
    • 说明: 命令按顺序执行,任何命令失败都会导致作业失败。

  4. before_script

    • 作用: 定义在 script 命令之前执行的命令。常用于环境准备。

    • 范围: 顶层 (default) 或作业级别。

    • 示例:

      my_job:
        before_script:
          - apt-get update -y
          - apt-get install -y curl
        script:
          - curl example.com
      
    • 说明: 如果在 default 和作业中都定义了,作业级别的 before_script 会覆盖 default 的。

  5. after_script

    • 作用: 定义在 script 命令之后执行的命令,无论作业成功或失败。常用于清理。

    • 范围: 顶层 (default) 或作业级别。

    • 示例:

      my_job:
        script: echo "Main task"
        after_script:
          - echo "Cleanup complete"
      
    • 说明: 即使 script 失败,after_script 也会运行。

  6. tags

    • 作用: 指定作业应该在哪些具有特定标签的 Runner 上运行。

    • 范围: 顶层 (default) 或作业级别。

    • 示例:

      my_job:
        tags:
          - docker
          - linux
      
    • 说明: Runner 必须至少拥有一个匹配的标签才能执行作业。

  7. rules

    • 作用: 定义作业何时运行的复杂条件逻辑。推荐替代 only/except

    • 范围: 作业级别。

    • 子字段:

      • if: 基于 CI/CD 变量的表达式。
      • changes: 如果指定文件或目录发生变化,则运行。
      • exists: 如果指定文件或目录存在,则运行。
      • variables: 检查特定变量是否存在或匹配值。
      • when: 定义规则匹配时的作业行为 (on_success, on_failure, always, manual, delayed, never).
      • start_in: (与 when: delayed 结合) 延迟作业执行的时间。
      • allow_failure: 允许此规则匹配时作业失败。
    • 示例:

      deploy_prod:
        stage: deploy
        script: deploy.sh
        rules:
          - if: '$CI_COMMIT_BRANCH == "main"'
            when: manual # 主分支提交时手动触发
          - if: '$CI_COMMIT_TAG =~ /^v\d+.\d+.\d+$/' # 匹配版本标签时自动触发
            when: on_success
      
    • 说明: 规则按顺序评估,第一个匹配的规则决定作业行为。

  8. when

    • 作用: 定义作业的执行时机。

    • 范围: 作业级别 (通常在 rules 内部使用,或直接在作业下)。

    • 可选值:

      • on_success (默认): 前一阶段所有作业成功时运行。
      • on_failure: 前一阶段有作业失败时运行。
      • always: 无论前一阶段结果如何都运行。
      • manual: 需要手动触发。
      • delayed: 延迟一段时间后自动运行。
      • never: 永不运行 (用于禁用作业)。
    • 示例:

      cleanup_job:
        stage: cleanup
        script: cleanup.sh
        when: always # 无论前面成功失败都运行
      
  9. allow_failure

    • 作用: 允许作业失败而不会导致整个流水线失败。

    • 范围: 作业级别。

    • 类型: booleanobject (用于定义退出码)。

    • 示例:

      optional_test:
        script: optional_test.sh
        allow_failure: true # 即使失败也不影响流水线
      
    • 说明: 失败的作业在 UI 中会显示为警告状态。

  10. needs

    • 作用: 定义作业之间的依赖关系,允许创建有向无环图 (DAG),打破阶段的严格顺序。

    • 范围: 作业级别。

    • 类型: Array<string | object>

    • 示例:

      build_frontend:
        stage: build
        script: build-fe.sh
      
      build_backend:
        stage: build
        script: build-be.sh
      
      test_integration:
        stage: test
        script: run-integration-tests.sh
        needs: ["build_frontend", "build_backend"] # 只有当这两个作业都成功后才运行
      
    • 说明: 使用 needs 的作业会立即开始,无需等待其所在阶段的前一个阶段完成。

  11. dependencies

    • 作用: 指定作业需要从哪些上游作业下载它们的 artifacts

    • 范围: 作业级别。

    • 类型: Array<string>

    • 示例:

      test_job:
        stage: test
        script: run_tests.sh
        dependencies:
          - build_job # 下载 build_job 的产物
      
    • 说明: 如果一个作业依赖于另一个作业的 artifacts,但没有使用 needs,它仍然会等待整个阶段完成。推荐结合 needs 使用。

  12. extends

    • 作用: 允许一个作业继承另一个作业的配置,实现配置的复用和 DRY (Don't Repeat Yourself) 原则。

    • 范围: 作业级别。

    • 类型: stringArray<string>

    • 示例:

      .base_job:
        script: echo "Base script"
        tags:
          - common
      
      my_job:
        extends: .base_job # 继承 .base_job 的配置
        script: echo "My specific script" # 覆盖 base_job 的 script
      ```    *   **说明**: 继承的配置会被当前作业的配置覆盖。
      
  13. interruptible

    • 作用: 如果设置为 true,当有新的流水线启动时,正在运行的旧流水线中的此作业可以被取消。

    • 范围: 顶层 (default) 或作业级别。

    • 类型: boolean

    • 示例:

      build_job:
        script: build.sh
        interruptible: true
      
    • 说明: 有助于节省 Runner 资源,避免不必要的旧流水线运行。

  14. timeout

    • 作用: 设置作业的最大执行时间。如果超过此时间,作业将被取消。

    • 范围: 顶层 (default) 或作业级别。

    • 类型: string (例如 1h 30m, 300s)

    • 示例:

      long_running_job:
        script: long_script.sh
        timeout: 1h
      
    • 说明: 确保作业不会无限期运行。

  15. retry

    • 作用: 定义作业失败时自动重试的次数。

    • 范围: 顶层 (default) 或作业级别。

    • 类型: integer (0-2)

    • 示例:

      flaky_test:
        script: run_flaky_tests.sh
        retry: 2 # 失败时最多重试两次
      
    • 说明: 适用于偶尔因为外部因素(如网络波动)导致失败的作业。

  16. parallel

    • 作用: 允许作业并行运行多次,每次运行使用不同的索引。

    • 范围: 作业级别。

    • 类型: integer (用于简单并行) 或 object (用于 matrix 策略)。

    • 示例:

      # 简单并行
      test_job:
        script: echo "Running test $CI_NODE_INDEX of $CI_NODE_TOTAL"
        parallel: 3
      
      # 矩阵并行
      matrix_test:
        script: echo "Running test on Node $NODE_VERSION and DB $DB_VERSION"
        parallel:
          matrix:
            - NODE_VERSION: ["16", "18"]
              DB_VERSION: ["pg", "mysql"]
      
    • 说明: parallel: matrix 是一个强大的功能,用于测试不同环境组合。

  17. resource_group

    • 作用: 确保在任何给定时间只有一个属于特定资源组的作业正在运行。

    • 范围: 作业级别。

    • 类型: string

    • 示例:

      deploy_prod:
        stage: deploy
        script: deploy_to_prod.sh
        resource_group: production_deploy
      
    • 说明: 防止并发部署导致的问题,特别是在部署到共享资源时。

C. 依赖与产物 (Dependencies & Artifacts)

这些字段用于管理作业之间的数据传递和构建产物的存储。

  1. artifacts

    • 作用: 定义作业完成后要保存的文件或目录,以便在后续作业中使用或供用户下载。

    • 范围: 作业级别。

    • 子字段:

      • paths: 要包含在产物中的文件或目录列表。
      • exclude: 要从产物中排除的文件或目录列表。
      • name: 产物压缩包的名称。
      • untracked: 是否包含 Git 未跟踪的文件。
      • expire_in: 产物在 GitLab 服务器上保留的时间。
      • reports: 生成特定类型的报告(如 junit, coverage_report, sast 等)。
      • public: 是否允许公开访问产物(即使项目是私有的)。
    • 示例:

      build_job:
        stage: build
        script: npm run build
        artifacts:
          paths:
            - build/
            - dist/
          exclude:
            - build/**/*.map
          name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
          expire_in: 1 week
          reports:
            junit: junit-report.xml # 将 junit 报告作为产物
      
    • 说明: 产物是 CI/CD 中传递构建结果的关键机制。

D. 缓存 (Caching)

这些字段用于缓存文件,以加速后续的流水线运行。

  1. cache

    • 作用: 定义要在流水线运行之间缓存的文件或目录。

    • 范围: 顶层 (default) 或作业级别。

    • 子字段:

      • key: 缓存的唯一标识符。如果 key 变化,则会创建新的缓存。
      • paths: 要缓存的文件或目录列表。
      • policy: 缓存的上传/下载策略 (pull-push, pull, push)。
      • when: 何时保存缓存 (on_success, on_failure, always)。
    • 示例:

      default:
        cache:
          key: "$CI_COMMIT_REF_SLUG" # 按分支缓存
          paths:
            - node_modules/
          policy: pull-push # 默认拉取并推送
      
      build_job:
        script: npm install
        cache:
          key: "my-custom-cache-key" # 覆盖默认 key
          paths:
            - .npm/
          policy: push # 只在当前作业结束后推送缓存
      
    • 说明: 缓存可以显著减少重复下载依赖的时间。

E. 变量 (Variables)

除了顶层 variables 之外,还可以定义更具体的变量类型。

  1. variables (作为映射)

    • 作用: 当定义为映射时,可以为变量添加更多元数据。

    • 范围: 顶层或作业级别。

    • 子字段:

      • value: 变量的实际值。
      • description: 变量的描述,在 UI 中可见。
      • options: (用于下拉列表变量) 定义可选值。
    • 示例:

      variables:
        DEPLOY_ENV:
          value: "staging"
          description: "Target deployment environment"
          options:
            - "staging"
            - "production"
      
    • 说明: 提高变量的可管理性和用户友好性。

F. 服务 (Services)

  1. services

    • 作用: 定义要在作业主 Docker 镜像旁边运行的 Docker 镜像。常用于数据库、消息队列等服务。

    • 范围: 顶层 (default) 或作业级别。

    • 类型: Array<string | object>

    • 示例:

      test_db_job:
        image: ruby:latest
        services:
          - name: postgres:13
            alias: db # 可以通过 'db' 主机名访问
          - redis:latest
        script:
          - bundle install
          - bundle exec rake db:create db:migrate
          - bundle exec rake test
      
    • 说明: 服务镜像在作业开始时启动,并在作业结束时停止。它们通过 Docker 网络的别名相互通信。

G. 环境与部署 (Environments & Deployments)

这些字段用于管理部署到不同环境的流水线。

  1. environment

    • 作用: 定义与部署相关的环境信息。

    • 范围: 作业级别。

    • 子字段:

      • name: 环境的名称(例如 staging, production)。
      • url: 部署后环境的 URL,会在 GitLab UI 中显示。
      • on_stop: 当环境停止时要运行的作业名称。
      • action: (在 on_stop 作业中) 指定环境操作 (startstop)。
      • auto_stop_in: 自动停止环境的时间。
      • kubernetes: Kubernetes 集成配置。
      • auto_deploy: 自动部署策略。
    • 示例:

      deploy_staging:
        stage: deploy
        script: deploy_to_staging.sh
        environment:
          name: staging
          url: https://staging.example.com
          on_stop: stop_staging_env
      
      stop_staging_env:
        stage: cleanup
        script: stop_staging.sh
        when: manual
        environment:
          name: staging
          action: stop
      
    • 说明: 环境管理是 GitLab CI/CD 的核心功能之一,提供了部署历史和回滚能力。

H. 报告与质量门 (Reports & Quality Gates)

这些字段用于生成各种报告,帮助评估代码质量和安全性。

  1. coverage

    • 作用: 定义一个正则表达式,用于从作业日志中提取代码覆盖率百分比。

    • 范围: 作业级别。

    • 示例:

      test_job:
        script: npm test -- --coverage
        coverage: '/All files[^|]*|[^|]*\s+([\d.]+)/' # 匹配覆盖率百分比
      
    • 说明: 提取的覆盖率会显示在流水线和合并请求页面。

  2. artifacts: reports (作为 artifacts 的子字段)

    • 作用: 指定要从作业产物中解析并显示在 GitLab UI 中的报告类型。

    • 范围: 作业级别 (artifacts 下)。

    • 子字段:

      • junit: JUnit XML 格式的测试报告。
      • coverage_report: 代码覆盖率报告(例如 Cobertura XML)。
      • sast: 静态应用安全测试报告。
      • dast: 动态应用安全测试报告。
      • dependency_scanning: 依赖项扫描报告。
      • container_scanning: 容器镜像扫描报告。
      • license_scanning: 许可证扫描报告。
      • secret_detection: 秘密检测报告。
      • code_quality: 代码质量报告。
      • browser_performance: 浏览器性能测试报告。
      • load_performance: 负载性能测试报告。
      • metrics: 指标报告。
    • 示例:

      security_scan:
        stage: security
        script: run_sast_scan.sh
        artifacts:
          reports:
            sast: gl-sast-report.json
            dependency_scanning: gl-dependency-scanning-report.json
      
    • 说明: 这些报告是 GitLab 安全和合规性功能的核心,通常与 GitLab 提供的安全模板结合使用。

I. 发布管理 (Release Management)

  1. release

    • 作用: 定义一个 GitLab Release。

    • 范围: 作业级别。

    • 子字段:

      • tag_name: 发布关联的 Git 标签名称。
      • name: 发布的名称。
      • description: 发布的描述。
      • ref: 用于创建标签的 Git 引用。
      • milestones: 关联的里程碑。
      • released_at: 发布日期。
      • assets: 要附加到发布的资产列表(例如二进制文件、文档)。
    • 示例:

      create_release:
        stage: deploy
        image: registry.gitlab.com/gitlab-org/release-cli:latest
        script:
          - echo "Creating release for $CI_COMMIT_TAG"
        rules:
          - if: '$CI_COMMIT_TAG' # 只有打标签时才运行
        release:
          tag_name: '$CI_COMMIT_TAG'
          name: 'Release $CI_COMMIT_TAG'
          description: 'Release created from CI/CD pipeline.'
          assets:
            links:
              - name: 'App Binary'
                url: 'https://example.com/downloads/app.zip'
                filepath: '/downloads/app.zip' # 可选,用于在 UI 中显示
                link_type: 'other'
      
    • 说明: 简化了发布流程,将发布信息和资产直接集成到 GitLab。

J. 其他常用字段 (Other Common Fields)

  1. only / except

    • 作用: (旧版,推荐使用 rules) 定义作业仅在特定分支、标签或 CI/CD 变量条件下运行 (only) 或不运行 (except)。

    • 范围: 作业级别。

    • 类型: Array<string>object (用于更复杂的匹配)。

    • 示例:

      deploy_prod:
        script: deploy.sh
        only:
          - main # 仅在 main 分支上运行
          - tags # 仅在打标签时运行
      
    • 说明: 虽然仍然可用,但 rules 提供了更强大和灵活的条件逻辑。

  2. pages

    • 作用: 一个特殊的作业名称,用于部署 GitLab Pages 网站。

    • 范围: 作业级别。

    • 示例:

      pages:
        stage: deploy
        script:
          - npm run build
          - mv public .public # 确保产物在 public 目录下
        artifacts:
          paths:
            - public
        rules:
          - if: '$CI_COMMIT_BRANCH == "main"'
      
    • 说明: pages 作业必须将网站文件放置在名为 public 的目录中,并将其作为 artifacts 导出。


这个列表涵盖了 GitLab CI/CD 中最核心和常用的字段,它们是构建高效、可靠和安全的 CI/CD 流水线的基础。掌握这些字段的用法,将使你能够充分利用 GitLab 的强大功能。