GitLab CI/CD

GitLab 是一个完整的 DevOps 平台,提供代码托管、CI/CD、项目管理等一站式解决方案。与 GitHub 类似,GitLab 提供 Git 仓库管理功能,两者都内置了 CI/CD 功能(GitLab CI/CD 和 GitHub Actions),无需依赖第三方服务(如 Travis CI、CircleCI、Jenkins)。

文档:docs.gitlab.com

GitLab CI/CD 简介

GitLab CI/CD 是 GitLab 内置的持续集成和持续部署工具。通过在项目根目录添加 .gitlab-ci.yml 文件,你就可以定义自动化的构建、测试和部署流程。

核心概念

scss 复制代码
Pipeline (流水线)
  ├── Stage (阶段)
  │     ├── Job (任务)
  │     ├── Job
  │     └── Job
  ├── Stage
  └── Stage

每次 git push 触发一个 Pipeline
Pipeline 包含多个 Stage(如 build, test, deploy)
同一 Stage 内的 Job 并行执行
不同 Stage 按顺序执行

工作流程

markdown 复制代码
┌─────────────┐
│  git push   │
└──────┬──────┘
       ↓
┌─────────────────┐
│ GitLab 检测到   │
│ .gitlab-ci.yml  │
└──────┬──────────┘
       ↓
┌─────────────────┐
│ 创建 Pipeline   │
└──────┬──────────┘
       ↓
┌─────────────────┐
│ GitLab Runner   │ ← 执行 Job 的服务
│ 执行各个 Job    │
└──────┬──────────┘
       ↓
┌─────────────────┐
│ 反馈执行结果    │
└─────────────────┘

.gitlab-ci.yml 配置详解

基础结构

yaml 复制代码
# .gitlab-ci.yml

# 定义 Stage(执行阶段)
stages:
  - build
  - test
  - deploy

# 定义 Job(具体任务)
build-job:
  stage: build
  script:
    - echo "Building the app..."
    - npm install
    - npm run build

test-job:
  stage: test
  script:
    - echo "Running tests..."
    - npm run test

deploy-job:
  stage: deploy
  script:
    - echo "Deploying..."
    - npm run deploy

1. stages(阶段定义)

yaml 复制代码
stages:
  - install      # 安装依赖
  - lint         # 代码检查
  - test         # 测试
  - build        # 构建
  - deploy       # 部署

特点:

  • Stage 按顺序执行
  • 只有前一个 Stage 全部成功,才会执行下一个
  • 同一 Stage 内的 Job 并行执行

2. Job 配置

每个 Job 的基本结构:

yaml 复制代码
job-name:
  stage: build           # 属于哪个 Stage
  image: node:20         # 使用的 Docker 镜像
  before_script:         # 在 script 之前执行
    - npm install
  script:                # 主要执行脚本(必需)
    - npm run build
  after_script:          # 在 script 之后执行(即使失败也会执行)
    - echo "Cleanup..."
  cache:                 # 缓存配置
    paths:
      - node_modules/
  artifacts:             # 保存构建产物
    paths:
      - dist/
  only:                  # 仅在特定分支/标签执行
    - main
  except:                # 排除特定分支
    - develop
  when: manual           # 手动触发
  allow_failure: true    # 允许失败
  needs:                 # 依赖其他 Job
    - install-job
  retry: 2               # 失败重试次数

3. image(Docker 镜像)

指定运行 Job 的容器环境:

yaml 复制代码
# 全局指定
image: node:20

# 单个 Job 指定
build-job:
  image: node:20-alpine
  script:
    - npm run build

# 使用私有镜像
test-job:
  image: registry.example.com/my-image:latest
  script:
    - npm test

常用镜像:

  • node:20 - Node.js
  • python:3.11 - Python
  • golang:1.21 - Go
  • alpine:latest - 轻量级 Linux
  • docker:latest - Docker-in-Docker

4. script(执行脚本)

