CI 从Git hooks学起

简介: 前端工程化前端工程化是前端的一个重要领域,简单的从代码规范开始,复杂的到团队脚手架搭建。在小团队中大多由开发兼任,在大团队中则可能有专门的基建团队负责。可见工程化的普及度是非常高的,只是不同团队的水平或复杂度参差不齐。工程化对于前端开发是个必备技能。不说要学的多深多厉害,起码能 hold 住一个普通项目。我们先从 Git 的 hooks 学起,这是很多自动化的关键。

前端工程化

前端工程化是前端的一个重要领域,简单的从代码规范开始,复杂的到团队脚手架搭建。在小团队中大多由开发兼任,在大团队中则可能有专门的基建团队负责。可见工程化的普及度是非常高的,只是不同团队的水平或复杂度参差不齐。

工程化对于前端开发是个必备技能。不说要学的多深多厉害,起码能 hold 住一个普通项目。我们先从 Git 的 hooks 学起,这是很多自动化的关键。


Git hooks


以前可能还会时常遇到使用 SVN 管理的代码仓库,而现在已经很少见到了,绝大多数项目应该都使用或切换到 Git 管理了。其中两个最重要的原因就是 Git 的分布式及便捷的分支管理。关于 Git 的使用就不细说了,而 Git hooks 顾名思义就是 Git 提供的一些钩子,我们可以利用其做一些自动化的事情。


Git 提供的钩子可以在仓库的 .git 文件中可以看到,在 .git/hooks 下有这么一些文件

.
├── applypatch-msg.sample
├── commit-msg.sample
├── fsmonitor-watchman.sample
├── post-update.sample
├── pre-applypatch.sample
├── pre-commit.sample
├── pre-merge-commit.sample
├── pre-push.sample
├── pre-rebase.sample
├── pre-receive.sample
├── prepare-commit-msg.sample
├── push-to-checkout.sample
└── update.sample
复制代码


他们都是以 .sample 结尾的 bash 文件,其实就是钩子的示例文件了,我们把 .sample 去掉便可让 bash 生效,在特定的时期就会执行这些钩子文件代码,例如 pre-commit 会在我们执行 git commit 的时候执行,如果 pre-commit 的执行结果状态为 0,则 commit 成功,否则 commit 会失败。所以说,通过 Git 提供的各类钩子,我们可以在流程中加入各类校验,或者自动化相关的能力,各种工具包实际也产生于此。


其中最简单常用的应该是 pre-commitcommit-msg 钩子了。pre-commit 多用于规范校验、自动修复,commit-msg 多用于 commit message 规范校验、提示。

看到这里,我想大家可以联想到团队项目在使用 Git 命令时候的一些自动化的原理了吧,很酷但原理实际很简单。


husky


上面说了原理很简单,但是操作起来还是有一些需要思考的点的。例如

  • .git/hooks 的内容是不会被 push 到远程的,pull 的时候自然也无法同步,那团队间该如何同步呢
  • .git 一般在编辑器上默认也是隐藏文件,想要修改其内容需要先设置为显示,修改完再隐藏吗


所以 husky 就来了,其作用在于帮助开发者创建修改 hooks 并同步。husky 在很多文章都有介绍,并且会对比其新旧版本。我们这边仅仅学习下新版本的使用就好了。


新版本的新在于利用了 Git 的新能力,在 .git/config 下可以通过 hooksPath 自定义 hooks 目录

[core]
  hooksPath = xxx
复制代码


简单介绍下使用


安装

npm install husky --save-dev
复制代码


命令式配置 package.json,作用是以后每次执行完 install 都会执行 husky install,实际就是自动帮你修改 .git 配置文件,修改 hooks 目录,解决一致性问题

npm set-script prepare "husky install"
npm run prepare
复制代码


添加 hooks

npx husky add .husky/pre-commit "npm run lint"
复制代码


这时候在项目根目录下会创建 .husky 目录,好奇的你可以看看 ./git/config 的配置中多了 hooksPath = .husky


我们来看看新建的 ./husky/pre-commit 的内容,实际就是个执行 npm run lint 的 bash。当然,其中是通过 husky.sh 执行的,细节不再展开。

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run lint
复制代码


我们继续配置 lint,在 package.json 的 script 中添加

{
    "lint": "eslint --ext .js src/"
}
复制代码


当然安装 eslint 及配置规则必不可少

npm i eslint -D
复制代码


.eslintrc

