{"id":21379684,"url":"https://github.com/jobinsjp/automaticchangelog","last_synced_at":"2026-05-19T19:04:31.705Z","repository":{"id":140503547,"uuid":"411546226","full_name":"JoBinsJP/AutomaticChangeLog","owner":"JoBinsJP","description":"Automatically generate changelog from git commit messages.","archived":false,"fork":false,"pushed_at":"2021-09-29T07:26:02.000Z","size":61,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-16T10:30:20.050Z","etag":null,"topics":["commitlint","conventional-changelog","conventional-commits","git","husky","semantic-versioning"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JoBinsJP.png","metadata":{"files":{"readme":"readme.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-09-29T05:49:11.000Z","updated_at":"2024-06-03T20:38:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"39dc1652-cdd6-4b8d-843c-02e569803996","html_url":"https://github.com/JoBinsJP/AutomaticChangeLog","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/JoBinsJP/AutomaticChangeLog","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoBinsJP%2FAutomaticChangeLog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoBinsJP%2FAutomaticChangeLog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoBinsJP%2FAutomaticChangeLog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoBinsJP%2FAutomaticChangeLog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JoBinsJP","download_url":"https://codeload.github.com/JoBinsJP/AutomaticChangeLog/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoBinsJP%2FAutomaticChangeLog/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265151841,"owners_count":23719123,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["commitlint","conventional-changelog","conventional-commits","git","husky","semantic-versioning"],"created_at":"2024-11-22T10:23:29.565Z","updated_at":"2026-05-19T19:04:31.680Z","avatar_url":"https://github.com/JoBinsJP.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"Generate Changelog From Git Commit Messages\n===============================================================================\n\nIn our current projects, creating the changelog is a manual process that is often undesired, error-prone, and time-consuming.\nThis blog describes some tools that can help to automate the changelog creation based on the Git history.\n\nLet’s start with some basics.\n\nSemantic Versioning[](#semantic-versioning)\n-------------------------------------------\n\n[Semantic Versioning (SemVer)](https://semver.org/) is a de facto standard for code versioning. It specifies that a version number always contains these three parts:\n\nAccording to semantic versioning, there are three major parts of a version number:\n\n* **MAJOR NUMBER**: changing it means a breaking change was introduced, usually as new API incompatible with the previous one;\n* **MINOR NUMBER**: changing it means a feature was added to the software, but still being backward compatible;\n* **PATCH NUMBER**: changing it means a bug fix or non-relevant change (e.g. refactor) was introduced\n\nConventional Commits[](#conventional-commits)\n---------------------------------------------\n\n\u003e The Conventional Commits specification proposes introducing a standardized lightweight convention on top of commit messages. This convention dovetails with SemVer, asking software developers to describe in commit messages, features, fixes, and breaking changes that they make.\n\nDevelopers tend to write commit messages that [serve no purpose](http://whatthecommit.com/). Usually, the message does not describe where changes were made, what was changed, and what was the motivation for making the changes.\n\nSo I recommend writing commit messages using the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0-beta.2/):\n\n    \u003ctype\u003e[optional scope]: \u003cdescription\u003e\n    \n    [optional body]\n    \n    [optional footer]\n\nAn example of such a message:\n\n    fix: ABC-123: Throwable exception not caught\n    \n    We did not catch the throwable exception thrown by the API call\n    and therefore we could not show the error message to the user\n\nThe commit type `\u003ctype\u003e` can take one of these value:\n\n* `fix:` Patch of a bug in your codebase and correlates with the patch version in semantic versioning\n* `feat:` Introduces a new feature to the codebase and correlates with a minor version in semantic versioning\n* `BREAKING CHANGE:` a commit that has the text `BREAKING CHANGE:` at the beginning of its optional body or footer section introduces a breaking API change and correlates with a major version in semantic versioning. A breaking change can be part of commits of any type. e.g., a `fix:`, `feat:` \u0026 `chore:` types would all be valid, in addition to any other type.\n\nOther types like `chore:`, `docs:`, `style:`, `refactor:`, `perf:`, `test:` are recommended by the [Angular convention](https://github.com/angular/angular/blob/22b96b9/CONTRIBUTING.md#-commit-message-guidelines).\n\nAuto Generate Changelog[](#conventional-commits)\n------------------------------------------------\n\nNow we can start to automate the changelog creation.\n\n1. Follow the [Conventional Commits Specification](https://conventionalcommits.org/) in your repository. We will use [@commitlint/config-conventional](https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint/config-conventional) to enforce this via [Git hooks](https://git-scm.com/docs/githooks).\n2. Use [standard-version](https://github.com/conventional-changelog/standard-version), a utility for versioning using SemVer and changelog generation powered by [Conventional Commits](https://www.conventionalcommits.org/).\n\nI will demonstrate the usage based on this [demo](https://github.com/crestamr/AutomaticChangeLog) project which was initialized running npm init.\n\nThe next step is to install [husky](https://github.com/typicode/husky), which sets up your [Git hooks](https://git-scm.com/docs/githooks):\n\n    npx husky-init \u0026\u0026 npm install\n\nThen install [commitlint](https://github.com/conventional-changelog/commitlint) with a config, which will be used to lint your commit message:\n\n    npm install @commitlint/{cli,config-conventional}\n\nAs we are using `config-conventional` we are automatically following the [Angular commit convention](https://github.com/angular/angular/blob/22b96b9/CONTRIBUTING.md#-commit-message-guidelines).\n\nNow we need to tell Husky to run `commitlint` during the Git commit hook. Therefore, we need to add a `commit-msg` file to the `.husky` folder:\n\n    #!/bin/sh\n    . \"$(dirname \"$0\")/_/husky.sh\"\n    \n    npx --no-install commitlint --edit \"$1\"\n\nFinally, we create a `.commitlintrc.json` file which extends the rules from [config-conventional](https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint/config-conventional):\n\n    {\n      \"extends\": [\"@commitlint/config-conventional\"]\n    }\n\nRunning `git commit` with an invalid message will now cause an error:\n\n    ▶ git commit -m \"this commit message is invalid\"\n    husky \u003e commit-msg (node v14.16.1)\n    ⧗   input: this commit message is invalid\n    ✖   subject may not be empty [subject-empty]\n    ✖   type may not be empty [type-empty]\n    \n    ✖   found 2 problems, 0 warnings\n    ⓘ   Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint\n    \n    husky \u003e commit-msg hook failed (add --no-verify to bypass)\n\nand valid commits will work:\n\n    ▶ git commit -m \"feat: initial feature commit\"\n    [master (root-commit) a87f2ea] feat: initial feature commit\n     5 files changed, 1228 insertions(+)\n     create mode 100644 .commitlintrc.json\n     create mode 100644 .gitignore\n     create mode 100644 index.js\n     create mode 100644 package-lock.json\n     create mode 100644 package.json\n\nNow we are safe and can guarantee that only valid commit messages are in our repository.\n\nGenerate Changelog[](#generate-changelog)\n-----------------------------------------\n\nFinally, we can create our changelog from our Git history. First step is to install [standard-version](https://github.com/conventional-changelog/standard-version):\n\n    npm i --save-dev standard-version\n\nNow we can create some npm scripts in our `package.json`:\n\n      \"scripts\": {\n        \"release\": \"standard-version\",\n        \"release:minor\": \"standard-version --release-as minor\",\n        \"release:patch\": \"standard-version --release-as patch\",\n        \"release:major\": \"standard-version --release-as major\"\n      },\n\nThe changelog generation can be configured via a `.versionrc.json` file or placing a `standard-version` stanza in your `package.json`.\n\nIn our demo we use a `.versionrc.json` file based on the [Conventional Changelog Configuration Spec](https://github.com/conventional-changelog/conventional-changelog-config-spec/blob/master/versions/2.1.0/README.md):\n\n    {\n        \"types\": [\n          {\"type\": \"feat\", \"section\": \"Features\"},\n          {\"type\": \"fix\", \"section\": \"Bug Fixes\"},\n          {\"type\": \"chore\", \"hidden\": true},\n          {\"type\": \"docs\", \"hidden\": true},\n          {\"type\": \"style\", \"hidden\": true},\n          {\"type\": \"refactor\", \"hidden\": true},\n          {\"type\": \"perf\", \"hidden\": true},\n          {\"type\": \"test\", \"hidden\": true}\n        ],\n        \"commitUrlFormat\": \"https://github.com/crestamr/AutomaticChangeLog/commits/{{hash}}\",\n        \"compareUrlFormat\": \"https://github.com/crestamr/AutomaticChangeLog/compare/{{previousTag}}...{{currentTag}}\"\n      }\n\n\nAn array of `type` objects represents the explicitly supported commit message types, and whether they should show up in the generated changelog file. `commitUrlFormat` is an URL representing a specific commit at a hash and `compareUrlFormat` is an URL representing the comparison between two git shas.\n\nThe first release can be created by running `npm run release -- --first-release` in the terminal:\n\n    ▶ npm run release -- --first-release\n    \n    \u003e changelog-generator-demo@0.0.0 release /Users/amr/Sites/AutomaticChangeLog\n    \u003e standard-version \"--first-release\"\n    \n    ✖ skip version bump on first release\n    ✔ created CHANGELOG.md\n    ✔ outputting changes to CHANGELOG.md\n    ✔ committing CHANGELOG.md\n    ✔ tagging release v0.0.0\n    ℹ Run `git push --follow-tags origin master \u0026\u0026 npm publish` to publish\n\nConclusion[](#conclusion)\n-------------------------\nIn my opinion, it is worth the effort to introduce the Git commit convention and the changelog generation in our projects.\nAdditionally, we can easily share this with the users of our software so that they also see what they can expect from each new release.\n\n\nReferences[](#references)\n-------------------------\n\n1) [How to Write Good Commit Messages: A Practical Git Guide](https://www.freecodecamp.org/news/writing-good-commit-messages-a-practical-guide/)\n2) [Automatic Changelog And Standard version](https://lukasznojek.com/blog/2020/03/automatic-changelog-md-or-commitizer-and-standard-version-family/)\n\nDemo Project Link[](#references)\n-------------------------\n[Changelog Generator Demo](https://github.com/JoBinsJP/AutomaticChangeLog/blob/master/CHANGELOG.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjobinsjp%2Fautomaticchangelog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjobinsjp%2Fautomaticchangelog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjobinsjp%2Fautomaticchangelog/lists"}