Day943.持续集成流水线 -系统重构实战
持续集成流水线
Hi,我是阿昌,今天学习记录的是关于持续集成流水线的内容。
从团队协作的角度上来看,在版本发布过程中,经常出现测试依赖开发手工生成制品、版本发布也从开发本地出版本的问题。而且项目架构如果从单体演进至组件化架构,随着越来越多的组件分离,以前一次构建可能就能出制品,但是组件化后需要先构建多个组件,然后再进行组件的集成,协作的复杂度也会更高。
最终后果就是团队的协作效率低,版本的质量也没办法控制。开发同学日常的开发工作经常被打断,沦为名副其实的“打包工程师”。
如何解决这些问题呢?最好的方式就是创建可靠、可重复的软件发布过程,让整个过程尽可能地自动化,从而提高整体的集成发布效率。通过自动化减少低价值的重复工作。
一、持续集成流水线
持续集成流水线 是一种软件开发实践。
如下图所示,每当开发提交代码后,都会触发流水线执行对应的步骤,这些步骤通常包含扫描检查、构建、测试、部署等环节。
如果提交的代码不满足流水线上设置的检查时,流水线的执行就会失败,不允许代码合入仓库。

那么使用持续流水线能够给团队带来什么价值呢?
- 一方面是明显的效率提升。在没有使用持续集成流水线前,版本的构建发布都得依赖本地构建,如果一天需要构建多个版本,那么效率非常低下。有了流水线,就可以自动化地帮我们
完成这些低价值的工作。另外,也可以在团队内形成协作规范,大家都以流水线推送的版本为准,可以减少不必要的沟通。 - 另一方面是明显的
质量提升。本地构建的版本不可控的因素非常多,例如开发本地的构建环节、代码是否拉取了最新、签名是否正确等等,都可能影响最终的制品质量。有了持续集成流水线,就有了统一的构建环境和规范的构建过程,有效保证制品质量稳定。另外,可以在流水线上设置相应的质量门禁,如静态代码检查、自动化测试验证、架构守护验证等等,当提交代码不符合要求时,可以不允许入库,这有助于团队尽快发现相关错误。
要让流水线发挥最佳的效果,关键还需要团队能够关注流水线的运行状态,并且及时响应。下面我2 个在实践过程中需要遵循的流水线纪律。
- 第一个是流水线如果构建失败了,不允许提交代码,尽快修复。当流水线构建失败时,应该立马排查失败的原因,尽快修复,避免影响出版本。如果短时间内无法修复,应该及时回滚代码,不要影响团队其他人的代码合入。
- 第二个是每天下班前一定要保证最后一次流水线构建是成功的。这个纪律叫 CI 红不过夜,通常要保证至少每天都有一个可用于测试的版本,这样才不会影响第二天的测试及相关人员拿到版本作验证。
二、Sharing 流水线设计
对于组件化的架构来说,由于抽离了多个组件,通过自动化来管理组件的发布及集成作用就更加明显了。
如果不能通过自动化来转移这部分复杂度,那么对于团队来说,拆分组件也许是另外一种负担,需要频繁地手工管理组件的构建发布,组件的集成发布等问题。因此,需要设计组件化架构的流水线,实现组件管理的自动化。Sharing 来看看如何设计流水线。
首先,需要给流水线做个分级,拆分为组件流水线以及基座流水线。
组件流水线的设计分主要分为 4 个操作步骤,也就是质量门禁检查、代码检视、组件制品管理及发布通知。

具体步骤是后面这样。
- 组件开发人员提交代码后自动触发流水线质量门禁检查,质量门禁包含代码扫描、编译及自动化测试等环节。
- 团队内架构师进行检视后代码合入。
- 发布最新的组件版本到 maven 制品库。
- 将构建结果及制品通知到相关干系人。
基座流水线的设计主要分为 5 个操作步骤,分别是提交组件集成清单、进行质量门禁检查、代码检视、发布制品到版本库及最后确认进行发布。

