Switch to file-per-change changelog (#3774)

## Motivation and Context
Implements [RFC: File-per-change
changelog](https://smithy-lang.github.io/smithy-rs/design/rfcs/rfc0042_file_per_change_changelog.html#rfc-file-per-change-changelog)

## Description
When this PR is merged to `main`, it will impact developer workflow for
creating a changelog entry that goes with a PR.
Prior to this, one edited `CHANGELOG.next.toml` to enter a changelog
entry, but it often caused merge conflicts among us. With this PR, one
creates a `.md` file (any filename stem will do) under the
`smithy-rs/.changelog` directory. This Markdown file has the YAML front
matter, and it can be created manually or via the `ChangeLogger` CLI
(see [this
commit](83cda76608)
for more details).

Here are the highlights of the code changes:
- [The release
script](https://github.com/smithy-lang/smithy-rs/pull/3774/files#diff-162dc2b82eb3d72b105291d2fc5fc8d10c4fbc1e6f35862bc08ac0d6a7c53f76)
has been pointed to `smithy-rs/.changelog`. This is pretty much what it
takes to let the `smithy-rs` release infra switch to the new changelog
mode.
-
[sdk-lints](efcc772b37)
now disallows `CHANGELOG.next.toml`. It will complain if the file is
present.
- The `--source-to-truncate` option for the `changelogger`'s `render` is
now optional because our internal release infra code no longer needs to
specify that option (i.e. there is nothing to truncate there).
- Tests in `smithy-rs-tool-common` and `changelogger` have been updated
so TOML changelog entries used in tests have been re-written to Markdown
changelog entries. We want to avoid giving the false impression that
TOML changelog entries are still well-supported.

## Testing
- Existing tests & lints in CI
- Ran `smithy-rs` [dry-run
release](https://github.com/smithy-lang/smithy-rs/actions/runs/10100442953)
and confirmed the correctness of `CHANGELOG.md` and
`SDK_CHANGELOG.next.json` in the release artifacts
- Ran the internal release and confirmed `CHANGELOG.md` was rendered
correctly in `aws-sdk-rust`

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
This commit is contained in:
ysaito1001 2024-07-31 23:31:19 -05:00 committed by GitHub
parent 63753f3fc7
commit 10a92052b1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 839 additions and 898 deletions

10
.changelog/.example Normal file
View File

@ -0,0 +1,10 @@
# Example changelog entry, Markdown with YAML front matter
# ---
# applies_to: ["client", "server", "aws-sdk-rust"] # "aws-sdk-rust" here duplicates this entry into release notes in `aws-sdk-rust`
# authors: ["rcoh"]
# references: ["smithy-rs#920"]
# breaking: false
# new_feature: false
# bug_fix: false
# ---
# Fix typos in module documentation for generated crates

View File

14
.changelog/1722464864.md Normal file
View File

@ -0,0 +1,14 @@
---
applies_to:
- aws-sdk-rust
- client
authors:
- landonxjames
references:
- smithy-rs#3765
- smithy-rs#3757
breaking: false
new_feature: false
bug_fix: true
---
Fix incorrect redaction of `@sensitive` types in maps and lists.

12
.changelog/1722464947.md Normal file
View File

@ -0,0 +1,12 @@
---
applies_to:
- client
authors:
- ysaito1001
references:
- smithy-rs#3767
breaking: false
new_feature: false
bug_fix: true
---
Fix client error correction to properly parse structure members that target a `Union` containing that structure recursively.

View File

@ -12,8 +12,8 @@
## Checklist ## Checklist
<!--- If a checkbox below is not applicable, then please DELETE it rather than leaving it unchecked --> <!--- If a checkbox below is not applicable, then please DELETE it rather than leaving it unchecked -->
- [ ] I have updated `CHANGELOG.next.toml` if I made changes to the smithy-rs codegen or runtime crates - [ ] For changes to the smithy-rs codegen or runtime crates, I have created a changelog entry Markdown file in the `.changelog` directory, specifying "client," "server," or both in the `applies_to` key.
- [ ] I have updated `CHANGELOG.next.toml` if I made changes to the AWS SDK, generated SDK code, or SDK runtime crates - [ ] For changes to the AWS SDK, generated SDK code, or SDK runtime crates, I have created a changelog entry Markdown file in the `.changelog` directory, specifying "aws-sdk-rust" in the `applies_to` key.
---- ----

View File

@ -1,30 +0,0 @@
# Example changelog entries
# [[aws-sdk-rust]]
# message = "Fix typos in module documentation for generated crates"
# references = ["smithy-rs#920"]
# meta = { "breaking" = false, "tada" = false, "bug" = false }
# author = "rcoh"
#
# [[smithy-rs]]
# message = "Fix typos in module documentation for generated crates"
# references = ["smithy-rs#920"]
# meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "client | server | all"}
# author = "rcoh"
[[aws-sdk-rust]]
message = "Fix incorrect redaction of `@sensitive` types in maps and lists."
references = ["smithy-rs#3765", "smithy-rs#3757"]
meta = { "breaking" = false, "tada" = false, "bug" = true }
author = "landonxjames"
[[smithy-rs]]
message = "Fix incorrect redaction of `@sensitive` types in maps and lists."
references = ["smithy-rs#3765", "smithy-rs#3757"]
meta = { "breaking" = false, "tada" = false, "bug" = true, "target" = "client" }
author = "landonxjames"
[[smithy-rs]]
message = "Fix client error correction to properly parse structure members that target a `Union` containing that structure recursively."
references = ["smithy-rs#3767"]
meta = { "breaking" = false, "tada" = false, "bug" = true, "target" = "client" }
author = "ysaito1001"

View File

@ -34,7 +34,9 @@ To send us a pull request, please:
2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
3. Ensure local tests pass. 3. Ensure local tests pass.
4. Commit to your fork using clear commit messages. 4. Commit to your fork using clear commit messages.
5. Send us a pull request, answering any default questions in the pull request interface. 5. Send us a pull request, answering any default questions in the pull request interface. To create a changelog entry Markdown file in the `.changelog` directory, you can do either of the following:
- Use the `new` subcommand of [changelogger](https://github.com/smithy-lang/smithy-rs/tree/main/tools/ci-build/changelogger) CLI (**preferred**)
- Create one manually. Name the file `XXX.md`, where `XXX` can be any name you choose, as long as it is unique in the `.changelog` directory. Ensure the contents follow Markdown syntax with the YAML front matter. For reference, see [.example](https://github.com/smithy-lang/smithy-rs/blob/3e250cf9f61ee17ccd66e16314d4e47f3dd95e25/.changelog/.example) or other Markdown files in the `.changelog` directory.
6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
7. Ask maintainers to manually trigger [canary](https://github.com/smithy-lang/smithy-rs/actions/workflows/manual-canary.yml) and [PR bot](https://github.com/smithy-lang/smithy-rs/actions/workflows/manual-pull-request-bot.yml) workflows using your pull request number. Those workflows cannot run in your fork and are always skipped as such. 7. Ask maintainers to manually trigger [canary](https://github.com/smithy-lang/smithy-rs/actions/workflows/manual-canary.yml) and [PR bot](https://github.com/smithy-lang/smithy-rs/actions/workflows/manual-pull-request-bot.yml) workflows using your pull request number. Those workflows cannot run in your fork and are always skipped as such.

View File

@ -1,7 +1,7 @@
RFC: File-per-change changelog RFC: File-per-change changelog
============================== ==============================
> Status: RFC > Status: Implemented
> >
> Applies to: client and server > Applies to: client and server
@ -119,15 +119,15 @@ entry on behalf of a contributor).
Changes checklist Changes checklist
----------------- -----------------
- [ ] Refactor changelogger and smithy-rs-tool-common to separate the changelog - [x] Refactor changelogger and smithy-rs-tool-common to separate the changelog
serialization format from the internal representation used for rendering and splitting. serialization format from the internal representation used for rendering and splitting.
- [ ] Implement deserialization for the new Markdown entry format - [x] Implement deserialization for the new Markdown entry format
- [ ] Incorporate new format into the `changelogger render` subcommand - [x] Incorporate new format into the `changelogger render` subcommand
- [ ] Incorporate new format into the `changelogger split` subcommand - [x] Incorporate new format into the `changelogger split` subcommand
- [ ] Port existing `CHANGELOG.next.toml` to individual entries - [x] Port existing `CHANGELOG.next.toml` to individual entries
- [ ] Update `sdk-lints` to fail if `CHANGELOG.next.toml` exists at all to avoid losing - [x] Update `sdk-lints` to fail if `CHANGELOG.next.toml` exists at all to avoid losing
changelog entries during merges. changelog entries during merges.
- [ ] Dry-run test against the smithy-rs release process. - [x] Dry-run test against the smithy-rs release process.
- [ ] Dry-run test against the SDK release process. - [x] Dry-run test against the SDK release process.
[Changes Checklist]: #changes-checklist [Changes Checklist]: #changes-checklist

View File

@ -4,9 +4,9 @@ version = 3
[[package]] [[package]]
name = "addr2line" name = "addr2line"
version = "0.21.0" version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
dependencies = [ dependencies = [
"gimli", "gimli",
] ]
@ -28,19 +28,19 @@ dependencies = [
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.82" version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
[[package]] [[package]]
name = "async-trait" name = "async-trait"
version = "0.1.80" version = "0.1.81"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.58", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -49,22 +49,22 @@ version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [ dependencies = [
"hermit-abi", "hermit-abi 0.1.19",
"libc", "libc",
"winapi", "winapi",
] ]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.2.0" version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]] [[package]]
name = "backtrace" name = "backtrace"
version = "0.3.71" version = "0.3.73"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a"
dependencies = [ dependencies = [
"addr2line", "addr2line",
"cc", "cc",
@ -89,9 +89,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.5.0" version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
@ -101,9 +101,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]] [[package]]
name = "bytes" name = "bytes"
version = "1.6.0" version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" checksum = "fca2be1d5c43812bae364ee3f30b3afcb7877cf59f4aeb94c66f313a41d2fac9"
[[package]] [[package]]
name = "cargo_toml" name = "cargo_toml"
@ -112,14 +112,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a98356df42a2eb1bd8f1793ae4ee4de48e384dd974ce5eac8eee802edb7492be" checksum = "a98356df42a2eb1bd8f1793ae4ee4de48e384dd974ce5eac8eee802edb7492be"
dependencies = [ dependencies = [
"serde", "serde",
"toml 0.8.12", "toml 0.8.19",
] ]
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.92" version = "1.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41" checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
@ -129,7 +129,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "changelogger" name = "changelogger"
version = "0.1.0" version = "0.2.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
@ -203,9 +203,9 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
[[package]] [[package]]
name = "crates-index" name = "crates-index"
version = "2.7.0" version = "2.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879bde76e7fb6166c3d36dd2b1e376d012e8b110b52cbec72bf59c40d20ec9fe" checksum = "b8a348a0130383cd8598969ba9f429d9a57b4a1fb3135ad048039012ee7226f0"
dependencies = [ dependencies = [
"hex", "hex",
"home", "home",
@ -218,7 +218,7 @@ dependencies = [
"serde_json", "serde_json",
"smol_str", "smol_str",
"thiserror", "thiserror",
"toml 0.8.12", "toml 0.8.19",
] ]
[[package]] [[package]]
@ -269,9 +269,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]] [[package]]
name = "errno" name = "errno"
version = "0.3.8" version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys 0.52.0", "windows-sys 0.52.0",
@ -363,9 +363,9 @@ dependencies = [
[[package]] [[package]]
name = "gimli" name = "gimli"
version = "0.28.1" version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
[[package]] [[package]]
name = "h2" name = "h2"
@ -379,7 +379,7 @@ dependencies = [
"futures-sink", "futures-sink",
"futures-util", "futures-util",
"http", "http",
"indexmap 2.2.6", "indexmap 2.3.0",
"slab", "slab",
"tokio", "tokio",
"tokio-util", "tokio-util",
@ -394,9 +394,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.14.3" version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]] [[package]]
name = "heck" name = "heck"
@ -413,6 +413,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "hermit-abi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
[[package]] [[package]]
name = "hex" name = "hex"
version = "0.4.3" version = "0.4.3"
@ -455,9 +461,9 @@ dependencies = [
[[package]] [[package]]
name = "httparse" name = "httparse"
version = "1.8.0" version = "1.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9"
[[package]] [[package]]
name = "httpdate" name = "httpdate"
@ -467,9 +473,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "0.14.28" version = "0.14.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-channel", "futures-channel",
@ -524,12 +530,12 @@ dependencies = [
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.2.6" version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown 0.14.3", "hashbrown 0.14.5",
] ]
[[package]] [[package]]
@ -555,33 +561,33 @@ dependencies = [
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.153" version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
version = "0.4.13" version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.21" version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.7.2" version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]] [[package]]
name = "mime" name = "mime"
@ -591,31 +597,31 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.7.2" version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
dependencies = [ dependencies = [
"adler", "adler",
] ]
[[package]] [[package]]
name = "mio" name = "mio"
version = "0.8.11" version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4"
dependencies = [ dependencies = [
"hermit-abi 0.3.9",
"libc", "libc",
"wasi", "wasi",
"windows-sys 0.48.0", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
name = "native-tls" name = "native-tls"
version = "0.2.11" version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466"
dependencies = [ dependencies = [
"lazy_static",
"libc", "libc",
"log", "log",
"openssl", "openssl",
@ -644,9 +650,9 @@ dependencies = [
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.18" version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [ dependencies = [
"autocfg", "autocfg",
] ]
@ -662,9 +668,9 @@ dependencies = [
[[package]] [[package]]
name = "object" name = "object"
version = "0.32.2" version = "0.36.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@ -677,11 +683,11 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]] [[package]]
name = "openssl" name = "openssl"
version = "0.10.64" version = "0.10.66"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1"
dependencies = [ dependencies = [
"bitflags 2.5.0", "bitflags 2.6.0",
"cfg-if", "cfg-if",
"foreign-types", "foreign-types",
"libc", "libc",
@ -698,7 +704,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.58", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -709,9 +715,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]] [[package]]
name = "openssl-sys" name = "openssl-sys"
version = "0.9.102" version = "0.9.103"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6"
dependencies = [ dependencies = [
"cc", "cc",
"libc", "libc",
@ -800,9 +806,9 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.79" version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -818,9 +824,9 @@ dependencies = [
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.10.4" version = "1.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@ -830,9 +836,9 @@ dependencies = [
[[package]] [[package]]
name = "regex-automata" name = "regex-automata"
version = "0.4.6" version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@ -841,9 +847,9 @@ dependencies = [
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.8.3" version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
[[package]] [[package]]
name = "reqwest" name = "reqwest"
@ -887,9 +893,9 @@ dependencies = [
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.23" version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]] [[package]]
name = "rustc-hash" name = "rustc-hash"
@ -899,11 +905,11 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.38.32" version = "0.38.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
dependencies = [ dependencies = [
"bitflags 2.5.0", "bitflags 2.6.0",
"errno", "errno",
"libc", "libc",
"linux-raw-sys", "linux-raw-sys",
@ -921,9 +927,9 @@ dependencies = [
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.17" version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]] [[package]]
name = "schannel" name = "schannel"
@ -936,11 +942,11 @@ dependencies = [
[[package]] [[package]]
name = "security-framework" name = "security-framework"
version = "2.10.0" version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [ dependencies = [
"bitflags 1.3.2", "bitflags 2.6.0",
"core-foundation", "core-foundation",
"core-foundation-sys", "core-foundation-sys",
"libc", "libc",
@ -949,9 +955,9 @@ dependencies = [
[[package]] [[package]]
name = "security-framework-sys" name = "security-framework-sys"
version = "2.10.0" version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf"
dependencies = [ dependencies = [
"core-foundation-sys", "core-foundation-sys",
"libc", "libc",
@ -959,46 +965,47 @@ dependencies = [
[[package]] [[package]]
name = "semver" name = "semver"
version = "1.0.22" version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.197" version = "1.0.204"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.197" version = "1.0.204"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.58", "syn 2.0.72",
] ]
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.115" version = "1.0.121"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609"
dependencies = [ dependencies = [
"itoa", "itoa",
"memchr",
"ryu", "ryu",
"serde", "serde",
] ]
[[package]] [[package]]
name = "serde_spanned" name = "serde_spanned"
version = "0.6.5" version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d"
dependencies = [ dependencies = [
"serde", "serde",
] ]
@ -1021,7 +1028,7 @@ version = "0.9.34+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [ dependencies = [
"indexmap 2.2.6", "indexmap 2.3.0",
"itoa", "itoa",
"ryu", "ryu",
"serde", "serde",
@ -1059,18 +1066,18 @@ dependencies = [
[[package]] [[package]]
name = "smol_str" name = "smol_str"
version = "0.2.1" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6845563ada680337a52d43bb0b29f396f2d911616f6573012645b9e3d048a49" checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead"
dependencies = [ dependencies = [
"serde", "serde",
] ]
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.5.6" version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys 0.52.0", "windows-sys 0.52.0",
@ -1095,9 +1102,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.58" version = "2.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1160,22 +1167,22 @@ checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.58" version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.58" version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.58", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -1201,9 +1208,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]] [[package]]
name = "tinyvec" name = "tinyvec"
version = "1.6.0" version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938"
dependencies = [ dependencies = [
"tinyvec_macros", "tinyvec_macros",
] ]
@ -1216,9 +1223,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.37.0" version = "1.39.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1"
dependencies = [ dependencies = [
"backtrace", "backtrace",
"bytes", "bytes",
@ -1226,7 +1233,7 @@ dependencies = [
"mio", "mio",
"pin-project-lite", "pin-project-lite",
"socket2", "socket2",
"windows-sys 0.48.0", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
@ -1241,16 +1248,15 @@ dependencies = [
[[package]] [[package]]
name = "tokio-util" name = "tokio-util"
version = "0.7.10" version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-core", "futures-core",
"futures-sink", "futures-sink",
"pin-project-lite", "pin-project-lite",
"tokio", "tokio",
"tracing",
] ]
[[package]] [[package]]
@ -1265,9 +1271,9 @@ dependencies = [
[[package]] [[package]]
name = "toml" name = "toml"
version = "0.8.12" version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
dependencies = [ dependencies = [
"serde", "serde",
"serde_spanned", "serde_spanned",
@ -1277,20 +1283,20 @@ dependencies = [
[[package]] [[package]]
name = "toml_datetime" name = "toml_datetime"
version = "0.6.5" version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
dependencies = [ dependencies = [
"serde", "serde",
] ]
[[package]] [[package]]
name = "toml_edit" name = "toml_edit"
version = "0.22.9" version = "0.22.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d"
dependencies = [ dependencies = [
"indexmap 2.2.6", "indexmap 2.3.0",
"serde", "serde",
"serde_spanned", "serde_spanned",
"toml_datetime", "toml_datetime",
@ -1322,7 +1328,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.58", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -1369,9 +1375,9 @@ checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
[[package]] [[package]]
name = "url" name = "url"
version = "2.5.0" version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
dependencies = [ dependencies = [
"form_urlencoded", "form_urlencoded",
"idna", "idna",
@ -1386,9 +1392,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.4" version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]] [[package]]
name = "want" name = "want"
@ -1426,7 +1432,7 @@ dependencies = [
"once_cell", "once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.58", "syn 2.0.72",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -1460,7 +1466,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.58", "syn 2.0.72",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -1511,11 +1517,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]] [[package]]
name = "winapi-util" name = "winapi-util"
version = "0.1.6" version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b"
dependencies = [ dependencies = [
"winapi", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
@ -1539,7 +1545,7 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [ dependencies = [
"windows-targets 0.52.4", "windows-targets 0.52.6",
] ]
[[package]] [[package]]
@ -1559,17 +1565,18 @@ dependencies = [
[[package]] [[package]]
name = "windows-targets" name = "windows-targets"
version = "0.52.4" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [ dependencies = [
"windows_aarch64_gnullvm 0.52.4", "windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.4", "windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.4", "windows_i686_gnu 0.52.6",
"windows_i686_msvc 0.52.4", "windows_i686_gnullvm",
"windows_x86_64_gnu 0.52.4", "windows_i686_msvc 0.52.6",
"windows_x86_64_gnullvm 0.52.4", "windows_x86_64_gnu 0.52.6",
"windows_x86_64_msvc 0.52.4", "windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
] ]
[[package]] [[package]]
@ -1580,9 +1587,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]] [[package]]
name = "windows_aarch64_gnullvm" name = "windows_aarch64_gnullvm"
version = "0.52.4" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
@ -1592,9 +1599,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.52.4" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
@ -1604,9 +1611,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.52.4" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
@ -1616,9 +1629,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.52.4" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
@ -1628,9 +1641,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.52.4" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
@ -1640,9 +1653,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.52.4" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
@ -1652,15 +1665,15 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.52.4" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.6.6" version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352" checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]

View File

@ -1,8 +1,8 @@
[package] [package]
name = "changelogger" name = "changelogger"
version = "0.1.0" version = "0.2.0"
authors = ["AWS Rust SDK Team <aws-sdk-rust@amazon.com>"] authors = ["AWS Rust SDK Team <aws-sdk-rust@amazon.com>"]
description = "A CLI tool render and update changelogs from TOML changelog files" description = "A CLI tool render and update changelogs from changelog files"
edition = "2021" edition = "2021"
license = "Apache-2.0" license = "Apache-2.0"
publish = false publish = false

View File

@ -1,14 +1,82 @@
# ChangeLogger # ChangeLogger
The Changelogger tool generates public facing `.md` changelogs from the structured `CHANGELOG.next.toml` formats that developers modify. The changelogger runs during smithy-rs releases to generate the smithy-rs specific changelog as well as during SDK releases to generate the SDK changelog. The smithy-rs changelog generation moves the AWS changelog entries into a separate file so that they can later be consumed. The ChangeLogger tool generates public facing `.md` changelogs from the individual changelog entry Markdown files stored in the `.changelog` directory. The changelogger runs during smithy-rs releases to generate the smithy-rs specific changelog as well as during SDK releases to generate the SDK changelog. The smithy-rs changelog generation duplicates the AWS changelog entries into a separate file so that they can later be consumed.
[smithy-rs-maintainers.txt](./smithy-rs-maintainers.txt) controls the set of users that is **not** acknowledged for their contributions in changelogs. [smithy-rs-maintainers.txt](./smithy-rs-maintainers.txt) controls the set of users that is **not** acknowledged for their contributions in changelogs.
## Commands ## Commands
### Split ### Ls
Splits changelog entries into two `json` files, splitting up `aws-sdk-rust` entries from `smithy-rs` entries. This is a prestep to full changelog generation. The end result is `aws/SDK_CHANGELOG.next.json`. Display a preview of pending changelog entries (either for `smithy-rs` or for `aws-sdk-rust`) since the last release to standard output.
This command is invoked as part of `smithy-rs-release`. This command is intended for developer use.
### New
Create a new changelog entry Markdown file in the `.changelog` directory.
This command is intended for developer use.
### Render ### Render
Render a `.md` format changelog from a structured changelog. Render a `.md` format changelog from changelog entry Markdown files stored in the `.changelog` directory.
This command is intended for automation and invoked as part of `smithy-rs-release`.
### Split
Duplicate `aws-sdk-rust` entries from those in the `.changelog` directory into `aws/SDK_CHANGELOG.next.json`, which is a prestep to full changelog generation.
This command is intended for automation and invoked as part of `smithy-rs-release`.
## Installation
To install, run the following from this README path:
```
$ cargo install --locked --path .
```
Confirm the installation:
```
$ changelogger --version
```
## How to Use
### Ls
To preview changelog entries for an upcoming release in `smithy-rs`:
```
$ changelogger ls --change-set smithy-rs
```
To preview changelog entries for an upcoming release in `aws-sdk-rust`:
```
$ changelogger ls --change-set aws-sdk
```
### New
An example usage:
```
$ changelogger new \
--applies-to client \
--applies-to aws-sdk-rust \
--references smithy-rs#1234 \
--authors someone \
--bug-fix \
--message "Some changelog for \`foo\`"
The following changelog entry has been written to "<smithy-rs root>/.changelog/8814816.md":
---
applies_to:
- aws-sdk-rust
- client
authors:
- someone
references:
- smithy-rs#1234
breaking: false
new_feature: false
bug_fix: true
---
Some changelog for `foo`
```
The following CLI arguments are "logically" required
- `--applies-to`
- `--authors`
- `--references`
- `--message`
If any of the above is not passed a value at command line, then the user's editor is opened for further edit (which editor to open can be configured per the [edit crate](https://docs.rs/edit/0.1.5/edit/)).

View File

@ -1,16 +0,0 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
use crate::render::EXAMPLE_ENTRY;
use clap::Parser;
use std::io::Write;
#[derive(Parser, Debug, Eq, PartialEq)]
pub struct InitArgs {}
pub fn subcommand_init(_args: &InitArgs) -> anyhow::Result<()> {
writeln!(std::io::stdout(), "{}", EXAMPLE_ENTRY)?;
Ok(())
}

View File

@ -4,7 +4,6 @@
*/ */
pub mod entry; pub mod entry;
pub mod init;
pub mod ls; pub mod ls;
pub mod new; pub mod new;
pub mod render; pub mod render;

View File

@ -4,21 +4,26 @@
*/ */
use anyhow::Result; use anyhow::Result;
use changelogger::init::subcommand_init;
use changelogger::ls::subcommand_ls; use changelogger::ls::subcommand_ls;
use changelogger::new::subcommand_new; use changelogger::new::subcommand_new;
use changelogger::render::subcommand_render; use changelogger::render::subcommand_render;
use changelogger::split::subcommand_split; use changelogger::split::subcommand_split;
use clap::Parser; use clap::{Parser, Subcommand};
#[derive(Parser, Debug, Eq, PartialEq)] #[derive(Parser, Debug, Eq, PartialEq)]
#[clap(name = "changelogger", author, version, about)] #[clap(name = "changelogger", author, version, about)]
pub enum Args { pub struct Args {
/// Print to stdout the empty "next" CHANGELOG template #[clap(subcommand)]
Init(changelogger::init::InitArgs), command: Command,
}
#[derive(Subcommand, Debug, Eq, PartialEq)]
enum Command {
/// Create a new changelog entry Markdown file in the `smithy-rs/.changelog` directory /// Create a new changelog entry Markdown file in the `smithy-rs/.changelog` directory
#[clap(visible_alias("n"))]
New(changelogger::new::NewArgs), New(changelogger::new::NewArgs),
/// Render a preview of changelog entries since the last release /// Render a preview of changelog entries since the last release
#[clap(visible_alias("l"))]
Ls(changelogger::ls::LsArgs), Ls(changelogger::ls::LsArgs),
/// Render a TOML/JSON changelog into GitHub-flavored Markdown /// Render a TOML/JSON changelog into GitHub-flavored Markdown
Render(changelogger::render::RenderArgs), Render(changelogger::render::RenderArgs),
@ -27,18 +32,18 @@ pub enum Args {
} }
fn main() -> Result<()> { fn main() -> Result<()> {
match Args::parse() { use Command::*;
Args::Init(init) => subcommand_init(&init), match Args::parse().command {
Args::New(new) => subcommand_new(new), New(new) => subcommand_new(new),
Args::Ls(ls) => subcommand_ls(ls), Ls(ls) => subcommand_ls(ls),
Args::Render(render) => subcommand_render(&render), Render(render) => subcommand_render(&render),
Args::Split(split) => subcommand_split(&split), Split(split) => subcommand_split(&split),
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::Args; use super::{Args, Command};
use changelogger::entry::ChangeSet; use changelogger::entry::ChangeSet;
use changelogger::ls::LsArgs; use changelogger::ls::LsArgs;
use changelogger::new::NewArgs; use changelogger::new::NewArgs;
@ -52,12 +57,14 @@ mod tests {
#[test] #[test]
fn args_parsing() { fn args_parsing() {
assert_eq!( assert_eq!(
Args::Split(SplitArgs { Args {
source: PathBuf::from("fromplace"), command: Command::Split(SplitArgs {
destination: PathBuf::from("someplace"), source: PathBuf::from("fromplace"),
since_commit: None, destination: PathBuf::from("someplace"),
smithy_rs_location: None, since_commit: None,
}), smithy_rs_location: None,
})
},
Args::try_parse_from([ Args::try_parse_from([
"./changelogger", "./changelogger",
"split", "split",
@ -70,18 +77,20 @@ mod tests {
); );
assert_eq!( assert_eq!(
Args::Render(RenderArgs { Args {
change_set: ChangeSet::SmithyRs, command: Command::Render(RenderArgs {
independent_versioning: false, change_set: ChangeSet::SmithyRs,
source: vec![PathBuf::from("fromplace")], independent_versioning: false,
source_to_truncate: PathBuf::from("fromplace"), source: vec![PathBuf::from("fromplace")],
changelog_output: PathBuf::from("some-changelog"), changelog_output: PathBuf::from("some-changelog"),
release_manifest_output: Some(PathBuf::from("some-manifest")), source_to_truncate: Some(PathBuf::from("fromplace")),
current_release_versions_manifest: None, release_manifest_output: Some(PathBuf::from("some-manifest")),
previous_release_versions_manifest: None, current_release_versions_manifest: None,
date_override: None, previous_release_versions_manifest: None,
smithy_rs_location: None, date_override: None,
}), smithy_rs_location: None,
})
},
Args::try_parse_from([ Args::try_parse_from([
"./changelogger", "./changelogger",
"render", "render",
@ -100,21 +109,23 @@ mod tests {
); );
assert_eq!( assert_eq!(
Args::Render(RenderArgs { Args {
change_set: ChangeSet::AwsSdk, command: Command::Render(RenderArgs {
independent_versioning: true, change_set: ChangeSet::AwsSdk,
source: vec![ independent_versioning: true,
PathBuf::from("fromplace"), source: vec![
PathBuf::from("fromanotherplace") PathBuf::from("fromplace"),
], PathBuf::from("fromanotherplace")
source_to_truncate: PathBuf::from("fromplace"), ],
changelog_output: PathBuf::from("some-changelog"), changelog_output: PathBuf::from("some-changelog"),
release_manifest_output: None, source_to_truncate: Some(PathBuf::from("fromplace")),
current_release_versions_manifest: None, release_manifest_output: None,
previous_release_versions_manifest: None, current_release_versions_manifest: None,
date_override: None, previous_release_versions_manifest: None,
smithy_rs_location: None, date_override: None,
}), smithy_rs_location: None,
})
},
Args::try_parse_from([ Args::try_parse_from([
"./changelogger", "./changelogger",
"render", "render",
@ -134,18 +145,22 @@ mod tests {
); );
assert_eq!( assert_eq!(
Args::Render(RenderArgs { Args {
change_set: ChangeSet::AwsSdk, command: Command::Render(RenderArgs {
independent_versioning: true, change_set: ChangeSet::AwsSdk,
source: vec![PathBuf::from("fromplace")], independent_versioning: true,
source_to_truncate: PathBuf::from("fromplace"), source: vec![PathBuf::from("fromplace")],
changelog_output: PathBuf::from("some-changelog"), changelog_output: PathBuf::from("some-changelog"),
release_manifest_output: None, source_to_truncate: Some(PathBuf::from("fromplace")),
current_release_versions_manifest: None, release_manifest_output: None,
previous_release_versions_manifest: Some(PathBuf::from("path/to/versions.toml")), current_release_versions_manifest: None,
date_override: None, previous_release_versions_manifest: Some(PathBuf::from(
smithy_rs_location: None, "path/to/versions.toml"
}), )),
date_override: None,
smithy_rs_location: None,
})
},
Args::try_parse_from([ Args::try_parse_from([
"./changelogger", "./changelogger",
"render", "render",
@ -165,22 +180,24 @@ mod tests {
); );
assert_eq!( assert_eq!(
Args::Render(RenderArgs { Args {
change_set: ChangeSet::AwsSdk, command: Command::Render(RenderArgs {
independent_versioning: true, change_set: ChangeSet::AwsSdk,
source: vec![PathBuf::from("fromplace")], independent_versioning: true,
source_to_truncate: PathBuf::from("fromplace"), source: vec![PathBuf::from("fromplace")],
changelog_output: PathBuf::from("some-changelog"), changelog_output: PathBuf::from("some-changelog"),
release_manifest_output: None, source_to_truncate: Some(PathBuf::from("fromplace")),
current_release_versions_manifest: Some(PathBuf::from( release_manifest_output: None,
"path/to/current/versions.toml" current_release_versions_manifest: Some(PathBuf::from(
)), "path/to/current/versions.toml"
previous_release_versions_manifest: Some(PathBuf::from( )),
"path/to/previous/versions.toml" previous_release_versions_manifest: Some(PathBuf::from(
)), "path/to/previous/versions.toml"
date_override: None, )),
smithy_rs_location: None, date_override: None,
}), smithy_rs_location: None,
})
},
Args::try_parse_from([ Args::try_parse_from([
"./changelogger", "./changelogger",
"render", "render",
@ -202,19 +219,21 @@ mod tests {
); );
assert_eq!( assert_eq!(
Args::New(NewArgs { Args {
applies_to: Some(vec![Target::Client, Target::AwsSdk]), command: Command::New(NewArgs {
authors: Some(vec!["external-contrib".to_owned(), "ysaito1001".to_owned()]), applies_to: Some(vec![Target::Client, Target::AwsSdk]),
references: Some(vec![ authors: Some(vec!["external-contrib".to_owned(), "ysaito1001".to_owned()]),
Reference::from_str("smithy-rs#1234").unwrap(), references: Some(vec![
Reference::from_str("aws-sdk-rust#5678").unwrap() Reference::from_str("smithy-rs#1234").unwrap(),
]), Reference::from_str("aws-sdk-rust#5678").unwrap()
breaking: false, ]),
new_feature: true, breaking: false,
bug_fix: false, new_feature: true,
message: Some("Implement a long-awaited feature for S3".to_owned()), bug_fix: false,
basename: None, message: Some("Implement a long-awaited feature for S3".to_owned()),
}), basename: None,
})
},
Args::try_parse_from([ Args::try_parse_from([
"./changelogger", "./changelogger",
"new", "new",
@ -238,16 +257,20 @@ mod tests {
); );
assert_eq!( assert_eq!(
Args::Ls(LsArgs { Args {
change_set: ChangeSet::SmithyRs command: Command::Ls(LsArgs {
}), change_set: ChangeSet::SmithyRs
})
},
Args::try_parse_from(["./changelogger", "ls", "--change-set", "smithy-rs",]).unwrap() Args::try_parse_from(["./changelogger", "ls", "--change-set", "smithy-rs",]).unwrap()
); );
assert_eq!( assert_eq!(
Args::Ls(LsArgs { Args {
change_set: ChangeSet::AwsSdk command: Command::Ls(LsArgs {
}), change_set: ChangeSet::AwsSdk
})
},
Args::try_parse_from(["./changelogger", "ls", "--change-set", "aws-sdk",]).unwrap() Args::try_parse_from(["./changelogger", "ls", "--change-set", "aws-sdk",]).unwrap()
); );
} }

View File

@ -99,7 +99,8 @@ fn new_entry(markdown: Markdown) -> anyhow::Result<String> {
// This doesn't present practical issues when rendering changelogs. See // This doesn't present practical issues when rendering changelogs. See
// https://github.com/dtolnay/serde-yaml/issues/355 // https://github.com/dtolnay/serde-yaml/issues/355
let front_matter = serde_yaml::to_string(&markdown.front_matter)?; let front_matter = serde_yaml::to_string(&markdown.front_matter)?;
let changelog_entry = format!("---\n{}---\n{}", front_matter, markdown.message); // the last `\n` satisfies the `fix end of files` check in `sdk-lints`
let changelog_entry = format!("---\n{}---\n{}\n", front_matter, markdown.message);
let changelog_entry = if any_required_field_needs_to_be_filled(&markdown) { let changelog_entry = if any_required_field_needs_to_be_filled(&markdown) {
edit::edit(changelog_entry).context("failed while editing changelog entry)")? edit::edit(changelog_entry).context("failed while editing changelog entry)")?
} else { } else {
@ -151,7 +152,7 @@ mod tests {
"one or more required fields were not populated" "one or more required fields were not populated"
); );
let expected = "---\napplies_to:\n- client\nauthors:\n- ysaito1001\nreferences:\n- smithy-rs#1234\nbreaking: false\nnew_feature: true\nbug_fix: false\n---\nImplement a long-awaited feature for S3"; let expected = "---\napplies_to:\n- client\nauthors:\n- ysaito1001\nreferences:\n- smithy-rs#1234\nbreaking: false\nnew_feature: true\nbug_fix: false\n---\nImplement a long-awaited feature for S3\n";
let actual = new_entry(markdown).unwrap(); let actual = new_entry(markdown).unwrap();
assert_eq!(expected, &actual); assert_eq!(expected, &actual);

View File

@ -21,19 +21,16 @@ use std::fs;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use time::OffsetDateTime; use time::OffsetDateTime;
pub const EXAMPLE_ENTRY: &str = r#" pub const EXAMPLE_ENTRY: &str = r#"# Example changelog entry, Markdown with YAML front matter
# Example changelog entries # ---
# [[aws-sdk-rust]] # applies_to: ["client", "server", "aws-sdk-rust"] # "aws-sdk-rust" here duplicates this entry into release notes in `aws-sdk-rust`
# message = "Fix typos in module documentation for generated crates" # authors: ["rcoh"]
# references = ["smithy-rs#920"] # references: ["smithy-rs#920"]
# meta = { "breaking" = false, "tada" = false, "bug" = false } # breaking: false
# author = "rcoh" # new_feature: false
# # bug_fix: false
# [[smithy-rs]] # ---
# message = "Fix typos in module documentation for generated crates" # Fix typos in module documentation for generated crates
# references = ["smithy-rs#920"]
# meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "client | server | all"}
# author = "rcoh"
"#; "#;
pub const USE_UPDATE_CHANGELOGS: &str = pub const USE_UPDATE_CHANGELOGS: &str =
@ -62,11 +59,12 @@ pub struct RenderArgs {
/// Source changelog entries to render /// Source changelog entries to render
#[clap(long, action, required(true))] #[clap(long, action, required(true))]
pub source: Vec<PathBuf>, pub source: Vec<PathBuf>,
/// Which source to overwrite with an empty changelog template /// Where to output the rendered changelog entries
#[clap(long, action)]
pub source_to_truncate: PathBuf,
#[clap(long, action)] #[clap(long, action)]
pub changelog_output: PathBuf, pub changelog_output: PathBuf,
/// Optional directory path to the changelog directory to empty, leaving only `.example` in it
#[clap(long, action)]
pub source_to_truncate: Option<PathBuf>,
/// Optional path to output a release manifest file to /// Optional path to output a release manifest file to
#[clap(long, action)] #[clap(long, action)]
pub release_manifest_output: Option<PathBuf>, pub release_manifest_output: Option<PathBuf>,
@ -328,13 +326,15 @@ fn update_changelogs(
update.push_str(&current); update.push_str(&current);
std::fs::write(&args.changelog_output, update).context("failed to write rendered changelog")?; std::fs::write(&args.changelog_output, update).context("failed to write rendered changelog")?;
if args.source_to_truncate.is_dir() { if let Some(source_to_truncate) = &args.source_to_truncate {
fs::remove_dir_all(&args.source_to_truncate) fs::remove_dir_all(source_to_truncate)
.and_then(|_| fs::create_dir(&args.source_to_truncate)) .and_then(|_| fs::create_dir(source_to_truncate))
.with_context(|| format!("failed to empty directory {:?}", &args.source_to_truncate))?; .with_context(|| format!("failed to empty directory {:?}", source_to_truncate))
} else { .and_then(|_| {
fs::write(&args.source_to_truncate, EXAMPLE_ENTRY.trim()) let dot_example = source_to_truncate.join(".example");
.with_context(|| format!("failed to truncate source {:?}", &args.source_to_truncate))?; fs::write(dot_example.clone(), EXAMPLE_ENTRY)
.with_context(|| format!("failed to create {:?}", dot_example))
})?;
} }
eprintln!("Changelogs updated!"); eprintln!("Changelogs updated!");
Ok(()) Ok(())
@ -565,7 +565,7 @@ Thank you for your contributions! ❤
"#; "#;
#[test] #[test]
fn end_to_end_changelog_entry_markdown_files() { fn end_to_end_changelog() {
let temp_dir = TempDir::new().unwrap(); let temp_dir = TempDir::new().unwrap();
let smithy_rs_entry1 = r#"--- let smithy_rs_entry1 = r#"---
applies_to: ["client", "server"] applies_to: ["client", "server"]
@ -690,83 +690,6 @@ message = "Some API change"
pretty_assertions::assert_str_eq!(AWS_SDK_EXPECTED_END_TO_END, aws_sdk_rendered); pretty_assertions::assert_str_eq!(AWS_SDK_EXPECTED_END_TO_END, aws_sdk_rendered);
} }
#[test]
fn end_to_end_changelog() {
let changelog_toml = r#"
[[smithy-rs]]
author = ["rcoh", "jdisanti"]
message = "I made a major change to update the code generator"
meta = { breaking = true, tada = false, bug = false }
references = ["smithy-rs#445"]
[[smithy-rs]]
author = ["external-contrib", "other-external-dev"]
message = "I made a change to update the code generator"
meta = { breaking = false, tada = true, bug = false }
references = ["smithy-rs#446", "aws-sdk#123"]
[[smithy-rs]]
author = "another-contrib"
message = "I made a minor change"
meta = { breaking = false, tada = false, bug = false }
references = ["smithy-rs#200"]
[[aws-sdk-rust]]
author = "rcoh"
message = "I made a major change to update the AWS SDK"
meta = { breaking = true, tada = false, bug = false }
references = ["smithy-rs#445"]
[[aws-sdk-rust]]
author = "external-contrib"
message = "I made a change to update the code generator"
meta = { breaking = false, tada = true, bug = false }
references = ["smithy-rs#446"]
[[smithy-rs]]
authors = ["external-contrib", "other-external-dev"]
message = """
I made a change to update the code generator
**Update guide:**
blah blah
"""
meta = { breaking = false, tada = true, bug = false }
references = ["smithy-rs#446", "smithy-rs#447"]
[[aws-sdk-model]]
module = "aws-sdk-s3"
version = "0.14.0"
kind = "Feature"
message = "Some new API to do X"
[[aws-sdk-model]]
module = "aws-sdk-ec2"
version = "0.12.0"
kind = "Documentation"
message = "Updated some docs"
[[aws-sdk-model]]
module = "aws-sdk-ec2"
version = "0.12.0"
kind = "Feature"
message = "Some API change"
"#;
let changelog: Changelog = ChangelogLoader::default()
.parse_str(changelog_toml)
.expect("valid changelog");
let ChangelogEntries {
aws_sdk_rust,
smithy_rs,
} = changelog.into();
let smithy_rs_rendered = render_full(&smithy_rs, "v0.3.0 (January 4th, 2022)");
pretty_assertions::assert_str_eq!(SMITHY_RS_EXPECTED_END_TO_END, smithy_rs_rendered);
let aws_sdk_rust_rendered = render_full(&aws_sdk_rust, "v0.1.0 (January 4th, 2022)");
pretty_assertions::assert_str_eq!(AWS_SDK_EXPECTED_END_TO_END, aws_sdk_rust_rendered);
}
#[test] #[test]
fn test_date_based_release_metadata() { fn test_date_based_release_metadata() {
let now = OffsetDateTime::from_unix_timestamp(100_000_000).unwrap(); let now = OffsetDateTime::from_unix_timestamp(100_000_000).unwrap();
@ -778,53 +701,75 @@ message = "Some API change"
#[test] #[test]
fn test_partition_client_server() { fn test_partition_client_server() {
let sample = r#" let smithy_rs_entry1 = r#"---
[[smithy-rs]] applies_to: ["server"]
author = "external-contrib" authors: ["external-contrib"]
message = """ references: ["smithy-rs#446"]
breaking: true
new_feature: true
bug_fix: false
---
this is a multiline this is a multiline
message message
""" "#;
meta = { breaking = false, tada = true, bug = false, target = "server" } let smithy_rs_entry2 = r#"---
references = ["smithy-rs#446"] applies_to: ["client"]
authors: ["external-contrib"]
references: ["smithy-rs#446"]
breaking: false
new_feature: true
bug_fix: false
---
a client message
"#;
let smithy_rs_entry3 = r#"---
applies_to: ["client", "server"]
authors: ["rcoh"]
references: ["smithy-rs#446"]
breaking: false
new_feature: false
bug_fix: false
---
a change for both
"#;
let smithy_rs_entry4 = r#"---
applies_to: ["client", "server"]
authors: ["external-contrib", "other-external-dev"]
references: ["smithy-rs#446", "smithy-rs#447"]
breaking: false
new_feature: true
bug_fix: false
---
I made a change to update the code generator
**Update guide:**
blah blah
"#;
let model_update = r#"
[[aws-sdk-model]] [[aws-sdk-model]]
module = "aws-sdk-s3" module = "aws-sdk-s3"
version = "0.14.0" version = "0.14.0"
kind = "Feature" kind = "Feature"
message = "Some new API to do X" message = "Some new API to do X"
[[smithy-rs]]
author = "external-contrib"
message = "a client message"
meta = { breaking = false, tada = true, bug = false, target = "client" }
references = ["smithy-rs#446"]
[[smithy-rs]]
message = "a change for both"
meta = { breaking = false, tada = true, bug = false, target = "all" }
references = ["smithy-rs#446"]
author = "rcoh"
[[smithy-rs]]
message = "a missing sdk meta"
meta = { breaking = false, tada = true, bug = false }
references = ["smithy-rs#446"]
author = "rcoh"
"#; "#;
let changelog: Changelog = ChangelogLoader::default() let loader = ChangelogLoader::default();
.parse_str(sample) let changelog = [
.expect("valid changelog"); smithy_rs_entry1,
smithy_rs_entry2,
smithy_rs_entry3,
smithy_rs_entry4,
model_update,
]
.iter()
.fold(Changelog::new(), |mut combined_changelog, value| {
combined_changelog.merge(loader.parse_str(value).expect("String should have parsed"));
combined_changelog
});
let ChangelogEntries { let ChangelogEntries {
aws_sdk_rust: _, aws_sdk_rust: _,
smithy_rs, smithy_rs,
} = changelog.into(); } = changelog.into();
let affected = vec![ let affected = vec![SdkAffected::Server, SdkAffected::Client, SdkAffected::All];
SdkAffected::Server,
SdkAffected::Client,
SdkAffected::All,
SdkAffected::All,
];
let entries = smithy_rs let entries = smithy_rs
.iter() .iter()
.filter_map(ChangelogEntry::hand_authored) .filter_map(ChangelogEntry::hand_authored)

View File

@ -14,12 +14,6 @@ use std::{env, fs, mem};
// SDK changelog entries, but small enough that the SDK changelog file // SDK changelog entries, but small enough that the SDK changelog file
// doesn't get too long. // doesn't get too long.
const MAX_ENTRY_AGE: usize = 5; const MAX_ENTRY_AGE: usize = 5;
// TODO(file-per-change-changelog): Remove `INTERMEDIATE_SOURCE_HEADER` once we have switched over
// to the new markdown format.
const INTERMEDIATE_SOURCE_HEADER: &str =
"# This is an intermediate file that will be replaced after automation is complete.\n\
# It will be used to generate a changelog entry for smithy-rs.\n\
# Do not commit the contents of this file!\n";
const DEST_HEADER: &str = const DEST_HEADER: &str =
"# This file will be used by automation when cutting a release of the SDK\n\ "# This file will be used by automation when cutting a release of the SDK\n\
@ -67,16 +61,10 @@ pub fn subcommand_split(args: &SplitArgs) -> Result<()> {
Changelog::new() Changelog::new()
}; };
let (smithy_rs_entries, new_sdk_entries) = ( let new_sdk_entries =
smithy_rs_entries(combined_changelog.clone()), sdk_entries(args, combined_changelog).context("failed to filter SDK entries")?;
sdk_entries(args, combined_changelog).context("failed to filter SDK entries")?,
);
let sdk_changelog = merge_sdk_entries(current_sdk_changelog, new_sdk_entries); let sdk_changelog = merge_sdk_entries(current_sdk_changelog, new_sdk_entries);
// TODO(file-per-change-changelog): Remove writing to `INTERMEDIATE_SOURCE_HEADER` once we have
// switched over to the new markdown format.
write_entries(&args.source, INTERMEDIATE_SOURCE_HEADER, &smithy_rs_entries)
.context("failed to write source")?;
write_entries(&args.destination, DEST_HEADER, &sdk_changelog) write_entries(&args.destination, DEST_HEADER, &sdk_changelog)
.context("failed to write destination")?; .context("failed to write destination")?;
Ok(()) Ok(())
@ -106,12 +94,6 @@ fn sdk_entries(args: &SplitArgs, mut changelog: Changelog) -> Result<Changelog>
Ok(changelog) Ok(changelog)
} }
fn smithy_rs_entries(mut changelog: Changelog) -> Changelog {
changelog.aws_sdk_rust.clear();
changelog.sdk_models.clear();
changelog
}
fn merge_sdk_entries(old_changelog: Changelog, new_changelog: Changelog) -> Changelog { fn merge_sdk_entries(old_changelog: Changelog, new_changelog: Changelog) -> Changelog {
let mut merged = old_changelog; let mut merged = old_changelog;
merged.merge(new_changelog); merged.merge(new_changelog);

View File

@ -10,32 +10,43 @@ use smithy_rs_tool_common::changelog::{Changelog, HandAuthoredEntry};
use smithy_rs_tool_common::git::{CommitHash, Git, GitCLI}; use smithy_rs_tool_common::git::{CommitHash, Git, GitCLI};
use smithy_rs_tool_common::shell::handle_failure; use smithy_rs_tool_common::shell::handle_failure;
use std::fs; use std::fs;
use std::path::Path; use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
use tempfile::TempDir; use tempfile::TempDir;
use time::OffsetDateTime; use time::OffsetDateTime;
const SOURCE_TOML: &str = r#" const SOURCE_MARKDOWN1: &str = r#"---
[[aws-sdk-rust]] applies_to: ["aws-sdk-rust"]
message = "Some change" authors: ["test-dev"]
references = ["aws-sdk-rust#123", "smithy-rs#456"] references: ["aws-sdk-rust#123", "smithy-rs#456"]
meta = { "breaking" = false, "tada" = false, "bug" = true } breaking: false
since-commit = "REPLACE_SINCE_COMMIT_1" new_feature: false
author = "test-dev" bug_fix: true
---
Some change
"#;
[[aws-sdk-rust]] const SOURCE_MARKDOWN2: &str = r#"---
message = "Some other change" applies_to: ["aws-sdk-rust"]
references = ["aws-sdk-rust#234", "smithy-rs#567"] authors: ["test-dev"]
meta = { "breaking" = false, "tada" = false, "bug" = true } references: ["aws-sdk-rust#234", "smithy-rs#567"]
since-commit = "REPLACE_SINCE_COMMIT_2" breaking: false
author = "test-dev" new_feature: false
bug_fix: true
---
Some other change
"#;
[[smithy-rs]] const SOURCE_MARKDOWN3: &str = r#"---
message = "Another change" applies_to: ["client", "server"]
references = ["smithy-rs#1234"] authors: ["another-dev"]
meta = { "breaking" = false, "tada" = false, "bug" = false } references: ["smithy-rs#1234"]
author = "another-dev" breaking: false
"#; new_feature: false
bug_fix: false
---
Another change
"#;
const SDK_MODEL_SOURCE_TOML: &str = r#" const SDK_MODEL_SOURCE_TOML: &str = r#"
[[aws-sdk-model]] [[aws-sdk-model]]
@ -128,15 +139,36 @@ fn create_fake_repo_root(
(release_commits.remove(0), release_commits.remove(0)) (release_commits.remove(0), release_commits.remove(0))
} }
fn create_changelog_entry_markdown_files(
markdown_files: &[&str],
changelog_dir: &Path,
) -> Vec<PathBuf> {
let mut source_paths = Vec::with_capacity(markdown_files.len());
markdown_files.iter().enumerate().for_each(|(i, md)| {
let source_path = changelog_dir.join(format!("source{i}.md"));
fs::write(&source_path, md.trim()).unwrap();
source_paths.push(source_path);
});
source_paths
}
#[test] #[test]
fn split_aws_sdk() { fn split_aws_sdk() {
let tmp_dir = TempDir::new().unwrap(); let tmp_dir = TempDir::new().unwrap();
let source_path = tmp_dir.path().join("source.toml"); let dot_changelog = TempDir::new_in(tmp_dir.path()).unwrap();
let dot_changelog_path = dot_changelog.path().to_owned();
let dest_path = tmp_dir.path().join("dest.toml"); let dest_path = tmp_dir.path().join("dest.toml");
create_fake_repo_root(tmp_dir.path(), "0.42.0", "0.12.0"); create_fake_repo_root(tmp_dir.path(), "0.42.0", "0.12.0");
create_changelog_entry_markdown_files(
fs::write(&source_path, SOURCE_TOML).unwrap(); // Exclude `SOURCE_MARKDOWN2` to make string comparison verification at the end of this
// function deterministic across platforms. If `SOURCE_MARKDOWN2` were included, `dest_path`
// might list `SOURCE_MARKDOWN1` and `SOURCE_MARKDOWN2` in an non-deterministic order due to
// the use of `std::fs::read_dir` in `ChangelogLoader::load_from_dir`, making the test
// brittle.
&[SOURCE_MARKDOWN1, SOURCE_MARKDOWN3],
&dot_changelog_path,
);
let mut original_dest_changelog = Changelog::new(); let mut original_dest_changelog = Changelog::new();
original_dest_changelog original_dest_changelog
@ -162,43 +194,15 @@ fn split_aws_sdk() {
.unwrap(); .unwrap();
subcommand_split(&SplitArgs { subcommand_split(&SplitArgs {
source: source_path.clone(), source: dot_changelog_path,
destination: dest_path.clone(), destination: dest_path.clone(),
since_commit: Some("test-commit-hash".into()), since_commit: Some("test-commit-hash".into()),
smithy_rs_location: Some(tmp_dir.path().into()), smithy_rs_location: Some(tmp_dir.path().into()),
}) })
.unwrap(); .unwrap();
let source = fs::read_to_string(&source_path).unwrap();
let dest = fs::read_to_string(&dest_path).unwrap(); let dest = fs::read_to_string(&dest_path).unwrap();
pretty_assertions::assert_str_eq!(
r#"# This is an intermediate file that will be replaced after automation is complete.
# It will be used to generate a changelog entry for smithy-rs.
# Do not commit the contents of this file!
{
"smithy-rs": [
{
"message": "Another change",
"meta": {
"bug": false,
"breaking": false,
"tada": false,
"target": "all"
},
"author": "another-dev",
"references": [
"smithy-rs#1234"
],
"since-commit": null
}
],
"aws-sdk-rust": [],
"aws-sdk-model": []
}"#,
source
);
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
r#"# This file will be used by automation when cutting a release of the SDK r#"# This file will be used by automation when cutting a release of the SDK
# to include code generator change log entries into the release notes. # to include code generator change log entries into the release notes.
@ -233,21 +237,6 @@ fn split_aws_sdk() {
], ],
"since-commit": "test-commit-hash", "since-commit": "test-commit-hash",
"age": 1 "age": 1
},
{
"message": "Some other change",
"meta": {
"bug": true,
"breaking": false,
"tada": false
},
"author": "test-dev",
"references": [
"aws-sdk-rust#234",
"smithy-rs#567"
],
"since-commit": "test-commit-hash",
"age": 1
} }
], ],
"aws-sdk-model": [] "aws-sdk-model": []
@ -259,13 +248,17 @@ fn split_aws_sdk() {
#[test] #[test]
fn render_smithy_rs() { fn render_smithy_rs() {
let tmp_dir = TempDir::new().unwrap(); let tmp_dir = TempDir::new().unwrap();
let source_path = tmp_dir.path().join("source.toml"); let dot_changelog = TempDir::new_in(tmp_dir.path()).unwrap();
let dot_changelog_path = dot_changelog.path().to_owned();
let dest_path = tmp_dir.path().join("dest.md"); let dest_path = tmp_dir.path().join("dest.md");
let release_manifest_path = tmp_dir.path().join("smithy-rs-release-manifest.json"); let release_manifest_path = tmp_dir.path().join("smithy-rs-release-manifest.json");
create_fake_repo_root(tmp_dir.path(), "0.42.0", "0.12.0"); create_fake_repo_root(tmp_dir.path(), "0.42.0", "0.12.0");
fs::write(&source_path, SOURCE_TOML).unwrap(); create_changelog_entry_markdown_files(
&[SOURCE_MARKDOWN1, SOURCE_MARKDOWN2, SOURCE_MARKDOWN3],
&dot_changelog_path,
);
fs::write( fs::write(
&dest_path, &dest_path,
format!( format!(
@ -279,9 +272,9 @@ fn render_smithy_rs() {
subcommand_render(&RenderArgs { subcommand_render(&RenderArgs {
change_set: ChangeSet::SmithyRs, change_set: ChangeSet::SmithyRs,
independent_versioning: true, independent_versioning: true,
source: vec![source_path.clone()], source: vec![dot_changelog_path.clone()],
source_to_truncate: source_path.clone(),
changelog_output: dest_path.clone(), changelog_output: dest_path.clone(),
source_to_truncate: Some(dot_changelog_path.clone()),
release_manifest_output: Some(tmp_dir.path().into()), release_manifest_output: Some(tmp_dir.path().into()),
date_override: Some(OffsetDateTime::UNIX_EPOCH), date_override: Some(OffsetDateTime::UNIX_EPOCH),
current_release_versions_manifest: None, current_release_versions_manifest: None,
@ -290,11 +283,11 @@ fn render_smithy_rs() {
}) })
.unwrap(); .unwrap();
let source = fs::read_to_string(&source_path).unwrap(); let dot_example = fs::read_to_string(dot_changelog_path.join(".example")).unwrap();
let dest = fs::read_to_string(&dest_path).unwrap(); let dest = fs::read_to_string(&dest_path).unwrap();
let release_manifest = fs::read_to_string(&release_manifest_path).unwrap(); let release_manifest = fs::read_to_string(&release_manifest_path).unwrap();
pretty_assertions::assert_str_eq!(EXAMPLE_ENTRY.trim(), source); pretty_assertions::assert_str_eq!(EXAMPLE_ENTRY, dot_example);
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
r#"<!-- Do not manually edit this file. Use the `changelogger` tool. --> r#"<!-- Do not manually edit this file. Use the `changelogger` tool. -->
January 1st, 1970 January 1st, 1970
@ -328,23 +321,42 @@ Old entry contents
#[test] #[test]
fn render_aws_sdk() { fn render_aws_sdk() {
let tmp_dir = TempDir::new().unwrap(); let tmp_dir = TempDir::new().unwrap();
let source1_path = tmp_dir.path().join("source1.toml"); let dot_changelog = TempDir::new_in(tmp_dir.path()).unwrap();
let source2_path = tmp_dir.path().join("source2.toml"); let dot_changelog_path = dot_changelog.path().to_owned();
let model_source_path = tmp_dir.path().join("model_source.toml");
let dest_path = tmp_dir.path().join("dest.md"); let dest_path = tmp_dir.path().join("dest.md");
let release_manifest_path = tmp_dir.path().join("aws-sdk-rust-release-manifest.json"); let release_manifest_path = tmp_dir.path().join("aws-sdk-rust-release-manifest.json");
let previous_versions_manifest_path = tmp_dir.path().join("versions.toml"); let previous_versions_manifest_path = tmp_dir.path().join("versions.toml");
let (release_1_commit, release_2_commit) = let (last_release_commit, _) = create_fake_repo_root(tmp_dir.path(), "0.42.0", "0.12.0");
create_fake_repo_root(tmp_dir.path(), "0.42.0", "0.12.0"); let source_paths = create_changelog_entry_markdown_files(
&[SOURCE_MARKDOWN1, SOURCE_MARKDOWN3],
&dot_changelog_path,
);
// Replicate the state by running the `split` subcommand where `SOURCE_MARKDOWN1` is saved in
// `dest_path` as an old release SDK changelog entry. That's done by `last_release_commit` will
// be the value of `since-commit` for SOURCE_MARKDOWN1
subcommand_split(&SplitArgs {
source: dot_changelog_path.clone(),
destination: dest_path.clone(),
since_commit: Some(last_release_commit.as_ref().to_owned()),
smithy_rs_location: Some(tmp_dir.path().into()),
})
.unwrap();
// After split, make sure to remove `SOURCE_MARKDOWN1` from the changelog directory otherwise
// it'd be rendered when the subcommand `render` runs below.
fs::remove_file(&source_paths[0]).unwrap();
// Now that `SOURCE_MARKDOWN1` has been saved in `dest_path` as an old SDK entry, create a new
// SDK changelog entry in the changelog directory.
fs::write( fs::write(
&source1_path, &dot_changelog_path.join(format!("123456.md")),
SOURCE_TOML SOURCE_MARKDOWN2.trim(),
.replace("REPLACE_SINCE_COMMIT_1", release_1_commit.as_ref())
.replace("REPLACE_SINCE_COMMIT_2", release_2_commit.as_ref()),
) )
.unwrap(); .unwrap();
fs::write(&source2_path, SDK_MODEL_SOURCE_TOML).unwrap();
fs::write(&model_source_path, SDK_MODEL_SOURCE_TOML).unwrap();
fs::write( fs::write(
&dest_path, &dest_path,
format!( format!(
@ -357,9 +369,9 @@ fn render_aws_sdk() {
fs::write( fs::write(
&previous_versions_manifest_path, &previous_versions_manifest_path,
format!( format!(
"smithy_rs_revision = '{release_1_commit}' "smithy_rs_revision = '{last_release_commit}'
aws_doc_sdk_examples_revision = 'not-relevant' aws_doc_sdk_examples_revision = 'not-relevant'
[crates]", [crates]",
), ),
) )
.unwrap(); .unwrap();
@ -367,9 +379,9 @@ fn render_aws_sdk() {
subcommand_render(&RenderArgs { subcommand_render(&RenderArgs {
change_set: ChangeSet::AwsSdk, change_set: ChangeSet::AwsSdk,
independent_versioning: true, independent_versioning: true,
source: vec![source1_path.clone(), source2_path.clone()], source: vec![dot_changelog_path.clone(), model_source_path.clone()],
source_to_truncate: source1_path.clone(),
changelog_output: dest_path.clone(), changelog_output: dest_path.clone(),
source_to_truncate: Some(dot_changelog_path.clone()),
release_manifest_output: Some(tmp_dir.path().into()), release_manifest_output: Some(tmp_dir.path().into()),
date_override: Some(OffsetDateTime::UNIX_EPOCH), date_override: Some(OffsetDateTime::UNIX_EPOCH),
current_release_versions_manifest: None, current_release_versions_manifest: None,
@ -378,13 +390,13 @@ fn render_aws_sdk() {
}) })
.unwrap(); .unwrap();
let source1 = fs::read_to_string(&source1_path).unwrap(); let dot_example = fs::read_to_string(dot_changelog_path.join(".example")).unwrap();
let source2 = fs::read_to_string(&source2_path).unwrap(); let model_source = fs::read_to_string(&model_source_path).unwrap();
let dest = fs::read_to_string(&dest_path).unwrap(); let dest = fs::read_to_string(&dest_path).unwrap();
let release_manifest = fs::read_to_string(&release_manifest_path).unwrap(); let release_manifest = fs::read_to_string(&release_manifest_path).unwrap();
pretty_assertions::assert_str_eq!(EXAMPLE_ENTRY.trim(), source1); pretty_assertions::assert_str_eq!(EXAMPLE_ENTRY, dot_example);
pretty_assertions::assert_str_eq!(SDK_MODEL_SOURCE_TOML, source2); pretty_assertions::assert_str_eq!(SDK_MODEL_SOURCE_TOML, model_source);
// It should only have one of the SDK changelog entries since // It should only have one of the SDK changelog entries since
// the other should be filtered out by the `since_commit` attribute // the other should be filtered out by the `since_commit` attribute
@ -421,62 +433,32 @@ Old entry contents
); );
} }
/// entries with target set to each of the possible ones, and one entry with no target
/// set, which should result in the default
#[test] #[test]
fn render_smithy_entries() { fn render_server_smithy_entry() {
const NEXT_CHANGELOG: &str = r#" const SERVER_ONLY_MARKDOWN: &str = r#"---
# Example changelog entries applies_to: ["server"]
# [[aws-sdk-rust]] authors: ["server-dev"]
# message = "Fix typos in module documentation for generated crates" references: ["smithy-rs#1"]
# references = ["smithy-rs#920"] breaking: false
# meta = { "breaking" = false, "tada" = false, "bug" = false } new_feature: false
# author = "rcoh" bug_fix: false
# ---
# [[smithy-rs]] Change from server
# message = "Fix typos in module documentation for generated crates"
# references = ["smithy-rs#920"]
# meta = { "breaking" = false, "tada" = false, "bug" = false }
# author = "rcoh"
[[aws-sdk-rust]]
message = "Some change"
references = ["aws-sdk-rust#123", "smithy-rs#456"]
meta = { "breaking" = false, "tada" = false, "bug" = true }
since-commit = "REPLACE_SINCE_COMMIT_1"
author = "test-dev"
[[smithy-rs]]
message = "First change - server"
references = ["smithy-rs#1"]
meta = { "breaking" = false, "tada" = false, "bug" = false, target = "server" }
author = "server-dev"
[[smithy-rs]]
message = "Second change - should be all"
references = ["smithy-rs#2"]
meta = { "breaking" = false, "tada" = false, "bug" = false, target = "all" }
author = "another-dev"
[[smithy-rs]]
message = "Third change - empty"
references = ["smithy-rs#3"]
meta = { "breaking" = true, "tada" = false, "bug" = false }
author = "rcoh"
[[smithy-rs]]
message = "Fourth change - client"
references = ["smithy-rs#4"]
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "client" }
author = "rcoh"
"#; "#;
let tmp_dir = TempDir::new().unwrap(); let tmp_dir = TempDir::new().unwrap();
let source_path = tmp_dir.path().join("source.toml"); let dot_changelog = TempDir::new_in(tmp_dir.path()).unwrap();
let dot_changelog_path = dot_changelog.path().to_owned();
let dest_path = tmp_dir.path().join("dest.md"); let dest_path = tmp_dir.path().join("dest.md");
let release_manifest_path = tmp_dir.path().join("smithy-rs-release-manifest.json"); let release_manifest_path = tmp_dir.path().join("smithy-rs-release-manifest.json");
create_fake_repo_root(tmp_dir.path(), "0.42.0", "0.12.0"); create_fake_repo_root(tmp_dir.path(), "0.42.0", "0.12.0");
fs::write(&source_path, NEXT_CHANGELOG).unwrap(); create_changelog_entry_markdown_files(
// Not include other `smithy-rs` targeted entries other than `SERVER_ONLY_MARKDOWN` to make
// string comparison verification deterministic
&[SOURCE_MARKDOWN1, SOURCE_MARKDOWN2, SERVER_ONLY_MARKDOWN],
&dot_changelog_path,
);
fs::write( fs::write(
&dest_path, &dest_path,
format!( format!(
@ -490,9 +472,9 @@ author = "rcoh"
subcommand_render(&RenderArgs { subcommand_render(&RenderArgs {
change_set: ChangeSet::SmithyRs, change_set: ChangeSet::SmithyRs,
independent_versioning: true, independent_versioning: true,
source: vec![source_path.clone()], source: vec![dot_changelog_path.clone()],
source_to_truncate: source_path.clone(),
changelog_output: dest_path.clone(), changelog_output: dest_path.clone(),
source_to_truncate: Some(dot_changelog_path.clone()),
release_manifest_output: Some(tmp_dir.path().into()), release_manifest_output: Some(tmp_dir.path().into()),
date_override: Some(OffsetDateTime::UNIX_EPOCH), date_override: Some(OffsetDateTime::UNIX_EPOCH),
current_release_versions_manifest: None, current_release_versions_manifest: None,
@ -501,26 +483,20 @@ author = "rcoh"
}) })
.unwrap(); .unwrap();
let source = fs::read_to_string(&source_path).unwrap(); let dot_example = fs::read_to_string(dot_changelog_path.join(".example")).unwrap();
let dest = fs::read_to_string(&dest_path).unwrap(); let dest = fs::read_to_string(&dest_path).unwrap();
// source file should be empty // source file should be empty
pretty_assertions::assert_str_eq!(EXAMPLE_ENTRY.trim(), source); pretty_assertions::assert_str_eq!(EXAMPLE_ENTRY, &dot_example);
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
r#"<!-- Do not manually edit this file. Use the `changelogger` tool. --> r#"<!-- Do not manually edit this file. Use the `changelogger` tool. -->
January 1st, 1970 January 1st, 1970
================= =================
**Breaking Changes:**
- :warning: (all, [smithy-rs#3](https://github.com/smithy-lang/smithy-rs/issues/3)) Third change - empty
**New this release:** **New this release:**
- (server, [smithy-rs#1](https://github.com/smithy-lang/smithy-rs/issues/1), @server-dev) First change - server - (server, [smithy-rs#1](https://github.com/smithy-lang/smithy-rs/issues/1), @server-dev) Change from server
- (all, [smithy-rs#2](https://github.com/smithy-lang/smithy-rs/issues/2), @another-dev) Second change - should be all
- (client, [smithy-rs#4](https://github.com/smithy-lang/smithy-rs/issues/4)) Fourth change - client
**Contributors** **Contributors**
Thank you for your contributions! Thank you for your contributions!
- @another-dev ([smithy-rs#2](https://github.com/smithy-lang/smithy-rs/issues/2))
- @server-dev ([smithy-rs#1](https://github.com/smithy-lang/smithy-rs/issues/1)) - @server-dev ([smithy-rs#1](https://github.com/smithy-lang/smithy-rs/issues/1))
@ -533,61 +509,32 @@ Old entry contents
); );
} }
/// aws_sdk_rust should not be allowed to have target entries
#[test] #[test]
fn aws_sdk_cannot_have_target() { fn render_client_smithy_entry() {
const NEXT_CHANGELOG: &str = r#" const CLIENT_ONLY_MARKDOWN: &str = r#"---
# Example changelog entries applies_to: ["client"]
# [[aws-sdk-rust]] authors: ["client-dev"]
# message = "Fix typos in module documentation for generated crates" references: ["smithy-rs#4"]
# references = ["smithy-rs#920"] breaking: false
# meta = { "breaking" = false, "tada" = false, "bug" = false } new_feature: false
# author = "rcoh" bug_fix: false
# ---
# [[smithy-rs]] Change from client
# message = "Fix typos in module documentation for generated crates"
# references = ["smithy-rs#920"]
# meta = { "breaking" = false, "tada" = false, "bug" = false }
# author = "rcoh"
[[aws-sdk-rust]]
message = "Some change"
references = ["aws-sdk-rust#123", "smithy-rs#456"]
meta = { "breaking" = false, "tada" = false, "bug" = true, "target" = "client" }
since-commit = "REPLACE_SINCE_COMMIT_1"
author = "test-dev"
[[smithy-rs]]
message = "First change - server"
references = ["smithy-rs#1"]
meta = { "breaking" = false, "tada" = false, "bug" = false, target = "server" }
author = "server-dev"
[[smithy-rs]]
message = "Second change - should be all"
references = ["smithy-rs#2"]
meta = { "breaking" = false, "tada" = false, "bug" = false, target = "all" }
author = "another-dev"
[[smithy-rs]]
message = "Third change - empty"
references = ["smithy-rs#3"]
meta = { "breaking" = true, "tada" = false, "bug" = false }
author = "rcoh"
[[smithy-rs]]
message = "Fourth change - client"
references = ["smithy-rs#4"]
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "client" }
author = "rcoh"
"#; "#;
let tmp_dir = TempDir::new().unwrap(); let tmp_dir = TempDir::new().unwrap();
let source_path = tmp_dir.path().join("source.toml"); let dot_changelog = TempDir::new_in(tmp_dir.path()).unwrap();
let dot_changelog_path = dot_changelog.path().to_owned();
let dest_path = tmp_dir.path().join("dest.md"); let dest_path = tmp_dir.path().join("dest.md");
let release_manifest_path = tmp_dir.path().join("smithy-rs-release-manifest.json"); let release_manifest_path = tmp_dir.path().join("smithy-rs-release-manifest.json");
create_fake_repo_root(tmp_dir.path(), "0.42.0", "0.12.0"); create_fake_repo_root(tmp_dir.path(), "0.42.0", "0.12.0");
fs::write(&source_path, NEXT_CHANGELOG).unwrap(); create_changelog_entry_markdown_files(
// Not include other `smithy-rs` targeted entries other than `CLIENT_ONLY_MARKDOWN` to make
// string comparison verification deterministic
&[SOURCE_MARKDOWN1, SOURCE_MARKDOWN2, CLIENT_ONLY_MARKDOWN],
&dot_changelog_path,
);
fs::write( fs::write(
&dest_path, &dest_path,
format!( format!(
@ -598,40 +545,61 @@ author = "rcoh"
.unwrap(); .unwrap();
fs::write(release_manifest_path, "overwrite-me").unwrap(); fs::write(release_manifest_path, "overwrite-me").unwrap();
let result = subcommand_render(&RenderArgs { subcommand_render(&RenderArgs {
change_set: ChangeSet::SmithyRs, change_set: ChangeSet::SmithyRs,
independent_versioning: true, independent_versioning: true,
source: vec![source_path.clone()], source: vec![dot_changelog_path.clone()],
source_to_truncate: source_path, changelog_output: dest_path.clone(),
changelog_output: dest_path, source_to_truncate: Some(dot_changelog_path.clone()),
release_manifest_output: Some(tmp_dir.path().into()), release_manifest_output: Some(tmp_dir.path().into()),
date_override: Some(OffsetDateTime::UNIX_EPOCH), date_override: Some(OffsetDateTime::UNIX_EPOCH),
current_release_versions_manifest: None, current_release_versions_manifest: None,
previous_release_versions_manifest: None, previous_release_versions_manifest: None,
smithy_rs_location: Some(tmp_dir.path().into()), smithy_rs_location: Some(tmp_dir.path().into()),
}); })
.unwrap();
if let Err(e) = result { let dot_example = fs::read_to_string(dot_changelog_path.join(".example")).unwrap();
let index = e let dest = fs::read_to_string(&dest_path).unwrap();
.to_string()
.find("aws-sdk-rust changelog entry cannot have an affected target"); // source file should be empty
assert!(index.is_some()); pretty_assertions::assert_str_eq!(EXAMPLE_ENTRY, &dot_example);
} else { pretty_assertions::assert_str_eq!(
panic!("This should have been error that aws-sdk-rust has a target entry"); r#"<!-- Do not manually edit this file. Use the `changelogger` tool. -->
} January 1st, 1970
=================
**New this release:**
- (client, [smithy-rs#4](https://github.com/smithy-lang/smithy-rs/issues/4), @client-dev) Change from client
**Contributors**
Thank you for your contributions!
- @client-dev ([smithy-rs#4](https://github.com/smithy-lang/smithy-rs/issues/4))
v0.41.0 (Some date in the past)
=========
Old entry contents
"#,
dest
);
} }
#[test] #[test]
fn render_crate_versions() { fn render_crate_versions() {
let tmp_dir = TempDir::new().unwrap(); let tmp_dir = TempDir::new().unwrap();
let source_path = tmp_dir.path().join("source.toml"); let dot_changelog = TempDir::new_in(tmp_dir.path()).unwrap();
let dot_changelog_path = dot_changelog.path().to_owned();
let dest_path = tmp_dir.path().join("dest.md"); let dest_path = tmp_dir.path().join("dest.md");
let release_manifest_path = tmp_dir.path().join("smithy-rs-release-manifest.json"); let release_manifest_path = tmp_dir.path().join("smithy-rs-release-manifest.json");
let current_versions_manifest_path = tmp_dir.path().join("versions.toml"); let current_versions_manifest_path = tmp_dir.path().join("versions.toml");
create_fake_repo_root(tmp_dir.path(), "0.54.1", "0.24.0"); create_fake_repo_root(tmp_dir.path(), "0.54.1", "0.24.0");
fs::write(&source_path, SOURCE_TOML).unwrap(); create_changelog_entry_markdown_files(
&[SOURCE_MARKDOWN1, SOURCE_MARKDOWN2, SOURCE_MARKDOWN3],
&dot_changelog_path,
);
fs::write( fs::write(
&dest_path, &dest_path,
format!( format!(
@ -646,9 +614,9 @@ fn render_crate_versions() {
subcommand_render(&RenderArgs { subcommand_render(&RenderArgs {
change_set: ChangeSet::SmithyRs, change_set: ChangeSet::SmithyRs,
independent_versioning: true, independent_versioning: true,
source: vec![source_path.clone()], source: vec![dot_changelog_path.clone()],
source_to_truncate: source_path.clone(),
changelog_output: dest_path.clone(), changelog_output: dest_path.clone(),
source_to_truncate: Some(dot_changelog_path.clone()),
release_manifest_output: Some(tmp_dir.path().into()), release_manifest_output: Some(tmp_dir.path().into()),
date_override: Some(OffsetDateTime::UNIX_EPOCH), date_override: Some(OffsetDateTime::UNIX_EPOCH),
current_release_versions_manifest: Some(current_versions_manifest_path), current_release_versions_manifest: Some(current_versions_manifest_path),
@ -657,12 +625,11 @@ fn render_crate_versions() {
}) })
.unwrap(); .unwrap();
let source = fs::read_to_string(&source_path).unwrap(); let dot_example = fs::read_to_string(dot_changelog_path.join(".example")).unwrap();
let dest = fs::read_to_string(&dest_path).unwrap(); let dest = fs::read_to_string(&dest_path).unwrap();
let release_manifest = fs::read_to_string(&release_manifest_path).unwrap(); let release_manifest = fs::read_to_string(&release_manifest_path).unwrap();
// source file should be empty pretty_assertions::assert_str_eq!(EXAMPLE_ENTRY, dot_example);
pretty_assertions::assert_str_eq!(EXAMPLE_ENTRY.trim(), source);
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
r#"<!-- Do not manually edit this file. Use the `changelogger` tool. --> r#"<!-- Do not manually edit this file. Use the `changelogger` tool. -->
January 1st, 1970 January 1st, 1970

View File

@ -23,6 +23,30 @@ impl Lint for ChangelogNext {
} }
impl Check for ChangelogNext { impl Check for ChangelogNext {
fn check(&self, path: impl AsRef<Path> + Debug) -> Result<Vec<LintError>> {
if path.as_ref().exists() {
Ok(vec![LintError::new(
"the legacy `CHANGELOG.next.toml` should no longer exist",
)])
} else {
Ok(vec![])
}
}
}
pub(crate) struct DotChangelog;
impl Lint for DotChangelog {
fn name(&self) -> &str {
".changelog"
}
fn files_to_check(&self) -> Result<Vec<PathBuf>> {
Ok(vec![repo_root().join(".changelog")])
}
}
impl Check for DotChangelog {
fn check(&self, path: impl AsRef<Path> + Debug) -> Result<Vec<LintError>> { fn check(&self, path: impl AsRef<Path> + Debug) -> Result<Vec<LintError>> {
match check_changelog_next(path) { match check_changelog_next(path) {
Ok(_) => Ok(vec![]), Ok(_) => Ok(vec![]),
@ -31,13 +55,10 @@ impl Check for ChangelogNext {
} }
} }
// TODO(file-per-change-changelog): Use `.load_from_dir` to read from the `.changelog` directory /// Validate that changelog entries in the `.changelog` directory follows best practices
// and run the validation only when the directory has at least one changelog entry file, otherwise
// a default constructed `ChangeLog` won't pass the validation.
/// Validate that `CHANGELOG.next.toml` follows best practices
fn check_changelog_next(path: impl AsRef<Path> + Debug) -> std::result::Result<(), Vec<LintError>> { fn check_changelog_next(path: impl AsRef<Path> + Debug) -> std::result::Result<(), Vec<LintError>> {
let parsed = ChangelogLoader::default() let parsed = ChangelogLoader::default()
.load_from_file(path) .load_from_dir(path)
.map_err(|e| vec![LintError::via_display(e)])?; .map_err(|e| vec![LintError::via_display(e)])?;
parsed parsed
.validate(ValidationSet::Development) .validate(ValidationSet::Development)

View File

@ -236,13 +236,13 @@ impl HandAuthoredEntry {
} }
} }
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Eq, Deserialize, PartialEq, Serialize)]
pub enum SdkModelChangeKind { pub enum SdkModelChangeKind {
Documentation, Documentation,
Feature, Feature,
} }
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Eq, Deserialize, PartialEq, Serialize)]
pub struct SdkModelEntry { pub struct SdkModelEntry {
/// SDK module name (e.g., "aws-sdk-s3" for S3) /// SDK module name (e.g., "aws-sdk-s3" for S3)
pub module: String, pub module: String,
@ -467,174 +467,140 @@ impl ChangelogLoader {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::changelog::parser::Toml;
use anyhow::Context; use anyhow::Context;
#[test] #[test]
fn errors_are_combined() { fn errors_are_combined() {
let buffer = r#" const ENTRY: &str = r#"
[[aws-sdk-rust]] ---
message = "Fix typos in module documentation for generated crates" applies_to: ["aws-sdk-rust"]
references = ["smithy-rs#920"] authors: [""]
meta = { "breaking" = false, "tada" = false, "bug" = false } references: ["smithy-rs#920"]
author = "" breaking: false
[[smithy-rs]] new_feature: false
message = "Fix typos in module documentation for generated crates" bug_fix: false
references = ["smithy-rs#920"] ---
meta = { "breaking" = false, "tada" = false, "bug" = false } Fix typos in module documentation for generated crates
author = ""
[[smithy-rs]]
message = "Fix typos in module documentation for generated crates"
references = ["smithy-rs#920"]
meta = { "breaking" = false, "tada" = false, "bug" = false }
author = "fz"
"#; "#;
// three errors should be produced, missing authors x 2 and a SdkAffected is not set to default let loader = ChangelogLoader::default();
let changelog: Changelog = toml::from_str(buffer).expect("valid changelog"); let mut changelog = loader.parse_str(ENTRY).unwrap();
changelog.merge(loader.parse_str(ENTRY).unwrap());
// two errors should be produced, missing authors x 2
let res = changelog.validate(ValidationSet::Development); let res = changelog.validate(ValidationSet::Development);
assert!(res.is_err()); assert_eq!(
if let Err(e) = res { 2,
assert_eq!(3, e.len()); res.err().expect("changelog validation should fail").len()
assert!(e.contains(&"smithy-rs entry must have an affected target".to_string())) );
}
}
// TODO(file-per-change-changelog): Remove this test once we have switched to the new markdown
// format because targets will be explicit and there won't be defaults set.
#[test]
fn confirm_smithy_rs_defaults_set() {
let buffer = r#"
[[aws-sdk-rust]]
message = "Fix typos in module documentation for generated crates"
references = ["smithy-rs#920"]
meta = { "breaking" = false, "tada" = false, "bug" = false }
author = "rcoh"
[[smithy-rs]]
message = "Fix typos in module documentation for generated crates"
references = ["smithy-rs#920"]
meta = { "breaking" = false, "tada" = false, "bug" = false }
author = "rcoh"
[[smithy-rs]]
message = "Fix typos in module documentation for generated crates"
references = ["smithy-rs#920"]
meta = { "breaking" = false, "tada" = false, "bug" = false }
author = "fz"
"#;
{
// parsing directly using `toml::from_str` won't set the default target field
let changelog: Changelog = toml::from_str(buffer).expect("valid changelog");
let res = changelog.validate(ValidationSet::Development);
assert!(res.is_err());
if let Err(e) = res {
assert!(e.contains(&"smithy-rs entry must have an affected target".to_string()))
}
}
{
// parsing through the `Toml` parser will result in no error
let changelog: Changelog = Toml::default().parse(buffer).expect("valid changelog");
let res = changelog.validate(ValidationSet::Development);
assert!(res.is_ok());
if let Err(e) = res {
panic!("some error has been produced {e:?}");
}
assert_eq!(changelog.smithy_rs[1].meta.target, Some(SdkAffected::All));
}
} }
#[test] #[test]
fn test_hand_authored_sdk() { fn test_hand_authored_sdk() {
let loader = ChangelogLoader::default();
// server target // server target
let value = r#" let value = r#"
message = "Fix typos in module documentation for generated crates" ---
references = ["smithy-rs#920"] applies_to: ["server"]
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "Server" } authors: ["rcoh"]
author = "rcoh" references: ["smithy-rs#920"]
"#; breaking: false
new_feature: false
bug_fix: false
---
Fix typos in module documentation for generated crates
"#;
{ {
let value: HandAuthoredEntry = toml::from_str(value) let changelog = loader
.parse_str(value)
.context("String should have parsed") .context("String should have parsed")
.unwrap(); .unwrap();
assert_eq!(Some(SdkAffected::Server), value.meta.target); assert_eq!(
Some(SdkAffected::Server),
changelog.smithy_rs.first().unwrap().meta.target
);
} }
// client target // client target
let value = r#" let value = r#"
message = "Fix typos in module documentation for generated crates" ---
references = ["smithy-rs#920"] applies_to: ["client"]
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "Client" } authors: ["rcoh"]
author = "rcoh" references: ["smithy-rs#920"]
"#; breaking: false
new_feature: false
bug_fix: false
---
Fix typos in module documentation for generated crates
"#;
{ {
let value: HandAuthoredEntry = toml::from_str(value) let changelog = loader
.parse_str(value)
.context("String should have parsed") .context("String should have parsed")
.unwrap(); .unwrap();
assert_eq!(Some(SdkAffected::Client), value.meta.target); assert_eq!(
Some(SdkAffected::Client),
changelog.smithy_rs.first().unwrap().meta.target
);
} }
// Both target // Both target
let value = r#" let value = r#"
message = "Fix typos in module documentation for generated crates" ---
references = ["smithy-rs#920"] applies_to: ["server", "client"]
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "all" } authors: ["rcoh"]
author = "rcoh" references: ["smithy-rs#920"]
"#; breaking: false
new_feature: false
bug_fix: false
---
Fix typos in module documentation for generated crates
"#;
{ {
let value: HandAuthoredEntry = toml::from_str(value) let changelog = loader
.parse_str(value)
.context("String should have parsed") .context("String should have parsed")
.unwrap(); .unwrap();
assert_eq!(Some(SdkAffected::All), value.meta.target); assert_eq!(
Some(SdkAffected::All),
changelog.smithy_rs.first().unwrap().meta.target
);
} }
// an invalid sdk value // an invalid `applies_to` value
let value = r#" let value = r#"
message = "Fix typos in module documentation for generated crates" ---
references = ["smithy-rs#920"] applies_to: ["Some other invalid"]
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "Some other invalid" } authors: ["rcoh"]
author = "rcoh" references: ["smithy-rs#920"]
"#; breaking: false
new_feature: false
bug_fix: false
---
Fix typos in module documentation for generated crates
"#;
{ {
let value: Result<HandAuthoredEntry, _> = let changelog = loader
toml::from_str(value).context("String should not have parsed"); .parse_str(value)
assert!(value.is_err()); .context("String should not have parsed");
} assert!(changelog.is_err());
// missing sdk in the meta tag
let value = r#"
message = "Fix typos in module documentation for generated crates"
references = ["smithy-rs#920"]
meta = { "breaking" = false, "tada" = false, "bug" = false }
author = "rcoh"
"#;
{
let value: HandAuthoredEntry = toml::from_str(value)
.context("String should have parsed as it has none meta.sdk")
.unwrap();
assert_eq!(None, value.meta.target);
}
// single author
let value = r#"
message = "Fix typos in module documentation for generated crates"
references = ["smithy-rs#920"]
meta = { "breaking" = false, "tada" = false, "bug" = false }
author = "rcoh"
"#;
{
let value: HandAuthoredEntry = toml::from_str(value)
.context("String should have parsed with multiple authors")
.unwrap();
assert_eq!(Authors(vec!["rcoh".to_string()]), value.authors);
} }
// multiple authors // multiple authors
let value = r#" let value = r#"
message = "Fix typos in module documentation for generated crates" ---
references = ["smithy-rs#920"] applies_to: ["client", "server"]
meta = { "breaking" = false, "tada" = false, "bug" = false } authors: ["rcoh", "crisidev"]
authors = ["rcoh", "crisidev"] references: ["smithy-rs#920"]
"#; breaking: false
new_feature: false
bug_fix: false
---
Fix typos in module documentation for generated crates
"#;
{ {
let value: HandAuthoredEntry = toml::from_str(value) let changelog = loader
.parse_str(value)
.context("String should have parsed with multiple authors") .context("String should have parsed with multiple authors")
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
Authors(vec!["rcoh".to_string(), "crisidev".to_string()]), Authors(vec!["rcoh".to_string(), "crisidev".to_string()]),
value.authors changelog.smithy_rs.first().unwrap().authors,
); );
} }
} }

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
use crate::changelog::{Changelog, Markdown, SdkAffected}; use crate::changelog::{Changelog, Markdown};
use anyhow::{bail, Context, Result}; use anyhow::{bail, Context, Result};
use std::fmt::Debug; use std::fmt::Debug;
@ -15,17 +15,7 @@ pub(crate) trait ParseIntoChangelog: Debug {
pub(super) struct Toml; pub(super) struct Toml;
impl ParseIntoChangelog for Toml { impl ParseIntoChangelog for Toml {
fn parse(&self, value: &str) -> Result<Changelog> { fn parse(&self, value: &str) -> Result<Changelog> {
let mut changelog: Changelog = toml::from_str(value).context("Invalid TOML changelog format")
toml::from_str(value).context("Invalid TOML changelog format")?;
// all smithry-rs entries should have meta.target set to the default value instead of None
// TODO(file-per-change-changelog): Remove the following fix-up once we have switched over
// to the new markdown format since it won't be needed.
for entry in &mut changelog.smithy_rs {
if entry.meta.target.is_none() {
entry.meta.target = Some(SdkAffected::default());
}
}
Ok(changelog)
} }
} }
@ -100,6 +90,7 @@ impl ParseIntoChangelog for ParserChain {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::changelog::{SdkAffected, SdkModelChangeKind, SdkModelEntry};
#[test] #[test]
fn parse_json() { fn parse_json() {
@ -149,49 +140,38 @@ mod tests {
#[test] #[test]
fn parse_toml() { fn parse_toml() {
// TODO(file-per-change-changelog): We keep the following test string while transitioning
// to the new markdown format. Once we have switched to the new format, only use
// `[[aws-sdk-model]]` in the test string because after the cutover, `[[aws-sdk-rust]]` or
// `[[smithy-rs]]` are not a recommended way of writing changelogs.
let toml = r#" let toml = r#"
[[aws-sdk-rust]] [[aws-sdk-model]]
message = "Fix typos in module documentation for generated crates" module = "aws-sdk-s3"
references = ["smithy-rs#920"] version = "0.14.0"
meta = { "breaking" = false, "tada" = false, "bug" = false } kind = "Feature"
author = "rcoh" message = "Some new API to do X"
[[smithy-rs]] [[aws-sdk-model]]
message = "Fix typos in module documentation for generated crates" module = "aws-sdk-ec2"
references = ["smithy-rs#920"] version = "0.12.0"
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "client" } kind = "Documentation"
author = "rcoh" message = "Updated some docs"
[[smithy-rs]]
message = "Fix typos in module documentation for generated crates"
references = ["smithy-rs#920"]
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "server" }
author = "rcoh"
[[smithy-rs]]
message = "Fix typos in module documentation for generated crates"
references = ["smithy-rs#920"]
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "all" }
author = "rcoh"
[[smithy-rs]]
message = "Fix typos in module documentation for generated crates"
references = ["smithy-rs#920"]
meta = { "breaking" = false, "tada" = false, "bug" = false }
author = "rcoh"
"#; "#;
let changelog = Toml::default().parse(toml).unwrap(); let changelog = Toml::default().parse(toml).unwrap();
assert_eq!(4, changelog.smithy_rs.len()); assert_eq!(2, changelog.sdk_models.len());
assert_eq!( assert_eq!(
Some(SdkAffected::Client), SdkModelEntry {
changelog.smithy_rs[0].meta.target, module: "aws-sdk-s3".to_string(),
version: "0.14.0".to_string(),
kind: SdkModelChangeKind::Feature,
message: "Some new API to do X".to_string(),
},
changelog.sdk_models[0]
); );
assert_eq!( assert_eq!(
Some(SdkAffected::Server), SdkModelEntry {
changelog.smithy_rs[1].meta.target, module: "aws-sdk-ec2".to_string(),
version: "0.12.0".to_string(),
kind: SdkModelChangeKind::Documentation,
message: "Updated some docs".to_string(),
},
changelog.sdk_models[1]
); );
assert_eq!(Some(SdkAffected::All), changelog.smithy_rs[2].meta.target);
assert_eq!(Some(SdkAffected::All), changelog.smithy_rs[3].meta.target);
} }
#[test] #[test]

View File

@ -1,17 +0,0 @@
#!/bin/bash
#
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
#
set -eux
SMITHY_RS_DIR="$(pwd)/smithy-rs"
ARTIFACTS_DIR="$(pwd)/artifacts/generate-new-changelog-next-toml"
changelogger init > "${SMITHY_RS_DIR}/CHANGELOG.next.toml"
pushd "${ARTIFACTS_DIR}"
cp -r "${SMITHY_RS_DIR}" .
git -C smithy-rs status
popd

View File

@ -8,19 +8,20 @@ set -eux
SMITHY_RS_DIR="$(pwd)/smithy-rs" SMITHY_RS_DIR="$(pwd)/smithy-rs"
ARTIFACTS_DIR="$(pwd)/artifacts/smithy-rs-release" ARTIFACTS_DIR="$(pwd)/artifacts/smithy-rs-release"
CHANGELOG_DIR="${SMITHY_RS_DIR}/.changelog"
mkdir -p "${ARTIFACTS_DIR}" mkdir -p "${ARTIFACTS_DIR}"
pushd "${SMITHY_RS_DIR}" pushd "${SMITHY_RS_DIR}"
# Split AWS SDK changelog entries into a separate file # Duplicate AWS SDK changelog entries into a separate file
changelogger split \ changelogger split \
--source CHANGELOG.next.toml \ --source "${CHANGELOG_DIR}" \
--destination aws/SDK_CHANGELOG.next.json --destination aws/SDK_CHANGELOG.next.json
# Render the remaining smithy-rs changelog entries # Render the smithy-rs changelog entries
changelogger render \ changelogger render \
--independent-versioning \ --independent-versioning \
--change-set smithy-rs \ --change-set smithy-rs \
--source CHANGELOG.next.toml \ --source "${CHANGELOG_DIR}" \
--source-to-truncate CHANGELOG.next.toml \ --source-to-truncate "${CHANGELOG_DIR}" \
--changelog-output CHANGELOG.md \ --changelog-output CHANGELOG.md \
--release-manifest-output "${ARTIFACTS_DIR}" --release-manifest-output "${ARTIFACTS_DIR}"
# Commit changelog changes if there are any # Commit changelog changes if there are any