yaml 复制代码
script:
  # 单行命令
  - npm install

  # 多行脚本
  - |
    if [ "$CI_COMMIT_BRANCH" == "main" ]; then
      echo "Building for production"
      npm run build:prod
    else
      echo "Building for development"
      npm run build:dev
    fi

  # 检查命令执行结果
  - npm test || exit 1

  # 链式命令
  - npm install && npm run build && npm test

5. cache(缓存)

加速构建的关键:

yaml 复制代码
# 全局缓存
cache:
  key: ${CI_COMMIT_REF_SLUG}  # 基于分支名生成缓存 key
  paths:
    - node_modules/
    - .npm/
  policy: pull-push  # pull: 只拉取, push: 只推送, pull-push: 默认

# Job 级别缓存
install-job:
  cache:
    key: npm-$CI_COMMIT_REF_SLUG
    paths:
      - node_modules/

# 多个缓存
test-job:
  cache:
    - key: npm-cache
      paths:
        - node_modules/
    - key: build-cache
      paths:
        - dist/

6. artifacts(构建产物)

保存 Job 生成的文件,供后续 Job 使用或下载:

yaml 复制代码
build-job:
  script:
    - npm run build
  artifacts:
    paths:
      - dist/              # 保存 dist 目录
      - coverage/          # 保存测试覆盖率
    exclude:
      - dist/**/*.map      # 排除 sourcemap
    expire_in: 1 week      # 保存 1 周(默认 30 天)
    when: on_success       # on_success, on_failure, always
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml

7. needs(Job 依赖)

打破 Stage 顺序限制,实现跨 Stage 并行:

yaml 复制代码
stages:
  - build
  - test
  - deploy

# 传统方式:test 必须等 build stage 全部完成
# build-a -> build-b ->  等待  -> test-a -> test-b

# 使用 needs:test-a 只等待 build-a
build-a:
  stage: build
  script:
    - npm run build:a

build-b:
  stage: build
  script:
    - npm run build:b

test-a:
  stage: test
  needs:
    - build-a  # 只依赖 build-a,不等 build-b
  script:
    - npm run test:a

test-b:
  stage: test
  needs:
    - build-b
  script:
    - npm run test:b

8. only/except 和 rules(条件执行)

传统方式:only/except

yaml 复制代码
# 只在特定分支执行
deploy-job:
  only:
    - main
    - /^release-.*$/  # 正则匹配 release-* 分支
  script:
    - npm run deploy

# 排除特定分支
test-job:
  except:
    - develop
  script:
    - npm test

现代方式:rules(更强大)

yaml 复制代码
# 基于分支和变更文件
test-job:
  script:
    - npm test
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
      when: always
    - if: '$CI_COMMIT_BRANCH =~ /^feature-/'
      when: manual
    - changes:
        - "src/**/*.ts"
      when: on_success
    - when: never

# 基于 MR(Merge Request)
mr-pipeline:
  script:
    - npm run lint
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

# 组合条件
deploy-job:
  script:
    - npm run deploy
  rules:
    - if: '$CI_COMMIT_TAG'  # 有 tag
      when: manual
    - if: '$CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE == "push"'
      when: on_success

9. variables(变量)

yaml 复制代码
# 全局变量
variables:
  NODE_ENV: "production"
  API_URL: "https://api.example.com"

# Job 级别变量
build-job:
  variables:
    BUILD_MODE: "release"
  script:
    - echo "Building in $BUILD_MODE mode"
    - echo "API URL: $API_URL"

# 使用 CI 内置变量
deploy-job:
  script:
    - echo "Deploying branch $CI_COMMIT_BRANCH"
    - echo "Commit SHA: $CI_COMMIT_SHA"
    - echo "Pipeline ID: $CI_PIPELINE_ID"

常用内置变量:

  • $CI_COMMIT_BRANCH - 分支名
  • $CI_COMMIT_SHA - Commit SHA
  • $CI_COMMIT_TAG - Tag 名
  • $CI_PROJECT_NAME - 项目名
  • $CI_PIPELINE_ID - Pipeline ID
  • $CI_JOB_NAME - Job 名称
  • $CI_REGISTRY - GitLab 容器镜像仓库地址

10. environment(环境)

