From 1aa9906e331a93d623f9dd365263fcb12b794cdf Mon Sep 17 00:00:00 2001 From: Levi Zim Date: Tue, 25 Feb 2025 22:46:30 +0800 Subject: [PATCH 1/7] RFC: Crate changelog field Co-authored-by: Artyom Pavlov --- text/0000-crate-changelog-field.md | 226 +++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 text/0000-crate-changelog-field.md diff --git a/text/0000-crate-changelog-field.md b/text/0000-crate-changelog-field.md new file mode 100644 index 00000000000..f0380487532 --- /dev/null +++ b/text/0000-crate-changelog-field.md @@ -0,0 +1,226 @@ +- Feature Name: crate-changelog-field +- Start Date: 2025-02-25 +- RFC PR: (leave this empty) +- Rust Issue: (leave this empty) + +# Summary +[summary]: #summary + +Add changelog support to `cargo`, [crates.io](https://crates.io/) and [doc.rs](https://doc.rs/). + +# Motivation +[motivation]: #motivation + +Citing [keepachangelog.com](http://keepachangelog.com): + +> What is a changelog? +> +> A changelog is a file which contains a curated, chronologically ordered list of notable changes for each version of a project. +> +> Why keep a changelog? +> +> To make it easier for users and contributors to see precisely what notable changes have been made between each release (or version) of the project. +> +> Who needs a changelog? +> +> People do. Whether consumers or developers, the end users of software are +> human beings who care about what's in the software. When the software changes, +> people want to know why and how. + +Encouraging crate authors to keep changelogs and increase its visibility for +crate users will definitely benefit crates ecosystem. + +From a consumer's perspective, this feature could make the discovery of the changelog much easier. +For instance, the "crates" plugin could leaverage this field to show a link to +the changelog when a user hovers on a dependency in `Cargo.toml`. + +Current situation: a consumer usually need to jump through several hops to find the changelog: + +```mermaid +flowchart LR; + editor["crates" plugin in vscode] + crates-io[crates.io crate page] + doc-rs[doc.rs crate page] + crate-web[crate website] + github[crate repository] + google["Google search result"] + repo-changelog[changelog in repository] + web-changelog[changelog on a website] + doc-changelog[changelog on doc.rs] + editor --> crates-io + editor --> doc-rs + crates-io --> github + github --> repo-changelog + github --> web-changelog + github --> doc-changelog + google --> crates-io + google --> github + google --> doc-rs + google -->|unlikely| repo-changelog + google --> web-changelog + google --> doc-changelog + google --> crate-web + crate-web --> web-changelog + crate-web --> repo-changelog + crate-web --> doc-changelog + doc-rs --> doc-changelog + doc-rs --> web-changelog + doc-rs --> crates-io + doc-rs --> crate-web + doc-rs --> github +``` + +This topic was brought several times, most notable notions are: + +- [Previously closed RFC](https://github.com/rust-lang/rfcs/pull/2129) +- [Rustaceans: Please Keep a Changelog!](https://blog.dbrgn.ch/2015/12/1/rust-crates-keep-a-changelog/) ([reddit](https://www.reddit.com/r/rust/comments/3v1ndl/)) +- [Cargo issue](https://github.com/rust-lang/cargo/issues/2188) +- [Reddit thread](https://www.reddit.com/r/rust/comments/6vvhjh/) + +# Guide-level explanation +[guide-level-explanation]: #guide-level-explanation + +An optional `changelog` field is available, which is currently in the format +of a URL to an external resource. + +Examples: + +```toml +[package] +name = "foo" +version = "0.1.0" +changelog = "https://github.com/foo-org/foo/releases" +``` + +```toml +[package] +name = "bar" +version = "1.0.0" +changelog = "https://github.com/bar-org/bar/blob/main/CHANGELOG.md" +``` + +For crates with `changelog` field, crates.io and docs.rs show a link to the +changelog in the corresponding page of the crate. + +# Reference-level explanation +[reference-level-explanation]: #reference-level-explanation + +## Cargo + +A new `changelog` field will be added to crate manifest, +which only accepts valid URL for now. +However, it is explicitly stated that in the future the field could be +extended to handle other formats than URL and such a change is not considered +breaking. +So external tools should expect that the field could contain contents that are +not valid URL and handle it with caution. + +For a cargo workspace, it is possible for several crates to share a changelog +via the usage of `changelog.workspace`, just like +[`documentation.workspace`](https://doc.rust-lang.org/cargo/reference/workspaces.html#the-package-table). + +For now, `cargo publish` will check if the `changelog` field is a valid URL, +unless `--no-verify` is also specified. +`cargo publish` does not check if the URL in the `changelog` field points +to a valid changelog resource. + +## Crates.io and docs.rs + +A new link to the changelog will show up in crates.io and docs.rs for crates +that uses the `changelog` field. + +crates.io and docs.rs should again check if the field is valid URL. +If the field is not valid URL, nothing shows. + +For docs.rs, this link can be added to the `Links` section of the +`-` drop-down menu. + +For crates.io, this link can be placed in the right(in desktop mode) sidebar, +alongside with other links like `Repository` and `Documentation`. +And additionally, the link can show in the crate cards in crates.io search +results, as `Homepage` and `Repository` links also show there. + +# Drawbacks +[drawbacks]: #drawbacks + +- This proposal does not check if the `changelog` field points to a valid + external changelog, requiring crate authors to do that check themselves. +- This proposal does not require the changelog to be present in the crate, + making offline usage of the `chagelog` field impractical. +- This proposal does not constrain the format of the changelog, making it hard + for external tools to consume the contents of the changelog. + +# Rationale and Alternatives +[rationale-and-alternatives]: #rationale-and-alternatives + +## Rationale +[rationale]: #rationale + +Most of the time, the producer of changelogs are crate authors +and the consumer of changelogs are other crate authors. +For human consumption, it is ideal to have the changelog in a rendered format. +But handling rendering of various formats in crates.io is a heavy task. +However, many existing crates already have changelogs available in their +repository and the websites backing their repositories can already render the +changelogs. So, in order to avoid unnecessary efforts, this RFC proposes to +just use a valid URL for the `changelog` field. + +## Alternative: Local File +[alternative-local-file]: #alternative-local-file + +The `changelog` field can be a path to a file within the crate, +which opens the possibility for crates.io to render it directly. +However, people have different opinions when it comes to what format the +changelog should use. While markdown is currently the most popular choice, +plain text and reStructuredText are also in use. +Instead of handling the rendering of various different formats of changelog in +crates.io, it is much easier to just have an external link, where an external +website handles the rendering of the changelog so that crate authors can use +any format they see fit for their changelogs. + +And changelogs grow over time, which can take significant amount of disk spaces +for crates.io, considering that usually every single release of a crate +will contain all changelogs up to that release. +This particular drawback can be solved by introducing new linting rules. + +From another perspective, using an external link can guarantee that we can +always link to the latest changelog, which is supposed to contain all +changelog entries from initial versions to unreleased commits. +If we adopt the local file approach, when we view an outdated version of a +crate on docs.rs, we only get a link to the outdated changelog, which is not +helpful for viewing the breaking changes introduced in new versions, requring +another click on the doc.rs page to switch to the latest version. + +## Alternative: Do Nothing +[alternative-do-nothing]: #alternative-do-nothing + +It has been several years after the initial changelog RFC. +We can continue to live without this enhancement. + +It is possible to create an external registry that collects the links of +changelogs. However, such effort is neither scalable nor ideal. + +# Prior art +[prior-art]: #prior-art + +[Previously closed RFC](https://github.com/rust-lang/rfcs/pull/2129) +proposed to use a strictly formatted Markdown file or an external link for the +changelog field. The strict format, while ideal for machine consumption, +imposes too much constraint and lead to a refusal. + +# Unresolved questions +[unresolved]: #unresolved-questions + + +# Future possibilities +[future-possibilities]: #future-possibilities + +Future RFC could make other formats of the `changelog` field possible +as this RFC has explicitly reserved that possibility. + +Future RFC could introduce `changelog.generator`/`changelog.format` fields +which could indicate the generator or the format of the changelog. +This is helpful for machine consumption. + +Future RFC could introduce a clippy warning that warns if the crate does not +contain a `changelog` field. From 452e2cd5ae7d08d1660d72cc7ded2ae958897bc2 Mon Sep 17 00:00:00 2001 From: Levi Zim Date: Tue, 25 Feb 2025 22:56:17 +0800 Subject: [PATCH 2/7] Add picture and fix typo --- text/0000-crate-changelog-field.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/text/0000-crate-changelog-field.md b/text/0000-crate-changelog-field.md index f0380487532..64274a8a08b 100644 --- a/text/0000-crate-changelog-field.md +++ b/text/0000-crate-changelog-field.md @@ -34,7 +34,9 @@ From a consumer's perspective, this feature could make the discovery of the chan For instance, the "crates" plugin could leaverage this field to show a link to the changelog when a user hovers on a dependency in `Cargo.toml`. -Current situation: a consumer usually need to jump through several hops to find the changelog: +![crates-hover](https://github.com/user-attachments/assets/1f6c075b-fffb-4bd8-92d9-6bee16b0f6e3) + +Current situation: a consumer usually needs to jump through several hops to find the changelog: ```mermaid flowchart LR; From 4e99d9459fe3c68cfe9c3a1c833a404b6e196f62 Mon Sep 17 00:00:00 2001 From: Levi Zim Date: Tue, 25 Feb 2025 23:14:46 +0800 Subject: [PATCH 3/7] Move mention of previous RFC to alternatives --- text/0000-crate-changelog-field.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/text/0000-crate-changelog-field.md b/text/0000-crate-changelog-field.md index 64274a8a08b..98161bfc9f5 100644 --- a/text/0000-crate-changelog-field.md +++ b/text/0000-crate-changelog-field.md @@ -167,6 +167,14 @@ repository and the websites backing their repositories can already render the changelogs. So, in order to avoid unnecessary efforts, this RFC proposes to just use a valid URL for the `changelog` field. +## Alternative: Previously closed RFC +[alternative-previously-closed-rfc]: #alternative-previously-closed-rfc + +[Previously closed RFC](https://github.com/rust-lang/rfcs/pull/2129) +proposed to use a strictly formatted Markdown file or an external link for the +changelog field. The strict format, while ideal for machine consumption, +imposes too much constraint and lead to a refusal. + ## Alternative: Local File [alternative-local-file]: #alternative-local-file @@ -205,11 +213,6 @@ changelogs. However, such effort is neither scalable nor ideal. # Prior art [prior-art]: #prior-art -[Previously closed RFC](https://github.com/rust-lang/rfcs/pull/2129) -proposed to use a strictly formatted Markdown file or an external link for the -changelog field. The strict format, while ideal for machine consumption, -imposes too much constraint and lead to a refusal. - # Unresolved questions [unresolved]: #unresolved-questions From f36581d302d00931fab1716442fedc59e2e0b5f8 Mon Sep 17 00:00:00 2001 From: Levi Zim Date: Tue, 25 Feb 2025 23:25:41 +0800 Subject: [PATCH 4/7] Address another critic of previous RFC --- text/0000-crate-changelog-field.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/text/0000-crate-changelog-field.md b/text/0000-crate-changelog-field.md index 98161bfc9f5..cfe8ee9a5f6 100644 --- a/text/0000-crate-changelog-field.md +++ b/text/0000-crate-changelog-field.md @@ -175,6 +175,13 @@ proposed to use a strictly formatted Markdown file or an external link for the changelog field. The strict format, while ideal for machine consumption, imposes too much constraint and lead to a refusal. +Another critic of the previous RFC is that if this field is just a link that will be displayed, +then it seems to not bring much value over placing a link within a README. +However, placing a link in README adds another indirection for discovering the changelog, +and it effectively prevents other sources from making the changelog more discoverable. +For example, third-party editor plugins showing crate information in the context of cargo +manifest files cannot leverage the link from README to make changelog more discoverable. + ## Alternative: Local File [alternative-local-file]: #alternative-local-file @@ -198,7 +205,7 @@ always link to the latest changelog, which is supposed to contain all changelog entries from initial versions to unreleased commits. If we adopt the local file approach, when we view an outdated version of a crate on docs.rs, we only get a link to the outdated changelog, which is not -helpful for viewing the breaking changes introduced in new versions, requring +helpful for viewing the breaking changes introduced in new versions, requiring another click on the doc.rs page to switch to the latest version. ## Alternative: Do Nothing From ef9c71998d7fe9f512e3542f1c4ae6f30cc88941 Mon Sep 17 00:00:00 2001 From: Levi Zim Date: Thu, 27 Feb 2025 22:15:41 +0800 Subject: [PATCH 5/7] Add npm and pypi to prior-arts --- text/0000-crate-changelog-field.md | 38 ++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/text/0000-crate-changelog-field.md b/text/0000-crate-changelog-field.md index cfe8ee9a5f6..2e93eb842ea 100644 --- a/text/0000-crate-changelog-field.md +++ b/text/0000-crate-changelog-field.md @@ -220,6 +220,44 @@ changelogs. However, such effort is neither scalable nor ideal. # Prior art [prior-art]: #prior-art +## NPM + +[Before npm v7, files named `CHANGES` / `CHANGELOG` / `HISTORY` are always included regardless of settings](https://docs.npmjs.com/cli/v6/configuring-npm/package-json#files). +In npm v7, [those files are no longer always included](https://github.com/npm/npm-packlist/pull/61). +npm does not impose any constraint on the format of those files. +And the website of npm registry doesn't make the changelog more accessible to users. + +[A changelog RFC that purposes to introduce `changelog` command to npm](https://github.com/npm/rfcs/pull/8) +was approved in 2018 but got [withdrawn](https://github.com/npm/rfcs/blob/main/withdrawn/0002-changelog.md) later in 2021. +This command makes it easy to view the changelog for a library. + +The main points for withdrawal are + +- npm no longer always include `CHANGES` / `CHANGELOG` / `HISTORY` files after v7. +- Managing changelog is considered outside of the scope of the **npm cli** +- The RFC is long inactive after being approved. +- Current **npm cli** team is unlikely to implement it + +## PyPI + +`pyproject.toml` supports `project.urls` table which includes a list of URLs associated with the project. +And these URLs are displayed on the left sidebar of the project page on PyPI. + +```toml +[project.urls] +Homepage = "https://example.com" +Documentation = "https://readthedocs.org" +Repository = "https://github.com/me/spam.git" +Issues = "https://github.com/me/spam/issues" +Changelog = "https://github.com/me/spam/blob/master/CHANGELOG.md" +``` + +They keeps [a list of well-known labels](https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#urls) +which includes `changelog`(with alias `changes`, `whatsnew` and `history`) and `releasenotes`. + +A [search](https://grep.app/search?f.lang=TOML&f.lang.pattern=toml&f.path.pattern=pyproject.toml&q=Changelog+%3D) +for the usage of `changelog` url in `pyproject.toml` yields many results. + # Unresolved questions [unresolved]: #unresolved-questions From 2ac646d2574cda7206dfeffade633d18445dff48 Mon Sep 17 00:00:00 2001 From: Levi Zim Date: Fri, 28 Feb 2025 21:32:49 +0800 Subject: [PATCH 6/7] Add CRAN to prior-arts --- text/0000-crate-changelog-field.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/text/0000-crate-changelog-field.md b/text/0000-crate-changelog-field.md index 2e93eb842ea..63084bf0ae4 100644 --- a/text/0000-crate-changelog-field.md +++ b/text/0000-crate-changelog-field.md @@ -258,6 +258,29 @@ which includes `changelog`(with alias `changes`, `whatsnew` and `history`) and ` A [search](https://grep.app/search?f.lang=TOML&f.lang.pattern=toml&f.path.pattern=pyproject.toml&q=Changelog+%3D) for the usage of `changelog` url in `pyproject.toml` yields many results. +## CRAN + +The R community follows the GNU convention for [`NEWS`](https://www.gnu.org/prep/standards/standards.html#NEWS-File) +and [`ChangeLog`](https://www.gnu.org/prep/standards/standards.html#Change-Logs) files. + +The `NEWS` file contains a list of user-visible changes worth mentioning. Items for old versions are not discarded. +When `NEWS` file become too big, some of the older items should be moved into `ONEWS` file and +a note referring the user to that file should be put at the end of `NEWS` file. + +The `NEWS` file can be in plaintext(`NEWS`), Markdown(`NEWS.md`) or R document(`inst/NEWS.Rd`) formats. + + +The `Changelog` file is more detailed and accurate, including developer-facing changes. + +By default, `NEWS` file will be included into a CRAN package but `Changelog` will not, +as documented in the [package structure of an R package](https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Package-structure-1). + +The CRAN website shows a link to the [rendered `NEWS` file](https://cran.r-project.org/web/packages/ggplot2/news/news.html) +on the package's web page. + +R also provides a function `news()` for building and querying R or package news information, +which comes handy when in a REPL or IDE like RStudio. + # Unresolved questions [unresolved]: #unresolved-questions From bb7b34078dbd20a33c19bf4e8373708cfb027dbf Mon Sep 17 00:00:00 2001 From: Levi Zim Date: Fri, 28 Feb 2025 22:03:28 +0800 Subject: [PATCH 7/7] Drawbacks: mutable metadata handling --- text/0000-crate-changelog-field.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/text/0000-crate-changelog-field.md b/text/0000-crate-changelog-field.md index 63084bf0ae4..ca0e878e5d3 100644 --- a/text/0000-crate-changelog-field.md +++ b/text/0000-crate-changelog-field.md @@ -151,6 +151,12 @@ results, as `Homepage` and `Repository` links also show there. making offline usage of the `chagelog` field impractical. - This proposal does not constrain the format of the changelog, making it hard for external tools to consume the contents of the changelog. +- Although `changelog` URL usually won't change from release to release, + sometimes a crate might change its `changelog` URL, which could invalidate + the `changelog` URLs in previously published versions. This is a clear indication + that `changelog` URL is inheritly a piece of mutable metadata that could be kept per + crate instead of per crate version. However, currently there is no ideal solution + to handle mutable metadata associated with crates. # Rationale and Alternatives [rationale-and-alternatives]: #rationale-and-alternatives