本系列将会从宏观角度,讲述CI/CD相关知识。系列文章不求把每一项都讲仔细,而是让大家能对CI/CD整体流程有大致的概念。无论你是前端,后端,或是运维团队,只要是CI/CD链路上的一份子,相信这系列文章对你都会有帮助。 阅读更多专栏文章
本文讲述内容定位为:CI 持续集成
本地执行持续集成
现在市面上的大部分CI/CD工具已经非常成熟了,自动化程度都很高。然而,对于小型团队或者个人开发者来说,未必能得到额外的CI/CD服务资源 。对于这种情况,把CI过程放在本地执行,也许是最适合的方案。
优势
在之前介绍CI/CD的文章中提过,持续集成环节的目标是提前发现问题代码,确保上交代码的质量。从这个角度来看,这部分工作完全可以放在开发者本地进行。带来的好处是:
- 减低成本:免去额外的CI资源
- 个人定制化: 开发者可以根据实际情况,定制化修改CI规则。
缺点
诚然,大部分的团队不会选择在本地进行CI,因为它会带来一些问题:
- 额外的环境要求:开发者在搭建开发环境之余,还需要配置CI需要的运行环境。
- 增加代码提交时间:每次提交代码前,都需要执行CI操作,会使代码提交的时间变长。
- 占用开发资源:把CI放本地,本质上是运行资源的一种转嫁。开发者在执行CI时可能会被占用部分硬件资源,可能导致其他开发进度受阻。
在了解完把持续集成放本地的优劣之后,我们来看看有什么实现的方案。
利用Npm Scripts
这个方案是NodeJs开发者的专属。其实Npm设计scripts的时候,留了两个可供开发者调用的Hook—— pre 和 post 。
使用方式
开发者在定义 npm script 的时候,可以通过定义 pre + script 和 post + script 的方式,让npm自动执行某些命令。其中执行顺序为pre脚本——指定脚本——post脚本。举个例子:
{
...
"scripts": {
"precompress": "{{ compress命令执行之前触发的操作 }}",
"compress": "{{ compress命令 }}",
"postcompress": "{{ compress命令执行之后触发的操作 }}"
}
...
}
观察上方例子,假如我们已经有了一个compress命令,我们可以继续增加名为precompress或者postcompress的script。这样每次执行npm run compress的时候,Npm都会自动在package.json的script中找是否存在precompress或者postcompress命令,如果存在,就会指定顺序执行。
Life Cycle Scripts
虽然我们可以用pre、post很自由地为脚本添加hook命令,但这种自由并不是无限制的。Npm本身保留了一系列的默认脚本,官方把这些scripts叫作 Life Cycle Scripts(生命周期脚本) 。这些脚本是有固定执行条件的,换句话说,只要你在package.json中定义了这些脚本,只会在Npm规定的条件下执行,而不是按上文提的pre、post规则。
目前 Life Cycle Scripts 有以下例子:
使用场景
常见的Npm Scripts使用场景,是npm pack 和 npm publish。这种情况一般是某位开发者维护一个团队内部的npm包,每次修改完之后发布到指定的npm仓库。举个例子:开发者可以把源码构建的动作放在
prepare 中,这样只要执行publish就可以自动构建代码。同时,也可以做代码规范扫描等操作。
Git Hooks
与Npm Scripts相比Git Hooks是更通用的方式,因为它没有开发语言的限制,适用于所有开发者。
跟NpmScripts一样,Git Hooks是 Git 官方留的一些列git操作的生命周期钩子,用户定义之后,可以在某个git操作触发时,执行事先规定的脚本。
使用方式
Git Hooks的使用很简单,在任何一个初始化git 的项目目录下找到 .git/hooks 打开即可。
在默认情况下可以看到一些列以.sample结尾的文件,这些就是 Git Hooks 的用例示范,想要激活某个hook只要把文件名的.sample后缀删掉即可。现在随便打开一个文件,可以看到下图内容:
可以看到 Git Hooks 的脚本是用shell写的,这也是为什么说它适合所有开发者的原因。在sample文件中也写部分使用说明,上图内容就是pre-commit.sample的内容,pre-commit 的脚本会执行在 git commit 命令执行之前。
接下来我们来尝试一下,先在 .git/hooks/ 下新建一个文件,命名为 pre-commit。并写入内容
#!/bin/sh
echo 'pre-commit 执行了!'
然后在项目文件中,随便改点东西,再执行一次commit。
# 随便新建一个文件
touch ./temp.txt
# git add 处理
git add ./temp.txt
# 测试 git commit
git commit -m 'test'
可以看到下图输出结果:
现在,相信大家已经掌握了 Git Hooks 的使用了,开发者可以根据自己的时间情况来修改不同的脚本内容,以完善项目的CI步骤。
可选HOOKS
Git 留给我们可以选择的Hooks有很多,下面列举一些使用频率比较高的部分,如果有兴趣了解更多的朋友,可以自行到官网查阅。
名称 | 说明 |
---|---|
pre-commit | git commit执行前,可以通过git commit --no-verify绕过 |
post-commit | git commit执行后,因为不会影响commit的结果,所以一般用作通知提示。 |
pre-merge-commit | git merge执行前,可以通过git merge --no-verify绕过 |
commit-msg | git commit 和 git merge 执行前,可以通过 --no-verify参数绕过 |
pre-rebase | git rebase执行前。 |
使用场景
Git Hooks 是使用场景显然会更广,主要体现在两点:
- 没有开发语言限制,适用于所有开发者。
- 与 git 结合,可以有效保护仓库代码。
在此CI环节,我们可以实现诸如代码检查,分支管理,更新推送等操作。
Husky
相信大家已经发现,尽管我们改了git hooks 内容,但在 .git 文件夹中的内容是不参与git同步的,这样我们的脚本便不能跟团队其他成员共享。此时Husky出现了,它是一个专门处理 git hooks 的开源工具。
它的工作原理很简单,通过把所有的git hooks 定义在一个配置文件中,并把配置文件加入git管理。这样团队其他人都可以得到这个配置文件,从而实现把 git hooks 共享了。
配置文件例子:
{
"hooks": {
"pre-commit": "echo 'pre-commit 执行了!'"
}
}
Husky的Github 地址是: github.com/typicode/hu…,有兴趣的朋友可以自行了解。
总结
今天我们了解了在持续集成环节中,最低成本一种操作——把CI放在本地。这种操作对于小团队,或个人开发者来说是价值很高的选择。如果你真正学习CI/CD,这也是一个学习尝试很好的方式。希望大家在掌握这种方法之后,在面对合适的场景时,可以有更多的选择。
进一步了解
Npm Scripts文档:docs.npmjs.com/cli/v8/usin…
Git Hooks 文档:git-scm.com/docs/githoo…
如果你觉得本文对你有一点帮助,麻烦给我点个赞吧~~ 谢谢