NodeJs에서 프로처럼 커밋하기: 메시지

메시지가 중요한 이유는 무엇입니까?



커밋 메시지는 팀 내에서 매일 수행하는 공동 작업의 일부이며 발생한 일에 대한 기록으로 작동합니다.

Every time you perform a commit, you’re recording a snapshot of your project that you can revert to or compare to later.

— Pro Git Book



커밋 메시지는 다음을 포함하여 다양한 방식으로 사용됩니다.
  • 향후 독자가 변경된 사항과 변경된 이유를 빠르게 이해할 수 있도록 돕기 위해
  • 특정 변경 사항을 쉽게 실행 취소하도록 지원
  • 릴리스에 대한 변경 노트 또는 범프 버전을 준비하려면

  • 이 세 가지 사용 사례 모두 깨끗하고 일관된 커밋 메시지 스타일이 필요합니다.

    Commitizen으로 간편한 커밋 메시지



    이 도구의 목적은 규칙을 커밋하고 전달하는 표준 방법을 정의하는 것입니다. 그 이유는 읽기가 더 쉽고 설명적인 커밋 작성을 강제하기 때문입니다. 옵션의 모호함과 수동으로 표준을 따르는 정신적 부담을 제거합니다.

    Commitizen은 최종 커밋 메시지를 생성하는 일련의 질문을 표시합니다. 어댑터가 여러 개 있는데 제 경우에는 질문을 제어하는 ​​것을 선호하므로 cz-format-extension 을 사용합니다.



    다음 명령줄을 사용하여 프로젝트에 commitizen을 추가할 수 있습니다.

    npm install commitizen --save-dev # npm
    yarn add commitizen -D  # Yarn
    


    내 경우에는 adapters 사용 가능한 cz-format-extension 중 하나를 추가하십시오.

        npm install cz-format-extension --save-dev # npm
        yarn add cz-format-extension -D  # Yarn
    

    package.json에서 다음 섹션을 추가해야 합니다.

      ...
      "config": {
        ...
        "commitizen": {
          "path": "cz-format-extension"
        }
      }
      ...
    


    어댑터cz-format-extension.czfrec.js 파일에서 질문을 정의할 수 있으므로 엄청난 유연성을 허용합니다. 예를 들면 다음과 같습니다.

    const { contributors } = require('./package.json')
    
    module.exports = {
      questions({inquirer}) {
        return [
          {
            type: "list",
            name: "type",
            message: "'What is the type of this change:",
            choices: [
               {
                  type: "list",
                  name: "type",
                  message: "'What is the type of this change:",
                  choices: [
              {
                "name": "feat: A new feature",
                "value": "feat"
              },
              {
                "name": "fix: A bug fix",
                "value": "fix"
              },
              {
                "name": "docs: Documentation only changes",
                "value": "docs"
              },
              ...
            ]
          },
          {
            type: 'list',
            name: 'scope',
            message: 'What is the scope of this change:',
            choices: [
                {
                  "name": "core: base system of the application",
                  "value": "core"
                },
                {
                  "name": "extensions: systems that are observed",
                  "value": "extensions"
                },
                {
                  "name": "tools: other things in the project",
                  "value": "tools"
                },
            ]
          },
          {
            type: 'input',
            name: 'message',
            message: "Write a short, imperative tense description of the change\n",
            validate: (message) => message.length === 0 ? 'message is required' : true
          },
          {
            type: 'input',
            name: 'body',
            message: 'Provide a longer description of the change: (press enter to skip)\n',
          },
          {
            type: 'confirm',
            name: 'isBreaking',
            message: 'Are there any breaking changes?',
            default: false
          },
          {
            type: 'input',
            name: 'breaking',
            message: 'Describe the breaking changes:\n',
            when: answers => answers.isBreaking
          },
          {
            type: 'confirm',
            name: 'isIssueAffected',
            message: 'Does this change affect any open issues?',
            default: false
          },
          {
            type: 'input',
            name: 'issues',
            message: 'Add issue references:\n',
            when: answers => answers.isIssueAffected,
            default: undefined,
            validate: (issues) => issues.length === 0 ? 'issues is required' : true
          },
          {
            type: 'checkbox',
            name: 'coauthors',
            message: 'Select Co-Authors if any:',
            choices: contributors.map(contributor => ({
                name: contributor.name,
                value: `Co-authored-by: ${contributor.name} <${contributor.email}>`,
            }))
          },
        ]
      },
      commitMessage({answers}) {
        const scope = answers.scope ? `(${answers.scope})` : '';
        const head = `${answers.type}${scope}: ${answers.message}`;
        const body = answers.body ? answers.body : '';
        const breaking = answers.breaking ? `BREAKING CHANGE: ${answers.breaking}` : '';
        const issues = answers.issues ? answers.issues : '';
        const coauthors = answers.coauthors.join('\n');
    
        return [head, body, breaking, issues, coauthors].join('\n\n').trim()
      }
    }
    


    이 파일은 다음에 대한 질문 프로세스를 생성합니다.
  • 유형: 시맨틱 릴리스 메시지 사양과 일치
  • 범위: 애플리케이션의 영향을 받는 부분
  • 메시지: 명령형 서면 메시지
  • 본문: 자세한 설명
  • 중단: 시맨틱 릴리스를 위한 주요 변경 사항인지 확인하기 위해
  • 문제: 발권 시스템 관련 문제
  • 공동 저자: 페어 프로그래밍 중에 작업에 참여하는 사람들

  • 이 모든 질문은 수동 작업을 수행하는 두뇌의 힘이 아니라 대화식으로 질문됩니다.

    그런 다음 로컬 버전의 Commitizen을 가리키는 멋진 npm 스크립트를 package.json 파일에 추가할 수 있습니다.

      ...
      "scripts": {
        "commit": "cz"
      }
    

    이렇게 하면 사용자가 커밋을 원하는 경우 실행만 하면 되고npm run commit 커밋을 시작하는 데 필요한 프롬프트가 표시되므로 사용자에게 더 편리합니다!

    NOTE: If you are using precommit hooks thanks to something like husky, you will need to name your script something other than "commit" (e.g. "cm": "cz"). The reason is because npm scripts has a "feature" where it automatically runs scripts with the name prexxx where xxx is the name of another script. In essence, npm and husky will run "precommit" scripts twice if you name the script "commit", and the workaround is to prevent the npm-triggered precommit script.



    그게 전부입니다 :) . 커밋 메시지를 린트하는 데 매우 유용한 도구인 commitlint에 대해 특별히 언급하겠습니다. commitizen과 겹치는 부분이 있어 더 이상 사용하지 않습니다.

    좋은 웹페이지 즐겨찾기