From ec19a242d023892874c1d602cb8a22991113d308 Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Fri, 20 Dec 2024 14:20:51 -0700 Subject: [PATCH 01/11] Add guidelines for maintaining changelogs Changelogs seem straightforward enough to maintain, but recent updates in the `core` repo indicate that there may be misconceptions. The guidelines in this PR aim to clarify the purpose of a changelog and how to maintain them so that they are valuable for consumers at all times. This is a prequisite for updating the release process in the `core` monorepo but should prove valuable in many other MetaMask projects as well. --- README.md | 1 + docs/changelogs.md | 404 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 405 insertions(+) create mode 100644 docs/changelogs.md diff --git a/README.md b/README.md index 03f38f30..13b4847e 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ This is a living repository — nothing is set in stone! If you're member of Met ## Table of Contents +- [Changelog Guidelines](./docs/changelogs.md) - [Contributor Code of Conduct](https://github.com/MetaMask/.github/blob/main/CODE_OF_CONDUCT.md) - [Engineering Principles](./docs/engineering-principles.md) - [JavaScript Guidelines](./docs/javascript.md) diff --git a/docs/changelogs.md b/docs/changelogs.md new file mode 100644 index 00000000..6e3bc4c1 --- /dev/null +++ b/docs/changelogs.md @@ -0,0 +1,404 @@ +# Guide to Changelogs + +Changelogs are invaluable for capturing and communicating releases made to projects over time. Maintaining changelogs effectively is undeniably a bit of an art, but a lot of science goes into it as well, and this document aims to guide engineers accordingly. + +## tl;dr + +- Every MetaMask project for which versions are publicly downloadable (such as a package or a ) should have a changelog file, and it should be called `CHANGELOG.md`. +- A changelog should be written primarily for consumers of the project, and as such, it should be valuable to them at all times. +- A changelog is valuable when it clearly and concisely describes modifications that have been made to the surface area of the project at each version throughout time, highlighting special versions that require consumers to make changes to _their_ project to avoid problems or migrate to a different workflow to be able to continue to use the software effectively. +- The surface area of a project include the parts of the API, CLI, and/or GUI that consumers can "see" and use, as well as the external code that it relies on. + - The API of a project covers exported code and data, and may include classes, methods, functions, constants, and types. + - The CLI of a project covers executables, and may include commands, options, and workflows. + - The GUI of a project covers applications, and may include screens, interactive components, and workflows. + - The external code of a project is its dependencies or peer dependencies. + +## Keep and enforce a changelog + +Projects that use a release process to deploy new versions of the project to a publicly accessible location such as NPM or GitHub Pages should include a file in the repo that captures those releases and the changes included in each release. This file should be called `CHANGELOG.md`. + +The changelog should follow a [standard format](#understand-the-format-of-the-changelog). The [`@metamask/auto-changelog`](https://github.com/MetaMask/auto-changelog) tool should be installed in the repo to ensure that the format is followed at all times: + +- A `lint:changelog` package script should be present which runs `auto-changelog validate` +- A `lint` package script should be present which runs `lint:changelog` +- CI should be configured to run `lint` on all branches and prevent a PR from being merged if `lint` does not pass + +See the [module template](https://github.com/MetaMask/metamask-module-template) for an example of a project that does this. + +## Understand the format and structure of the changelog + +All changelogs should be written in a format based on the ["Keep a Changelog"](https://keepachangelog.com/) specification. This format is enforced by [`@metamask/auto-changelog`](https://github.com/MetaMask/auto-changelog). + +Here is an example for a fictitious `@metamask/logger` package: + +```markdown +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added + +- Add support for logging strategies ([#343](https://github.com/MetaMask/logger/pull/343)) + - The `logLevels` option to the `Logger` constructor may now be an object instead of an array, where each value is a function that takes a `message` and does something with it. + - You could use this, for instance, to log `debug` messages to the console but log `error` messages to Sentry. + +## [1.1.0] + +### Added + +- Add support for log level `info` ([#270](https://github.com/MetaMask/logger/pull/270)) + - The `Logger` constructor now supports `info` as a possible value to the `logLevels` option. + - Add `"info"` to the `LogLevel` type union. + +### Changed + +- Upgrade `loglevel` from `^3.1.0` to `^3.4.2` ([#211](https://github.com/MetaMask/logger/pull/211)) + +## [1.0.0] + +### Added + +- Initial release + +[Unreleased]: https://github.com/MetaMask/logger/compare/v1.1.0...HEAD +[1.1.0]: https://github.com/MetaMask/logger/compare/v1.0.0...v1.1.0 +[1.0.0]: https://github.com/MetaMask/logger/releases/tag/v1.0.0 +``` + +Broadly, the changelog has the following structure: + +1. Prelude, the top-level header and introduction +2. "Unreleased", a special section representing unpublished changes +3. One or more sections representing published versions and their changes +4. Link references for section headers + +The "Unreleased" section and version-specific sections begin with a header (either "Unreleased" or a version). Within each of these sections is set of categories. Although it is not necessary to provide every category, when present they must appear in the following order (enforced by `@auto-changelog` [here](https://github.com/MetaMask/auto-changelog/blob/ef3e86e15b0de7061856a53fd18c4f38e898f5e8/src/constants.ts)). Note that this diverges from the "Keep a Changelog" spec: + +1. Uncategorized +2. Added +3. Changed +4. Deprecated +5. Removed +6. Fixed +7. Security + +Finally, within each category section is a bulleted list of changelog entries. Each changelog entry must end with a link to the pull request that introduced the change. If necessary, another bulleted list may be placed under a changelog entry to explain its purpose and provide more details for usage or adoption. + +## List unreleased changes separately from released changes + +Entries for changes that have not been released should be filed under a section at the top of the file called "Unreleased". (When a new release is issued, the entries here will automatically be moved to a new section by `@metamask/auto-changelog`.) + +## Place changes into categories + +Before adding a new changelog entry, determine which category it belongs to, adding a new header for the category if it does not exist. Do not leave changes in "Uncategorized". + +Consult the [format](#understand-the-format-of-the-changelog) for the available list of change categories and the order in which they should appear. + +### Added + +A change should be filed under this category if it enables consumers to do or use something with the project that they couldn't before. + +Most additions are non-breaking, but see ["Highlight breaking changes"](#highlight-breaking-changes) for exceptions. + +This could include: + +- Adding a new package export (e.g., a new class, function, method, or type) ✅ +- Adding a new method to an exported class ✅ +- Adding a new argument to an exported function or a method of an exported class (as long as it doesn't change the signature in a non-compatible way) ✅ +- Adding a new option to an executable ✅ +- Adding a new subcommand to a executable ✅ +- Adding a new executable entirely ✅ +- Adding a new screen or workflow to a GUI ✅ + +Notably, this does not include: + +- Adding a new "production" or peer dependency (since consumers can't use dependencies directly) ❌ + - This should be filed under "Changed" +- Adding a new development dependency ❌ + - This should be excluded from the changelog entirely, since it is only relevant for developers +- Adding a new value to a TypeScript type union or enum ❌ + - This should be filed under "Changed" +- Adding a new property to a TypeScript type ❌ + - This should be filed under "Changed" +- Adding a new value to an array, map, or other data structure which is exported directly ❌ + - This should be filed under "Changed" +- Adding a new class, function, method, etc. that is not being exported ❌ + - This should be excluded from the changelog entirely, since only developers can "see" it + +### Removed + +A change should be filed under this category if it removes an ability for consumers to do or use something with the project that they previously had. + +In most cases, these kinds of changes should be marked as breaking (see ["Highlight breaking changes"](#higlight-breaking-changes) for the full list). + +This could include: + +- Removing a package export (e.g., a new class, function, method, or type) ✅ +- Removing a new method from an exported class ✅ +- Removing an argument from an exported function or a method of an exported class ✅ +- Removing an option from an executable ✅ +- Removing a subcommand from an executable ✅ +- Removing an executable entirely ✅ +- Removing a new screen or workflow from a GUI ✅ + +Notably, this does not include: + +- Removing a "production" or peer dependency (since consumers can't use dependencies directly) ❌ + - This should be filed under "Changed" +- Removing a development dependency ❌ + - This should be excluded from the changelog, since it is only relevant for developers +- Removing a value from a TypeScript type union or enum ❌ + - This should be filed under "Changed" +- Removing a property from a TypeScript type ❌ + - This should be filed under "Changed" +- Removing a value from an array, map, or other data structure which is exported directly ❌ + - This should be filed under "Changed" +- Removing a class, function, method, etc. that is not being exported ❌ + - This should be excluded from the changelog entirely, since only developers can "see" it + +### Fixed + +A change should be filed under this category if it corrects a problem that was introduced in a previous version. + +This could include: + +- Correcting confusing or illogical behavior ✅ +- Making a change that was advertised in a previous release but was accidentally left out ✅ +- Changing the TypeScript signature of a function or method to match existing runtime validation ✅ + +Notably, this does not include: + +- Upgrading a dependency to patch a security vulnerability + - This should be filed under "Security" + +### Deprecated + +A change should be filed under this category if it adds a warning for a part of the API that is planned to be removed in a future version (but has not been removed yet). + +### Security + +A change should be filed under this category if it patches a publicly known security vulnerability (usually one that has been assigned a ID in the CVE database and highlighted by GitHub's security auditing tools). + +Some changes fix vulnerabilities that are sensitive in nature, where exposure may pose a danger to Consensys, MetaMask, or community at large. These changes should be omitted entirely. (If in doubt, reach out to the MetaMask Security team.) + +### Changed + +A change should be filed under this category when it does not belong to any other category. + +This could include: + +- Changing the behavior of a public function or method ✅ +- Adding or removing a "production" or peer dependency ✅ +- Modifying a TypeScript type union or enum ✅ +- Modifying an array, map, or other data structure which is exported directly ✅ +- Adding a property to a TypeScript type ✅ +- Removing a property from a TypeScript type ✅ + +In some cases, these kinds of changes should be marked as breaking (see ["Highlight breaking changes"](#higlight-breaking-changes) for the full list). + +Notably, the Changed category does not include: + +- Adding or removing a development dependency ❌ + - This should be excluded from the changelog, since it is only relevant for developers + +## Highlight breaking changes + +A change is "breaking" if it forces the consumer to take some kind of action after upgrading to prevent or handle one of the following: + +- An error at install time (e.g., the consumer's package manager reports a Node version incompatibility) +- An error at compile time (e.g., a TypeScript type error) +- An error at runtime +- A surprising difference in behavior + +A changelog entry which refers to such a change should be preceded with `**BREAKING:**` so that it is more visible to consumers. + +Determining what is breaking is trickier than usual, particularly as it relates to TypeScript types. The following changes are always breaking: + +- Changing the arity of a function or method (adding or removing positional arguments) ✅ +- Adding a required option to the options bag of a function or method ✅ +- Narrowing the TypeScript type of an argument in a function or method ✅ +- Widening the return type of a function or method ✅ +- Changing a function or method to throw an error ✅ +- Adding a required property to a TypeScript type ✅ +- Removing a property from a TypeScript type (even an optional one) ✅ +- Narrowing the type of a property in a TypeScript object type ✅ +- Upgrading a dependency to a version which causes any of the above ✅ +- Adding a new peer dependency ✅ +- Bumping the version of an existing peer dependency ✅ +- Removing an export from the package ✅ +- Bumping the minimum supported Node.js version ✅ + +The following changes may or may not be breaking, depending on whether types are intended to be ["user-constructable"](https://www.semver-ts.org/formal-spec/1-definitions.html): + +- Adding an optional property to a TypeScript object type ❓ +- Narrowing the type of a property in a TypeScript object type ❓ +- Widening the TypeScript type of an argument in a function or method ❓ +- Narrowing the return type of function or method ❓ + +### Read more + +- ["Breaking Changes" in "Semantic Versioning for TypeScript Types"](https://www.semver-ts.org/formal-spec/2-breaking-changes.html) + +## Omit non-consumer-facing changes + +Since changelogs should be geared toward consumers, any other changes that do not have a material effect on the usable parts of a package should be omitted from the changelog. + +This includes: + +- Adding or removing a development dependency ❌ +- Refactoring code ❌ +- Adding new tests ❌ +- Adding tooling, CI checks, or making other infrastructure changes that only benefit developers ❌ + +## Describe changes to the surface area of a project + +It is tempting when leaving a changelog entry to simply reuse the message for the commit that introduced the change. Projects like [`release-please`](https://github.com/googleapis/release-please) or [`semantic-release`](https://github.com/semantic-release/semantic-release) have certainly popularized this practice. Due to character length requirements, however, commit messages can be rather cryptic, and so they are not as helpful in practice as they could be. + +Using succinct language is good, but it is more important to describe the exact changes that have made to the project's API, CLI, or GUI. (For instance, if a method in a class has changed, mention both.) Including this level of detail helps consumers who are upgrading to a new version of a project understand how they can (or, in some cases, _must_) use the project going forward. It also assists consumers who are looking to compare and understand the capabilities between two versions of the same project in different consuming projects. + +Be exact even when [linking out to a pull request](#include-links-to-pull-requests). Respect the reader's time and save them from needing to click through to the PR to obtain key information if it is possible to do so. + +🚫 **Doesn't mention any changes to the API** + +```markdown +- Add custom `getTransactions` ([#123](https://github.com/MetaMask/sample-project/pull/123)) +``` + +✅ **Mentions parts of the API affected** + +```markdown +- Make `fetch` argument for `fetchTokens` and `fetchTopAssets` optional, defaulting to a cached version ([#123](https://github.com/MetaMask/sample-project/pull/123)) +``` + +It may be desirable to couch new changes in terms of features that they enable in consuming projects. If so, consider [describing the specific interface differences underneath the broad description](#use-a-nested-list-to-provide-context-or-details-about-a-change) (although be careful not to [group too many things together](#split-disparate-changes-from-the-same-pull-request-into-multiple-entries-if-necessary) so they can be categorized appropriately). + +## 💡 Use a nested list to provide context or details about a change + +Sometimes it is desirable to provide details for a change, such as context, purpose, consequences, or instructions for the consumer to follow, but it would be unwieldy to incorporate that information on the same line as the change itself. + +In this situation, you can provide a broad description of the change and then give specifics in a nested list underneath it, similar in spirit to a commit message. For example: + +🚫 **Too long** + +```markdown +- Remove `trackMetaMetricsEvent` option from the NetworkController constructor, which was previously used in `upsertNetworkConfiguration` to create a MetaMetrics event when a new network was added, and should be replaced with a subscription to the `NetworkController:networkAdded` event ([#123](https://github.com/MetaMask/sample-project/pull/123)) +``` + +✅ **The main gist has been preserved, and more details have been added underneath** + +```markdown +- Remove `trackMetaMetricsEvent` option from the NetworkController constructor ([#123](https://github.com/MetaMask/sample-project/pull/123)) + - Previously, this was used in `upsertNetworkConfiguration` to create a MetaMetrics event when a new network was added. This can now be achieved by subscribing to the `NetworkController:networkAdded` event and creating the event inside of the event handler. +``` + +## Include links to pull requests + +After [providing a description of changes to the surface area](#describe-changes-to-the-surface-area-of-the-project), add links to the pull requests that included the changes: + +🚫 **Doesn't include any PR link** + +```markdown +- Make `fetch` argument for `fetchTokens` and `fetchTopAssets` optional, defaulting to a cached version +``` + +✅ **Includes a PR link** + +```markdown +- Make `fetch` argument for `fetchTokens` and `fetchTopAssets` optional, defaulting to a cached version ([#123](https://github.com/MetaMask/sample-project/pull/123)) +``` + +✅ **Includes more than one PR link** + +```markdown +- Make `fetch` argument for `fetchTokens` and `fetchTopAssets` optional, defaulting to a cached version ([#111](https://github.com/MetaMask/sample-project/pull/111), [#222](https://github.com/MetaMask/sample-project/pull/222)) +``` + +## Combine like changes from multiple pull requests into a single entry if necessary + +There is no requirement that each changelog entry map to exactly one commit. A changelog is not the same thing as a commit history, and sometimes it makes more sense to group together similar changes across multiple commits into one entry. + +When doing so, make sure to include all relevant pull request links on the same line: + +🚫 **These are separate entries that could really be one** + +```markdown +- Bump `@metamask/utils` from `^0.9.7` to `^1.0.0` ([#111](https://github.com/MetaMask/sample-project/pull/111)) +- Bump `@metamask/utils` from `^1.0.0` to `^2.0.0` ([#222](https://github.com/MetaMask/sample-project/pull/222)) +``` + +✅ **They are now combined** + +```markdown +- Bump `@metamask/utils` from `^0.9.7` to `^2.0.0` ([#111](https://github.com/MetaMask/sample-project/pull/111), [#222](https://github.com/MetaMask/sample-project/pull/222)) +``` + +## Split disparate changes from the same pull request into multiple entries if necessary + +Often, a commit contains distinct changes across different areas of the codebase. Although it is tempting to group changes by "feature", it can be easier for consumers looking for specific changes if specific changes to the surface area of the project are listed separately. + +🚫 **This is one entry, but really should be several** + +```markdown +### Changed + +- Replace deprecated legacy feature flag implementation with new implementation ([#111](https://github.com/MetaMask/sample-project/pull/111)) + - Remove `LegacyFeatureFlag` type + - Add `FeatureFlag` type + - Add new method `fetchFeatureFlags` + - Remove `fetchLegacyFeatureFlags` +``` + +✅ **The changes are now listed separately and divided into multiple categories** + +```markdown +### Added + +- Add `FeatureFlag` type ([#111](https://github.com/MetaMask/sample-project/pull/111)) +- Add new method `fetchFeatureFlags` ([#111](https://github.com/MetaMask/sample-project/pull/111)) + +### Removed + +- Remove deprecated `LegacyFeatureFlag` ([#111](https://github.com/MetaMask/sample-project/pull/111)) +- Remove deprecated `fetchLegacyFeatureFlags` method ([#111](https://github.com/MetaMask/sample-project/pull/111)) +``` + +If it is desirable to preserve context for the new changes, [use a nested list](#use-a-nested-list-to-provide-context-or-details-about-a-change) (but make sure to only group together entries within the same category): + +✅ **Context is provided using a nested list** + +```markdown +### Added + +- Add new implementation for feature flags ([#111](https://github.com/MetaMask/sample-project/pull/111)) + - Add `FeatureFlag` type + - Add new method `fetchFeatureFlags` + +### Removed + +- Remove legacy feature flag implementation ([#111](https://github.com/MetaMask/sample-project/pull/111)) + - Remove deprecated `LegacyFeatureFlag` + - Remove deprecated `fetchLegacyFeatureFlags` method +``` + +## Remove reverted changes + +Sometimes changes show up in the commit history and are then later reverted. Since consumers will never see those changes, there is no need to list them in the changelog: + +🚫 **All commits show up in the changelog, even the revert commit** + +```markdown +- Upgrade `lodash` to `^9.0.1` ([#111](https://github.com/MetaMask/sample-project/pull/111)) +- Update `labelIssues` so that it will also add labels from some other project ([#111](https://github.com/MetaMask/sample-project/pull/111)) +- revert: Upgrade `lodash` to `^9.0.1` ([#111](https://github.com/MetaMask/sample-project/pull/111)) +``` + +✅ **The changelog is now cleaned** + +```markdown +- Update `labelIssues` so that it will also add labels from some other project ([#111](https://github.com/MetaMask/sample-project/pull/111)) +``` From 1451d6adb12f0d1b20d90ef1dc89abfe0d975c0c Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Mon, 6 Jan 2025 16:44:00 -0700 Subject: [PATCH 02/11] Tweak --- docs/changelogs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelogs.md b/docs/changelogs.md index 6e3bc4c1..97b73981 100644 --- a/docs/changelogs.md +++ b/docs/changelogs.md @@ -4,7 +4,7 @@ Changelogs are invaluable for capturing and communicating releases made to proje ## tl;dr -- Every MetaMask project for which versions are publicly downloadable (such as a package or a ) should have a changelog file, and it should be called `CHANGELOG.md`. +- Every MetaMask project for which new versions are distributed publicly should have a changelog file, and it should be called `CHANGELOG.md`. - A changelog should be written primarily for consumers of the project, and as such, it should be valuable to them at all times. - A changelog is valuable when it clearly and concisely describes modifications that have been made to the surface area of the project at each version throughout time, highlighting special versions that require consumers to make changes to _their_ project to avoid problems or migrate to a different workflow to be able to continue to use the software effectively. - The surface area of a project include the parts of the API, CLI, and/or GUI that consumers can "see" and use, as well as the external code that it relies on. From 9f55cc8928c0faf76cb8e7173375fc2937bc7c35 Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Mon, 6 Jan 2025 16:50:18 -0700 Subject: [PATCH 03/11] Tweak --- docs/changelogs.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/changelogs.md b/docs/changelogs.md index 97b73981..3ee564a8 100644 --- a/docs/changelogs.md +++ b/docs/changelogs.md @@ -73,11 +73,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Broadly, the changelog has the following structure: 1. Prelude, the top-level header and introduction -2. "Unreleased", a special section representing unpublished changes -3. One or more sections representing published versions and their changes -4. Link references for section headers +2. Sections representing unpublished or published changes +3. Link references for section headers -The "Unreleased" section and version-specific sections begin with a header (either "Unreleased" or a version). Within each of these sections is set of categories. Although it is not necessary to provide every category, when present they must appear in the following order (enforced by `@auto-changelog` [here](https://github.com/MetaMask/auto-changelog/blob/ef3e86e15b0de7061856a53fd18c4f38e898f5e8/src/constants.ts)). Note that this diverges from the "Keep a Changelog" spec: +The central sections begin with a header (either "Unreleased" or a version). Within each of these sections is set of categories. Although it is not necessary to provide every category, when present they must appear in the following order (enforced by `@auto-changelog` [here](https://github.com/MetaMask/auto-changelog/blob/ef3e86e15b0de7061856a53fd18c4f38e898f5e8/src/constants.ts)) (note that this diverges from the "Keep a Changelog" spec): 1. Uncategorized 2. Added From ad2ec96cc5ba6bd6df5c8b5b3bd0c82a9966a6d8 Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Mon, 6 Jan 2025 16:54:23 -0700 Subject: [PATCH 04/11] Fix link; add example for breaking entry --- docs/changelogs.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/changelogs.md b/docs/changelogs.md index 3ee564a8..4d06e789 100644 --- a/docs/changelogs.md +++ b/docs/changelogs.md @@ -96,7 +96,7 @@ Entries for changes that have not been released should be filed under a section Before adding a new changelog entry, determine which category it belongs to, adding a new header for the category if it does not exist. Do not leave changes in "Uncategorized". -Consult the [format](#understand-the-format-of-the-changelog) for the available list of change categories and the order in which they should appear. +Consult the [format](#understand-the-format-and-structure-of-the-changelog) for the available list of change categories and the order in which they should appear. ### Added @@ -214,7 +214,14 @@ A change is "breaking" if it forces the consumer to take some kind of action aft - An error at runtime - A surprising difference in behavior -A changelog entry which refers to such a change should be preceded with `**BREAKING:**` so that it is more visible to consumers. +A changelog entry which refers to such a change should be preceded with `**BREAKING:**` so that it is more visible to consumers. Breaking changes should be listed above other entries in the same section. For example: + +```markdown +## Changed + +- **BREAKING:** The `getNetworkClientById` method now throws an error if a network client for the given ID cannot be found instead of returning `undefined` ([#123](https://github.com/MetaMask/sample-project/pull/123)) +- Upgrade `@metamask/utils` to `^1.2.3` ([#456](https://github.com/MetaMask/sample-project/pull/456)) +``` Determining what is breaking is trickier than usual, particularly as it relates to TypeScript types. The following changes are always breaking: From fa837054635bdd2ce099d1f8ccc2af7b96545095 Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Mon, 6 Jan 2025 16:55:47 -0700 Subject: [PATCH 05/11] Fix link --- docs/changelogs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelogs.md b/docs/changelogs.md index 4d06e789..64dd91c2 100644 --- a/docs/changelogs.md +++ b/docs/changelogs.md @@ -261,7 +261,7 @@ This includes: - Adding new tests ❌ - Adding tooling, CI checks, or making other infrastructure changes that only benefit developers ❌ -## Describe changes to the surface area of a project +## Describe changes to the surface area of the project It is tempting when leaving a changelog entry to simply reuse the message for the commit that introduced the change. Projects like [`release-please`](https://github.com/googleapis/release-please) or [`semantic-release`](https://github.com/semantic-release/semantic-release) have certainly popularized this practice. Due to character length requirements, however, commit messages can be rather cryptic, and so they are not as helpful in practice as they could be. From 68fa3df3baca5ab45186e1c663d85d98179df128 Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Mon, 6 Jan 2025 16:56:32 -0700 Subject: [PATCH 06/11] Fix link --- docs/changelogs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelogs.md b/docs/changelogs.md index 64dd91c2..ae3aee15 100644 --- a/docs/changelogs.md +++ b/docs/changelogs.md @@ -281,7 +281,7 @@ Be exact even when [linking out to a pull request](#include-links-to-pull-reques - Make `fetch` argument for `fetchTokens` and `fetchTopAssets` optional, defaulting to a cached version ([#123](https://github.com/MetaMask/sample-project/pull/123)) ``` -It may be desirable to couch new changes in terms of features that they enable in consuming projects. If so, consider [describing the specific interface differences underneath the broad description](#use-a-nested-list-to-provide-context-or-details-about-a-change) (although be careful not to [group too many things together](#split-disparate-changes-from-the-same-pull-request-into-multiple-entries-if-necessary) so they can be categorized appropriately). +It may be desirable to couch new changes in terms of features that they enable in consuming projects. If so, consider [describing the specific interface differences underneath the broad description](#-use-a-nested-list-to-provide-context-or-details-about-a-change) (although be careful not to [group too many things together](#split-disparate-changes-from-the-same-pull-request-into-multiple-entries-if-necessary) so they can be categorized appropriately). ## 💡 Use a nested list to provide context or details about a change From 2785c8cef8b8183cdf057a5776aed8a72e4e4b05 Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Mon, 6 Jan 2025 16:57:02 -0700 Subject: [PATCH 07/11] Fix link --- docs/changelogs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelogs.md b/docs/changelogs.md index ae3aee15..a4b09089 100644 --- a/docs/changelogs.md +++ b/docs/changelogs.md @@ -373,7 +373,7 @@ Often, a commit contains distinct changes across different areas of the codebase - Remove deprecated `fetchLegacyFeatureFlags` method ([#111](https://github.com/MetaMask/sample-project/pull/111)) ``` -If it is desirable to preserve context for the new changes, [use a nested list](#use-a-nested-list-to-provide-context-or-details-about-a-change) (but make sure to only group together entries within the same category): +If it is desirable to preserve context for the new changes, [use a nested list](#-use-a-nested-list-to-provide-context-or-details-about-a-change) (but make sure to only group together entries within the same category): ✅ **Context is provided using a nested list** From 868e45f89635b9848566520033e482475c4fd190 Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Fri, 22 Aug 2025 16:22:38 -0600 Subject: [PATCH 08/11] wip --- docs/changelogs.md | 93 +++++++++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 34 deletions(-) diff --git a/docs/changelogs.md b/docs/changelogs.md index a4b09089..403c0620 100644 --- a/docs/changelogs.md +++ b/docs/changelogs.md @@ -1,31 +1,15 @@ # Guide to Changelogs -Changelogs are invaluable for capturing and communicating releases made to projects over time. Maintaining changelogs effectively is undeniably a bit of an art, but a lot of science goes into it as well, and this document aims to guide engineers accordingly. +Changelogs are essential at MetaMask for communicating changes in projects to end users, and it is important to understand how to write them well. -## tl;dr +## Essential principles -- Every MetaMask project for which new versions are distributed publicly should have a changelog file, and it should be called `CHANGELOG.md`. -- A changelog should be written primarily for consumers of the project, and as such, it should be valuable to them at all times. -- A changelog is valuable when it clearly and concisely describes modifications that have been made to the surface area of the project at each version throughout time, highlighting special versions that require consumers to make changes to _their_ project to avoid problems or migrate to a different workflow to be able to continue to use the software effectively. -- The surface area of a project include the parts of the API, CLI, and/or GUI that consumers can "see" and use, as well as the external code that it relies on. - - The API of a project covers exported code and data, and may include classes, methods, functions, constants, and types. - - The CLI of a project covers executables, and may include commands, options, and workflows. - - The GUI of a project covers applications, and may include screens, interactive components, and workflows. - - The external code of a project is its dependencies or peer dependencies. +- Every MetaMask product, service, or library ("project") that follows a release process should have a "Keep a Changelog"-formatted changelog file called `CHANGELOG.md`. +- Changelogs should be tailored for its primary audience, the people that use the project ("users"). +- For each release, a changelog should clearly and concisely describe changes that matter to the users of the project, and it should provide advice on how to use adjust to them. +- Changelogs should be curated; they should be kept organized and free of noise. -## Keep and enforce a changelog - -Projects that use a release process to deploy new versions of the project to a publicly accessible location such as NPM or GitHub Pages should include a file in the repo that captures those releases and the changes included in each release. This file should be called `CHANGELOG.md`. - -The changelog should follow a [standard format](#understand-the-format-of-the-changelog). The [`@metamask/auto-changelog`](https://github.com/MetaMask/auto-changelog) tool should be installed in the repo to ensure that the format is followed at all times: - -- A `lint:changelog` package script should be present which runs `auto-changelog validate` -- A `lint` package script should be present which runs `lint:changelog` -- CI should be configured to run `lint` on all branches and prevent a PR from being merged if `lint` does not pass - -See the [module template](https://github.com/MetaMask/metamask-module-template) for an example of a project that does this. - -## Understand the format and structure of the changelog +## Format & structure All changelogs should be written in a format based on the ["Keep a Changelog"](https://keepachangelog.com/) specification. This format is enforced by [`@metamask/auto-changelog`](https://github.com/MetaMask/auto-changelog). @@ -72,22 +56,63 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Broadly, the changelog has the following structure: -1. Prelude, the top-level header and introduction -2. Sections representing unpublished or published changes -3. Link references for section headers +1. Prelude (the top-level header and introduction) +2. Unreleased changes +3. Previously published versions and their changes +4. Markdown link references for section headers -The central sections begin with a header (either "Unreleased" or a version). Within each of these sections is set of categories. Although it is not necessary to provide every category, when present they must appear in the following order (enforced by `@auto-changelog` [here](https://github.com/MetaMask/auto-changelog/blob/ef3e86e15b0de7061856a53fd18c4f38e898f5e8/src/constants.ts)) (note that this diverges from the "Keep a Changelog" spec): +Within each past or future release section, changes are placed into one of six categories (enforced by `@auto-changelog` [here](https://github.com/MetaMask/auto-changelog/blob/ef3e86e15b0de7061856a53fd18c4f38e898f5e8/src/constants.ts)): -1. Uncategorized -2. Added -3. Changed -4. Deprecated -5. Removed -6. Fixed -7. Security +1. Added +2. Changed +3. Deprecated +4. Removed +5. Fixed +6. Security Finally, within each category section is a bulleted list of changelog entries. Each changelog entry must end with a link to the pull request that introduced the change. If necessary, another bulleted list may be placed under a changelog entry to explain its purpose and provide more details for usage or adoption. +## Users and pertinent changes + +Products, services, and libraries have different kinds of users, and in order to tailor to the audience, their changelogs must focus on different things. + +### Apps and websites + +Apps and websites have non-developer users, and their changelogs should focus on: + +- New functionality +- Changes to the UI, particularly those that may change a standard workflow (moving a button or dropdown, reworking part of a screen, etc.) +- Fixes for bugs, security issues, etc. + +### Services (APIs) + +Services have developer users, and their changelogs should focus on: + +- New endpoints/routes +- Changes in request or response data for existing endpoints/routes +- Changes in behavior for existing endpoints/routes (different logic, new errors, etc.), particularly those that are surprising +- Removed endpoints/routes +- Fixes for bugs, security issues, etc. + +### Libraries or GitHub actions + +- The API of a project covers exported code and data, and may include classes, methods, functions, constants, and types. +- The CLI of a project covers executables, and may include commands, options, and workflows. +- The GUI of a project covers applications, and may include screens, interactive components, and workflows. +- The external code of a project is its dependencies or peer dependencies. + +## Keep and enforce a changelog + +Projects that use a release process to deploy new versions of the project to a publicly accessible location such as NPM or GitHub Pages should include a file in the repo that captures those releases and the changes included in each release. This file should be called `CHANGELOG.md`. + +The changelog should follow a [standard format](#understand-the-format-of-the-changelog). The [`@metamask/auto-changelog`](https://github.com/MetaMask/auto-changelog) tool should be installed in the repo to ensure that the format is followed at all times: + +- A `lint:changelog` package script should be present which runs `auto-changelog validate` +- A `lint` package script should be present which runs `lint:changelog` +- CI should be configured to run `lint` on all branches and prevent a PR from being merged if `lint` does not pass + +See the [module template](https://github.com/MetaMask/metamask-module-template) for an example of a project that does this. + ## List unreleased changes separately from released changes Entries for changes that have not been released should be filed under a section at the top of the file called "Unreleased". (When a new release is issued, the entries here will automatically be moved to a new section by `@metamask/auto-changelog`.) From 8565e7b14ca77807441e563681e8c220ffc522f3 Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Fri, 6 Feb 2026 15:26:55 -0700 Subject: [PATCH 09/11] Update doc --- docs/changelogs.md | 153 ++++++++++++++++++++++++++++++--------------- 1 file changed, 103 insertions(+), 50 deletions(-) diff --git a/docs/changelogs.md b/docs/changelogs.md index 403c0620..115f334a 100644 --- a/docs/changelogs.md +++ b/docs/changelogs.md @@ -1,15 +1,53 @@ -# Guide to Changelogs +# Changelogs -Changelogs are essential at MetaMask for communicating changes in projects to end users, and it is important to understand how to write them well. +Changelogs are essential at MetaMask for communicating changes in products to end users. -## Essential principles +This guide covers why changelogs are important, what they look like, how to add them to products, and how to write them well. -- Every MetaMask product, service, or library ("project") that follows a release process should have a "Keep a Changelog"-formatted changelog file called `CHANGELOG.md`. -- Changelogs should be tailored for its primary audience, the people that use the project ("users"). -- For each release, a changelog should clearly and concisely describe changes that matter to the users of the project, and it should provide advice on how to use adjust to them. -- Changelogs should be curated; they should be kept organized and free of noise. +## Guide -## Format & structure +### Summary + +- Every MetaMask app, API, library, or tool ("product") that is publicly available and released in versions should have a "Keep a Changelog"-formatted changelog file called `CHANGELOG.md`. +- Changelogs should be tailored for its primary audience, the people that use the product ("users"). +- For each release, a changelog should clearly and concisely describe changes to publicly usable parts of the product, and it should provide advice for users on how to adjust to unexpected changes. +- Changelogs should be curated for humans to read; they should be kept organized and free of noise. + +### The purpose of a changelog + +Why do products needs changelogs? + +A changelog answers the following questions that your users will probably have when a new release of your product is issued: + +- What can I use now that I couldn't use before? +- What changed about something that I may use now? +- I am used to using the product this way, do I need to use it a different way now? +- What was broken before that is now fixed? + +In addition, a changelog also answers the following questions that you will probably have in the future: + +- In which version was this change or fix introduced? +- Where was the code commit or pull request that introduced the change? + +## What changelogs are not + +Changelogs are not a list of commits to a codebase. + +Some opensource projects copy and paste the direct output of `git log` for their changelogs. But commit messages can be cryptic, and they often contain implementation details which may be useful for engineers but are irrelevant for end users. + +## Adding a changelog + +If you want to add a changelog to a new or existing repo: + +1. Ensure that you have a JavaScript package manager installed, and you've added a `package.json` to the root. +2. Add `@metamask/auto-changelog` to `devDependencies`. +3. Add a `lint:changelog` package script which runs `auto-changelog validate`. +4. Configure CI to reject PRs and pushes to `main` if `lint:changelog` does not pass. +5. Generate an initial changelog by running `yarn auto-changelog init` or `npm auto-changelog init`. + +See the [module template](https://github.com/MetaMask/metamask-module-template) for an example of a repo that has an existing changelog. + +### Format & structure All changelogs should be written in a format based on the ["Keep a Changelog"](https://keepachangelog.com/) specification. This format is enforced by [`@metamask/auto-changelog`](https://github.com/MetaMask/auto-changelog). @@ -47,7 +85,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Initial release +- Initial release ([#100](https://github.com/MetaMask/logger/pull/100)) [Unreleased]: https://github.com/MetaMask/logger/compare/v1.1.0...HEAD [1.1.0]: https://github.com/MetaMask/logger/compare/v1.0.0...v1.1.0 @@ -61,7 +99,7 @@ Broadly, the changelog has the following structure: 3. Previously published versions and their changes 4. Markdown link references for section headers -Within each past or future release section, changes are placed into one of six categories (enforced by `@auto-changelog` [here](https://github.com/MetaMask/auto-changelog/blob/ef3e86e15b0de7061856a53fd18c4f38e898f5e8/src/constants.ts)): +Within each past or future release section, changes are placed into one of six categories (enforced by `@metamask/auto-changelog` [here](https://github.com/MetaMask/auto-changelog/blob/ef3e86e15b0de7061856a53fd18c4f38e898f5e8/src/constants.ts)): 1. Added 2. Changed @@ -72,64 +110,78 @@ Within each past or future release section, changes are placed into one of six c Finally, within each category section is a bulleted list of changelog entries. Each changelog entry must end with a link to the pull request that introduced the change. If necessary, another bulleted list may be placed under a changelog entry to explain its purpose and provide more details for usage or adoption. -## Users and pertinent changes +### Pertinent changes + +Different kinds of products are used differently, and in order to be useful, their changelogs must be tailored to the kinds of things users can see and interact with. -Products, services, and libraries have different kinds of users, and in order to tailor to the audience, their changelogs must focus on different things. + -### Apps and websites +### UI-based products (apps, websites, graphical tools, etc.) -Apps and websites have non-developer users, and their changelogs should focus on: +Changelogs for these products should at least mention: -- New functionality -- Changes to the UI, particularly those that may change a standard workflow (moving a button or dropdown, reworking part of a screen, etc.) +- New features (e.g., a new tab on the home page, a new setting, etc.) +- Changes to the UI, particularly those that may interrupt a standard workflow (moving a button or dropdown to another screen, reworking part of a screen, etc.) - Fixes for bugs, security issues, etc. -### Services (APIs) +### CLIs + +Changelogs for command-line tools should at least mention: + +- New commands, options, or workflows +- Changes to existing commands, options, or workflows +- Fixes for bugs, security issues, etc -Services have developer users, and their changelogs should focus on: +### HTTP APIs + +Changelogs for APIs accessible via HTTP should at least mention: - New endpoints/routes - Changes in request or response data for existing endpoints/routes -- Changes in behavior for existing endpoints/routes (different logic, new errors, etc.), particularly those that are surprising +- Changes in behavior for existing endpoints/routes (different logic, new errors, etc.), particularly those that are unexpected - Removed endpoints/routes - Fixes for bugs, security issues, etc. -### Libraries or GitHub actions +### Libraries -- The API of a project covers exported code and data, and may include classes, methods, functions, constants, and types. -- The CLI of a project covers executables, and may include commands, options, and workflows. -- The GUI of a project covers applications, and may include screens, interactive components, and workflows. -- The external code of a project is its dependencies or peer dependencies. +Changelogs for libraries should at least mention: -## Keep and enforce a changelog +- New exports (classes, functions, types, constants, etc.) +- Extensions to existing types or values (options, properties, methods, values within type unions, etc.) +- Changes in behavior, particularly those that are unexpected +- Removed exports or symbols in existing exports +- Fixes for bugs, security issues, etc. -Projects that use a release process to deploy new versions of the project to a publicly accessible location such as NPM or GitHub Pages should include a file in the repo that captures those releases and the changes included in each release. This file should be called `CHANGELOG.md`. +### GitHub actions/workflows -The changelog should follow a [standard format](#understand-the-format-of-the-changelog). The [`@metamask/auto-changelog`](https://github.com/MetaMask/auto-changelog) tool should be installed in the repo to ensure that the format is followed at all times: +Yes, public actions and workflows should have changelogs too! They should at least mention: -- A `lint:changelog` package script should be present which runs `auto-changelog validate` -- A `lint` package script should be present which runs `lint:changelog` -- CI should be configured to run `lint` on all branches and prevent a PR from being merged if `lint` does not pass +- New options +- Changes in behavior, particularly those that are unexpected +- Removed options +- Fixes for bugs, security issues, etc. -See the [module template](https://github.com/MetaMask/metamask-module-template) for an example of a project that does this. +## Best practices -## List unreleased changes separately from released changes +### List unreleased changes separately from released changes Entries for changes that have not been released should be filed under a section at the top of the file called "Unreleased". (When a new release is issued, the entries here will automatically be moved to a new section by `@metamask/auto-changelog`.) -## Place changes into categories +### Place changes into categories Before adding a new changelog entry, determine which category it belongs to, adding a new header for the category if it does not exist. Do not leave changes in "Uncategorized". Consult the [format](#understand-the-format-and-structure-of-the-changelog) for the available list of change categories and the order in which they should appear. -### Added +#### Added -A change should be filed under this category if it enables consumers to do or use something with the project that they couldn't before. +A change should be filed under this category if the project provides a new "feature", an extension of the product that users they couldn't do or use before. Most additions are non-breaking, but see ["Highlight breaking changes"](#highlight-breaking-changes) for exceptions. -This could include: +
Examples + +"Added" changes could include: - Adding a new package export (e.g., a new class, function, method, or type) ✅ - Adding a new method to an exported class ✅ @@ -139,7 +191,7 @@ This could include: - Adding a new executable entirely ✅ - Adding a new screen or workflow to a GUI ✅ -Notably, this does not include: +"Added" changes do not include: - Adding a new "production" or peer dependency (since consumers can't use dependencies directly) ❌ - This should be filed under "Changed" @@ -153,8 +205,9 @@ Notably, this does not include: - This should be filed under "Changed" - Adding a new class, function, method, etc. that is not being exported ❌ - This should be excluded from the changelog entirely, since only developers can "see" it +
-### Removed +#### Removed A change should be filed under this category if it removes an ability for consumers to do or use something with the project that they previously had. @@ -185,7 +238,7 @@ Notably, this does not include: - Removing a class, function, method, etc. that is not being exported ❌ - This should be excluded from the changelog entirely, since only developers can "see" it -### Fixed +#### Fixed A change should be filed under this category if it corrects a problem that was introduced in a previous version. @@ -200,17 +253,17 @@ Notably, this does not include: - Upgrading a dependency to patch a security vulnerability - This should be filed under "Security" -### Deprecated +#### Deprecated A change should be filed under this category if it adds a warning for a part of the API that is planned to be removed in a future version (but has not been removed yet). -### Security +#### Security A change should be filed under this category if it patches a publicly known security vulnerability (usually one that has been assigned a ID in the CVE database and highlighted by GitHub's security auditing tools). Some changes fix vulnerabilities that are sensitive in nature, where exposure may pose a danger to Consensys, MetaMask, or community at large. These changes should be omitted entirely. (If in doubt, reach out to the MetaMask Security team.) -### Changed +#### Changed A change should be filed under this category when it does not belong to any other category. @@ -230,7 +283,7 @@ Notably, the Changed category does not include: - Adding or removing a development dependency ❌ - This should be excluded from the changelog, since it is only relevant for developers -## Highlight breaking changes +### Highlight breaking changes A change is "breaking" if it forces the consumer to take some kind of action after upgrading to prevent or handle one of the following: @@ -271,11 +324,11 @@ The following changes may or may not be breaking, depending on whether types are - Widening the TypeScript type of an argument in a function or method ❓ - Narrowing the return type of function or method ❓ -### Read more +#### Read more - ["Breaking Changes" in "Semantic Versioning for TypeScript Types"](https://www.semver-ts.org/formal-spec/2-breaking-changes.html) -## Omit non-consumer-facing changes +### Omit non-consumer-facing changes Since changelogs should be geared toward consumers, any other changes that do not have a material effect on the usable parts of a package should be omitted from the changelog. @@ -286,7 +339,7 @@ This includes: - Adding new tests ❌ - Adding tooling, CI checks, or making other infrastructure changes that only benefit developers ❌ -## Describe changes to the surface area of the project +### Describe changes to the surface area of the project It is tempting when leaving a changelog entry to simply reuse the message for the commit that introduced the change. Projects like [`release-please`](https://github.com/googleapis/release-please) or [`semantic-release`](https://github.com/semantic-release/semantic-release) have certainly popularized this practice. Due to character length requirements, however, commit messages can be rather cryptic, and so they are not as helpful in practice as they could be. @@ -308,7 +361,7 @@ Be exact even when [linking out to a pull request](#include-links-to-pull-reques It may be desirable to couch new changes in terms of features that they enable in consuming projects. If so, consider [describing the specific interface differences underneath the broad description](#-use-a-nested-list-to-provide-context-or-details-about-a-change) (although be careful not to [group too many things together](#split-disparate-changes-from-the-same-pull-request-into-multiple-entries-if-necessary) so they can be categorized appropriately). -## 💡 Use a nested list to provide context or details about a change +### 💡 Use a nested list to provide context or details about a change Sometimes it is desirable to provide details for a change, such as context, purpose, consequences, or instructions for the consumer to follow, but it would be unwieldy to incorporate that information on the same line as the change itself. @@ -349,7 +402,7 @@ After [providing a description of changes to the surface area](#describe-changes - Make `fetch` argument for `fetchTokens` and `fetchTopAssets` optional, defaulting to a cached version ([#111](https://github.com/MetaMask/sample-project/pull/111), [#222](https://github.com/MetaMask/sample-project/pull/222)) ``` -## Combine like changes from multiple pull requests into a single entry if necessary +### Combine like changes from multiple pull requests into a single entry if necessary There is no requirement that each changelog entry map to exactly one commit. A changelog is not the same thing as a commit history, and sometimes it makes more sense to group together similar changes across multiple commits into one entry. @@ -368,7 +421,7 @@ When doing so, make sure to include all relevant pull request links on the same - Bump `@metamask/utils` from `^0.9.7` to `^2.0.0` ([#111](https://github.com/MetaMask/sample-project/pull/111), [#222](https://github.com/MetaMask/sample-project/pull/222)) ``` -## Split disparate changes from the same pull request into multiple entries if necessary +### Split disparate changes from the same pull request into multiple entries if necessary Often, a commit contains distinct changes across different areas of the codebase. Although it is tempting to group changes by "feature", it can be easier for consumers looking for specific changes if specific changes to the surface area of the project are listed separately. @@ -416,7 +469,7 @@ If it is desirable to preserve context for the new changes, [use a nested list]( - Remove deprecated `fetchLegacyFeatureFlags` method ``` -## Remove reverted changes +### Remove reverted changes Sometimes changes show up in the commit history and are then later reverted. Since consumers will never see those changes, there is no need to list them in the changelog: From 9c1b3ed3c51c53a5bce56223c22c7f6b64b88b4f Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Fri, 6 Feb 2026 15:28:18 -0700 Subject: [PATCH 10/11] Update doc --- docs/changelogs.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/changelogs.md b/docs/changelogs.md index 115f334a..d1c5a919 100644 --- a/docs/changelogs.md +++ b/docs/changelogs.md @@ -6,7 +6,7 @@ This guide covers why changelogs are important, what they look like, how to add ## Guide -### Summary +### tl;dr - Every MetaMask app, API, library, or tool ("product") that is publicly available and released in versions should have a "Keep a Changelog"-formatted changelog file called `CHANGELOG.md`. - Changelogs should be tailored for its primary audience, the people that use the product ("users"). @@ -35,18 +35,6 @@ Changelogs are not a list of commits to a codebase. Some opensource projects copy and paste the direct output of `git log` for their changelogs. But commit messages can be cryptic, and they often contain implementation details which may be useful for engineers but are irrelevant for end users. -## Adding a changelog - -If you want to add a changelog to a new or existing repo: - -1. Ensure that you have a JavaScript package manager installed, and you've added a `package.json` to the root. -2. Add `@metamask/auto-changelog` to `devDependencies`. -3. Add a `lint:changelog` package script which runs `auto-changelog validate`. -4. Configure CI to reject PRs and pushes to `main` if `lint:changelog` does not pass. -5. Generate an initial changelog by running `yarn auto-changelog init` or `npm auto-changelog init`. - -See the [module template](https://github.com/MetaMask/metamask-module-template) for an example of a repo that has an existing changelog. - ### Format & structure All changelogs should be written in a format based on the ["Keep a Changelog"](https://keepachangelog.com/) specification. This format is enforced by [`@metamask/auto-changelog`](https://github.com/MetaMask/auto-changelog). @@ -161,6 +149,18 @@ Yes, public actions and workflows should have changelogs too! They should at lea - Removed options - Fixes for bugs, security issues, etc. +## Adding a changelog + +If you want to add a changelog to a new or existing repo: + +1. Ensure that you have a JavaScript package manager installed, and you've added a `package.json` to the root. +2. Add `@metamask/auto-changelog` to `devDependencies`. +3. Add a `lint:changelog` package script which runs `auto-changelog validate`. +4. Configure CI to reject PRs and pushes to `main` if `lint:changelog` does not pass. +5. Generate an initial changelog by running `yarn auto-changelog init` or `npm auto-changelog init`. + +See the [module template](https://github.com/MetaMask/metamask-module-template) for an example of a repo that has an existing changelog. + ## Best practices ### List unreleased changes separately from released changes From d5c340a7dedf10a49748b48781d3061af7be2dca Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Fri, 6 Feb 2026 15:30:33 -0700 Subject: [PATCH 11/11] Update --- docs/changelogs.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/changelogs.md b/docs/changelogs.md index d1c5a919..38f78792 100644 --- a/docs/changelogs.md +++ b/docs/changelogs.md @@ -17,7 +17,7 @@ This guide covers why changelogs are important, what they look like, how to add Why do products needs changelogs? -A changelog answers the following questions that your users will probably have when a new release of your product is issued: +A changelog answers the following questions that users of your project will probably have when you make a new release: - What can I use now that I couldn't use before? - What changed about something that I may use now? @@ -29,7 +29,7 @@ In addition, a changelog also answers the following questions that you will prob - In which version was this change or fix introduced? - Where was the code commit or pull request that introduced the change? -## What changelogs are not +### What changelogs are not Changelogs are not a list of commits to a codebase. @@ -104,7 +104,7 @@ Different kinds of products are used differently, and in order to be useful, the -### UI-based products (apps, websites, graphical tools, etc.) +#### UI-based products (apps, websites, graphical tools, etc.) Changelogs for these products should at least mention: @@ -112,7 +112,7 @@ Changelogs for these products should at least mention: - Changes to the UI, particularly those that may interrupt a standard workflow (moving a button or dropdown to another screen, reworking part of a screen, etc.) - Fixes for bugs, security issues, etc. -### CLIs +#### CLIs Changelogs for command-line tools should at least mention: @@ -120,7 +120,7 @@ Changelogs for command-line tools should at least mention: - Changes to existing commands, options, or workflows - Fixes for bugs, security issues, etc -### HTTP APIs +#### HTTP APIs Changelogs for APIs accessible via HTTP should at least mention: @@ -130,7 +130,7 @@ Changelogs for APIs accessible via HTTP should at least mention: - Removed endpoints/routes - Fixes for bugs, security issues, etc. -### Libraries +#### Libraries Changelogs for libraries should at least mention: @@ -140,7 +140,7 @@ Changelogs for libraries should at least mention: - Removed exports or symbols in existing exports - Fixes for bugs, security issues, etc. -### GitHub actions/workflows +#### GitHub actions/workflows Yes, public actions and workflows should have changelogs too! They should at least mention: @@ -149,7 +149,7 @@ Yes, public actions and workflows should have changelogs too! They should at lea - Removed options - Fixes for bugs, security issues, etc. -## Adding a changelog +### Adding a changelog If you want to add a changelog to a new or existing repo: