GitLab教程(6): CI/CD基础与.gitlab-ci.yml入门
GitLab CI/CD是GitLab内置的持续集成和持续部署功能。本文将介绍CI/CD的基本概念和.gitlab-ci.yml配置文件的编写方法。
什么是GitLab CI/CD
# CI/CD流程
代码提交 → 自动构建 → 自动测试 → 自动部署
↓ ↓ ↓ ↓
push compile test deploy
↓ ↓ ↓
artifacts reports environment
# 核心概念
- Pipeline: 流水线,一次完整的CI/CD过程
- Stage: 阶段,流水线中的步骤
- Job: 作业,具体执行的任务
- Runner: 执行器,运行Job的代理
- Artifact: 产物,Job生成的文件
# 触发方式
- Push到分支
- 合并请求
- 定时计划
- API触发
- 手动触发
第一个Pipeline
# 在项目根目录创建 .gitlab-ci.yml
# 最简单的例子
stages:
- build
- test
- deploy
build-job:
stage: build
script:
- echo "Building the application..."
- echo "Build complete!"
test-job:
stage: test
script:
- echo "Running tests..."
- echo "All tests passed!"
deploy-job:
stage: deploy
script:
- echo "Deploying application..."
- echo "Deployment complete!"
# 提交并推送
git add .gitlab-ci.yml
git commit -m "Add CI/CD configuration"
git push origin main
# 查看Pipeline
# Project > CI/CD > Pipelines
# Pipeline输出示例
Pipeline #1 passed
├── build-job ✓ (10s)
│ Running with gitlab-runner 16.8.0
│ $ echo "Building the application..."
│ Building the application...
│ $ echo "Build complete!"
│ Build complete!
│ Job succeeded
├── test-job ✓ (8s)
└── deploy-job ✓ (5s)
.gitlab-ci.yml基本结构
# 完整的配置示例
# 定义阶段(按顺序执行)
stages:
- build
- test
- deploy
# 全局变量
variables:
APP_NAME: "my-app"
NODE_VERSION: "18"
# 全局默认值
default:
image: node:18-alpine
before_script:
- echo "Starting job..."
after_script:
- echo "Job finished."
# 构建作业
build:
stage: build
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 hour
# 测试作业
test:
stage: test
script:
- npm run test
coverage: '/Lines\s*:\s*(\d+\.?\d*)%/'
# 部署作业
deploy:
stage: deploy
script:
- echo "Deploying $APP_NAME"
environment:
name: production
url: https://example.com
only:
- main
Job关键字详解
script - 执行命令
# script是唯一必需的关键字
job-name:
script:
- echo "Single command"
- |
echo "Multi-line"
echo "commands"
if [ -f "file.txt" ]; then
cat file.txt
fi
- npm install
- npm run build
# before_script - script之前执行
build:
before_script:
- npm ci
script:
- npm run build
# after_script - 无论成功失败都执行
test:
script:
- npm run test
after_script:
- echo "Cleanup..."
- rm -rf temp/
image - Docker镜像
# 指定运行环境
# 全局镜像
image: node:18
jobs:
build:
script:
- node --version
# Job级别覆盖
build-java:
image: maven:3.8-openjdk-17
script:
- mvn clean package
build-python:
image: python:3.11
script:
- pip install -r requirements.txt
- python setup.py build
build-go:
image: golang:1.21
script:
- go build ./...
# 使用私有镜像
build:
image:
name: registry.example.com/my-image:latest
entrypoint: [""] # 覆盖默认入口点
script:
- my-command
variables - 变量
# 全局变量
variables:
GLOBAL_VAR: "global value"
DATABASE_URL: "postgres://localhost/mydb"
# Job级别变量
build:
variables:
BUILD_ENV: "production"
script:
- echo $GLOBAL_VAR
- echo $BUILD_ENV
# 预定义变量(自动可用)
job:
script:
- echo $CI_COMMIT_SHA # 提交SHA
- echo $CI_COMMIT_BRANCH # 分支名
- echo $CI_COMMIT_REF_NAME # 引用名
- echo $CI_PIPELINE_ID # Pipeline ID
- echo $CI_JOB_ID # Job ID
- echo $CI_PROJECT_NAME # 项目名
- echo $CI_PROJECT_PATH # 项目路径
- echo $CI_REGISTRY_IMAGE # 镜像仓库地址
- echo $GITLAB_USER_EMAIL # 用户邮箱
# 敏感变量(在Settings > CI/CD > Variables设置)
# 不要在.gitlab-ci.yml中硬编码密码!
deploy:
script:
- echo $DEPLOY_PASSWORD # 从CI/CD变量获取
artifacts - 构建产物
# 保存构建产物供后续Job使用
build:
stage: build
script:
- npm run build
artifacts:
paths:
- dist/
- node_modules/
expire_in: 1 week
name: "build-$CI_COMMIT_SHA"
test:
stage: test
script:
- npm run test
artifacts:
reports:
junit: test-results.xml
coverage_report:
coverage_format: cobertura
path: coverage/cobertura.xml
when: always # 即使失败也保存
# 下载artifacts
# Job页面 > Download按钮
# 或后续Job自动获取
deploy:
stage: deploy
script:
- ls dist/ # 自动从build job获取
- ./deploy.sh
cache - 缓存
# 缓存依赖加速构建
# Node.js项目缓存
build:
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
script:
- npm ci
- npm run build
# 基于文件的缓存key
build:
cache:
key:
files:
- package-lock.json
paths:
- node_modules/
script:
- npm ci
# Maven项目缓存
build-java:
cache:
key: maven-cache
paths:
- .m2/repository/
variables:
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
script:
- mvn clean package
# Python项目缓存
build-python:
cache:
key: pip-cache
paths:
- .cache/pip/
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
script:
- pip install -r requirements.txt
控制Job执行
only/except - 条件执行
# 只在特定分支执行
deploy-prod:
script:
- ./deploy.sh production
only:
- main
- master
# 排除分支
test:
script:
- npm run test
except:
- schedules # 不在定时任务时运行
# 标签触发
release:
script:
- ./release.sh
only:
- tags
# 合并请求触发
review:
script:
- ./deploy-review.sh
only:
- merge_requests
rules - 高级条件(推荐)
# rules比only/except更灵活
deploy-prod:
script:
- ./deploy.sh production
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual # 手动触发
- if: $CI_COMMIT_TAG
when: on_success # 自动执行
test:
script:
- npm run test
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"
- if: $CI_COMMIT_BRANCH == "develop"
# 文件变更触发
frontend-test:
script:
- npm run test:frontend
rules:
- changes:
- src/frontend/**/*
- package.json
backend-test:
script:
- mvn test
rules:
- changes:
- src/main/**/*
- pom.xml
# 组合条件
deploy:
rules:
- if: $CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE == "push"
when: manual
allow_failure: false
when - 执行时机
# when选项
# on_success: 前面的job都成功时执行(默认)
# on_failure: 前面的job失败时执行
# always: 总是执行
# manual: 手动触发
# delayed: 延迟执行
# never: 不执行
deploy-prod:
stage: deploy
script:
- ./deploy.sh
when: manual # 需要手动点击触发
notify-failure:
stage: notify
script:
- ./send-alert.sh
when: on_failure # 只在失败时执行
cleanup:
stage: cleanup
script:
- ./cleanup.sh
when: always # 无论成功失败都执行
delayed-job:
script:
- echo "Delayed execution"
when: delayed
start_in: 30 minutes
验证配置
# 使用CI Lint验证配置
# Project > CI/CD > Editor > Validate
# 或访问
# https://gitlab.example.com/project/-/ci/lint
# 粘贴配置内容,点击"Validate"
# 验证结果示例
Status: syntax is correct
Jobs:
- build
- test
- deploy
# 错误示例
Status: syntax is incorrect
Error: jobs:build:script config should be a string or a nested array of strings
实际项目示例
# Node.js项目完整示例
stages:
- install
- build
- test
- deploy
variables:
NODE_ENV: production
default:
image: node:18-alpine
cache:
key:
files:
- package-lock.json
paths:
- node_modules/
install:
stage: install
script:
- npm ci
artifacts:
paths:
- node_modules/
expire_in: 1 hour
build:
stage: build
script:
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 week
lint:
stage: test
script:
- npm run lint
test:
stage: test
script:
- npm run test:coverage
coverage: '/Statements\s*:\s*(\d+\.?\d*)%/'
artifacts:
reports:
junit: junit.xml
coverage_report:
coverage_format: cobertura
path: coverage/cobertura.xml
deploy-staging:
stage: deploy
script:
- npm run deploy:staging
environment:
name: staging
url: https://staging.example.com
rules:
- if: $CI_COMMIT_BRANCH == "develop"
deploy-production:
stage: deploy
script:
- npm run deploy:production
environment:
name: production
url: https://example.com
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
总结
本文介绍了GitLab CI/CD的基础知识和.gitlab-ci.yml的常用配置。掌握这些概念后,你可以为项目配置自动化的构建、测试和部署流程。
下一篇我们将学习GitLab Runner的安装和配置。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。







