【CI/CD·入门篇】核心概念全解:构建、测试、集成、交付、部署与回滚
前言上一篇我们了解了 CI/CD 的整体面貌但构建测试部署这些词看似简单实际操作中有很多细节和坑。本篇逐一拆解流水线中的核心概念让你在后续搭建流水线时清楚知道每个阶段在做什么、为什么要做、怎么做。一、构建Build从源码到产物什么是构建构建是将人类可读的源代码转化为机器可执行的产物的过程。不同语言栈的构建方式不同| 语言/框架 | 构建工具 | 产物类型 | 示例命令 ||-----------|---------|---------|---------|| Java | Maven / Gradle | JAR / WAR |mvn clean package|| Go | go build | 二进制文件 |go build -o app .|| Node.js | npm / yarn / pnpm | dist 目录 |npm run build|| Python | pip / poetry | wheel / egg |python setup.py bdist_wheel|| 前端 | webpack / vite | 静态文件 |npm run build|构建阶段的关键实践1. 确定性构建同一个代码版本不管在谁的机器上构建结果应该一致。实现方式# 固定基础镜像版本 FROM node:18.19.0-alpine AS builder WORKDIR /app # 先复制 lock 文件利用 Docker 缓存层 COPY package-lock.json ./ RUN npm ci # ci 模式严格按 lock 文件安装不用 package.json COPY . . RUN npm run build**踩坑提示**用 npm install 而非 npm ci 会导致不同时间构建出不同的依赖版本。CI 环境必须用 npm ci或 yarn install --frozen-lockfile。2. 构建缓存大型项目全量构建可能需要10-20分钟。利用缓存可以大幅提速# GitLab CI 缓存示例 build: cache: key: ${CI_COMMIT_REF_SLUG} paths: - .m2/repository # Maven 本地仓库 - node_modules/ # Node 依赖 script: - mvn clean package -DskipTests3. 构建产物的版本管理每次构建出的产物应该有一个唯一标识通常用 Git commit hash 构建时间VERSION$(git rev-parse --short HEAD)-$(date %Y%m%d%H%M) docker build -t myapp:${VERSION} .二、测试Test流水线的守门员测试金字塔/\ / \ E2E 测试少量 /----\ 速度慢、成本高、维护难 / \ / 集成 \ 集成测试适量 / 测试 \ 验证模块间交互 /------------\ / \ / 单元测试大量\ 速度快、覆盖率高 -------------------- CI 中跑得最多的CI 中的测试策略| 测试类型 | CI 中执行 | 说明 ||---------|----------|------|| 单元测试 | 每次提交 | 必须跑覆盖率应 70% || 集成测试 | 每次提交/每日 | 模块间接口验证 || E2E 测试 | 每日/发版前 | 全链路验证慢但重要 || 性能测试 | 每周/发版前 | 基线性能对比 || 安全测试 | 每次提交 | SAST/DAST 扫描 |测试报告与质量门禁CI 流水线不仅要跑测试还要对结果做决策——这就是质量门禁Quality Gate# GitHub Actions 示例测试覆盖率低于 70% 则失败 - name: Run tests with coverage run: mvn test - name: Check coverage run: | COVERAGE$(grep -oP line-rate\K[0-9.] target/site/jacoco/jacoco.xml) echo Coverage: ${COVERAGE} # 转换为百分比 PERCENT$(awk BEGIN {print ${COVERAGE} * 100}) if [ $(awk BEGIN {print ($PERCENT 70)}) -eq 1 ]; then echo Coverage ${PERCENT}% is below 70% threshold exit 1 fi**培训要点**不要一上来就设90%覆盖率门禁这会逼着团队写无意义的测试来凑数。从50%开始逐步提高每季度提升5-10个百分点。三、集成Integration代码合并的艺术持续集成的核心集成不是把代码打包那么简单它的核心是让多人协作的代码尽早、频繁地合并。常见的分支策略与集成方式1. Git Flow适合发版周期长的项目master ──────────●──────────────●──── (生产) \ / / \ / / develop ──●───●────●───●──●──●──── (开发主干) \ / feature ●───●──●─● (功能分支)2. GitHub Flow适合持续部署的项目master ──●──●──●──●──●──●──●── (直接就是生产) \ │ │ / PR ──●──┘ │ └──● │ PR ──────●3. Trunk-Based Development最适合 CI/CDmain ──●──●──●──●──●──●──●──●──●── (所有人频繁合并到 main) \ / \ /\ / short ●─● ●─● ●─● (短生命周期分支1天)**踩坑提示**功能分支存活时间越长合并冲突越大。Trunk-Based Development 要求分支生命周期不超过24小时这对测试自动化要求很高但收益最大。集成触发机制# GitLab CIPR 合并到主干时触发完整流水线 workflow: rules: - if: $CI_PIPELINE_SOURCE merge_request_event when: always - if: $CI_COMMIT_BRANCH main when: always - when: never # 其他情况不触发四、交付与部署Delivery Deployment从代码到线上持续交付 vs 持续部署持续交付Continuous Delivery: 代码 → CI → 测试通过 → 可发布状态 → [人工点击] → 生产环境 持续部署Continuous Deployment: 代码 → CI → 测试通过 → 自动部署 → 生产环境部署策略| 策略 | 原理 | 适用场景 ||------|------|---------|| 滚动部署Rolling | 逐步替换旧实例 | 无状态服务 || 蓝绿部署Blue-Green | 两套环境切换 | 需要快速回滚 || 金丝雀发布Canary | 少量流量先试新版本 | 风险较高的变更 || 影子部署Shadow | 新版本接收流量但不处理 | 性能验证 |部署配置示例Kubernetes 滚动更新apiVersion: apps/v1 kind: Deployment metadata: name: myapp spec: replicas: 4 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 # 滚动过程中最多多出1个Pod maxUnavailable: 0 # 滚动过程中不允许减少可用Pod template: spec: containers: - name: app image: myapp:v2 readinessProbe: # 就绪探针只有健康检查通过才接收流量 httpGet: path: /health port: 8080 initialDelaySeconds: 10 periodSeconds: 5**踩坑提示**maxUnavailable: 0 readinessProbe 是零停机部署的关键组合。如果缺少就绪探针Kubernetes 会把流量打到还没启动完的 Pod 上导致用户看到 502。五、回滚Rollback出问题后的救命稻草回滚的两种方式1. 重新部署旧版本推荐# 重新部署上一个版本 kubectl rollout undo deployment/myapp # 回滚到指定版本 kubectl rollout undo deployment/myapp --to-revision3 # 查看部署历史 kubectl rollout history deployment/myapp2. 蓝绿切换瞬间回滚# 当前流量在蓝色环境出问题后瞬间切回绿色 kubectl patch service myapp -p {spec:{selector:{version:green}}}数据库变更的回滚难题代码可以一键回滚但数据库变更DDL往往不可逆-- 正向迁移 ALTER TABLE orders ADD COLUMN status VARCHAR(20); -- 回滚迁移需要提前写好 ALTER TABLE orders DROP COLUMN status;**踩坑提示**数据库迁移必须遵循扩展-收缩Expand-Contract模式。先加新列兼容旧代码部署新代码验证无误后再删旧列。千万不要一步到位改表结构。六、本篇要点回顾1.构建要确定性——同一份代码每次构建结果一致2.测试遵循金字塔——大量单元测试 适量集成测试 少量E2E3.集成要频繁——分支生命周期越短越好4.部署要选对策略——无状态用滚动高风险用金丝雀5.回滚要提前准备——尤其是数据库变更用扩展-收缩模式下一篇预告《CI vs CD vs Continuous Deployment三个层次的区别与联系》——我们用三个实际的流水线配置来展示三个层次的具体差异。

相关新闻

告别下载限速:3步解锁九大网盘直链下载权限

告别下载限速:3步解锁九大网盘直链下载权限

告别下载限速:3步解锁九大网盘直链下载权限 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘 / 迅雷…

2026/10/20 10:41:55 阅读更多 →
如何彻底掌控Windows安全防护:Defender Control完整实践指南

如何彻底掌控Windows安全防护:Defender Control完整实践指南

如何彻底掌控Windows安全防护:Defender Control完整实践指南 【免费下载链接】defender-control An open-source windows defender manager. Now you can disable windows defender permanently. 项目地址: https://gitcode.com/gh_mirrors/de/defender-control …

2026/10/15 16:06:04 阅读更多 →
DeepSeek + Codex

DeepSeek + Codex

DeepSeek V4 Flash 昨天发布了、并且原生支持 Responses API&#xff0c;并且对 Codex 完成了适配&#xff0c;这个格式是 oai 的新版通用格式。DeepSeek 官方更是直接提供了一键部署脚本 &#x1f4a1; macOS / Linux 用户在终端中执行&#xff1a; bash <(curl -fsSL http…

2026/10/15 16:29:45 阅读更多 →

最新新闻

AI+Wireshark智能抓包:从过滤表达式到异常定位的排障实战

AI+Wireshark智能抓包:从过滤表达式到异常定位的排障实战

