팀의 커밋 컨벤션이 정해졌다.
이모지를 활용한 커밋 컨벤션인데 깃모지는 아니다.
익숙한 방식이 아니고 이모지도 입력해야하므로 CLI가 있으면 좋을 것 같다고 생각했다.
그래서 검색하다가 다른 좋은 패키지들도 알게되었다.
{
"scripts": {
"commit": "git-cz"
},
"config": {
"commitizen": {
"path": "@commitlint/cz-commitlint"
}
}
}
커밋 컨벤션에 맞지 않게 커밋을 하려고 하면 에러를 발생시키는 방법이 있다.
GitHooks 활용하면 된다.
하지만 githook은 공유하기 어렵고, 실수로 적용하지 않을 수도 있다는 단점이 있다.
그래서 githook을 적용하기 쉽게 해주는 Husky를 사용한다.
그리고 커밋이 컨벤션에 맞는지 확인해주는 commitlint를 설치한다.
husky 사용시 이점은 가비아 라이브러리의 글에 잘 정리되어 있다.
https://library.gabia.com/contents/8492/
npm install husky --save-dev
npx husky init
npm install --save-dev @commitlint/config-conventional @commitlint/cli
(옵션) 커밋 컨벤션에 맞게 커밋을 작성하는 것을 도와주는 CLI도 설치해준다.
npm install --save-dev @commitlint/cz-commitlint commitizen inquirer@9
여기까지 하면 .husky 폴더가 생기는데
echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg
이 명령어를 입력해주면 커밋시에 commitlint를 거치게 하는 코드를 commit-msg 파일에 적어주게 된다.
그리고 package.json에 다음을 추가해준다
{
"scripts": {
"commit": "git-cz"
},
"config": {
"commitizen": {
"path": "@commitlint/cz-commitlint"
}
}
}
루트 디렉토리에 commitlint.config.ts 라는 파일을 만들고 아래와 같이 적어준다.
import {
RuleConfigCondition,
RuleConfigSeverity,
TargetCaseType,
} from '@commitlint/types';
export default {
parserPreset: 'conventional-changelog-conventionalcommits',
rules: {
'body-leading-blank': [RuleConfigSeverity.Warning, 'always'] as const,
'body-max-line-length': [RuleConfigSeverity.Error, 'always', 100] as const,
'footer-leading-blank': [RuleConfigSeverity.Warning, 'always'] as const,
'footer-max-line-length': [
RuleConfigSeverity.Error,
'always',
100,
] as const,
'header-max-length': [RuleConfigSeverity.Error, 'always', 100] as const,
'header-trim': [RuleConfigSeverity.Error, 'always'] as const,
'subject-case': [
RuleConfigSeverity.Error,
'never',
['sentence-case', 'start-case', 'pascal-case', 'upper-case'],
] as [RuleConfigSeverity, RuleConfigCondition, TargetCaseType[]],
'subject-empty': [RuleConfigSeverity.Error, 'never'] as const,
'subject-full-stop': [RuleConfigSeverity.Error, 'never', '.'] as const,
'type-case': [RuleConfigSeverity.Error, 'always', 'lower-case'] as const,
'type-empty': [RuleConfigSeverity.Error, 'never'] as const,
'type-enum': [
RuleConfigSeverity.Error,
'always',
[
'build',
'chore',
'ci',
'docs',
'feat',
'fix',
'perf',
'refactor',
'revert',
'style',
'test',
],
] as [RuleConfigSeverity, RuleConfigCondition, string[]],
},
prompt: {
questions: {
type: {
description: "Select the type of change that you're committing",
enum: {
feat: {
description: 'A new feature',
title: 'Features',
emoji: '✨',
},
fix: {
description: 'A bug fix',
title: 'Bug Fixes',
emoji: '🐛',
},
docs: {
description: 'Documentation only changes',
title: 'Documentation',
emoji: '📚',
},
style: {
description:
'Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)',
title: 'Styles',
emoji: '💎',
},
refactor: {
description:
'A code change that neither fixes a bug nor adds a feature',
title: 'Code Refactoring',
emoji: '📦',
},
perf: {
description: 'A code change that improves performance',
title: 'Performance Improvements',
emoji: '🚀',
},
test: {
description: 'Adding missing tests or correcting existing tests',
title: 'Tests',
emoji: '🚨',
},
build: {
description:
'Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)',
title: 'Builds',
emoji: '🛠',
},
ci: {
description:
'Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)',
title: 'Continuous Integrations',
emoji: '⚙️',
},
chore: {
description: "Other changes that don't modify src or test files",
title: 'Chores',
emoji: '♻️',
},
revert: {
description: '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".)',
},
},
},
};
이렇게 하면 원래 끝이다.
npm run commit 이라고 입력하면 CLI로 commit도 작성할 수 있다.
하지만 2024.03.04 기준으로 패키지가 업데이트 되면서 오류가 있는 것 같다.
https://github.com/conventional-changelog/commitlint/issues/3949
이 오류가 해결되면 정상적으로 실행될 것 같다.
++
2024.04.29기준 해결되어 잘 작동한다
잘 작동하는 버전은 아래와 같다
{
"devDependencies": {
"@commitlint/cli": "^19.2.1",
"@commitlint/config-conventional": "^19.1.0",
"@commitlint/cz-commitlint": "^19.2.0",
"commitizen": "^4.3.0",
"husky": "^9.0.11",
"inquirer": "^9.2.17"
}
}