For a long time, we are not limited to this situation: Every member of the team submits code in a random way. There is no specification, and it is even more difficult to locate a commit record after a problem, or add a specification like CommitLint, and there is no change log to record the main content of each release, and release automation. This article starts with Git commit, automatically generates CHANGELOG, and then releases the version of the standard automation tool three aspects, one-stop solution to these problems.

preface

Every time Git commits code, write a Commit message, otherwise Commit is not allowed.

$ git commit -m "hello world"
Copy the code

The -m parameter in the code above is used to specify the commit mesage.

If one line is not enough, you can simply execute git Commit and the text editor will pop up and let you write multiple lines.

$ git commit
Copy the code

Basically, you can write anything (here, here and here).

However, in general, the Commit message should be clear and state the purpose of the commit.

\

There are currently several community specifications for how to write Commit messages. This article introduces the Angular specification (see figure above), which is the most widely used, rational, systematic, and tool-ready.

Git commit specification

1. Commit Message format

Formatted Commit Messages have several benefits.

(1) Provide more historical information for quick browsing.

For example, the following command shows the changes since the last release, with each commit occupying one line. You know the purpose of a commit just by looking at the top of the line.

$ git log <last tag> HEAD --pretty=format:%s

(2) You can filter certain commits (such as document changes) to make it easy to find information quickly.

For example, the command below shows only the functionality added to this release.

$ git log <last release> HEAD --grep feature

(3) You can generate Change log directly from COMMIT.

The Change Log is a document used to explain the differences between a new release and the previous release, as described below.

2. Format the Commit message

For each Commit, the Commit message consists of three parts: Header, Body, and Footer.

< type > (< scope >) : < subject > / / short line < body > / / short line < footer >Copy the code

The Header is required, and the Body and Footer can be omitted.

No line should be longer than 72 characters (or 100 characters) in any section. This is to avoid the aesthetics of wrapping.

2.1 the Header

The Header section is a single line with three fields: Type (required), scope (optional), and subject (required).

(1) type

Type indicates the type of commit. Only the following seven identifiers are allowed.

  • Feat: New Feature
  • Fix: Fixes bugs
  • -Jenny: There are some docs.
  • Style: format (changes that do not affect code execution)
  • Refactor: refactoring (i.e. code changes that are not new features or bug fixes)
  • Test: Adds a test
  • Chore: Changes to the build process or helper
  • Perf: Improves performance \

If type is feat and fix, the commit will definitely appear in the Change log. The other cases (Docs, chore, Style, Refactor, test) are up to you to decide whether to add the Change log or not, and the recommendation is not to.

(2) the scope

Scope is used to specify the scope of the commit impact, such as the data layer, control layer, view layer, and so on, depending on the project.

(3) the subject

Subject is a short description of the commit purpose, no more than 50 characters long.

  • Start with a verb and use the present first-person tense such as’ change ‘rather than’ changed ‘or’ changes’
  • The first letter is lowercase
  • Ending without a period (.)
<type>(<scope>): │ │ ├ ─ ├ ─ sci-press (⫸) │ ├ ─ sci-press <short summary> │ │ │ ├ ─ sci-press (⫸) │ │ ├ ─ sci-press (⫸) The scope should be The name of The component affected │ (as perceived by The person reading The │ changelog generated The from the commit messages). │ └ ─ ⫸ commit Type: build | ci | docs | feat | fix | perf | refactor | testCopy the code

2.2 the Body

The Body section is a detailed description of the commit, broken into multiple lines. Here’s an example.

More detailed explanatory text, if necessary. Wrap it to about 72 characters or so. Further paragraphs come after blank lines. – Bullet points are okay, too – Use a hanging indent

There are two caveats.

(1) Use the present tense of the first person, such as “change” rather than “changed” or “changes”.

(2) Explain the motivation for the code change and how it compares to previous actions.

2.3 the Footer

The Footer section is only used in two cases.

(1) Incompatible changes

If the current code is incompatible with the previous version, the Footer section begins with BREAKING CHANGE, followed by a description of the CHANGE, the reason for the CHANGE, and the migration method. BREAKING CHANGE: isolate scope bindings definition has changed. To migrate the code follow the example below: Before: scope: { myAttr: ‘attribute’, } After: scope: { myAttr: ‘@’, } The removed inject wasn’t generaly useful for directives so there should be no code using it.

