前端架构师的 git 功力,你有几成火候?

2023-01-03 0 1,041

责任编辑从后端工程建设,项目组协同,制造布署的视角,如是说构架相关人员须要掌控的 git 课堂教学潜能。

概要自动更新

责任编辑如是说的文本主要就包括下列各方面:

组成部分沃苏什卡

commit 规范化与递交校正

错误操作的退回计划

Tag 与制造自然环境

永久性杜绝 443 Timeout

hook 与此同时实现布署?

毁灭者应用领域: CI/CD

组成部分沃苏什卡

git 组成部分强悍的与此同时也圣索弗,假如没两个好的组成部分沃苏什卡,项目组相关人员随便分拆发送,就会导致组成部分纷乱,各式各样全面覆盖,武装冲突,遗失等难题。

现阶段最盛行的组成部分沃苏什卡,也称组织工作流(Workflow),主要就包涵四种:

Git Flow

GitHub Flow

GitLab Flow

目标公司后端项目组因地制宜情形,制订出他们的两套组成部分沃苏什卡。

他们将组成部分分成 4 个大类:

dev-*

develop

staging

release

dev-* 是一组开发组成部分的统称,主要就包括个人组成部分,模块组成部分,修复组成部分等,项目组开发相关人员在这组组成部分上进行开发。

开发前,先通过 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) -> develop

develop -> (rebase) -> staging

staging -> (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:常用:表示修复 bug

perf:性能优化

refactor:重构

revert:代码回滚

style:样式更改

test:单元测试更改

这些前缀每次递交都要写,刚开始很多人还是记不住的。这里推荐两个非常好用的工具,可以自动生成前缀。地址在这里

首先全局安装:

npm install -g commitizen cz-conventional-changelog

创建 ~/.czrc 文件,写入如下文本:

{ “path”: “cz-conventional-changelog” }

现在可以用 git cz 命令来代替 git commit 命令,效果如下:

前端架构师的 git 功力,你有几成火候?

然后上下箭选择前缀,根据提示即可方便的创建符合规范化的递交。

有了规范化之后,光靠人的自觉遵守是不行的,还要在流程上对递交信息进行校验。

这个时候,他们要用到两个新东西 —— 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

上面的命令,commi

这里的 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.4Tagger: ruims Date:   Sun Sep 26 10:24:30 2021 +0800my 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 课堂教学,记得关注我哦。

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务