Wireshark 用了快十年&#xff0c;前几年我碰上问题&#xff0c;基本都是靠逮住一个包啃半天来定位。但这段时间我的工作习惯变了&#xff1a;AI 和 Wireshark 抓包放在一起之后&#xff0c;很多过去靠肉眼硬看才能发现的规律&#xff0c;秒级就能出来。这篇文章不是讲怎么装 W…

2026/10/20 16:30:14 阅读更多 →
GPIO驱动能力与输出摆率详解:信号质量、功耗与EMI的平衡秘诀

GPIO驱动能力与输出摆率详解:信号质量、功耗与EMI的平衡秘诀

你打开单片机厂商的图形化配置工具&#xff0c;看到一个引脚的下拉菜单里躺着“驱动能力”和“输出摆率”两个选项&#xff0c;旁边默认写着 Low 或 High。大部分人跟着感觉选了最大档&#xff0c;觉得“越大越稳”。我在项目里吃过亏之后才意识到&#xff0c;这两个参数是 GPI…

2026/10/20 16:30:14 阅读更多 →
基于单片机的智能窗帘控制系统设计与实现:从硬件到调试

基于单片机的智能窗帘控制系统设计与实现:从硬件到调试

先说结论&#xff1a;这类项目真正的难点不在单片机代码&#xff0c;而在机械装配和现场调试。很多人看到"基于单片机的智能窗帘控制系统设计"这个题目&#xff0c;第一反应是"单片机接个电机转起来就完事了"&#xff0c;其实远没有这么简单。我自己做这套…

2026/10/20 16:30:14 阅读更多 →
增量Delaunay三角剖分C++实现:点定位、翻边与避坑指南

增量Delaunay三角剖分C++实现:点定位、翻边与避坑指南

简介&#xff1a;本资源面向计算几何与图形学方向的 C 开发者&#xff0c;提供一套增量 Delaunay 三角剖分算法的完整实现&#xff0c;可用于最大化三角网格中所有三角形的最小内角&#xff0c;改善网格质量。项目采用顾贤峰教授提出的「半边」数据结构组织拓扑关系&#xff0c…

2026/10/20 16:30:14 阅读更多 →
DSP28335 XINTF外扩SRAM完整指南:从时序配置到CMD段分配

DSP28335 XINTF外扩SRAM完整指南:从时序配置到CMD段分配

做DSP开发的人&#xff0c;迟早会撞上内存不够用的墙。28335虽然带浮点单元&#xff0c;可内部那块SARAM总共也就三十几K字&#xff0c;跑个FFT、存一组采集数据、塞个查找表&#xff0c;说满就满。这时候最顺手的解法就是走XINTF外扩SRAM。这个实验在普中DSP28335开发攻略里被…

2026/10/20 16:30:14 阅读更多 →
从Softmax到混淆矩阵:分类模型标签转换与可视化实战

从Softmax到混淆矩阵:分类模型标签转换与可视化实战

分类模型训练完之后&#xff0c;真正让你睡不着的往往不是loss降不降得下去&#xff0c;而是模型在验证集上到底把哪些类别搞混了。而要把这个问题看清楚&#xff0c;就绕不开一个基础动作&#xff1a;把模型最后一层算出来的softmax概率&#xff0c;转成真正能拿来跟标注做对比…

2026/10/20 16:29:13 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →