GitLab CI/CD学习教程(第四章gitlab-ci.yml)

GitLab CI/CD学习教程(第四章gitlab-ci.yml)

🚀从零开始,结合具体场景和示例,让你彻底掌握 GitLab CI/CD 的配置!


目录

    • [1 定义](#1 定义)
    • [2 基础语法](#2 基础语法)
    • [3 关键配置项](#3 关键配置项)
    • [4 预定义变量](#4 预定义变量)
    • [5 简单示例](#5 简单示例)
      • [5.1 Vue.js 项目](#5.1 Vue.js 项目)
      • [5.2 Python Django 项目](#5.2 Python Django 项目)
      • [5.3 Qt/C++ 项目(Windows + shell环境)](#5.3 Qt/C++ 项目(Windows + shell环境))

1 定义

⭐ 什么是.gitlab-ci.yml

在上一章节中,我们详细讲述了Pipeline 的定义,本章节将重点讲解如何对Pipeline进行精细化的控制。

.gitlab-ci.yml 文件是 GitLab CI/CD 管道 的配置文件。它以 YAML 格式定义了流水线(Pipeline )的各个阶段(stages )和任务(jobs )。每当你向 GitLab 仓库提交代码时,GitLab 会根据 .gitlab-ci.yml 文件自动执行预定的任务。


2 基础语法

.gitlab-ci.yml 配置文件使用的是 YAML 语法,规则十分简单,是一种简洁的数据序列化语言,主要特点是可读性强 ,并且支持层级结构

  • 🧤 缩进空格(不能用 Tab),通常用 2 个空格缩进。
  • 🎎 键值对 配置项是由键key和值value组成的。例如:stages: [build, test, deploy]
  • 📊 列表- 表示列表项
  • ⚙ 多行脚本|>(保留换行/折叠换行)
  • 💬 注释# 开头的行表示注释,GitLab CI/CD 会忽略这些行。

3 关键配置项

项目 类型 作用 示例
workflow Object 用于控制整个 CI/CD 流水线的行为。 (定义全局规则,比如是否启用流水线、如何调度流水线的执行等) (通常与rules结合使用) workflow: rules : - if: '$CI_COMMIT_TAG #仅当打标签时触发整个流水线
variables 键值对 key-value 定义了在 CI/CD 流水线中使用的环境变量。 variables: version: 1.0.0.0 description: xxx
stages Array 定义了流水线的所有阶段,并指定这些阶段的执行顺序 stages: - build - test - deploy
jobs Object 具体执行的任务,每个任务定义了一个独立的操作。 任务通常包括以下配置项: * stage * script job1: stage: build script: - echo "Running job1"
stage String 指定任务属于哪个阶段。 (必须在 stages 中定义) job1: stage: build # 该作业属于build阶段
script Array 或 String 定义任务执行的实际命令。 (比如打印一句话) script: - echo "Running tests..."
before_script Array 或 String 定义在每个任务之前执行的脚本。 (常用于设置公共的执行步骤,安装依赖等) before_script: - scriptPath = " env:CI_PROJECT_DIR\test.py" if (-not (Test-Path scriptPath)) { Write-Error "错误:Python脚本不存在于 scriptPath" exit 1 } python $scriptPath
after_script Array 或 String 定义在每个任务之后执行的脚本。 (常用于清理操作、记录日志等) after_script: - echo "运行结束"
artifacts Object 用于指定在job 执行完成后需要保存的文件或目录。 (这些文件将在后续作业或流水线运行中可用。) artifacts: paths: - build/ expire_in: 30 minute # 30分钟后过期
timeout String 设置作业的超时时间。 (超出这个时间作业会被强制终止。) job1: timeout: 60 minutes
interruptible Boolean 是否允许中断当前作业。 (通常用于节省资源。) job1: interruptible: true
allow_failure Boolean 是否允许任务失败。 (如果设置为 true,即使任务失败,流水线会继续执行) job1: interruptible: true
needs Array 每个阶段内的作业默认是并行执行的,除非使用 needs 显式声明依赖关系。 job1: script: - eho "Running job1" job2: script: - eho "Running job2" needs: job1
only except Array only 定义job 应该在哪些分支或事件下执行 except 定义job 不应该在哪些情况下执行 (控制任务的触发条件) job1: only: - main # main分支才会触发
when Object 定义作业的执行时机。 常用的值包括: * on_success(成功时) * on_failure(失败时) * manual(手动触发) job1: when: manual
rules Array 或 Object 替代 onlyexcept 的更灵活的条件控制方法。 常用选项: * if: 用于表达条件判断 * when: 定义条件成立时作业的执行时机 * start_in:设置作业的启动延迟时间 rules: - if : ' CI_COMMIT_BRANCH'==main **when** : manual **- if**: 'CI_COMMIT_TAG'
image String 用于指定一个 Docker 镜像,镜像将在执行作业时被拉取和使用。 image: node:14
services Array 用于定义与作业一起运行的其他 Docker 容器(服务)。 (这些服务通常是数据库、缓存或其他依赖服务。) services: - mysql:5.7

这里需要对onlywhen 区别作一个详细的解释。(PS: 建议使用rules,它更强大和灵活)

  • 意图:only 更侧重于指定作业应该在哪种类型的变更(如特定分支或标签)上运行;而 when 则关注于作业在整个管道流程中的执行策略。
  • 灵活性:虽然两者都能影响作业是否执行,但是 when 提供了关于作业执行时机的更多选项,并且可以结合其他条件(例如通过 rules)来实现更为复杂的逻辑。

4 预定义变量

📙 官方文档

预定义变量在流水线执行的三个不同阶段可用:

  • 预流水线:预流水线变量在创建流水线之前可用。这些变量是仅使用 include:rules 来控制在创建流水线时要使用哪些配置文件。
  • 流水线:这些变量在流水线创建时可用。除了预流水线变量外,流水线- 变量还可以用于配置在作业中定义的 rules ,以确定要添加到流水线中的哪些作业。
  • 仅作业:这些变量仅在 runner 选择作业并运行作业时为每个作业可用。

常用的预定义变量: (更多其他变量请查阅官方文档)

🎎 变量 🎨 描述
CI_COMMIT_AUTHOR Name 格式的提交作者。
CI_COMMIT_BEFORE_SHA 出现在分支或标签上的上一个最新提交。在合并请求的流水线中总是 0000000000000000000000000000000000000000。
CI_COMMIT_BRANCH 提交分支名称。在分支流水线中可用,包括默认分支的流水线。在合并请求流水线或标签流水线中不可用。
CI_COMMIT_DESCRIPTION 提交的描述。如果标题短于 100 个字符,则消息没有第一行。
CI_COMMIT_MESSAGE 完整的提交消息。
CI_COMMIT_REF_NAME 为其构建项目的分支或标签名称。
CI_COMMIT_SHORT_SHA CI_COMMIT_SHA 的前八个字符。
CI_COMMIT_TAG 提交标签名称。仅在标签流水线中可用。
CI_COMMIT_TAG_MESSAGE 提交标签消息。仅在标签流水线中可用。
CI_COMMIT_TIMESTAMP ISO 8601 格式的提交时间戳。
CI_COMMIT_TITLE 提交的标题。消息的完整第一行。
CI_CONFIG_PATH CI/CD 配置文件的路径。默认为.gitlab-ci.yml。在正在运行的流水线中只读。
CI_RELEASE_DESCRIPTION 发布的描述。仅在标签流水线上可用。描述长度限制为前 1024 个字符。
CI_JOB_IMAGE 运行作业的 Docker 镜像的名称。
CI_JOB_NAME 作业名称
CI_JOB_STAGE 作业阶段名称。
CI_JOB_STATUS 执行每个 runner 阶段时的作业状态。与 after_script 一起使用。可以是 success、failed 或 canceled。
CI_PIPELINE_SOURCE 流水线是如何触发的。可以是 push、web、schedule、api、external、chat、webide、merge_request_event、external_pull_request_event、parent_pipeline、trigger 或 pipeline 。
CI_PIPELINE_NAME workflow:name 中定义的名称。
CI_PROJECT_ID 当前项目的 ID。该 ID 在实例上的所有项目中都是唯一的。
CI_PROJECT_NAME 项目目录的名称。例如,如果项目 URL 是 gitlab.example.com/group-name/project-1,则 CI_PROJECT_NAME 是 project-1。
CI_PROJECT_NAMESPACE 作业的项目命名空间(用户名或群组名)。
CI_PROJECT_NAMESPACE_ID 作业的项目命名空间 ID。
CI_PROJECT_PATH 包含项目名称的项目命名空间。
CI_PROJECT_ROOT_NAMESPACE 作业的根项目命名空间(用户名或群组名)。例如,如果 CI_PROJECT_NAMESPACE 是 root-group/child-group/grandchild-group,则 CI_PROJECT_ROOT_NAMESPACE 是 root-group。
CI_PROJECT_TITLE Web 界面中显示的人类可读的项目名称。
CI_PROJECT_DESCRIPTION Web 界面中显示的项目描述。
CI_PROJECT_URL 项目的 HTTP(S) 地址。
CI_PROJECT_VISIBILITY 项目可见性。可以是 internal、private 或 public。
CI_REPOSITORY_URL 克隆 Git 仓库的 URL。
GITLAB_USER_EMAIL 启动流水线的用户的电子邮件,除非作业是手动作业。在手动作业中,该值是启动作业的用户的电子邮件。
GITLAB_USER_ID 启动流水线的用户的 ID,除非作业是手动作业。在手动作业中,该值是启动作业的用户的 ID。
GITLAB_USER_LOGIN 启动流水线的用户的用户名,除非作业是手动作业。在手动作业中,该值是启动作业的用户的用户名。
GITLAB_USER_NAME 启动流水线的用户的姓名,除非作业是手动作业。在手动作业中,该值是启动作业的用户的姓名。

5 简单示例

5.1 Vue.js 项目

yaml 复制代码
image: node:18

stages:
  - install
  - build
  - deploy

cache:
  key: $CI_COMMIT_REF_SLUG
  paths:
    - node_modules/

install-deps:
  stage: install
  script:
    - npm ci
  only:
    - main

build-prod:
  stage: build
  script:
    - npm run build
  artifacts:
    paths:
      - dist/

deploy-s3:
  stage: deploy
  image: amazon/aws-cli:latest
  script:
    - aws s3 sync dist/ s3://my-bucket/ --delete
  only:
    - main

5.2 Python Django 项目

yaml 复制代码
image: python:3.10

stages:
  - test

services:
  - postgres:13

variables:
  POSTGRES_DB: mydb
  POSTGRES_USER: runner
  POSTGRES_PASSWORD: ""
  DATABASE_URL: "postgres://runner:@postgres:5432/mydb"

test:
  stage: test
  before_script:
    - pip install -r requirements.txt
    - python manage.py migrate
  script:
    - pytest --cov=.
  coverage: '/^TOTAL.+?(\d+\%)$/'

5.3 Qt/C++ 项目(Windows + shell环境)

yaml 复制代码
# 包含共享配置
include:
  - local: '/.ci-templates/variables.yml'  # 共享变量定义

# 定义工作流规则
workflow:
  rules:
    - if: '$CI_COMMIT_TAG'                 # 标签提交触发完整流水线
      variables:
        DEPLOY_ENV: "production"
    - if: '$CI_COMMIT_BRANCH == "main"'    # main分支触发构建、测试、打包
      variables:
        DEPLOY_ENV: "staging"
    - when: manual                         # 允许手动触发

# 全局配置
variables:
  QT_ROOT: "C:\\Qt"
  QIFW_BIN: "C:\\Qt\\Tools\\QtInstallerFramework\\4.6\\bin"
  BUILD_SCRIPT: "scripts/build.py"
  PACKAGE_SCRIPT: "scripts/package.py"
  RELEASE_SCRIPT: "scripts/release.py"

# 阶段定义
stages:
  - prepare
  - build
  - test
  - package
  - release

# 公共before_script
before_script:
  - echo "Running on $CI_RUNNER_DESCRIPTION"
  - python --version
  - pip install -r requirements-ci.txt
  - export ARTIFACTS_DIR="$CI_PROJECT_DIR/artifacts"
  - mkdir -p $ARTIFACTS_DIR

# 公共after_script
after_script:
  - echo "Cleaning temporary files..."
  - rm -rf tmp_build

# 准备阶段
prepare-env:
  stage: prepare
  rules:
    - if: '$DEPLOY_ENV == "production" || $DEPLOY_ENV == "staging"'
  script:
    - python $BUILD_SCRIPT prepare
      --qt-version 5.15.2
      --platform win64
      --output-dir $ARTIFACTS_DIR
  artifacts:
    paths:
      - $ARTIFACTS_DIR/qt_env.bat
    expire_in: 1h

# 并行构建任务
build-windows:
  stage: build
  needs: ["prepare-env"]  # 显式声明依赖
  parallel: 2  # 并行构建两个配置
  rules:
    - if: '$DEPLOY_ENV == "production"'
      variables:
        BUILD_TYPE: "release"
    - if: '$DEPLOY_ENV == "staging"'
      variables:
        BUILD_TYPE: "debug"
  script:
    - call $ARTIFACTS_DIR/qt_env.bat
    - python $BUILD_SCRIPT compile
      --type $BUILD_TYPE
      --jobs 4
      --output $ARTIFACTS_DIR/$BUILD_TYPE
  artifacts:
    paths:
      - $ARTIFACTS_DIR/$BUILD_TYPE/**
    reports:
      dotenv: $ARTIFACTS_DIR/build_info.env

# 测试阶段
run-tests:
  stage: test
  needs:
    - job: build-windows
      artifacts: true
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
  script:
    - python -m pytest tests/ -v --junitxml=test-results.xml
    - python $BUILD_SCRIPT analyze-coverage
      --input build/coverage
      --output $ARTIFACTS_DIR/coverage_report.html
  artifacts:
    paths:
      - test-results.xml
      - $ARTIFACTS_DIR/coverage_report.html
    reports:
      junit: test-results.xml

# 打包阶段
create-installer:
  stage: package
  needs:
    - build-windows
    - run-tests
  rules:
    - if: '$DEPLOY_ENV == "production"'
  script:
    - python $PACKAGE_SCRIPT
      --config installer/windows/config.xml
      --source $ARTIFACTS_DIR/release
      --output $ARTIFACTS_DIR/installer
      --tool-path $QIFW_BIN
  artifacts:
    paths:
      - $ARTIFACTS_DIR/installer/*.exe
    expire_in: 1 week

# 发布阶段
deploy-release:
  stage: release
  needs: ["create-installer"]
  rules:
    - if: '$CI_COMMIT_TAG != null'
  script:
    - python $RELEASE_SCRIPT
      --tag $CI_COMMIT_TAG
      --artifact $ARTIFACTS_DIR/installer/*.exe
      --changelog changelog.md
  environment:
    name: production
    url: https://downloads.example.com

# 安全扫描(动态包含)
include:
  - template: Security/SAST.gitlab-ci.yml

上一篇:《GitLab CI/CD学习教程 第三章Pipeline》

下一篇:《GitLab CI/CD学习教程 第五章高级示例》正在编写中...

相关推荐
西岸行者6 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意7 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码7 天前
嵌入式学习路线
学习
毛小茛7 天前
计算机系统概论——校验码
学习
babe小鑫7 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms7 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下7 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。7 天前
2026.2.25监控学习
学习
im_AMBER7 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J7 天前
从“Hello World“ 开始 C++
c语言·c++·学习