前端规范工程-5:Git提交信息规范(commitlint + czg)

前面讲的都是在git提交之前的一些检查流程,然而我们git提交信息的时候,也应该是需要规范的。直接进入主题:

目录

    • 需安装插件清单
    • `commitlint` 介绍
    • 安装
    • 配置
    • 配置`commit-msg`钩子
    • 提交填写`commit`信息
    • czg
    • 后续
      • 方式一:push触动build并上传到ftp服务
      • 方案二:push触发CI/CD工作流

需安装插件清单

依赖描述
@commitlint/cligit提交规范检验工具,对提交信息的 message 规范进行校验
@commitlint/config-conventional基于 conventional commits 规范的配置文件
czg交互式命令行工具生成标准化的 git commit message

commitlint 介绍

在使用Git提交代码时,通常都需要填写提交说明,也就是Commit Message

git commit -m '提交测试'

说白了,Commit Message就是我们提交的时候,在-m后面写的提交说明,在小项目中基本是随意去写这个message的,但是当项目到了一定规模,什么东西都需要形成规范,包括这个提交Message,不然协同开发的同事根本不知道你这次提交到底是在干嘛,只能通过点开Git Graph查看明细,或口头阐述给对方。

当然,仅仅只是口头约束并没有实质上的作用,为了禁止不符合规范的Commit Message的提交,我们就需要采用一些工具,只有当开发者编写了符合规范的Commit Message才能够进行commit。而commitlint就是这样一种工具,通过结合husky一起使用,可以在开发者进行commit前就对Commit Message进行检查,只有符合规范,才能够进行commit

上面我们提到过,git最常用的钩子函数有两个,一个是pre-commit,前面我们已经对这个阶段需要做的规范做了介绍,并且还使用了lint-staged工具。另外一个常用的钩子函数就是commit-msg,在这个阶段,用到的工具就是commitlint

安装

需要下载两个依赖包:

pnpm add @commitlint/cli @commitlint/config-conventional -D

注意:现阶段由于stylelint版本的问题,可能会和之前的一些包产生冲突,如果你用的是npm,这里还是直接使用--legacy-peer-deps忽略到依赖冲突,后面的一些安装都有可能造成这个问题,就不再重复了。

通过 npm 安装时添加 --legacy-peer-deps 注意事项

在使用 npm 安装包时,--legacy-peer-deps 参数的作用是告诉 npm 在处理依赖关系时采用旧的(legacy)方式,而不是严格按照 npm 7 及更新版本的新规则来处理对等依赖(peer dependencies)。

从 npm 7 开始,npm 引入了一些更严格的对等依赖解析规则。这些规则要求依赖包必须显式地声明其对其他包的对等依赖,否则 npm 会给出警告或错误,并且可能会拒绝安装或更新这些依赖。

使用 --legacy-peer-deps 参数可以绕过这些新规则,采用更宽松的对等依赖解析方式,允许安装那些在新规则下可能会被拒绝的依赖。

假设你要安装一个依赖包 example-package,并且你知道这个包的依赖可能会与新的 npm 对等依赖规则冲突。你可以这样使用 --legacy-peer-deps

npm install @commitlint/cli @commitlint/config-conventional -D --legacy-peer-deps

这样 npm 将会使用旧的对等依赖解析方式来安装 example-package 及其依赖,而不会严格遵循 npm 7 的新规则。

注意了,使用 --legacy-peer-deps 应谨慎,因为它可能会导致依赖安装时出现不一致或错误的情况。只有在你确信使用旧规则不会影响项目稳定性或安全性时才应该使用这个参数。

依赖说明

依赖描述说明
@commitlint/config-conventional基于 conventional commits 规范的配置文件
@commitlint/clicommitlint 工具的核心

配置

具体的规范配置可以查看: conventional-changelog/commitlint

在项目根目录下创建配置文件 commitlint.config.cjs

# 使用命令行创建文件
echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.cjs

commitlint.config.cjs 内容:

module.exports = { extends: ['@commitlint/config-conventional'] };

以下是我经常使用的type-enum,这里定义的Commit Message就是继承了@commitlint/config-conventional规则集,这个规则集定义了Git 提交信息定义一致性格式,使得提交信息更易于理解和自动化处理。

feat:     新增功能
fix:      修复缺陷
docs:     文档变更
style:    代码格式
refactor: 代码重构
perf:     性能优化
test:     添加测试
build:    构建相关
ci:       持续集成修改
revert:   回滚到上一个版本
wip:      开发中
chore:    构建过程或辅助工具的变动

配置commit-msg钩子

上面的commitlint配置好之后,我们还需要commit-msg钩子函数触发

# V9
echo "npx --no-install commitlint --edit $1" > .husky/commit-msg

提交填写commit信息

现在我们提交的时候,就不需要再写git commit -m "提交测试"这种简单的message信息了。我们只需要执行git commit,钩子函数会自动帮我们弹出一个Vim风格的文本输入框。

Vim 是一款经典的文本编辑器,它拥有强大的编辑和操作功能,以下是一些常用的 Vim 风格操作:

  • i 进入插入模式,可以开始编辑文本。
  • Esc 退出插入模式,回到命令模式。
  • :wq 保存并退出编辑器。
  • :q! 放弃修改并退出编辑器。
  • dd 删除当前行。
  • yy 复制当前行。
  • p 粘贴复制的内容。

Vim文本编辑器,需要填写按规范提交。符合规范的Commit Message的提交格式如下,包含了页眉(header), 正文(body)页脚(footer) 三部分。其中,header是必须的,bodyfooter可以忽略。

type([scope]): subject
// 空一行
[body]
// 空一行
[footer]

在这里插入图片描述

需要注意的是,在commitlint.config.cjs配置了哪些类型,Commit Message时候type就只能哪些类型,想要更多的type类型,可以继承extends其他的规范集,或者自己写。

czg

上面Vim模式,这种需要开发者一个个输入commit信息的形式很容易出现问题,因此czg CLI做的事情很简单,就是帮我们提供了一个交互式撰写commit信息的插件。

  • 为什么选择czg CLI

    • 我们先来讲讲他的历史迭代。在czg还没问世之前,他的前身是Commitizen CLI + cz-git。然而cz-git一直以来都是作为Commitizen CLI的适配器,作者Q.Ben就是为了解决这种强依赖关系,所以开发了czg。这里简单的理解就是czg CLI = (Commitizen CLI + cz-git)
  • 特性优点

    • 🤖 OpenAI 支持. 让 AI 来辅助生成你 git commit 的描述信息

    • ⚡️ 轻量级 :零依赖项 (1.31MB)。

    • 🤗 简单且快速 : 无需前置配置,无需适配器,没有额外的步骤,你可以使用 npx | npm 脚本 | 全局下载... 在你的任何项目中快速启动。

    • 😎 高度可定制化 : 内部包含 cz-git 的核心,继承了 cz-git 的所有特性,具有相同的行为,配置加载… 你可以根据自己的需要配置的 CLI 的行为。

  • 在过去

    • 使用cz-git的安装使用流程
      npm install -g commitizen 
      npm install -D cz-git
      
      // package.json
      {"scripts": {"commit": "git-cz"},"config": {"commitizen": {"path": "node_modules/cz-git"}}
      }
      
  • 而现在

    • 使用 czg CLI 的安装使用流程
      npm install -g czg
      
      // package.json
      {{"scripts": {"cz": "czg"}}
      }
      
  • 总结

    • czg 无需任何前置配置
    • 在原有基础上拓展 cz-git 的基础功能
    • 启动速度更快
    • 更轻量化,使用 npx 在项目中启动使用
    • 当然,以上两种方案可以混用: 即 czg CLICommitizen CLI + cz-git
  • 参考

    • 心路历程
    • cz-git配置
    • 配置模板

🚀 安装

pnpm add czg -D

🚀 配置package.json脚本命令

"scripts": {//......其他省略"commit": "git add -A && czg && git push"
}

上面在scripts脚本中配置了commit命令,用来替代git commit,并且合并了git addgit push命令

📹 效果演示
在这里插入图片描述

根据上gif图演示,1、选择提交类型,2、自定义scope,3、输入commit。完成了一个简易的交互式提交,当然他的亮点并不是单单的提交,它结合了我之前写的规范工程篇章1~4的代码规范检查(检查暂存区文件)。

🚀 语法提示

下面我们需要对 commitlint.config.cjs 进一步配置成,在配置之前,我们需要添加 代码提示。添加 @type 到文件中:

/** @type {import('czg').UserConfig} */
module.exports = {// 其他代码
}

🚀 英译中

  • commitlint.config.cjs 文件内容:

    不推荐使用纯中文进行commit,因为终端对于中文输入的支持并不是很友好,并且在使用搜索时没有英文交互来得自然。
    推荐使用中英文对照,可以很好给予团队的新人帮助。

    module.exports = {// 其他代码prompt: {messages: {type: "Select the type of change that you're committing:",scope: "Denote the SCOPE of this change (optional):",customScope: "Denote the SCOPE of this change:",subject: "Write a SHORT, IMPERATIVE tense description of the change:\n",body: 'Provide a LONGER description of the change (optional). Use "|" to break new line:\n',breaking: 'List any BREAKING CHANGES (optional). Use "|" to break new line:\n',footerPrefixSelect: "Select the ISSUES type of changeList by this change (optional):",customFooterPrefix: "Input ISSUES prefix:",footer: "List any ISSUES by this change. E.g.: #31, #34:\n",confirmCommit: "Are you sure you want to proceed with the commit above?"// 中文对照// type: "选择你要提交的类型 :",// scope: "选择一个提交范围(可选):",// customScope: "请输入自定义的提交范围 :",// subject: "填写简短精炼的变更描述 :\n",// body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n',// breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n',// footerPrefixSelect: "选择关联issue前缀(可选):",// customFooterPrefix: "输入自定义issue前缀 :",// footer: "列举关联issue (可选) 例如: #31, #I3244 :\n",// confirmCommit: "是否提交或修改commit ?"},types: {{value: "feat",name: "feat:      |  A new feature",},{value: "fix",name: "fix:       |  A bug fix",},{value: "docs",name: "docs:      |  Documentation only changes",},{value: "style",name: "style:     |  Changes that do not affect the meaning of the code",},{value: "refactor",name: "refactor:  |  A code change that neither fixes a bug nor adds a feature",},{value: "perf",name: "perf:      |  A code change that improves performance",},{value: "test",name: "test:      |  Adding missing tests or correcting existing tests",},{value: "build",name: "build:     |  Changes that affect the build system or external dependencies",},{value: "ci",name: "ci:        |  Changes to our CI configuration files and scripts",},{value: "revert",name: "revert:    |  Reverts a previous commit",},{value: "wip",name: "wip:       |  Work in process",},{value: "chore",name: "chore:     |  Other changes that don't modify src or test files",}// 中文对照// { value: "feat", name: "特性:   |  新增功能" },// { value: "fix", name: "修复:   |  修复缺陷" },// { value: "docs", name: "文档:   |  文档变更" },// { value: "style", name: "格式:   |  代码格式(不影响功能,例如空格、分号等格式修正)" },// { value: "refactor", name: "重构:   |  代码重构(不包括 bug 修复、功能新增)" },// { value: "perf", name: "性能:    |  性能优化" },// { value: "test", name: "测试:   |  添加疏漏测试或已有测试改动" },// { value: "build", name: "构建:   |  构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)" },// { value: "ci", name: "集成:   |  修改 CI 配置、脚本" },// { value: "revert", name: "回退:   |  回滚 commit" },// { value: "wip", name: "开发:   |  正在开发中" },// { value: "chore", name: "其他:   |  对构建过程或辅助工具和库的更改(不影响源文件、测试用例)" }},}
    }
    

