GitLab CI/CD 指南
本文档结合 calculator 项目,介绍 GitLab CI/CD 的核心概念、配置方法和工具链集成。
项目地址:
http://192.168.1.130:8090/lizhihua/calculator
概念关系图
GitLab CI/CD 的核心元素及其关系如下:
┌──────────────────────────────────────────────────────────────────────┐
│ GitLab CI/CD 概念关系图 │
│ │
│ ┌─────────────┐ push ┌──────────────┐ 调度 ┌────────┐ │
│ │ Git 仓库 │ ──────────► │ .gitlab-ci │ ────────► │Pipeline│ │
│ │ (calculator) │ │ .yml │ │(流水线) │ │
│ └─────────────┘ └──────────────┘ └───┬────┘ │
│ │ │
│ 拆分为多个 Job │ │
│ ┌────────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Pipeline (流水线) │ │
│ │ │ │
│ │ Stage 1 Stage 2 Stage 3 Stage 4 │ │
│ │ ┌─────┐ ┌─────┐ ┌──────┐ ┌──────┐ ┌──────┐ │ │
│ │ │test │ │ lint│ │ sec │ ────► │review│ ──► │deploy│ │ │
│ │ │ Job │ │ Job │ │ Job │ │ Job │ │ Job │ │ │
│ │ └──┬──┘ └──┬──┘ └──┬───┘ └──────┘ └──────┘ │ │
│ │ │ │ │ │ │
│ │ ▼ ▼ ▼ │ │
│ │ ┌─────────────────────────┐ │ │
│ │ │ Runner (执行器) │ │ │
│ │ │ Docker / Shell / K8s │ │ │
│ │ └─────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────┐ 产出 ┌───────────┐ 产出 ┌──────────────┐ │
│ │ Job 执行 │ ──────► │ Artifacts │ ──────► │ Reports / │ │
│ │ │ │ (产物) │ │ 部署包 │ │
│ └──────────┘ └───────────┘ └──────────────┘ │
└──────────────────────────────────────────────────────────────────────┘
说明:
| 元素 | 用途 |
|---|---|
| Git 仓库 | 存储项目源码和 .gitlab-ci.yml 配置文件,代码提交自动触发流水线 |
.gitlab-ci.yml |
CI/CD 的核心配置文件,定义阶段(stages)、任务(jobs)、变量、缓存等 |
| Pipeline(流水线) | 每次代码提交创建的完整 CI/CD 流程,包含多个阶段 |
| Stage(阶段) | 流水线中的一个步骤,如 test、build、deploy。同阶段内的 Job 可并行执行 |
| Job(任务) | 阶段中的具体执行单元,每个 Job 在独立的 Docker 容器中运行 |
| Runner(执行器) | 负责执行 Job 的进程,本项目使用 Docker executor,为每个 Job 创建容器 |
| Artifacts(产物) | Job 执行后生成的文件(测试报告、覆盖率、部署包),可在阶段间传递 |
| Cache(缓存) | 持久化依赖包(如 pip 缓存),加速后续 Job 的依赖安装 |
操作指南与配置说明
Git 仓库配置
1. 克隆仓库
bash
git clone http://192.168.1.130:8090/lizhihua/calculator.git
cd calculator
2. 项目结构
calculator/
├── .gitlab-ci.yml # CI/CD 配置文件(核心)
├── calculator.py # 主程序 - 命令行计算器
├── test_calculator.py # 单元测试
├── ci/
│ ├── claude_review.py # AI 代码审查脚本
│ └── auto_merge.py # 自动合并脚本
├── deploy/
│ ├── docker-compose.yml # GitLab + Runner 部署编排
│ ├── setup.sh # 一键部署脚本
│ └── fix-cicd-500.sh # CI/CD 500 错误修复脚本
├── CI-CD.md # CI/CD 配置说明
├── CI-EXECUTION-FLOW.md # 执行流程详解
├── TROUBLESHOOTING.md # 故障排查手册
├── OPTIMIZATION-PLAN.md # 优化计划
├── CHANGELOG.md # 变更日志
└── README.md # 项目说明
3. 分支策略
| 分支 | 触发行为 |
|---|---|
main(默认分支) |
完整流水线:测试 → 检查 → 审查 → 部署 → 合并 |
| 功能分支 | 测试 → 检查 → 审查(无部署),通过 MR 合并到 main |
CI/CD 工作流配置
完整配置文件(.gitlab-ci.yml)
yaml
image: python:3.11-slim
stages:
- test
- code-quality
- security
- review
- deploy
- merge
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
PIP_INDEX_URL: "https://pypi.tuna.tsinghua.edu.cn/simple"
PIP_TRUSTED_HOST: "pypi.tuna.tsinghua.edu.cn"
cache:
key: "${CI_COMMIT_REF_SLUG}"
paths:
- .cache/pip
before_script:
- python --version
- pip --version
- pip install pytest pytest-cov -q
# ======================== 测试阶段 ========================
run_tests:
stage: test
needs: []
script:
- pytest test_calculator.py -v --junitxml=report.xml --cov=calculator --cov-report=term-missing --cov-report=xml:coverage.xml
artifacts:
when: always
reports:
junit: report.xml
coverage_report:
coverage_format: cobertura
path: coverage.xml
expire_in: 1 week
coverage: '/TOTAL.*\s+(\d+%)/'
# ======================== 代码质量 ========================
code_quality:
stage: code-quality
needs: []
script:
- pip install pylint -q
- pylint calculator.py --output-format=text --exit-zero
allow_failure: true
# ======================== 安全扫描 ========================
security_scan:
stage: security
needs: []
script:
- pip install bandit -q
- bandit -r calculator.py -f txt || true
allow_failure: true
# ======================== Claude 代码审查 ========================
claude_review:
stage: review
before_script: []
script:
- python ci/claude_review.py
artifacts:
when: always
paths: []
expire_in: 1 week
allow_failure: true
rules:
- if: $ANTHROPIC_API_KEY
- if: $ANTHROPIC_API_KEY == null
when: never
# ======================== 部署阶段 ========================
deploy:
stage: deploy
image: python:3.11-slim
before_script: []
script:
- echo "Deploy started"
- echo "Packaging application..."
- echo "Deploy done"
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
# ======================== 自动合并 ========================
auto_merge:
stage: merge
before_script: []
script:
- python ci/auto_merge.py
rules:
- if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $GITLAB_TOKEN
allow_failure: true
说明:
image: python:3.11-slim--- 全局默认镜像,所有 Job 使用 Python 3.11 精简版容器运行needs: []--- test、code-quality、security 三个 Job 并行执行(不等待同阶段其他 Job),显著缩短流水线耗时allow_failure: true--- code-quality、security、review 失败不阻塞流水线,仅作为参考rules--- 控制 Job 的执行条件:deploy 仅在主分支执行,auto_merge 仅在非主分支且有 MR 时执行cache--- 按分支缓存 pip 依赖,命中缓存时pip install从 ~30s 降到 ~5sartifacts--- 测试报告和覆盖率报告保留 1 周,可在 MR 中直接查看
工具配置 - Python
代码检查工具配置
支持的工具列表
| 工具 | 用途 | 安装方式 | 对应 Job |
|---|---|---|---|
| pylint | 代码规范、潜在错误、复杂度检查 | pip install pylint |
code_quality |
| bandit | Python 安全漏洞检测(硬编码密码、注入风险等) | pip install bandit |
security_scan |
| Claude AI | AI 驱动的代码审查(逻辑错误、安全、最佳实践) | 调用 API | claude_review |
代码检查工具配置示例
Pylint(代码质量检查)
yaml
code_quality:
stage: code-quality
needs: []
script:
- pip install pylint -q
- pylint calculator.py --output-format=text --exit-zero
allow_failure: true
--output-format=text--- 输出文本格式报告,便于在 CI 日志中查看--exit-zero--- 即使发现问题也以退出码 0 结束,不阻塞流水线allow_failure: true--- 标记为非阻塞 Job,检查失败不影响后续阶段
Bandit(安全扫描)
yaml
security_scan:
stage: security
needs: []
script:
- pip install bandit -q
- bandit -r calculator.py -f txt || true
allow_failure: true
-r--- 递归扫描目录-f txt--- 输出文本格式报告|| true--- 确保即使发现安全问题也不中断流水线
Claude AI(AI 代码审查)
yaml
claude_review:
stage: review
before_script: []
script:
- python ci/claude_review.py
artifacts:
when: always
paths: []
expire_in: 1 week
allow_failure: true
rules:
- if: $ANTHROPIC_API_KEY
- if: $ANTHROPIC_API_KEY == null
when: never
before_script: []--- 覆盖全局before_script,不需要安装 pytestrules--- 仅当ANTHROPIC_API_KEY变量存在时才执行审查- 审查结果发布为 GitLab commit comment 和 MR comment
- 支持 Anthropic 原生 API 和 OpenAI 兼容格式(OpenRouter 等代理)
- 脚本位置:
ci/claude_review.py
说明:
AI 代码审查的工作流程:
- 通过 GitLab API 获取当前 commit 的 diff
- 将 diff 发送给 AI 模型进行审查
- AI 返回 APPROVE 或 REQUEST_CHANGES 结论
- 审查结果发布到 commit comment 和 MR comment
- auto_merge 会检查 review 结果,REQUEST_CHANGES 时跳过合并
构建工具配置
本项目为纯 Python 项目,无需传统编译构建。构建阶段(deploy)执行应用打包:
yaml
deploy:
stage: deploy
image: python:3.11-slim
before_script: []
script:
- echo "Deploy started"
- echo "Packaging application..."
- echo "Deploy done"
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
说明:
- 当前 deploy 为占位实现,后续可扩展为 SSH 部署、Docker 部署或 K8s 部署
- 仅在主分支(
$CI_DEFAULT_BRANCH)执行,功能分支不触发部署 - 可扩展方案:
| 部署方式 | 适用场景 | 实现思路 |
|---|---|---|
| SSH 部署 | 单机服务器 | ssh + rsync + systemctl restart |
| Docker 部署 | 容器化环境 | docker build + push + pull + run |
| K8s 部署 | 集群环境 | kubectl apply / helm upgrade |
单元测试工具配置
使用 pytest 作为测试框架,配合 pytest-cov 生成覆盖率报告:
yaml
run_tests:
stage: test
needs: []
script:
- pytest test_calculator.py -v --junitxml=report.xml --cov=calculator --cov-report=term-missing --cov-report=xml:coverage.xml
artifacts:
when: always
reports:
junit: report.xml
coverage_report:
coverage_format: cobertura
path: coverage.xml
expire_in: 1 week
coverage: '/TOTAL.*\s+(\d+%)/'
-v--- 详细输出模式,显示每个测试用例的结果--junitxml=report.xml--- 生成 JUnit XML 格式报告,GitLab MR 中可直接查看测试结果--cov=calculator--- 统计calculator.py的代码覆盖率--cov-report=term-missing--- 在终端显示未覆盖的行号--cov-report=xml:coverage.xml--- 生成 Cobertura XML 格式覆盖率报告coverage: '/TOTAL.*\s+(\d+%)/'--- 从输出中提取覆盖率百分比,显示在 MR 中
本地运行测试
bash
# 运行测试并显示覆盖率
pytest test_calculator.py -v --cov=calculator --cov-report=term-missing
# 仅运行测试
pytest test_calculator.py -v
系统测试工具配置
当前项目为命令行工具,系统测试通过单元测试覆盖。如需扩展到交互式系统测试,可考虑:
| 工具 | 用途 | 安装方式 |
|---|---|---|
| pytest-subtests | 参数化子测试 | pip install pytest-subtests |
| pytest-timeout | 测试超时控制 | pip install pytest-timeout |
| expect/pexpect | 交互式命令行测试 | pip install pexpect |
工具配置 - 通用
以下为跨语言通用的 CI/CD 工具配置,可根据项目需要选择性启用。
代码检查工具配置
支持的工具列表
| 工具 | 语言 | 用途 | 安装方式 |
|---|---|---|---|
| pylint | Python | 代码规范、潜在错误 | pip install pylint |
| flake8 | Python | PEP8 风格检查 | pip install flake8 |
| mypy | Python | 静态类型检查 | pip install mypy |
| bandit | Python | 安全漏洞检测 | pip install bandit |
| shellcheck | Shell | Shell 脚本检查 | apt install shellcheck |
| hadolint | Dockerfile | Dockerfile 最佳实践 | Docker 镜像 |
代码检查工具配置示例
多工具组合检查
yaml
lint:
stage: code-quality
needs: []
script:
- pip install pylint flake8 mypy -q
- pylint calculator.py --output-format=text --exit-zero
- flake8 calculator.py --max-line-length=120 || true
- mypy calculator.py --ignore-missing-imports || true
allow_failure: true
Shell 脚本检查(适用于 deploy/ 目录)
yaml
shellcheck:
stage: code-quality
needs: []
image: koalaman/shellcheck-alpine:latest
before_script: []
script:
- shellcheck deploy/setup.sh deploy/fix-cicd-500.sh || true
allow_failure: true
构建工具配置
根据项目类型选择构建工具:
| 项目类型 | 构建工具 | 安装方式 |
|---|---|---|
| Python | setuptools / poetry / pip | pip install build |
| Node.js | npm / yarn / pnpm | 自带 |
| Java | Maven / Gradle | 镜像自带 |
| Go | go build | 镜像自带 |
| C/C++ | gcc / cmake / make | apt install build-essential cmake |
单元测试工具配置
| 语言 | 测试框架 | 覆盖率工具 | JUnit 报告 |
|---|---|---|---|
| Python | pytest | pytest-cov | --junitxml=report.xml |
| Node.js | jest / mocha | jest --coverage | --reporters=jest-junit |
| Java | JUnit | JaCoCo | 原生支持 |
| Go | testing | go test -cover | go-junit-report |
| C/C++ | Google Test | gcov / lcov | --gtest_output=xml |
系统测试工具配置
| 工具 | 用途 | 适用场景 |
|---|---|---|
| Selenium | 浏览器自动化测试 | Web 应用 UI 测试 |
| Cypress | E2E 测试 | 前端应用 |
| Postman/Newman | API 测试 | REST API 项目 |
| k6 | 性能/负载测试 | API 服务 |
| pexpect | 交互式命令行测试 | CLI 工具(如本项目) |
CI/CD 变量配置
在 GitLab 项目的 Settings > CI/CD > Variables 中配置以下变量:
| 变量名 | 类型 | 说明 |
|---|---|---|
ANTHROPIC_API_KEY |
Masked, Protected | AI 代码审查 API Key(DashScope / Anthropic) |
CLAUDE_API_URL |
- | AI API 端点 URL(默认 Anthropic 原生 API) |
CLAUDE_MODEL |
- | AI 模型名称(如 claude-sonnet-4-20250514) |
GITLAB_TOKEN |
Masked, Protected | GitLab API Token(用于自动合并 MR) |
PIP_INDEX_URL |
- | PyPI 镜像源(加速依赖安装,已配置清华源) |
PIP_TRUSTED_HOST |
- | PyPI 信任域名 |
部署 GitLab + Runner
一键部署
项目提供一键部署脚本,在目标服务器上执行即可搭建完整的 GitLab + Runner 环境:
bash
cd deploy
chmod +x setup.sh
sudo ./setup.sh
部署脚本会自动完成以下操作:
- 检查 Docker 和 Docker Compose 是否已安装
- 配置 Docker 镜像加速(国内环境)
- 启动 GitLab CE 容器
- 等待 GitLab 就绪(首次启动约 5-10 分钟)
- 获取管理员初始密码
- 注册 GitLab Runner(Docker executor)
Docker Compose 配置
deploy/docker-compose.yml 定义了两个服务:
| 服务 | 镜像 | 端口 | 说明 |
|---|---|---|---|
| gitlab | gitlab/gitlab-ce:latest |
8090 (HTTP), 8443 (HTTPS), 2222 (SSH) | GitLab 主服务 |
| gitlab-runner | gitlab/gitlab-runner:latest |
- | CI/CD 执行器 |
资源需求
| 资源 | 最低 | 推荐 |
|---|---|---|
| 内存 | 4 GB | 6 GB |
| CPU | 2 核 | 4 核 |
| 磁盘 | 20 GB | 40 GB |
本地测试
在提交代码前,可以在本地运行各项检查:
bash
# 运行测试
pytest test_calculator.py -v --cov=calculator
# 代码质量检查
pip install pylint && pylint calculator.py
# 安全扫描
pip install bandit && bandit -r calculator.py
常见问题
Q: 如何跳过 CI?
提交信息中添加 [skip ci] 即可。
Q: 流水线卡在 pending?
检查 Runner 是否在线:
bash
# 检查 Runner 容器
docker ps | grep runner
# 查看 Runner 状态
docker exec gitlab-runner gitlab-runner list
# 查看 Runner 日志
docker logs --tail 20 gitlab-runner
Q: 镜像拉取失败?
在服务器 Docker 配置中添加镜像加速,参见 deploy/setup.sh 中的 setup_docker_mirror 函数。
Q: 并发数设多少合适?
取决于 Docker Desktop 分配的资源:
| 内存 | 推荐并发数 |
|---|---|
| 4 GB | 1-2 |
| 6 GB | 2-3 |
| 8 GB | 3-4 |
当前配置 concurrent = 3。
Q: 更多问题?
详见 故障排查手册,涵盖:
- CI/CD 设置页 500 错误
- CI Job Token / JWT Signing Key 配置
- Runner 注册与丢失
- Artifact 上传失败
- 加密字段损坏修复
- Docker Desktop 异常
配置文件索引
| 文件 | 说明 |
|---|---|
| <.gitlab-ci.yml> | CI/CD 流水线配置(核心) |
| <deploy/docker-compose.yml> | GitLab + Runner 容器编排 |
| <deploy/setup.sh> | 一键部署脚本 |
| <deploy/fix-cicd-500.sh> | CI/CD 500 错误修复脚本 |
| <ci/claude_review.py> | AI 代码审查脚本 |
| <ci/auto_merge.py> | 自动合并脚本 |
| <CI-CD.md> | CI/CD 配置说明 |
| <CI-EXECUTION-FLOW.md> | 流水线执行流程详解 |
| <TROUBLESHOOTING.md> | 故障排查手册 |
| <OPTIMIZATION-PLAN.md> | 优化计划 |