定义部署环境,GitLab 会自动追踪部署历史:

yaml 复制代码
deploy-production:
  stage: deploy
  script:
    - npm run deploy
  environment:
    name: production
    url: https://example.com
    on_stop: stop-production  # 指定停止环境的 Job
    auto_stop_in: 1 week      # 自动停止环境

# 动态环境
deploy-review:
  stage: deploy
  script:
    - npm run deploy:review
  environment:
    name: review/$CI_COMMIT_REF_NAME
    url: https://$CI_COMMIT_REF_SLUG.example.com
    on_stop: stop-review
  only:
    - merge_requests

stop-review:
  stage: deploy
  script:
    - npm run cleanup:review
  environment:
    name: review/$CI_COMMIT_REF_NAME
    action: stop
  when: manual

高级功能

1. 多项目 Pipeline

触发其他项目的 Pipeline:

yaml 复制代码
trigger-downstream:
  stage: deploy
  trigger:
    project: group/downstream-project
    branch: main
    strategy: depend  # 等待下游 Pipeline 完成

2. 父子 Pipeline

将复杂 Pipeline 拆分成多个文件:

yaml 复制代码
# .gitlab-ci.yml
trigger-child:
  trigger:
    include: .gitlab-ci-child.yml
    strategy: depend

# .gitlab-ci-child.yml
stages:
  - child-build
  - child-test

child-build:
  stage: child-build
  script:
    - echo "Child pipeline job"

3. include(复用配置)

yaml 复制代码
# 引入本地文件
include:
  - local: .gitlab-ci/build.yml
  - local: .gitlab-ci/deploy.yml

# 引入远程文件
include:
  - remote: 'https://example.com/ci-templates/build.yml'

# 引入项目文件
include:
  - project: 'group/ci-templates'
    ref: main
    file: '/templates/build.yml'

# 引入模板
include:
  - template: Auto-DevOps.gitlab-ci.yml

调试和优化

1. 本地调试 CI

使用 gitlab-runner 在本地运行:

bash 复制代码
# 安装 gitlab-runner
brew install gitlab-runner

# 本地执行 Job
gitlab-runner exec docker build-job --docker-image=node:20

# 调试特定 Job
gitlab-runner exec docker test-job

2. 优化 Pipeline 速度

使用缓存:

yaml 复制代码
cache:
  key: npm-cache
  paths:
    - node_modules/
    - .npm/

并行执行:

yaml 复制代码
test:
  parallel: 4
  script:
    - npm test -- --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL

使用 needs 打破顺序:

yaml 复制代码
build:
  stage: build
  script:
    - npm run build

deploy:
  stage: deploy
  needs:
    - build  # 不等待 build stage 的其他 Job
  script:
    - npm run deploy

减小 Docker 镜像:

yaml 复制代码
# 使用 alpine 版本
image: node:20-alpine

# 或自定义轻量镜像
image: registry.example.com/minimal-node:20

GitLab Runner

GitLab Runner 是执行 CI/CD Job 的服务。

相关推荐
你的人类朋友17 小时前
hotfix分支的使用
git·gitlab·github
颇有几分姿色20 小时前
Git将本地项目推送到GitLab
git·gitlab
DevOps探索之旅21 小时前
国产开源代码管理工具 GitPuk 安装+入门全流程解析
gitlab·tiklab·gitpuk·国产开源代码管理工具·安装与入门教程
半梦半醒*1 天前
gitlab部署
linux·运维·centos·ssh·gitlab·jenkins
dalianwawatou2 天前
GitLab 代码基础操作清单
大数据·elasticsearch·gitlab
爱宇阳5 天前
从零开始部署 GitLab CE 18.4.2:Docker Compose 新手教程
docker·容器·gitlab
Narutolxy5 天前
从混合部署到高可用:在内网环境下搭建 GitLab-Jenkins-OpenResty的完整实战复盘20251014
gitlab·jenkins·openresty
字节逆旅6 天前
Git提交后追加修改操作指南
gitlab
爱宇阳6 天前
GitLab Docker Compose 迁移教程
docker·容器·gitlab