🚀 加入emoji

  • 要想实现直观、美观的 git 追踪流,添加 emoji 图标:

    module.exports = {// 其他代码prompt: {types: {{value: "feat",name: "feat:      ✨  A new feature",emoji: "✨"},{value: "fix",name: "fix:       🐛  A bug fix",emoji: "🐛"},{value: "docs",name: "docs:      📚  Documentation only changes",emoji: "📚"},{value: "style",name: "style:     🎨  Changes that do not affect the meaning of the code",emoji: "🎨"},{value: "refactor",name: "refactor:  🌈  A code change that neither fixes a bug nor adds a feature",emoji: "🌈"},{value: "perf",name: "perf:      ⚡️  A code change that improves performance",emoji: "⚡️"},{value: "test",name: "test:      🧪  Adding missing tests or correcting existing tests",emoji: "🧪"},{value: "build",name: "build:     📦  Changes that affect the build system or external dependencies",emoji: "📦"},{value: "ci",name: "ci:        🎡  Changes to our CI configuration files and scripts",emoji: "🎡"},{value: "revert",name: "revert:    ⏪️  Reverts a previous commit",emoji: "⏪️"},{value: "wip",name: "wip:       🕔  Work in process",emoji: "🕔"},{value: "chore",name: "chore:     🔨  Other changes that don't modify src or test files",emoji: "🔨"}// 中文对照// { value: "feat", name: "特性:   ✨  新增功能", emoji: "✨" },// { value: "fix", name: "修复:   🐛  修复缺陷", emoji: "🐛" },// { value: "docs", name: "文档:   📚  文档变更", emoji: "📚" },// { value: "style", name: "格式:   🎨  代码格式(不影响功能,例如空格、分号等格式修正)", emoji: "🎨" },// { value: "refactor", name: "重构:   🌈  代码重构(不包括 bug 修复、功能新增)", emoji: "🌈" },// { value: "perf", name: "性能:    ⚡️  性能优化", emoji: "⚡️" },// { value: "test", name: "测试:   🧪  添加疏漏测试或已有测试改动", emoji: "🧪" },// { value: "build", name: "构建:   📦️  构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)", emoji: "📦️" },// { value: "ci", name: "集成:   🎡  修改 CI 配置、脚本", emoji: "🎡" },// { value: "revert", name: "回退:   ⏪️  回滚 commit", emoji: "⏪️" },// { value: "wip", name: "开发:   🕔  正在开发中", emoji: "🕔" },// { value: "chore", name: "其他:   🔨  对构建过程或辅助工具和库的更改(不影响源文件、测试用例)", emoji: "🔨" }},useEmoji: true,emojiAlign: "center",}
    }
    

🚀 自定义配置scopes

光有 emoji 还不够!有时候为了其他明了展示你的修改区域范围,或给刚入职的萌新定位,我们还需要加入scopes,就是项目业务区,它能够使Git Graph更明确修改位置,配置:

// commitlint.config.cjs
const fs = require('node:fs')
const path = require('node:path')const packages = fs.readdirSync(path.resolve(__dirname, "src"), { withFileTypes: true }).filter(dirent => dirent.isDirectory());
module.exports = {rules: {'scope-enum': [2, 'always', [...packages]]}
}

🚀 最终效果展示

结合之前篇章1~4的代码格式化、语法校验等lint通过之后,才会正式提交到远端仓库

在这里插入图片描述

后续

🌈 上面提到,最后一个动作是 git push 命令,将本地代码更新到 远端仓库
那么它实际并未完成整个前端工作流程,那么我们还需要借助husky来处理自动化构建动作,触发它能做些什么呢?如:

