前言:在使用git提交代码过程中,git commit的规范常不被大多数人注意,然而版本管理工具中,代码的提交规范对项目的后续维护有着很重要的作用。故本文从以下几个方面展开述说工程开发中git commit优化的几个工具:
- commitizen:简单的 commit 规范
- cz-conventional-changelog:执行会将项目npm发布新版本,并自动生成CHANGELOG.md文件
- husky:Git的钩子,在此作用为代码的提交规范和规范的校验
- commitlint:格式校验工具
- standard-version:辅助 cz-conventional-changelog 打 version 等功能
eslint
- 下载:https://eslint.org/docs/latest/use/getting-started#quick-start
- package.json中配置命令:
"lint": "eslint .",
prettier
- 下载:https://prettier.io/docs/en/install
- package.json中配置命令:
"format": "prettier --write .",
prettier-plugin-tailwindcss
- 格式化tailwindcss的排序
- 下载:https://github.com/tailwindlabs/prettier-plugin-tailwindcss
- 官方提供的排序方式:https://tailwindcss.com/blog/automatic-class-sorting-with-prettier#how-classes-are-sorted
prettier-plugin-merge
- prettier可以合并多个插件
- 下载:https://github.com/ony3000/prettier-plugin-merge
husky
commitlint
eg:react版本的问题
> git -c user.useConfigOnly=true commit --quiet --allow-empty-message --file -
> vite-react-typescript-starter@0.0.0 lint
> eslint .
Warning: React version not specified in eslint-plugin-react settings. See https://github.com/jsx-eslint/eslint-plugin-react#configuration .
D:\project\DF.JackYun.Web.Common\core-r\commitlint.config.js
1:0 error Parsing error: File appears to be binary
✖ 1 problem (1 error, 0 warnings)
husky - pre-commit script failed (code 1)
eg:文件格式的问题
D:\project\DF.JackYun.Web.Common\core-r\commitlint.config.js
1:0 error Parsing error: File appears to be binary
✖ 1 problem (1 error, 0 warnings)
PS D:\project\DF.JackYun.Web.Common\npm run lint
> vite-react-typescript-starter@0.0.0 lint
> eslint .
文件编码要改为UTF-8
eg:如果没有按照规则提交commit会报以下错
> git -c user.useConfigOnly=true commit --quiet --allow-empty-message --file -
> vite-react-typescript-starter@0.0.0 lint
> eslint src
> vite-react-typescript-starter@0.0.0 commitlint
> commitlint --edit
⧗ input: husky commitlint
✖ subject may not be empty [subject-empty]
✖ type may not be empty [type-empty]
✖ found 2 problems, 0 warnings
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
husky - commit-msg script failed (code 1)
- commitlint默认配置:https://github.com/conventional-changelog/commitlint/blob/master/%40commitlint/config-conventional/src/index.ts
commitlint with prompt
@commitlint/prompt-cli
PS D:\project\DF.JackYun.Web.Common\core-r> npm run commit
> vite-react-typescript-starter@0.0.0 commit
> commit
Please enter a type: [required] [tab-completion] [header]
<type> holds information about the goal of a change.
<type>(<scope>): <subject>
<body>
<footer>
? type: feat
Please enter a scope: [optional] [header]
<scope> marks which sub-component of the project is affected
feat(<scope>): <subject>
<body>
<footer>
? scope: all
Please enter a subject: [required] [header]
<subject> is a short, high-level description of the change
feat(all): <subject>
<body>
<footer>
? subject: add commitlint prompt
Please enter a body: [optional] [multi-line]
<body> holds additional information about the change
feat(all): add commitlint prompt
<body>
<footer>
? body:
use origin commitlint prompt feature.
Please enter a footer: [optional] [multi-line]
<footer> holds further meta data, such as breaking changes and issue ids
feat(all): add commitlint prompt
use origin commitlint prompt feature.
<footer>
? footer:
footer some info
> vite-react-typescript-starter@0.0.0 lint
> eslint src
> vite-react-typescript-starter@0.0.0 commitlint
> commitlint --edit
[main 9ccb26e] feat(all): add commitlint prompt
2 files changed, 637 insertions(+), 1 deletion(-)
- 官网也列举其他prompt工具:https://commitlint.js.org/guides/use-prompt.html#an-alternative-to-commitlint-prompt-cli-commitizen
⛔@commitlint/prompt
- 是由于 @commitlint/prompt 模块使用了 ES Module 格式,而 commitizen 还在使用 CommonJS 的 require() 方式导入模块所导致的兼容性问题。
- 社区解决方案:https://github.com/conventional-changelog/commitlint/issues/3949
- 参考https://github.com/conventional-changelog/commitlint/issues/3949#issuecomment-1993735126,不再使用@commitlint/prompt(需要添加一个额外adapt脚本),转而使用第二种prompt方案————@commitlint/cz-commitlint。
✅@commitlint/cz-commitlint
PS D:\project\DF.JackYun.Web.Common\core-r> npm run commit
> vite-react-typescript-starter@0.0.0 commit
> git-cz
cz-cli@4.3.1, @commitlint/cz-commitlint@19.5.0
? Select the type of change that you're committing: feat
? What is the scope of this change (e.g. component or file name) (press enter to skip): (max 96 chars)
(12) package.json
? Write a short, imperative tense description of the change: (max 82 chars)
(29) add @commitlint/cz-commitlint
? Provide a longer description of the change (press enter to skip):
add other prompt method
? Are there any breaking changes?: No
? Does this change affect any open issues?: No
> vite-react-typescript-starter@0.0.0 lint
> eslint src
> vite-react-typescript-starter@0.0.0 commitlint
> commitlint --edit
[main b1bc10b] feat(package.json): add @commitlint/cz-commitlint
2 files changed, 648 insertions(+), 1 deletion(-)
commitlint with emoji
修改commitlint.config.js
配置,自定义header正则规则
const RuleConfigSeverity = {
Disabled: 0,
Warning: 1,
Error: 2
}
export default {
extends: ['@commitlint/config-conventional'],
parserPreset: {
parserOpts: {
headerPattern: /^(?<type>:[a-z_]+:\s\w+)(?:\((?<scope>.*)\))?!?:\s(?<subject>(?:(?!#).)*(?:(?!\s).))$/,
headerCorrespondence: ['type', 'scope', 'subject']
}
},
rules: {
'body-leading-blank': [RuleConfigSeverity.Warning, 'always'],
'body-max-line-length': [RuleConfigSeverity.Error, 'always', 100],
'footer-leading-blank': [RuleConfigSeverity.Warning, 'always'],
'footer-max-line-length': [
RuleConfigSeverity.Error,
'always',
1,
],
'header-max-length': [RuleConfigSeverity.Error, 'always', 100],
'header-trim': [RuleConfigSeverity.Error, 'always'],
'subject-case': [
RuleConfigSeverity.Error,
'never',
['sentence-case', 'start-case', 'pascal-case', 'upper-case'],
],
'subject-empty': [RuleConfigSeverity.Error, 'never'],
'subject-full-stop': [RuleConfigSeverity.Error, 'never', '.'],
'type-case': [RuleConfigSeverity.Error, 'always', 'lower-case'],
'type-empty': [RuleConfigSeverity.Error, 'never'],
'type-enum': [
RuleConfigSeverity.Error,
'always',
[
':sparkles: feat',
':bug: fix',
':pencil2: docs',
':lipstick: style',
':recycle: refactor',
':zap: perf',
':white_check_mark: test',
':rocket: chore',
':rewind: revert',
':package: build',
':construction_worker: ci',
],
],
},
prompt: {
questions: {
type: {
description: "Select the type of change that you're committing",
enum: {
':sparkles: feat': {
description: '✨ feat -> A new feature',
title: 'Features',
emoji: '✨',
},
':bug: fix': {
description: '🐛 fix -> A bug fix',
title: 'Bug Fixes',
emoji: '🐛',
},
':pencil2: docs': {
description: '📚 docs -> Documentation only changes',
title: 'Documentation',
emoji: '📚',
},
':lipstick: style': {
description: '💎 style -> Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)',
title: 'Styles',
emoji: '💎',
},
':recycle: refactor': {
description: '📦 refactor -> A code change that neither fixes a bug nor adds a feature',
title: 'Code Refactoring',
emoji: '📦',
},
':zap: perf': {
description: '🚀 perf -> A code change that improves performance',
title: 'Performance Improvements',
emoji: '🚀',
},
':white_check_mark: test': {
description: '🚨 test -> Adding missing tests or correcting existing tests',
title: 'Tests',
emoji: '🚨',
},
':package: build': {
description: '🛠 build -> Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)',
title: 'Builds',
emoji: '🛠',
},
':construction_worker: ci': {
description: '⚙️ ci -> Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)',
title: 'Continuous Integrations',
emoji: '⚙️',
},
':rocket: chore': {
description: '♻️ chore -> Other changes that don\'t modify src or test files',
title: 'Chores',
emoji: '♻️',
},
':rewind: revert': {
description: '🗑 revert -> Reverts a previous commit',
title: 'Reverts',
emoji: '🗑',
},
},
},
scope: {
description: 'What is the scope of this change (e.g. component or file name)',
},
subject: {
description: 'Write a short, imperative tense description of the change',
},
body: {
description: 'Provide a longer description of the change',
},
isBreaking: {
description: 'Are there any breaking changes?',
},
breakingBody: {
description: 'A BREAKING CHANGE commit requires a body. Please enter a longer description of the commit itself',
},
breaking: {
description: 'Describe the breaking changes',
},
isIssueAffected: {
description: 'Does this change affect any open issues?',
},
issuesBody: {
description: 'If issues are closed, the commit requires a body. Please enter a longer description of the commit itself',
},
issues: {
description: 'Add issue references (e.g. "fix #123", "re #123".)',
},
},
},
};;
semantic-release
⛔node环境要求
- 对node环境有要求,需要
20.8.1+
[semantic-release]: node version >=20.8.1 is required. Found v18.20.2.
See https://github.com/semantic-release/semantic-release/blob/master/docs/support/node-version.md for more details and solutions.
⛔本地执行
- 执行
npx semantic-release
- 报错(没有权限)
- GitHub Token未设置报错
[09:44:44] [semantic-release] » ℹ Start step "verifyConditions" of plugin "@semantic-release/github"
[09:44:44] [semantic-release] [@semantic-release/github] » ℹ Verify GitHub authentication
[09:44:44] [semantic-release] » ✘ Failed step "verifyConditions" of plugin "@semantic-release/github"
[09:44:44] [semantic-release] » ⚠ Skip step "fail" of plugin "@semantic-release/github" in dry-run mode
[09:44:44] [semantic-release] » ✘ ENOGHTOKEN No GitHub token specified.
A GitHub personal token (https://github.com/semantic-release/github/blob/master/README.md#github-authentication) must be created and set in the GH_TOKEN or GITHUB_TOKEN environment variable on your CI environment.
Please make sure to create a GitHub personal token (https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line) and to set it in the GH_TOKEN or GITHUB_TOKEN environment variable on your CI environment. The token must allow
to push to the repository wztlink1013/vite-react.
AggregateError:
SemanticReleaseError: No GitHub token specified.
- 使用ci执行自动让GitHub打标签发版
name: Release
on:
push:
branches:
- main
permissions:
contents: read # for checkout
jobs:
release:
permissions:
contents: write # to be able to publish a GitHub release
issues: write # to be able to comment on released issues
pull-requests: write # to be able to comment on released pull requests
id-token: write # to enable use of OIDC for npm provenance
name: release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: npm
node-version: lts/*
- run: npm clean-install
- run: corepack npm audit signatures
- run: npx semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
Others
others
- 版本构建:standard-version: 自动生成 CHANGELOG
下载插件
cnpm i --save-dev standard-version
package.json添加如下
{
"scripts": {
"release": "standard-version"
}
}
执行npm run release,在根目录会生成CHANGELOG.md文件
评论区