- 产品团队根据版本规划,提交组件集成版本清单。
- 质量门禁包含代码检查、编译、集成测试、性能测试等。
- 团队内架构师进行检视,产品经理进行确认后代码合入。
- 发布最新的应用版本到制品库。
- 团队确认后选择渠道(内测、灰度、应用市场、全量)进行发布。
在实际过程中,可以根据项目情况以及内部的工具完善度,灵活调整流水线的各个步骤。
流水线的设计应该和代码一样,可以持续迭代,而不是一成不变。
比如通常来说,最后的发布阶段不会是自动化的,还需要进行人工测试确认后再触发流水线进行发布部署。
三、使用 GitHub Action 搭建流水线示例
目前持续集成工具非常多,例如 Jenkins、GitLab CI、GitHub Action、AzureDevOps 等等,由于 Sharing 项目目前在 GitHub 托管,所以使用 GitHub Action 来演示如何搭建流水线。首先来看看如何基于 GitHub Action 配置流水线。
GitHub Action 采用 yml 配置文件的方式来描述 CI 的构建状态,在.github/workflows 目录下创建对应的 yml 文件即可。
可以参考后面的代码,在每个配置上备注了具体的注释。
//配置工作流的名称
name: Sharing CI
//配置当master分支有PR或者代码提交时会触发该流水线
on:push:branches: [ master ]pull_request:branches: [ master ]
//配置运行的任务
jobs:build:
//配置运行的服务器环节,一般使用默认runs-on: ubuntu-latest
//配置流水线的步骤steps:
//配置系统的构建环境- uses: actions/checkout@v3- name: set up JDK 11uses: actions/setup-java@v3with:java-version: 11distribution: 'temurin'cache: gradle
//检查Gradle运行环境- name: Grant execute permission for gradlewrun: chmod +x gradlew
//执行静态代码扫描,使用lint检查- name: Code Scan run: ./gradlew app:lint
//执行代码架构检查- name: Arch Test run: ./gradlew app:testDUT --tests com.jkb.junbin.sharing.ArchRuleTest
//执行功能自动化冒烟测试 - name: Smoke Test run: ./gradlew app:testDUT --tests com.jkb.junbin.sharing.SmokeTesting
//构建版本- name: buildrun: ./gradlew app:assembleRelease
//推送版本到artifact制品库- name: Upload apk to artifactuses: actions/upload-artifact@v3if: always()with:name: sharing_apppath: ${{ github.workspace }}/app/build/outputs/apk/release/*.apk
完成了流水线的配置以后,当有代码合入时则会触发流水线的运行,可以在项目的 Action 选项中查看对应的构建情况。

另外,除了自动触发以外,也可以点击进入详情,手动重新触发流水线的执行。

当流水线执行成功以后,则可以在详情中查看到构建的制品。