方式一:push触动build并上传到ftp服务

  1. 配置husky监听git hooks (push),实现自动 build本地构建。
    • 通过nodejs:fs.readFileSync识别.git/HEAD工作区(即分支名),如果是测试分支或者生产分支,则构建,否则不触发构建动作。
  2. 构建完成通过ftp插件实现文件传输。
    • 配置ftp账号信息,供ftp插件调用;
    • 根据分支规则上传到对应ftp服务;

方案二:push触发CI/CD工作流

  1. 创建CI/CD流(gitlab、github)
    • 指定触发工作流的分支,如master
    • 定义每个阶段的任务、需要的镜像依赖等
  2. 触发动机
    • 手动push
    • CR分支合并;

以上两种方案
第一种学习成本相对较低,主要是在开发者本地运行;
第二种学习成本相对高,自定义方面强。包括设置任务延时发布(比如你可以选择在半夜更新)、重试机制和报警(邮件通知)等等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/880743.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux编译部署PHP环境

1.准备工作 安装前我们需要设置防护墙,开放端口,更新yum源 # 1.防火墙 systemctl status firewalld 看到active(running)就意味着防火墙打开了 systemctl stop firewalld 看到inactive(dead)就意味着防火墙关闭了 systemctl start fire…

深入理解Java中的垃圾回收机制

深入理解Java中的垃圾回收机制 大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿! Java的垃圾回收(Garbage Collection, GC)机制是Java语言的一大特色,它负责自动…

DataEase v2 开源代码 Windows 从0到1环境搭建

一、环境准备 功能名称 描述 其它 操作系统 Windows 数据库 Mysql8.0 开发环境 JDK17以上 本项基于的21版本开发 Maven 3.9版本 开发工具 idea2024.2版本 前端 VSCode TIPS:如果你本地有jdk8版本,需要切换21版本,请看…

Android中大量使用建造者模式(Builder Pattern)的原因可以归结为以下几点:

1. 解耦对象的构建与表示 建造者模式将复杂对象的构建过程与其表示分离,这使得同样的构建过程可以创建不同的表示。在Android开发中,许多组件和视图需要配置多个属性和参数,通过建造者模式可以清晰地将这些属性的设置与对象的实际构造过程分…

深入浅出MySQL事务处理:从基础概念到ACID特性及并发控制

1、什么是事务 在实际的业务开发中,有些业务操作要多次访问数据库。一个业务要发送多条SQL语句给数据库执行。需要将多次访问数据库的操作视为一个整体来执行,要么所有的SQL语句全部执行成功。如果其中有一条SQL语句失败,就进行事务的回滚&a…

RabbitMQ的应用问题

一、幂等性保障 幂等性是数学和计算机科学中某些运算的性质, 它们可以被多次应⽤, ⽽不会改变初始应⽤的结果 数学上的幂等性: f(x)f(f(x)) |x| 数据库操作幂等性: 数据库的 select 操作. 不同时间两次查询的结果可能不同, 但是这个操作是符合幂等性…

教务系统登录的分析

武汉纺织大学屏蔽了正方教务系统的默认登录页面,他们学校自定义的登录页面用户名和密码都是明文传输。可以使用Httpclient模拟登录。手动登录后,5次get请求才能获得真实的cookies。合肥工业大学需要3次。 第一次是POST请求。 Post请求的的下一个Location…

yum使用阿里云的镜像源报错 Failed connect to mirrors.aliyuncs.com:80; Connection refused“

报错:Failed connect to mirrors.aliyuncs.com:80; Connection refused",如果单独只是这个报错的话,那么原因是由于非阿里云ECS用户无法解析主机“mirrors.cloud.aliyuncs.com”。如果不单单只是这个报错另外还有其它报错请参考我其它文…

【SQL】筛选字符串与正则表达式

目录 语法 需求 示例 分析 代码 语法 SELECT column1, column2, ... FROM table_name WHERE condition; WHERE 子句用于指定过滤条件,以限制从数据库表中检索的数据。当你执行一个查询时,WHERE 子句允许你筛选出满足特定条件的记录。如果记录满…

