{"id":17398493,"url":"https://github.com/vweevers/common-changelog","last_synced_at":"2025-04-05T15:05:52.195Z","repository":{"id":47014937,"uuid":"364062098","full_name":"vweevers/common-changelog","owner":"vweevers","description":"Write changelogs for humans. A style guide.","archived":false,"fork":false,"pushed_at":"2024-11-08T16:40:11.000Z","size":247,"stargazers_count":143,"open_issues_count":7,"forks_count":9,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-03-29T14:09:15.631Z","etag":null,"topics":["changelog","draft","styleguide"],"latest_commit_sha":null,"homepage":"https://common-changelog.org","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vweevers.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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-05-03T21:10:50.000Z","updated_at":"2025-03-24T20:58:49.000Z","dependencies_parsed_at":"2025-01-06T01:06:34.983Z","dependency_job_id":"b360cf5b-f162-4a22-853d-0f209b3d8a12","html_url":"https://github.com/vweevers/common-changelog","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vweevers%2Fcommon-changelog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vweevers%2Fcommon-changelog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vweevers%2Fcommon-changelog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vweevers%2Fcommon-changelog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vweevers","download_url":"https://codeload.github.com/vweevers/common-changelog/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247353730,"owners_count":20925329,"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":["changelog","draft","styleguide"],"created_at":"2024-10-16T14:57:30.808Z","updated_at":"2025-04-05T15:05:52.177Z","avatar_url":"https://github.com/vweevers.png","language":"JavaScript","funding_links":[],"categories":["Guides \u0026 Resources"],"sub_categories":["Individual Episodes"],"readme":"# [![logo](./logo.svg)](https://common-changelog.org)\n\n**Write changelogs for humans.**\n\nCommon Changelog is a style guide for changelogs, adapted from and a stricter subset of [Keep a Changelog](https://keepachangelog.com/). It embraces the guiding principle of [Keep a Changelog](https://keepachangelog.com/) that changelogs must be written by humans and for humans, while recognizing that a clean changelog starts with a clean git history. Let them strengthen each other.\n\n[![draft](https://img.shields.io/badge/status-draft-orange)](https://github.com/vweevers/common-changelog)\n[![Common Changelog](https://common-changelog.org/badge.svg)](https://common-changelog.org)\n[![License](https://img.shields.io/badge/license-MIT-informational)](LICENSE)\n\n🚀 _Too long didn't read? Here's an [example](https://github.com/Level/level/blob/master/CHANGELOG.md)._\n\n## Table of Contents\n\n\u003cdetails\u003e\u003csummary\u003eClick to expand\u003c/summary\u003e\n\n- [1. Introduction](#1-introduction)\n  - [1.1. What is a changelog?](#11-what-is-a-changelog)\n  - [1.2. Guiding principles](#12-guiding-principles)\n  - [1.3. Prerequisites](#13-prerequisites)\n- [2. Format](#2-format)\n  - [2.1. File format](#21-file-format)\n  - [2.2. Release](#22-release)\n  - [2.3. Notice](#23-notice)\n  - [2.4. Change group](#24-change-group)\n    - [2.4.1. Change](#241-change)\n    - [2.4.2. References](#242-references)\n    - [2.4.3. Authors](#243-authors)\n    - [2.4.4. Prefixes](#244-prefixes)\n  - [2.5. Markdown formatting](#25-markdown-formatting)\n- [3. Writing](#3-writing)\n  - [3.1. Generate a draft](#31-generate-a-draft)\n  - [3.2. Remove noise](#32-remove-noise)\n  - [3.3. Rephrase changes](#33-rephrase-changes)\n  - [3.4. Merge related changes](#34-merge-related-changes)\n  - [3.5. Skip no-op changes](#35-skip-no-op-changes)\n  - [3.6. Separate commit message and description](#36-separate-commit-message-and-description)\n  - [3.7. Promoting a prerelease](#37-promoting-a-prerelease)\n- [4. Antipatterns](#4-antipatterns)\n  - [4.1. Verbatim copying of content](#41-verbatim-copying-of-content)\n  - [4.2. Conventional Commits](#42-conventional-commits)\n  - [4.3. Confusing dates](#43-confusing-dates)\n- [5. Integration](#5-integration)\n  - [5.1. GitHub Actions](#51-github-actions)\n- [6. FAQ](#6-faq)\n  - [6.1. Why spend time on a changelog?](#61-why-spend-time-on-a-changelog)\n  - [6.2. How is this different from Keep a Changelog?](#62-how-is-this-different-from-keep-a-changelog)\n  - [6.3. Is there a badge?](#63-is-there-a-badge)\n  - [6.4. What about yanked releases?](#64-what-about-yanked-releases)\n  - [6.5. Should you ever rewrite a changelog?](#65-should-you-ever-rewrite-a-changelog)\n  - [6.6. Is Common Changelog a commit convention?](#66-is-common-changelog-a-commit-convention)\n - [7. License](#7-license)\n\n\u003c/details\u003e\n\n## 1. Introduction\n\n### 1.1. What is a changelog?\n\nA changelog is a file that contains a curated, ordered list of notable changes for each versioned release of a project. Its purpose is to make it easier for consumers (and to a lesser extent contributors) to see precisely what changes have been made between two releases.\n\nThe consumers of software are human beings who care about what's in the software. They must be able to quickly understand the impact of a release. Semantic Versioning helps as a signaling mechanism but is not enough by itself. When software changes, people want to know why and how.\n\n### 1.2. Guiding principles\n\n- Changelogs are for humans.\n- Communicate the impact of changes.\n- Sort content by importance.\n- Skip content that isn't important.\n- Link each change to further information.\n\n### 1.3. Prerequisites\n\n- Project is under version control (this document assumes git).\n- Each released version has a corresponding git tag.\n- Project adheres to [Semantic Versioning](https://semver.org/).\n\n## 2. Format\n\n### 2.1. File format\n\nFilename must be `CHANGELOG.md`. File content must be [Markdown](https://daringfireball.net/projects/markdown/) and start with a first-level heading:\n\n```md\n# Changelog\n```\n\nSubsequent Markdown content must be zero or more releases, also referred to as changelog entries. Releases must be sorted latest-first according to [Semantic Versioning](https://semver.org/) rules, even if a release with a smaller version was published at a later time. This means that the semantically latest (and hence most important and frequently sought) release is at the top of the changelog. There must be an entry for every new stable release.\n\n### 2.2. Release\n\nA release must start with second-level Markdown heading in the following format:\n\n```md\n## VERSION - DATE\n```\n\nWhere `VERSION` is a semver-valid version (without \"v\" prefix) matching a git tag (with optional \"v\" prefix). If the version is new then the changelog entry should be committed before creating the git tag. The `DATE` must be in the form of `YYYY-MM-DD` ([ISO 8601](http://www.iso.org/iso/home/standards/iso8601.htm)). For example:\n\n```md\n## 1.0.1 - 2019-08-24\n```\n\nThe version should link to further information. If the project is hosted on GitHub, link the version to a [GitHub release](https://help.github.com/articles/creating-releases/) that should contain the same content as the changelog entry, alongside useful GitHub features like assets and the compare view. Preferably use [reference-style links](https://daringfireball.net/projects/markdown/syntax#link) to keep the unrendered Markdown form of the changelog readable.\n\n\u003cdetails\u003e\n\u003csummary\u003eExample\u003c/summary\u003e\n\n```md\n## [1.0.1] - 2019-08-24\n\n### Fixed\n\n- Prevent segmentation fault upon `close()`\n\n## [1.0.0] - 2019-08-23\n\n_Initial release._\n\n[1.0.1]: https://github.com/owner/name/releases/tag/v1.0.1\n[1.0.0]: https://github.com/owner/name/releases/tag/v1.0.0\n```\n\n\u003c/details\u003e\n\nAfter the heading, a release must have Markdown content that is either:\n\n1. One or more [change groups](#24-change-group);\n2. A [notice](#23-notice) followed by zero or more [change groups](#24-change-group).\n\nChange groups are only optional if a notice explains why there aren't any. No other content is permitted, because a changelog is not a blog or detailed upgrade guide. Those have other goals and concerns and must be kept separate from the changelog.\n\n### 2.3. Notice\n\nA release might have a separate upgrade guide or blog post that is considered essential reading. Other times a release may need to clarify its status, when it was yanked or contains zero changes.\n\nFor these purposes a _notice_ must be used. This is a single-sentence paragraph with otherwise arbitrary Markdown content. Adding Markdown emphasis markers is recommended. For example (links omitted):\n\n```md\n## [2.0.0] - 2020-07-23\n\n_If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md)._\n\n### Removed\n\n- **Breaking:** remove `write()` method from public API (`01e3a64`)\n```\n\nNotices are also useful to describe first releases (that have no changes). For example:\n\n```md\n## [1.0.0] - 2019-08-23\n\n_First release._\n```\n\nUse notices wisely, as they will be the first thing a reader sees at the expense of regularly structured content. There can only be one notice per release. If a notice pertains to code (rather than a release or associated artifacts) and has a suitable place outside of the changelog, write it there instead.\n\n### 2.4. Change group\n\nA change group must start with a third-level, text-only Markdown heading containing a category:\n\n```md\n### \u003ccategory\u003e\n```\n\nThe category must be one of (in order):\n\n- `Changed` for changes in existing functionality\n- `Added` for new functionality\n- `Removed` for removed functionality\n- `Fixed` for bug fixes.\n\nThe word _functionality_ here can also mean documentation, supported runtime environments and so forth. The categories exist to easily recognize the impact of changes and to allow skimming a changelog. Changes that are listed under `Removed` will typically be breaking, while anything under `Added` is potentially interesting to the reader but carries no risk when upgrading.\n\nThe heading must be followed by (and only by) an unnumbered Markdown list. Each item in the list should be a single line that must start with a [change](#241-change), followed by one or more [references](#242-references) and then zero or more [authors](#243-authors). For example, if Alice and Henry fixed a bug together (links omitted for brevity):\n\n```\n- Prevent buffer overflow (#28) (Alice, Henry)\n```\n\nThe list should be sorted: breaking changes first, then by other importance, then latest-first. The importance of a change is left to the writer's discretion.\n\n#### 2.4.1. Change\n\nWrite a change using the [imperative mood](https://en.wikipedia.org/wiki/Imperative_mood). It must start with a present-tense verb, for example (but not limited to) `Add`, `Refactor`, `Bump`, `Document`, `Fix`, `Deprecate`.\n\n\u003e 💡 It's highly recommended that git commits follow the same convention. A changelog draft can then be generated from git history without having to rephrase commit messages. Using the imperative mood tells someone what applying a commit will do. Similarly, in a changelog it tells someone what upgrading will do. It communicates an _intent_ of change. Most importantly though, the choice of imperative mood is meant to increase consistency and avoid bike shedding.\n\nEach change must be self-describing, as if no category heading exists. Instead of:\n\n```md\n### Added\n\n- Support of CentOS\n- `write()` method\n- Documentation for the `read()` method\n```\n\nWrite:\n\n```md\n### Added\n\n- Support CentOS\n- Add `write()` method\n- Document the `read()` method\n```\n\n#### 2.4.2. References\n\nA changelog is an alternative entrypoint to a codebase. It may be presented out-of-context in pull requests on third-party repositories, created by Dependabot or similar bots that read changelogs. Changes require context to understand and won't always be straightforward to describe, especially across language barriers.\n\nFor these reasons, changes must reference relevant commits, and should reference tickets or pull requests when available. Example:\n\n```md\n- Fix infinite loop ([#194](https://github.com/owner/name/issues/194))\n```\n\nReferences must be written after (and on the same line as) a change, so that content on that line is sorted by importance from left to right. References must be wrapped in parentheses. References of the same type may be separated by commas and only then wrapped in parentheses: `(#1, #2)` rather than `(#1) (#2)`. Each reference must be a Markdown link.\n\nWhen there are more than two available references, only include the best starting point for people that wish to learn more. For example, if a change happened in a pull request that closed a ticket, prefer to reference the pull request and not the ticket.\n\nReferences can be written in one of the following forms.\n\n**Commits**\n\n```md\n([`53bd922`](https://github.com/owner/name/commit/53bd922))\n([`owner/name@53bd922`](https://github.com/owner/name/commit/53bd922))\n```\n\nThe latter form should only be used for git submodules. If subsystem prefixes are used (see below) then the former short form is sufficient.\n\n**Pull Requests or issues**\n\n```md\n([#194](https://github.com/owner/name/issues/194))\n([owner/name#194](https://github.com/owner/name/issues/194))\n```\n\nThe latter form should only be used to reference issues in external repositories. This can be useful for cross-repository efforts where a single issue is used to track progress or to explain a common change in detail.\n\n**External tickets**\n\n```md\n([JIRA-837](https://example.atlassian.net/browse/JIRA-837))\n```\n\n#### 2.4.3. Authors\n\nAuthor names must be written after references, wrapped in parentheses and separated by commas. Example:\n\n```md\n- Fix infinite loop ([#194](https://github.com/owner/name/issues/194)) (Alice Meerkat)\n```\n\nWith multiple authors it would be (links omitted for brevity):\n\n```md\n- Fix infinite loop (#194) (Alice Meerkat, Milly Moose)\n```\n\nAlternatively, separate the references and authors by a semicolon, which can make lists of lists because a semicolon is a stronger punctuation mark than a comma. For example:\n\n```md\n- Fix infinite loop (#194, #195; Alice Meerkat, Milly Moose)\n```\n\nIf the project only has one contributor, author names can be omitted. For changes authored by bots, the author listed in the changelog should be the person that merged the relevant Pull Request(s).\n\nThere are no rules for whether to use the author's full name, username, or other. Common Changelog does recommend using the author's own preferred name, for which git is the most readily available source of truth.\n\n#### 2.4.4. Prefixes\n\nBreaking changes must be prefixed in bold with `**Breaking:** ` and should be listed before other changes (per category). For example (references omitted for brevity):\n\n```md\n### Changed\n\n- **Breaking:** emit `close` event after `end`\n- Refactor `sort()` internals to improve performance\n\n### Removed\n\n- **Breaking:** drop support of Node.js 8\n```\n\nFor projects that contain _subsystems_ (git submodules or other units of code) a change may be prefixed in bold with the name of that subsystem. It then also helps to sort changes by subsystem. A breaking change in a subsystem should be prefixed like so: `**\u003csubsystem\u003e (breaking):** `. For example:\n\n```md\n- **Installer (breaking):** enable silent mode by default\n- **UI**: tune button colors for accessibility\n```\n\n\u003e ✋ The use of subsystems should generally be avoided as it weakens semver signaling.\n\n### 2.5. Markdown formatting\n\nCommon Changelog has no opinions on Markdown formatting. The Markdown examples in this document follow the [`hallmark`](https://github.com/vweevers/hallmark) style guide.\n\n## 3. Writing\n\n### 3.1. Generate a draft\n\n\u003e 🚧 I personally use [`hallmark cc add`](https://github.com/vweevers/hallmark#usage) to generate the initial content of a new changelog entry. However, it comes with opinions about Markdown formatting that are out of scope for Common Changelog. That said, I do consider it an essential tool in my workflow and intend to make it less opinionated, time permitting.\n\n### 3.2. Remove noise\n\nExclude maintenance changes that are not interesting to consumers of the project (in its distributed form). To name a few:\n\n- Dotfile changes (`.gitignore`, `.github`, `.gitlab` and so forth)\n- Changes to development-only dependencies\n- Minor code style changes\n- Formatting changes in documentation.\n\nHowever, changes such as the following must _not_ be excluded:\n\n- Refactorings, which may have unintentional side effects. Let the community review them.\n- Changes to supported runtime environments (which may be reflected only in dotfiles)\n- Code style changes that use new language features\n- New documentation (if a feature was previously undocumented).\n\n### 3.3. Rephrase changes\n\nIn a project with multiple contributors, people will use different words to say the same thing. Consider rephrasing changes in order to consistently communicate types of changes to the outside world. In addition, add details where missing or strip details when irrelevant. For example in:\n\n```md\n- Upgrade json-parser from 2.2.0 to 3.0.1\n- Bump `xml-parser`\n```\n\nThe first change is too specific (because the dependency is not pinned to that exact version, let's say) while the second change is not specific enough. Instead write:\n\n```md\n- Bump `json-parser` from 2.x to 3.x\n- Bump `xml-parser` from 6.x to 8.x\n```\n\nDon't stray too far from the original commit messages though, because then fellow contributors will not recognize their changes in the changelog. Instead, make an effort on future changes to align terminology between contributors.\n\n### 3.4. Merge related changes\n\nIf a change happened over multiple commits, consider listing them as one. Here are some examples (with pseudo references for brevity).\n\n**Bumping the same dependency twice**\n\n```md\n- Bump `standard` from 15.x to 16.x (b)\n- Bump `standard` from 14.x to 15.x (a)\n```\n\nBecomes:\n\n```md\n- Bump `standard` from 14.x to 16.x (a, b)\n```\n\n**Fixups**\n\n```md\n- Fix code style of new filter (b)\n- Support filtering entries by name (a)\n```\n\nBecomes:\n\n```md\n- Support filtering entries by name (a, b)\n```\n\n### 3.5. Skip no-op changes\n\nA changelog entry describes the difference between two releases. If commits between those releases negate each other (for example because one reverts the other) then leave them out of the changelog.\n\n### 3.6. Separate commit message and description\n\nA change should be brief and to the point, no more than one line long. This makes a list of changes easy to scan. Consider that the reader could be presented with changelogs of multiple projects, as is common when dependency updates are batched or when a breaking change has a ripple effect on dependent projects.\n\nLong descriptions should be in commits or other references, even if the long description explains a breaking change. Given a commit like:\n\n```\nBreaking: bump yaml-parser from 4.x to 5.x\n\nRemoves the `unsafe` option.\n```\n\nThe change should be (links omitted for brevity):\n\n```md\n- **Breaking:** bump `yaml-parser` from 4.x to 5.x (`15d5a9e`)\n```\n\nThe only exception to this rule is if the commit lacks a description. Then one could write:\n\n```md\n- **Breaking:** bump `yaml-parser` from 4.x to 5.x (`15d5a9e`). Removes the `unsafe` option.\n```\n\nAlternatively, maintain a separate upgrade guide document for semver-major releases.\n\n### 3.7. Promoting a prerelease\n\nFor promoting a prerelease to a release, choose one of three approaches according to the type of project and the nature of the prerelease.\n\n**A. Copy content to release**\n\nA generic approach is to copy content from prereleases to the release. Follow the same practices as when creating a changelog entry from commits. Meaning to merge related changes and so forth (as described above). Write the changelog entry as if the prereleases don't exist.\n\n**B. Skip changelog entry for prerelease**\n\nA prerelease does not need a changelog entry if the prerelease is made for internal testing purposes rather than public consumption, for example to test CI/CD triggered by a git tag.\n\n**C. Refer to prerelease**\n\nAfter a round of prereleases that each had a changelog entry, the entry for the release could simply state `Stable release based on \u003cprerelease version\u003e` (using a [notice](#23-notice)).\n\nThis approach is suitable for private projects with a lengthier release flow where (crucially) all stakeholders are familiar with the contents of a release by the time it's deemed stable. One such flow is to perform Quality Assurance on internally distributed prereleases. By design, the stable release then doesn't contain new content to be communicated.\n\nFor example (links omitted):\n\n\u003cdetails\u003e\u003csummary\u003eClick to expand\u003c/summary\u003e\n\n```md\n## [3.1.0] - 2021-07-05\n\n_Stable release based on [3.1.0-rc.2]._\n\n## [3.1.0-rc.2] - 2021-07-04\n\n### Fixed\n\n- Use localized date formats on Schedule page (`a11eb73`)\n\n## [3.1.0-rc.1] - 2021-07-03\n\n### Added\n\n- Add Schedule page listing upcoming events (`59a03a9`)\n```\n\n\u003c/details\u003e\n\n## 4. Antipatterns\n\n### 4.1. Verbatim copying of content\n\nUsing `git log` as a changelog is a bad idea: it's full of noise. This doesn't necessarily mean that the commits are bad. They serve a different purpose: commits are meant to document a step in the evolution of source code.\n\nSimilarly, on projects that only land code through Pull Requests it may be tempting to write a changelog by listing those Pull Requests as-is. Which is not too different from listing commits.\n\nFor example (links omitted for brevity):\n\n```md\n- json-parser 8.0.2 is fixed (#295)\n- doc: fix dead link to xml-entities (#296)\n- Bump actions/checkout from v2.3.3 to v2.3.4 (#293)\n- docs: fix entryWritten example (#294)\n- Update test framework (#288)\n- docs: use brackets for hyphenated fields (#291)\n- fix: membrane options - misleading error message (#292)\n```\n\nThere are several problems here, stemming from verbatim copying of content that was only meaningful to contributors to begin with. The `json-parser` change doesn't explain or reference what was fixed. There are insignificant documentation tweaks and maintenance changes that don't affect the distributed software. This changelog is difficult to read both in detail and high level. Having no changelog would even be better because to understand these changes one has to visit each of the commits. Did the changelog reduce or increase reading time?\n\nHere's how one might improve it:\n\n```md\n### Changed\n\n- Unpin `json-parser` having fixed alice/json-parser#38 (#295)\n\n### Fixed\n\n- Clarify that hyphenated fields in `filter` option must use brackets (#291)\n- Use more specific errors for invalid `membrane` options (#292)\n```\n\nReaders that don't use the `filter` and `membrane` options can now skip those changes, which leaves them with only one task: follow the link to `json-parser` to learn what that's about. Or maybe not even that if the above changelog was for a semver-patch release. That's when semver signaling and clean changelogs really shine.\n\n### 4.2. Conventional Commits\n\n[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) adds cognitive overhead by injecting itself into the middle of a workflow. Changes do not start or end with commits.\n\nFor generating changelogs, Conventional Commits does help to initially categorize changes, but the use of Conventional Commits also means that commit messages must be converted to a more readable form. Using that form in the first place will align content across the board. Starting with stories and epics, then tickets, then commits, then pull requests, then changelogs. Ultimately this means less cognitive overhead, making room for everybody to understand and recognize each change presented in multiple contexts. This is the \"end-to-end\" approach of Common Changelog.\n\nIn [Why Use Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#why-use-conventional-commits) it's stated to be good for:\n\n\u003e Communicating the nature of changes to teammates, the public, and other stakeholders.\n\nCommon Changelog instead focuses on making changes descriptive and explaining _why_ a change is made. This tends to be forgotten in Conventional Commits because it gives commit authors the false impression that their messages are descriptive. To be fair, that is a general communication problem that Conventional Commits doesn't aim to solve. It is however a problem that should be prioritized - over automation and over rigid structure.\n\nCommon Changelog uses natural language (in the imperative mood) because it fits all contexts, including explaining changes to a stakeholder in person. Writing commit messages should be done like explaining them to humans. First and foremost to consumers, then to contributors and future selves.\n\nLet's see how these Common Changelog principles can improve commit messages and consequently changelogs, by rewriting the commit examples from the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#examples) homepage.\n\n**Unclear breaking change**\n\nThis Conventional Commit does not lead with the fact that it's breaking. The description of the feature on the first line does not explain how extending works. The second line does although according to its prefix (`BREAKING CHANGE`) it's instead supposed to explain why the change is breaking.\n\n```\nfeat: allow provided config object to extend other configs\n\nBREAKING CHANGE: `extends` key in config file is now used for extending other config files\n```\n\nInstead write (for example):\n\n```\nBreaking: support extending config files through `extends` key\n\nThis config key is now reserved and no longer exposed to userland code.\n```\n\n**Breaking change hidden as a refactoring**\n\nInstead of:\n\n```\nrefactor!: drop support for Node 6\n\nBREAKING CHANGE: refactor to use JavaScript features not available in Node 6.\n```\n\nWrite:\n\n```\nBreaking: refactor using new JavaScript features\n\nDrops support of Node 6.\n```\n\n**Documentation tweak in unknown file**\n\nInstead of:\n\n```\ndocs: correct spelling of CHANGELOG\n```\n\nWrite (for example):\n\n```\nFix spelling of CHANGELOG in README\n```\n\n**Redundant type and scope information**\n\nInstead of:\n\n```\nfeat(lang): add polish language\n```\n\nWrite:\n\n```\nAdd polish translation\n```\n\n**Unnecessarily long description**\n\nInstead of:\n\n```\nfix: correct minor typos in code\n\nsee the issue for details on typos fixed.\n\nReviewed-by: Z\nRefs #133\n```\n\nWrite:\n\n```\nFix minor typos in code (#133)\n\nReviewed-by: Z\n```\n\n### 4.3. Confusing dates\n\nRegional date formats vary throughout the world. The advantage of dates formatted like `2017-07-17` is that they follow the order of largest to smallest units: year, month, and day. This format also doesn't overlap in ambiguous ways with other date formats, unlike some regional formats that switch the position of month and day numbers. These reasons, and the fact this date format is an [ISO standard](http://www.iso.org/iso/home/standards/iso8601.htm), are why it is the recommended date format for changelog entries.\n\n## 5. Integration\n\n### 5.1. GitHub Actions\n\nThe following workflow is triggered by a tag and takes the changelog entry for that tag from `CHANGELOG.md` and creates a GitHub release with the same content. The [`anton-yurchenko/git-release`](https://github.com/anton-yurchenko/git-release) action that is used here also supports uploading assets to the GitHub release.\n\n```yaml\nname: Release\non:\n  push:\n    tags: ['*']\npermissions:\n  contents: write\njobs:\n  release:\n    name: Release\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v2\n      - name: Create GitHub release\n        uses: docker://antonyurchenko/git-release:latest\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n```\n\n## 6. FAQ\n\n### 6.1. Why spend time on a changelog?\n\nIn one word: reciprocity. Spending a modest amount of time on writing a changelog saves every reader twice as much time.\n\nOn any project regardless of git practices, there will be mistakes, noise and miscommunication. That's only natural. If needed a project can move fast in git and slow down for the changelog. The release can wait 15 minutes more.\n\nIn git history, a new feature may get described in more than one way because it takes time to develop a vocabulary. Maintainers will merge imperfect pull requests to stop a lenghty back-and-forth. Contributors forget that the quality of their commit messages deteriorates over time as context is lost. And so on.\n\nWriting the changelog is another feedback loop to think things through. A chance to look at the big picture: how do recent pull requests play together? Was anything missed? Does the version number accurately reflect changes? Perhaps changes are breaking in unforeseen ways. Or (rarer) the opposite of that, which could be a waste of semver-major signaling.\n\nDon't take the easy way out with full automation. This results in poor changelogs, defeating their purpose.\n\n### 6.2. How is this different from Keep a Changelog?\n\n[Keep a Changelog](https://keepachangelog.com/) was one of the first complete guides for writing a changelog. It has solid principles and offers a high-level layout for a changelog. Common Changelog was born to fill in various gaps and leave less room for interpretation. Common Changelog is undoubtedly more opinionated, while equally striving for an approach that's suitable for any project.\n\nMore specifically, there are some differences in the changelog format.\n\n**Additions**\n\nCommon Changelog adds [references](#242-references), [authors](#243-authors) and a way to [highlight breaking changes](#244-prefixes).\n\n**Less categories**\n\nCommon Changelog does not have `Deprecated` and `Security` categories. A deprecation can be listed under the `Changed` category. For example: \"Deprecate the security category\".\n\n**No Unreleased section**\n\nCommon Changelog does not have an `Unreleased` section at the top of the changelog, which Keep a Changelog recommends for listing unreleased changes as they land in the main branch of the project. In practice, especially with Common Changelog's addition of [references](#242-references), this is an unproductive workflow:\n\n1. Although a commit or pull request could describe itself in the `Unreleased` section, it cannot add the necessary (self) references. These can only be added after the fact.\n2. First-time contributors can't be expected to update the changelog. Maintainers would have to commit that separately, resulting in a noisy git history.\n3. Writing a changelog requires a bird's-eye view of the project, while individual changes are typically best reviewed and discussed in isolation.\n\n**No `[YANKED]` tag**\n\nInstead of a special notation for yanked releases, Common Changelog uses [notices](#23-notice) as a more generic (but unparsable) format.\n\n### 6.3. Is there a badge?\n\nYes! To promote the use of Common Changelog, the following Markdown can be placed in the project's readme:\n\n```md\n[![Common Changelog](https://common-changelog.org/badge.svg)](https://common-changelog.org)\n```\n\n[![Common Changelog](https://common-changelog.org/badge.svg)](https://common-changelog.org)\n\n### 6.4. What about yanked releases?\n\nA yanked release should still have an entry in the changelog, assuming the release was public for more than a few hours. Add a [notice](#23-notice) explaining the status of the release and linking to more information if available. For example (links omitted):\n\n```md\n## [8.5.1] - 2021-05-10\n\n_This release was never published to npm due to security issues (#123)._\n```\n\nThe notice should _not_ replace other content (i.e. the list of changes).\n\n### 6.5. Should you ever rewrite a changelog?\n\nSure. There are always good reasons to improve a changelog and not just the last release. It's a historical record and a useful reference to answer questions like \"When did X change?\".\n\n### 6.6. Is Common Changelog a commit convention?\n\nNo, if a commit convention means to encode information to be consumed by machines. The guidelines of Common Changelog can be used to write commit messages in a certain way and certainly recommend (but don't require) doing so. The key difference however is that Common Changelog targets human readers and avoids encoded communication. To say that `feat` is a feature and `!` denotes a breaking change for example.\n\n## 7. License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvweevers%2Fcommon-changelog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvweevers%2Fcommon-changelog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvweevers%2Fcommon-changelog/lists"}