(2) Close the Issue

If the current commit is for an issue, you can close the issue in the Footer section.

Closes #234

It is also possible to close multiple issues at once.

Closes #123, #245, #992

2.4 Revert

In a special case, if the current COMMIT is used to undo a previous COMMIT, you must start with REVERT:, followed by the headers of the revoked commit.

revert: feat(pencil): add ‘graphiteWidth’ option This reverts commit 667ecc1654a317a13331b17617d973392f415f02.

The format of the Body part is fixed. It must be written as This reverts commit <hash>. The hash is the SHA identifier of the revoked commit.

If the current commit is in the same release as the revoked commit, neither of them will appear in the Change log. If the two are published at different times, the current commit appears under the Reverts subheading of the Change log.

3. Interactive Commit Message generator: Commitizen

Commitizen is a tool for creating submissions interactively. It helps us set up the submission information step by step, starting with Type.

The installation command is as follows.

$ npm install -g commitizen
Copy the code

3.1 Verifying the Commit Message Format Forcibly

In daily development, we can enforce the specification with CommitLint + Husky to ensure that commit messages are written according to the specification. The principle is to use git hooks to validate information before the actual Git commit is committed to the remote repository, preventing non-conforming information from being committed to the remote repository.

  • Commitlint can help verify that our Commit message complies with the format specification.

  • Huskey: Git hooks made easy.
    • You can use it to lint your commit messages, run tests, lint code, etc… when you commit or push. Husky supports all Git hooks.

Generate Change log

conventional-changelog-cli

The convention-Changelog-CLI default recommended commit standard is from Angular projects. In addition to the Angular standard, It currently includes standards for Atom, Codemirror, Ember, ESLint, Express, jquery, and more.

The installation

# Help conventional-changelog --help
$ npm install -g conventional-changelog-cli
Copy the code

The basic use

$ conventional-changelog -p angular -i CHANGELOG.md -s

The -p angular parameter specifies the commit Message standard to use, or if you want to use atom:

$ conventional-changelog -p atom -i CHANGELOG.md -s

Parameter -i Changelog. md Reads CHANGELOG from Changelog. md. -s reads and writes CHANGELOG to the same file. Note that the changelog generated by this command is based on Changes (Feature, Fix, Breaking Changes, etc.) since the last tag version. So if you want to generate changelog from all the previous commit messages, you need to use this command:

$ conventional-changelog -p angular -i CHANGELOG.md -s -r 0

-r indicates the number of release versions required to generate Changelog. The default value is 1, and the value of all release versions is 0.

Custom parameters

Some common content in the generated Changlog can be changed on demand with custom parameters, such as version number, COMMIT address, and so on. The version number generated in Changelog is derived from the Version field in package.json. We need to change the repository address in package.json. The default issuse connection address in Changelog is also generated from repository. If you are using a third-party collaboration system (such as Bitbucket), then you can use the conventional- Changelog-Angular-Bitbucket standard. Or as we used Redmine to manage issSUE, we can use the Replace tool to handle the original address in the text after generating Changelog:

$ replace 'https://github.com/myproject/issues/' 'https://redmine.example.com' CHANGELOG.md

Finally, take a look at the general result:

More configurations of conventional- Changelog options can be seen here.

The sum of the sample

  • Install dependencies

    • @ commitlint/cli, @ commitlint/config – but

      • Commit Message format verification tool to verify that the message format complies with specifications.
    • husky

      • Git hook: a git hook that calls commitLint to verify a COMMIT message at commit time
    • But – the changelog – cli, but – changelog

      • The CHANGELOG tool is automatically generated based on git submission history.
npm install --save-dev @commitlint/cli @commitlint/config-conventional
npm install --save-dev conventional-changelog conventional-changelog-cli
npm install --save-dev husky
Copy the code
  • Configure commitLint (commitlint.config.js)
module.exports = { 
    extends: ['@commitlint/config-conventional']};Copy the code
  • Configuring git Hooks
{ 
    "husky": { 
        "hooks": { 
            "commit-msg": "npx commitlint -E HUSKY_GIT_PARAMS"}}}Copy the code
  • Configure the automatic generation of CHANGELOG
"scripts": { 
    "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0"
},
Copy the code
  • Perform several commits