module.exports = {
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": "eslint:recommended",
    "parserOptions": {
        "ecmaVersion": "latest",
        "sourceType": "module"
    },
    "rules": {
        "semi": [2, "never"]
    }
}
复制代码

好了,现在每次执行 git commit 都会先执行 npm run lint,只有通过 eslint 的检查,才能继续填写 commit message,否则将提交失败。


commitlint


前面了解了常见的 pre-commit 用于配置 lint 的情况。我们再来看看另一常见的钩子 commit-msg。当执行 git commit 提交时,如果 pre-commit 执行通过,则继续触发 commit-msg。如果自己写 bash 研究如何校验 message 格式会比较麻烦,而 commitlint 正是用于提供统一的校验规则并支持自定义配置。即通过配置的方式来校验 message,避免大家陷入不会 bash 的窘局。

我们看看其使用


安装

npm install @commitlint/cli @commitlint/config-conventional -D
复制代码


生成配置

echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
复制代码


通过 husky 添加 commit-msg

npx husky add .husky/commit-msg "npx commitlint --edit $1"
复制代码


现在再提交 commit 就会验证提交格式了,正确的 message 格式形如

git commit -m 'fix: 修复配置'
复制代码

当然,具体格式是支持自定义配置的,感兴趣可以查看其文档。


lint-staged


上面我们执行 eslint 检查的时候是对整个项目进行检查的,有没有办法对增量代码进行检查呢?在单测领域,增量检查,增量覆盖率是个很常见的需求。

借助 lint-staged 可以做到,lint-staged 仅仅作用于通过 git add 提交到暂存区的文件。


我们来看看其使用


安装

npm install --save-dev lint-staged
复制代码


添加 .lintstagedrc 配置,数组的形式意味着可以添加更多不同的命令,例如单元测试

{
    "src/**/*.js": ["npx eslint --fix", "git add"]
}
复制代码

顾名思义,对 JS 执行 eslint 检查并自动修复,再执行 git add 添加代码。这边的 git add 只会添加在前面命令中的自动修改的代码,不会提交你原本工作区的修改,实际上是通过 git stash 先缓存了工作区。



总结

本文介绍了 Git hooks 及常见的一些和 hooks 配合使用的 npm 插件 husky、commitlint、lint-staged。提供了自动化校验,提交信息校验的简单思路。



相关文章
|
6月前
|
测试技术 持续交付 开发工具
《Git 简易速速上手小册》第6章:Git 在持续集成/持续部署(CI/CD)中的应用(2024 最新版)
《Git 简易速速上手小册》第6章:Git 在持续集成/持续部署(CI/CD)中的应用(2024 最新版)
116 2
|
6月前
|
存储 前端开发 开发工具
Git Hooks实战:提交前检查修改文件中是否包含调试代码
Git Hooks实战:提交前检查修改文件中是否包含调试代码
98 0
|
前端开发 开发工具 git
一个 git 仓库下拥有多个项目的 git hooks 配置方案
一个 git 仓库下拥有多个项目的 git hooks 配置方案
202 0
|
Shell 开发工具 git
git hooks
如同 flask 框架的请求钩子一样,git 也有钩子 (hook) 的概念,下面就让我们一起来看看吧。
|
前端开发 JavaScript Shell
手写 git hooks 脚本(pre-commit、commit-msg)
手写 git hooks 脚本(pre-commit、commit-msg)
488 0
|
Devops 测试技术 开发工具
devops| git hooks 实战: 防分支 merge
基于工作中 git 工作流遇到的问题, 实战 git hooks, 防止测试分支合并到开发分支
588 0
|
Devops 开发工具 git
devops之CI极简教学视频---git(下)
devops之CI极简教学视频---git(下)
|
jenkins 测试技术 持续交付
|
IDE Shell 开发工具
在 Swift 中编写脚本:Git Hooks
这周,我决定完成因为工作而推迟了一周的 TODO 事项来改进我的 Git 工作流程。
192 1
在 Swift 中编写脚本:Git Hooks
|
存储 安全 JavaScript
Git 项目的 CI 流水线
持续集成是软件项目成功的关键。通过持续集成自动化地执行代码静态检查、构建、测试,能够及时发现代码变更引入的问题,有效保障项目质量。Git 作为一个成功的开源项目,自然少不了持续集成。Git 的持续集成Git 项目使用邮件列表进行代码评审,即使后来 GitHub 在开源社区如日中天,Git 项目也仅仅把 GitHub 作为多个代码托管源之一,视 GitHub 为一个可有可无的存在。改变来自于 CI(
1996 0
Git 项目的 CI 流水线