[RabbitMQ] 7种工作模式详细介绍

🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…

Android Studio 新版本 Logcat 的使用详解

点击进入官方Logcat介绍 一个好的Android程序员要会使用AndroidStudio自带的Logcat查看日志,会Log定位也是查找程序bug的第一关键。同时Logcat是一个查看和处理日志消息的工具,它可以更快的帮助开发者调试应用程序。 步入正题,看图说话。 点…

特征工程——一门提高机器学习性能的艺术

当前围绕人工智能(AI)和机器学习(ML)展开的许多讨论以模型为中心,聚焦于 ML和深度学习(DL)的最新进展。这种模型优先的方法往往对用于训练这些模型的数据关注不足,甚至完全忽视。类似MLOps的领域正迅速发展,通过系统性地训练和利用ML模型&…

Hive SQL业务场景:连续5天涨幅超过5%股票

一、需求描述 现有一张股票价格表 dwd_stock_trade_dtl 有3个字段分别是: 股票代码(stock_code), 日期(trade_date), 收盘价格(closing_price) 。 请找出满足连续5天以上(含)每天上涨超过5%的股票,并给出连续满足…

C++入门基础知识93(实例)——实例18【猴子吃桃问题】

成长路上不孤单😊😊😊😊😊😊 【14后😊///C爱好者😊///持续分享所学😊///如有需要欢迎收藏转发///😊】 今日分享关于猴子吃桃问题的相关内容! 关…

IP协议讲解

IP协议 IP协议的本质:提供一种能力,将数据跨网络从A主机传输到B主机 4位版本号(version): 指定IP协议的版本, 对于IPv4来说, 就是4. 4位头部长度(header length): IP头部的长度是多少个32bit, 也就是 length * 4 的字节数. 4bit表示最大 的数字是15, 因…

天坑!Spark+Hive+Paimon+Dolphinscheduler

背景: 数据中台项目使用Spark+Hive+Paimon做湖仓底层,调度任务使用的是基于Dolphinscheduler进行二开。在做离线脚本任务开发时,在Paimon库下执行非查询类SQL报错。 INSERT报错 DELETE报错 现状: 原始逻辑为数据中台中选择的Paimon数据源,实际上在Dolphinscheduler中是…

synchronized关键字的作用、使用场景及锁升级过程。ReentrantLock与synchronized的区别及适用场景。

synchronized关键字的作用、使用场景及锁升级过程。 synchronized关键字的作用 synchronized是Java中的一个关键字,主要用于实现线程之间的同步。它的主要作用包括: 确保线程互斥地访问同步代码:当一个线程进入synchronized代码块或方法时&…

视频集成与融合项目中需要视频编码,但是分辨率不兼容怎么办?

在众多视频整合项目中,一个显著的趋势是融合多元化的视频资源,以实现统一监管与灵活调度。这一需求促使项目团队不断探索新的集成方案,确保不同来源的视频流能够无缝对接,共同服务于统一的调看与管理平台,进而提升整体…

TI DSP TMS320F280025 Note13:CPUtimer定时器原理分析与使用

TMS320F280025 CPUtimer定时器原理分析与使用 ` 文章目录 TMS320F280025 CPUtimer定时器原理分析与使用框图分析定时器中断定时器使用CPUtimers.cCPUtimers.h框图分析 定时器框图如图所示 定时器有一个预分频模块和一个定时/计数模块, 其中预分频模块包括一个 16 位的定时器分…

【机器学习基础】Transformer学习

Transformer学习 梯度消失FeedForward层激活函数的主要作用是在网络中加入非线性变换 梯度消失 梯度爆炸 FeedForward层 Transformer结构: Transformer结构主要分为两大部分: 一是Encoder层结构:Encoder 的输入由 Input Embedding 和 Positional Embedding 求和输入Multi…