chore(init): init npm & git repo 
fix(cli): exit CLI with 1 when received SIGINT 
docs(readme): specify environment in code blocks 
feat(core): use cz-conventional-changelog as default adapter
Copy the code
  • Generate the CHANGELOG
npx conventional-changelog -p angular -i CHANGELOG.md -s
Copy the code

Tandard-version Version

Standard-version is a versioning and Changlog automation tool that follows the Semver and COMMIT Message standard specifications. Under normal circumstances, we do the following releases in the Master branch:

  1. git pull origin master
  2. Update the version number and changelog according to version in pacakage.json
  1. Git add -a, then git commit
  2. Git tag version operation
  1. Push versions of tag and master branch to the repository

2, 3, and 4 are automatically completed by the standard-version tool. With local shell scripts, a series of version releases can be automatically completed.

Installation & Use

Here I still recommend global installation:

$ npm install -g standard-version

or

$ npm install --save-dev standard-version

Perform:

$ standard-version

If you run the standard-version command, you will see log information about the entire execution process on the console. Note the following common parameters:

–release-as, -r specifies the version number

By default, the tool automatically generates a version number based on major, minor, or patch rules. For example, if you have a version of 1.0.0 in package.json, the version number will be 1.0.1 after execution. Customization can be done through:

$standard-version -r minor output 1.1.0Copy the code
$standard-version -r 2.0.0 output 2.0.0Copy the code
$standard-version -r 2.0.0-test output 2.0.0-testCopy the code

It is important to note that version names are not random characters, but are subject to the semantic version (Semver) specification

–prerelease, -p Prerelease name

Used to generate the pre-release version if the current version number is 2.0.0, for example:

$standard-version --prerelease alpha output 2.0.0-alpha.0Copy the code

–tag-prefix, -t version indicates the tag prefix

Used to prefix the generated tag, for example, if the previous version number was 2.0.0:

$ standard-version --tag-prefix "stable-"The output tag: stable - v2.0.0Copy the code

We may use a lot of these parameters, but other options can be viewed through standard-version –help.

Integration of NPM

Finally, integrate the command into the scripts of NPM package.json and use it with shell scripts as follows:

"scripts": {
  "release": "./scripts/release.sh"."changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md && npm run changeissueurl"."changeissueurl": "replace 'https://github.com/myproject/issues/' 'https://redmine.example.com/' CHANGELOG.md"
},
Copy the code

// Once configured, use NPM run to publish

$ npm run release

Add the release.sh script:

#! /bin/bash

while [[ "$#"> 0]];do 
    case The $1 in
    -r|--release) release="$2"; shift;;
    # -b|--branch) branch="$2"; shift;;
    -t|--tag-prefix) prefix="$2"; shift;;
    -p|--prerelease) prerelease="$2"; shift;;
    -n|--no-verify) no="true"; shift;;
    *) echo "❌ ❌ ❌ Unknown parameter passed:The $1"; exit 1;;
    esac; shift; 
done

# Default as minor, the argument major, minor or patch: 
if [ -z "$release" ]; then
    release="patch";
fi

echo "👌 🏻 Release the as$release"

# Default release branch is master 
# if [ -z "$branch" ] ; then
# branch="";
# fi;

# if [ "$branch" ]; 
# then
# echo "stocking Branch is $Branch"
# else
✔ Branch is current Branch
# fi;

# git pull origin $branch
Click ok. # echo "click ok."


# Generate version number and tag
if [ "$no" ]
then
    standard-version --no-erify --infile CHANGELOG.md
    echo "👌 🏻 no - erify"
else 
    standard-version -r $release --tag-prefix $prefix --prerelease $prerelease --infile CHANGELOG.md
fi;

git push --follow-tags
echo '✅ git push success'

npm publish

echo "🎉 🎉 🎉 Release finished."
Copy the code

The script above does a simple branch pull, performing standard-version and the final version push. If you want to do some custom execution parameters, you will need to make custom changes.

The last

Engineering projects is a very interesting thing, through automated tools, can effectively improve project maintainability and quality, and avoid a lot of uncertainty. If you see these problems in your work and don’t want to continue to solve them through human methods, then give them a try

reference

  1. Ruan Yifeng teacher: Commit message and Change log writing guide
  2. WEBJ2EE: [Git] : Commit specification + CHANGELOG generation
  1. Standard automation for Git commit, CHANGELOG, and release
  2. Wukong and king: standard-version used