这里特别推荐采用配置文件的方式来定义流水线,这样一方面可以将流水线的变更和代码也一同纳入到版本管理中,另外由于配置文件和代码在一起管理,也可以让开发的同事更关注流水线的设计。
目前主流的持续集成工具都支持使用配置文件定义流水线的方式,只是不同的工具配置的语法稍有差异,整体的流水线设计是通用的。
四、总结
持续流水线 是一种软件开发的实践,目的是通过自动化为软件的发布创造一个稳定且可重复的过程。
流水线带来的效果是显而易见的,从效率上帮助减少低价值的重复工作,例如本地编译打包,另外也能减少团队成员间不必要的沟通。
从质量上看,统一了构建发布环境,整个环境会更可靠,减少了人工操作带来的意外风险。另外,结合流水线增加质量门禁,可以在版本发布前检查代码质量,避免不符合规范及要求的代码合入代码仓库中。
当然要让流水线发挥最佳的作用,还得依靠团队成员共同来遵循流水线的纪律,保障流水线红不过夜,当运行失败时能及时修复。
对于组件化架构的流水线设计,可以采用分层分级的方式。具体就是通过设计组件的流水线来管理组件的构建和版本管理,另外再设计集成的流水线来管理组件的集成和发布。
通过 GitHub Action 给你演示了如何搭建一个持续集成流水线,GitHub Action 采用 yml 配置的方式来定义流水线,这种方式对于开发人员来说更加友好,只需要按照特定的语法格式描述步骤即可,同时这个配置文件也能和代码一同进行版本管理。
在实践过程中推荐使用这种配置文件定义流水线的方式。
相关文章:
Day943.持续集成流水线 -系统重构实战
持续集成流水线 Hi,我是阿昌,今天学习记录的是关于持续集成流水线的内容。 从团队协作的角度上来看,在版本发布过程中,经常出现测试依赖开发手工生成制品、版本发布也从开发本地出版本的问题。而且项目架构如果从单体演进至组件…...
How to use CCS to debug a running M4F core that was started by Linux?
参考FAQ:AM62x & AM64x: How to use CCS to debug a running M4F core that was started by Linux? 问题记录: 1.使用SD卡启动模式,板上运行Linux。 当Linux系统启动后,9表示M4F core: am64xx-evm login: root rootam64xx…...
216、组合总数III
难度:中等 找出所有相加之和为 n 的 k 个数的组合,且满足下列条件: 只使用数字1到9 每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。 示例 1: 输入: k 3, n 7…...
简单的重装系统教程
郁闷,最近电脑一直蓝屏重启,用 2 分钟就蓝屏一次,遂产生重装系统的想法。 准备 U盘(8G或以上) PE 工具: 微PE工具箱快速指引 | 微PE优盘使用说明书 (wepe.com.cn) 系统镜像: 官网 Windows 10 官网 Windows 11 M…...
机器学习---集成学习报告
1.原理以及举例 1.1原理 集成学习(Ensemble Learning)是一种机器学习策略,它通过结合多个基学习器(base learners)的预测来提高模型的性能。集成学习的目标是创建一个比单个基学习器更准确、更稳定的最终预测模型。这…...
教你如何将PDF文件转换成PPT演示文稿
在工作和学习中,我们可能需要将一些PDF文件转换成PPT演示文稿,以便于更好地展示和分享。虽然PPT和PDF是两种不同的文档格式,但是我们可以使用一些专业的软件或在线工具来实现这种转换。下面就让我们来教你如何将PDF文件转换成PPT演示文稿。 …...
涨点技巧: 谷歌强势推出优化器Lion,引入到Yolov5/Yolov7,内存更小、效率更高,秒杀Adam(W)
1.Lion优化器介绍 论文:https://arxiv.org/abs/2302.06675 代码:automl/lion at master google/automl GitHub 1.1 简单、内存高效、运行速度更快 1)与 AdamW 和各种自适应优化器需要同时保存一阶和二阶矩相比,Lion 只需要动量,将额外的内存占用减半; 2)由于 Lion…...
Windows GPU版本的深度学习环境安装
本文记录了cuda、cuDNN的安装配置。 参考文章: cuda-installation-guide-microsoft-windows 12.1 documentation Installation Guide :: NVIDIA cuDNN Documentation 一、cuda安装 注意事项: 1、cuda安装最重要的是查看自己应该安装的版本。 表格…...
C语言实践——通讯录(3)(文件版)
首先感谢上一篇博客的大佬们的点赞,非常感谢!!! 目录 前言 一、需要添加的功能 1.增加保存数据函数——可以保存数据到文件中 主要逻辑: 注意事项: 代码实现: 2.修改初始化函数——新…...
GPT撑腰,微软再战谷歌 | 大厂集体抢滩ChatGPT:谁真的有实力,谁在试点商业化?
国内互联网大厂已经很久没有这样的盛况了! 在各自领域成长为头部的互联网大厂们,近年来正在向“自留地”的纵深发展,正面交锋的机会并不多。直到大洋彼岸传来GPT的声音后,一下子抓住了大厂们的G点,他们仿佛听到了新一轮…...
【消息队列】细说Kafka消费者的分区分配和重平衡
消费方式 我们直到在性能设计中异步模式,一般要么是采用pull,要么采用push。而两种方式各有优缺点。 pull :说白了就是通过消费端进行主动拉去数据,会根据自身系统处理能力去获取消息,上有Broker系统无需关注消费端的…...
【Python从入门到人工智能】14个必会的Python内置函数(7)——打印输出(详细语法参考 + 参数说明 + 具体示例)| 附:Python输出表情包
你仔细想想,你和谁在一起的时候,最放得开、最自然、最舒服,又毫无顾忌,可以做回真实的你。那个人才是你心里最特别,最重要的人。 🎯作者主页: 追光者♂🔥 🌸个人简介: 💖[1] 计算机专业硕士研究生💖 🌟[2] 2022年度博客之星人工智能领域TOP4�…...
为什么要创建FAQ?这篇文章告诉你
什么是FAQ 通过上述的引入大家应该也了解到了,FAQ是为了“解决问题”而存在的。FAQ是英文Frequently Asked Questions的缩写,中文意思就是“经常问到的问题”,或者更通俗地叫做“常见问题解答”。FAQ是当前网络上提供在线帮助的主要手段&…...
基于html+css的盒子展示1
准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…...
Python 无监督学习实用指南:1~5
原文:Hands-on unsupervised learning with Python 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自【ApacheCN 深度学习 译文集】,采用译后编辑(MTPE)流程来尽可能提升效率。 不要担心自己的形象,只关…...
2023 腾讯暑期实习申请经验分享
首先要向还在等我出 CMU 15-445 后面实验的同学们说声抱歉,这个系列可能暂时要停更啦。 一方面是博主最近课程和实验室方面的任务比较多,另一方面是有幸拿下了今年腾讯 WXG 后端开发的暑期实习 Offer,后面可能要提前学习一些工作中用到的框架…...
Protocol Buffers 介绍
Protocol Buffers Protocol Buffers ,协议缓冲区。什么是Protocol Buffers呢?或者我们简称PB 吧。那么Protocol Buffers 是一种与语言无关、与平台无关的可扩展机制,用于序列化结构化的数据。 example message Person {optional string nam…...
【模电实验】基尔霍夫定律、叠加定理和戴维南定理验证实验
实验目的 验证基尔霍夫电流定律(KCL)和电压定律(KVL)加深对该定理的理解验证叠加定理,加深对该定理的理解验证戴维南定理,掌握有源二端口网络的开路电压,短路电流和入端等效电阻的测定方法通过实…...
java某百货店POS积分管理系统_积分点更新生成以及通票回收处理
百货店是生活中不可缺少的一部分,为了给顾客提供更方便的服务平台以及更好的服务质量,而设计了POS积分管理系统。百货店通过点积分的管理获得顾客更好的信誉,增加客户流量,获得更多的利益。在百货店经营的过程中,每天的…...
Flutter 常用指令
1.flutter create app_01 :创建一个新的Flutter项目 2.flutter run:运行应用程序 3.flutter run -d <deviceId>:运行指定模拟器或者真机 4.flutter devices:查看计算机上的真机设备和IOS模拟器 5.flutter emulators&…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
表单设计器拖拽对象时添加属性
背景:因为项目需要。自写设计器。遇到的坑在此记录 使用的拖拽组件时vuedraggable。下面放上局部示例截图。 坑1。draggable标签在拖拽时可以获取到被拖拽的对象属性定义 要使用 :clone, 而不是clone。我想应该是因为draggable标签比较特。另外在使用**:clone时要将…...
篇章一 论坛系统——前置知识
目录 1.软件开发 1.1 软件的生命周期 1.2 面向对象 1.3 CS、BS架构 1.CS架构编辑 2.BS架构 1.4 软件需求 1.需求分类 2.需求获取 1.5 需求分析 1. 工作内容 1.6 面向对象分析 1.OOA的任务 2.统一建模语言UML 3. 用例模型 3.1 用例图的元素 3.2 建立用例模型 …...
生成对抗网络(GAN)损失函数解读
GAN损失函数的形式: 以下是对每个部分的解读: 1. , :这个部分表示生成器(Generator)G的目标是最小化损失函数。 :判别器(Discriminator)D的目标是最大化损失函数。 GAN的训…...
AI书签管理工具开发全记录(十八):书签导入导出
文章目录 AI书签管理工具开发全记录(十八):书签导入导出1.前言 📝2.书签结构分析 📖3.书签示例 📑4.书签文件结构定义描述 🔣4.1. 整体文档结构4.2. 核心元素类型4.3. 层级关系4.…...
Linux 内核内存管理子系统全面解析与体系构建
一、前言: 为什么内存管理是核心知识 内存管理是 Linux 内核最核心也最复杂的子系统之一,其作用包括: 为软件提供独立的虚拟内存空间,实现安全隔离分配/回收物理内存资源,维持系统稳定支持不同类型的内存分配器,最优…...
