责任编辑如是说的文本主要包括下列各方面:
组成部分沃苏什卡commit 规范化与递交校正错误操作的退回计划Tag 与制造自然环境永久性避免出现 443 Timeouthook 与此同时实现布署?毁灭者应用领域: CI/CD组成部分沃苏什卡
git 组成部分强悍的与此同时也圣索弗,假如没有两个好的组成部分沃苏什卡,项目组相关人员随便分拆发送,就会导致组成部分纷乱,各式各样全面覆盖,武装冲突,遗失等难题。
现阶段最盛行的组成部分沃苏什卡,也称组织工作流(Workflow),主要包涵四种:
Git FlowGitHub FlowGitLab Flow目标公司后端项目组因地制宜情形,制订出他们的两套组成部分沃苏什卡。
我们将组成部分分成 4 个大类:
dev-*developstagingreleasedev-* 是几组合作开发组成部分的泛称,主要包括对个人组成部分,组件组成部分,复原组成部分等,项目组合作开发者在实蕨组成部分上展开合作开发。
合作开发前,先透过 merge 分拆 develop 组成部分的新一代标识符;合作开发顺利完成后,要透过 cherry-pick 分拆回 develop 组成部分。
develop 是两个原则上组成部分,相关联合作开发自然环境,留存新一代的完备的合作开发标识符。它只拒绝接受 cherry-pick 的分拆,不容许采用 merge。
staging 组成部分相关联试验自然环境。当 develop 组成部分有预览因此预备正式发布试验时,staging 要透过 rebase 分拆 develop 组成部分,接着将新一代标识符正式发布到试验伺服器,供试验相关人员试验。
试验辨认出难题后,再走 dev-* -> develop -> staging 的业务流程,直至试验透过。
release 则则表示制造自然环境。release 组成部分的新一代递交总有一天与线上制造自然环境标识符维持并行,换句话说,release 组成部分是即时可发布的。
当 staging 试验透过后,release 组成部分透过 rebase 分拆 staging 组成部分,接着将新一代标识符正式发布到制造伺服器。
归纳下分拆准则:
develop -> (merge) -> dev-*dev-* -> (cherry-pick) -> developdevelop -> (rebase) -> stagingstaging -> (rebase) -> release为什么分拆到 develop 要用 cherry-pick?采用 merge 分拆,假如有武装冲突,会产生分叉;dev-* 组成部分多而杂,直接 merge 到 develop 会产生错综复杂的分叉,难以理清递交进度。
而 cherry-pick 只将需要的 commit 分拆到 develop 组成部分上,且不会产生分叉,使 git 递交图谱(git graph)总有一天维持一条直线。
再有,组件合作开发组成部分顺利完成后,需要将多个 commit 合为两个 commit,再分拆到 develop 组成部分,避免了多余的 commit,这也是不用 merge 的原因之一。
为什么分拆到 staging/release 要用 rebase?release 译为变基,分拆同样不会产生分叉。当 develop 预览了许多功能,要分拆到 staging 试验,不可能用 cherry-pick 两个两个把 commit 分拆过去。因此要透过 rebase 一次性分拆过去,因此保证了 staging 与 develop 完全并行。
release 也一样,试验透过后,用 rebase 一次性将 staging 分拆过去,同样保证了 staging 与 release 完全并行。
commit 规范化与递交校正
commit 规范化是指 git commit 时填写的描述信息,要符合统一规范化。
试想,假如项目组成员的 commit 是随便填写的,在协作合作开发和 review 标识符时,其他人根本不知道这个 commit 是顺利完成了什么功能,或是复原了什么 Bug,很难把控进度。
为了直观的看出 commit 的预览文本,合作开发者社区诞生了一种规范化,将 commit 按照功能划分,加一些固定前缀,比如 fix:,feat:,用来标记这个 commit 主要做了什么事情。
现阶段主流的前缀主要包括下列部分:
build:则表示构建,正式发布版本可用这个ci:预览 CI/CD 等自动化配置chore:杂项,其他更改docs:预览文档feat:常用,则表示新增功能fix:常用:则表示复原 bugperf:性能优化refactor:重构revert:标识符回滚style:样式更改test:单元试验更改这些前缀每次递交都要写,刚开始很多人还是记不住的。这里推荐两个非常好用的工具,可以自动生成前缀。地址在这里
首先全局安装:
npm install -g commitizen cz-conventional-changelog
创建 ~/.czrc 文件,写入如下文本:
{ “path”: “cz-conventional-changelog”}
现在可以用 git cz 命令来代替 git commit 命令,效果如下:
接着上下箭选择前缀,根据提示即可方便的创建符合规范化的递交。
有了规范化之后,光靠人的自觉遵守是不行的,还要在业务流程上对递交信息展开校验。
这个时候,我们要用到两个新东西 —— git hook,也就是 git 钩子。
git hook 的作用是在 git 动作发生前后触发自定义脚本。这些动作主要包括递交,分拆,发送等,我们可以利用这些钩子在 git 业务流程的各个环节与此同时实现他们的业务逻辑。
git hook 分成客户端 hook 和服务端 hook。
客户端 hook 主要有四个:
pre-commit:递交信息前运行,可检查暂存区的标识符prepare-commit-msg:不常用commit-msg:非常重要,检查递交信息就用这个钩子post-commit:递交顺利完成后运行服务端 hook 主要包括:
pre-receive:非常重要,发送前的各式各样检查都在这post-receive:不常用update:不常用大多数项目组是在客户端做校验,所以我们用 commit-msg 钩子在客户端对 commit 信息做校验。
幸运的是,不需要我们手动去写校验逻辑,社区有成熟的计划:husky + commitlint
husky 是创建 git 客户端钩子的神器,commitlint 是校验 commit 信息是否符合上述规范化。两者配合,可以阻止创建不符合 commit 规范化的递交,从源头保证递交的规范化。
husky + commitlint 的具体采用方法请看这里
错误操作的退回计划
合作开发中频繁采用 git 拉取发送标识符,难免会有错误操作。这个时候不要慌,git 支持绝大多数场景的退回计划,我们来归纳一下。
退回主要是两个命令:reset 和 revert
git reset
reset 命令的原理是根据 commitId 来恢复版本。因为每次递交都会生成两个 commitId,所以说 reset 可以帮你恢复到历史的任何两个版本。
这里的版本和递交是两个意思,两个 commitId 就是两个版本
reset 命令格式如下:
$ git reset [option] [commitId]
比如,要退回到某一次递交,命令是这样:
$ git reset –hard cc7b5be
个值很长,我们取前 7 位即可。
这里的 option 用的是 –hard,其实共有 3 个值,具体含义如下:
–hard:撤销 commit,撤销 add,删除组织工作区改动标识符–mixed:默认参数。撤销 commit,撤销 add,还原组织工作区改动标识符–soft:撤销 commit,不撤销 add,还原组织工作区改动标识符这里要格外注意 –hard,采用这个参数恢复会删除组织工作区标识符。换句话说,假如你的项目中有未递交的标识符,采用该参数会直接删除掉,不可恢复,慎重啊!
除了采用 commitId 恢复,git reset 还提供了恢复到上一次递交的快捷方式:
$ git reset –soft HEAD^
HEAD^ 则表示上两个递交,可多次采用。
其实平日合作开发中最多的错误操作是这样:刚刚递交完,突然辨认出了难题,比如递交信息没写好,或者标识符更改有遗漏,这时需要退回到上次递交,修改标识符,接着重新递交。
这个业务流程大致是这样的:
# 1. 回退到上次递交$ git reset HEAD^
# 2. 修改标识符……
# 3. 加入暂存$ git add .
# 4. 重新递交$ git commit -m fix: ***针对这个业务流程,git 还提供了两个更便捷的方法:
$ git commit –amend
这个命令会直接修改当前的递交信息。假如标识符有更改,先执行 git add,接着再执行这个命令,比上述的业务流程更快捷更方便。
reset 还有两个非常重要的特性,就是真正的后退两个版本。
什么意思呢?比如说当前递交,你已经发送到了远程仓库;现在你用 reset 退回了一次递交,此时本地 git 仓库要落后于远程仓库两个版本。此时你再 push,远程仓库会拒绝,要求你先 pull。
假如你需要远程仓库也后退版本,就需要 -f 参数,强制发送,这时本地标识符会全面覆盖远程标识符。
注意,-f 参数非常危险!假如你对 git 原理和命令行不是非常熟悉,切记不要用这个参数。
那退回上两个版本的标识符,怎么并行到远程更安全呢?
计划就是下面要说的第二个命令:git revert
git revert
revert 与 reset 的作用一样,都是恢复版本,但是它们两的与此同时实现方式不同。
简单来说,reset 直接恢复到上两个递交,组织工作区标识符自然也是上两个递交的标识符;而 revert 是新增两个递交,但是这个递交是采用上两个递交的标识符。
因此,它们两恢复后的标识符是一致的,区别是两个新增递交(revert),两个回退递交(reset)。
正因为 revert 总有一天是在新增递交,因此本地仓库版本总有一天不可能落后于远程仓库,可以直接发送到远程仓库,故而解决了 reset 后发送需要加 -f 参数的难题,提高了安全性。
说完了原理,我们再看一下采用方法:
$ git revert -n [commitId]
掌握了原理采用就很简单,只要两个 commitId 就可以了。
Tag 与制造自然环境
git 支持对于历史的某个递交,打两个 tag 标签,常用于标识重要的版本预览。
现阶段普遍的做法是,用 tag 来则表示制造自然环境的版本。当新一代的递交透过试验,预备发布之时,我们就可以创建两个 tag,则表示要正式发布的制造自然环境版本。
比如我要发两个 v1.2.4 的版本:
$ git tag -a v1.2.4 -m “my version 1.2.4”接着可以查看:
$ git show v1.2.4
> tag v1.2.4
Tagger: ruims <[email protected]>
Date: Sun Sep 26 10:24:30 2021 +0800
my version 1.2.4
最后用 git push 将 tag 推到远程:
$ git push origin v1.2.4
这里注意:tag 和在哪个组成部分创建是没有关系的,tag 只是递交的别名。因此 commit 的能力 tag 均可采用,比如上面说的 git reset,git revert 命令。
当制造自然环境出难题,需要版本回退时,可以这样:
$ git revert [pre-tag]
# 若上一个版本是 v1.2.3,则:$ git revert v1.2.3
在频繁预览,commit 数量庞大的仓库里,用 tag 标识版本显然更清爽,可读性更佳。
再换两个角度思考 tag 的用处。
上面组成部分管理策略的部分说过,release 组成部分与制造自然环境标识符并行。在 CI/CD(下面会讲到)持续布署的业务流程中,我们是监听 release 组成部分的发送接着触发自动构建。
那是不是也可以监听 tag 发送再触发自动构建,这样版本预览的直观性是不是更好?
诸多用处,还待大家思考。
永久性避免出现 443 Timeout
我们项目组内部的标识符仓库是 GitHub,众所周知的原因,GitHub 拉取和发送的速度非常慢,甚至直接报错:443 Timeout。
我们开始的计划是,全员开启 VPN。虽然大多时候速度不错,但是确实有偶尔的两个小时,甚至一天,标识符死活推不上去,严重影响合作开发进度。
后来突然想到,速度慢超时是因为被墙,比如 GitHub 首页打不开。再究其根源,被墙的是访问网站时的 http 或 https 协议,那么其他协议是不是就不会有墙的情形?
想到就做。我们辨认出 GitHub 除了默认的 https 协议,还支持 ssh 协议。于是预备尝试一下采用 ssh 协议克隆标识符。
用 ssh 协议比较麻烦的一点,是要配置免密登录,否则每次 pull/push 时都要输入账号密码。
GitHub 配置 SSH 的官方文档在这里
英文吃力的同学,可以看这里
总之,生成公钥后,关上 GitHub 首页,点 Account -> Settings -> SSH and GPG keys -> Add SSH key,接着将公钥粘贴进去即可。
现在,我们用 ssh 协议克隆标识符,例子如下:
$ git clone[email protected]:[organi-name]/[project-name]
辨认出瞬间克隆下来了!再测几次 pull/push,速度飞起!
不管你用哪个标识符管理平台,假如遇到 443 Timeout 难题,请试试 ssh 协议!
hook 与此同时实现布署?
利用 git hook 与此同时实现布署,应该是 hook 的高级应用领域了。
现在有很多工具,比如 GitHub,GitLab,都提供了持续集成功能,也就是监听某几组成部分发送,接着触发自动构建,并自动布署。
其实,不管这些工具有多少花样,核心的功能(监听和构建)还是由 git 提供。只不过在核心功能上做了与自家平台更好的融合。
我们今天就抛开这些工具,追本溯源,采用纯 git 与此同时实现两个 react 项目的自动布署。掌握了这套核心逻辑,其他任何平台的持续布署也就没那么神秘了。
由于这一部分内容较多,所以原则上拆出去一篇文章,地址如下:
纯 Git 与此同时实现后端 CI/CD
毁灭者应用领域: CI/CD
上面的一些地方也提到了持续集成,持续布署这些字眼,现在,千呼万唤始出来,主角正式登场了!
可以这么说,上面写到的所有规范化准则,都是为了更好的设计和与此同时实现这个主角 ——— CI/CD。
首先了解一下,什么是 CI/CD ?
核心概念,CI(Continuous Integration)译为持续集成,CD 主要包括两部分,持续交付(Continuous Delivery)和持续布署(Continuous Deployment)
从全局看,CI/CD 是一种透过自动化业务流程来频繁向客户交付应用领域的方法。这个业务流程贯穿了应用领域的集成,试验,交付和布署的整个生命周期,泛称为 “CI/CD 管道”。
虽然都是像流水线一样自动化的管道,但是 CI 和 CD 各有分工。
持续集成是频繁地将标识符集成到主干组成部分。当新标识符递交,会自动执行构建、试验,试验透过则自动分拆到主干组成部分,与此同时实现了产品快速迭代的与此同时维持高质量。
持续交付是频繁地将软件的新版本,交付给质量项目组或者用户,以供评审。评审透过则可以正式发布制造自然环境。持续交付要求标识符(某个组成部分的新一代递交)是即时可正式发布的状态。
持续布署是标识符透过评审后,自动布署到制造自然环境。持续布署要求标识符(某个组成部分的新一代递交)是即时可布署的。
持续布署与持续交付的唯一区别,就是布署到制造自然环境这一步,是否是自动化。
布署自动化,看似是小小的一步,但是在实践过程中你会辨认出,这反而是 CI/CD 流水线中最难落实的一环。
为什么?首先,从持续集成到持续交付,这些个环节都是由合作开发项目组实施的。我们透过项目组内部协作,产出了新版本的待正式发布的应用领域。
然而将应用领域布署到伺服器,这是运维项目组的组织工作。我们要与此同时实现布署,就要与运维项目组沟通,然而合作开发同学不了解伺服器,运维同学不了解标识符,沟通起来困难重重。
再有,运维是手动布署,我们要与此同时实现自动布署,就要有伺服器权限,与伺服器交互。这也是个大难题,因为运维项目组一定会顾虑安全难题,因而推动起来节节受阻。
现阶段社区成熟的 CI/CD 计划有很多,比如老牌的 jenkins,react 采用的 circleci,还有我认为最好用的GitHub Action等,我们可以将这些计划接入到他们的系统当中。
这篇文章篇幅已经很长了,就到这里结束吧。接下来我会基于 GitHub Action 原则上出一篇详细的 react 后端项目 CI/CD 实践,记得关注我哦。
推荐阅读:Vue3.2 中的 Setup 语法糖,保证你看的明明白白!
VUE中文社区编程技巧 · 行业秘闻 · 技术动向