Unverified Commit dbafd684 authored by ysaito1001's avatar ysaito1001 Committed by GitHub
Browse files

Add crate versions in CHANGELOG (#2348)

* Move rendering external contributors to a function

This commit moves the code for rendering external contributors to its own
function, in line with other render_* functions.

* Add type alias `CrateVersionMetadataMap`

This commit adds a type alias `CrateVersionMetadataMap` for a field in
`VersionsManifest`. In a subsequent commit, the `changelogger` crate
will refer to this field, and it's better for that crate to not use the
field's bare type `BTreeMap<String, CrateVersion>`.

* Render crate versions in CHANGELOG

This commit addresses a pain point brought up in https://github.com/awslabs/aws-sdk-rust/issues/731.
A binary `changelogger` now has a new command line option
`--current-release-versions-manifest` that points to the latest
`versions.toml` in the `aws-sdk-rust` repository. The program
will generate a markdown table showing crate versions from that
manifest and include it in an expand/collapse section.

* Add a leading pipe when rendering markdown table

This commit addresses https://github.com/awslabs/smithy-rs/pull/2348#discussion_r1114164039



---------

Co-authored-by: default avatarYuki Saito <awsaito@amazon.com>
Co-authored-by: default avatarZelda Hessler <zhessler@amazon.com>
parent 5183ccbd
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ mod tests {
                source_to_truncate: PathBuf::from("fromplace"),
                changelog_output: PathBuf::from("some-changelog"),
                release_manifest_output: Some(PathBuf::from("some-manifest")),
                current_release_versions_manifest: None,
                previous_release_versions_manifest: None,
                date_override: None,
                smithy_rs_location: None,
@@ -97,6 +98,7 @@ mod tests {
                source_to_truncate: PathBuf::from("fromplace"),
                changelog_output: PathBuf::from("some-changelog"),
                release_manifest_output: None,
                current_release_versions_manifest: None,
                previous_release_versions_manifest: None,
                date_override: None,
                smithy_rs_location: None,
@@ -127,6 +129,7 @@ mod tests {
                source_to_truncate: PathBuf::from("fromplace"),
                changelog_output: PathBuf::from("some-changelog"),
                release_manifest_output: None,
                current_release_versions_manifest: None,
                previous_release_versions_manifest: Some(PathBuf::from("path/to/versions.toml")),
                date_override: None,
                smithy_rs_location: None,
@@ -148,5 +151,42 @@ mod tests {
            ])
            .unwrap()
        );

        assert_eq!(
            Args::Render(RenderArgs {
                change_set: ChangeSet::AwsSdk,
                independent_versioning: true,
                source: vec![PathBuf::from("fromplace")],
                source_to_truncate: PathBuf::from("fromplace"),
                changelog_output: PathBuf::from("some-changelog"),
                release_manifest_output: None,
                current_release_versions_manifest: Some(PathBuf::from(
                    "path/to/current/versions.toml"
                )),
                previous_release_versions_manifest: Some(PathBuf::from(
                    "path/to/previous/versions.toml"
                )),
                date_override: None,
                smithy_rs_location: None,
            }),
            Args::try_parse_from([
                "./changelogger",
                "render",
                "--change-set",
                "aws-sdk",
                "--independent-versioning",
                "--source",
                "fromplace",
                "--source-to-truncate",
                "fromplace",
                "--changelog-output",
                "some-changelog",
                "--current-release-versions-manifest",
                "path/to/current/versions.toml",
                "--previous-release-versions-manifest",
                "path/to/previous/versions.toml"
            ])
            .unwrap()
        );
    }
}
+194 −50
Original line number Diff line number Diff line
@@ -13,9 +13,10 @@ use smithy_rs_tool_common::changelog::{
    Changelog, HandAuthoredEntry, Reference, SdkModelChangeKind, SdkModelEntry,
};
use smithy_rs_tool_common::git::{find_git_repository_root, Git, GitCLI};
use smithy_rs_tool_common::versions_manifest::{CrateVersionMetadataMap, VersionsManifest};
use std::env;
use std::fmt::Write;
use std::path::PathBuf;
use std::path::{Path, PathBuf};
use time::OffsetDateTime;

pub const EXAMPLE_ENTRY: &str = r#"
@@ -67,6 +68,10 @@ pub struct RenderArgs {
    /// Optional path to output a release manifest file to
    #[clap(long, action)]
    pub release_manifest_output: Option<PathBuf>,
    /// Optional path to the SDK's versions.toml file for the current release.
    /// This is used to generate a markdown table showing crate versions.
    #[clap(long, action)]
    pub current_release_versions_manifest: Option<PathBuf>,
    /// Optional path to the SDK's versions.toml file for the previous release.
    /// This is used to filter out changelog entries that have `since_commit` information.
    #[clap(long, action)]
@@ -217,6 +222,16 @@ fn indented_message(message: &str) -> String {
    out
}

fn render_table_row(columns: [&str; 2], out: &mut String) {
    let mut row = "|".to_owned();
    for column in columns {
        row.push_str(column);
        row.push('|');
    }
    write!(out, "{row}").unwrap();
    out.push('\n');
}

fn load_changelogs(args: &RenderArgs) -> Result<Changelog> {
    let mut combined = Changelog::new();
    for source in &args.source {
@@ -233,6 +248,19 @@ fn load_changelogs(args: &RenderArgs) -> Result<Changelog> {
    Ok(combined)
}

fn load_current_crate_version_metadata_map(
    current_release_versions_manifest: Option<&Path>,
) -> CrateVersionMetadataMap {
    current_release_versions_manifest
        .and_then(
            |manifest_path| match VersionsManifest::from_file(manifest_path) {
                Ok(manifest) => Some(manifest.crates),
                Err(_) => None,
            },
        )
        .unwrap_or_default()
}

fn update_changelogs(
    args: &RenderArgs,
    smithy_rs: &dyn Git,
@@ -250,7 +278,13 @@ fn update_changelogs(
        args.change_set,
        args.previous_release_versions_manifest.as_deref(),
    )?;
    let (release_header, release_notes) = render(&entries, &release_metadata.title);
    let current_crate_version_metadata_map =
        load_current_crate_version_metadata_map(args.current_release_versions_manifest.as_deref());
    let (release_header, release_notes) = render(
        &entries,
        current_crate_version_metadata_map,
        &release_metadata.title,
    );
    if let Some(output_path) = &args.release_manifest_output {
        let release_manifest = ReleaseManifest {
            tag_name: release_metadata.tag.clone(),
@@ -329,35 +363,17 @@ fn render_sdk_model_entries<'a>(
    }
}

/// Convert a list of changelog entries into markdown.
/// Returns (header, body)
fn render(entries: &[ChangelogEntry], release_header: &str) -> (String, String) {
    let mut header = String::new();
    header.push_str(release_header);
    header.push('\n');
    for _ in 0..release_header.len() {
        header.push('=');
    }
    header.push('\n');

    let mut out = String::new();
    render_handauthored(
        entries.iter().filter_map(ChangelogEntry::hand_authored),
        &mut out,
    );
    render_sdk_model_entries(
        entries.iter().filter_map(ChangelogEntry::aws_sdk_model),
        &mut out,
    );

fn render_external_contributors(entries: &[ChangelogEntry], out: &mut String) {
    let mut external_contribs = entries
        .iter()
        .filter_map(|entry| entry.hand_authored().map(|e| &e.author))
        .filter(|author| !is_maintainer(author))
        .collect::<Vec<_>>();
    if external_contribs.is_empty() {
        return;
    }
    external_contribs.sort();
    external_contribs.dedup();
    if !external_contribs.is_empty() {
    out.push_str("**Contributors**\nThank you for your contributions! ❤\n");
    for contributor_handle in external_contribs {
        // retrieve all contributions this author made
@@ -384,14 +400,76 @@ fn render(entries: &[ChangelogEntry], release_header: &str) -> (String, String)
        out.push_str("- @");
        out.push_str(contributor_handle);
        if !contribution_references.is_empty() {
                write!(&mut out, " ({})", contribution_references)
            write!(out, " ({})", contribution_references)
                // The `Write` implementation for `String` is infallible,
                // see https://doc.rust-lang.org/src/alloc/string.rs.html#2815
                .unwrap()
        }
        out.push('\n');
    }
    out.push('\n');
}

fn render_details(summary: &str, body: &str, out: &mut String) {
    out.push_str("<details>");
    out.push('\n');
    write!(out, "<summary>{}</summary>", summary).unwrap();
    out.push('\n');
    // A blank line is required for the body to be rendered properly
    out.push('\n');
    out.push_str(body);
    out.push_str("</details>");
    out.push('\n');
}

fn render_crate_versions(crate_version_metadata_map: CrateVersionMetadataMap, out: &mut String) {
    if crate_version_metadata_map.is_empty() {
        // If the map is empty, we choose to not render anything, as opposed to
        // rendering the <details> element with empty contents and a user toggling
        // it only to find out there is nothing in it.
        return;
    }

    out.push_str("**Crate Versions**");
    out.push('\n');

    let mut table = String::new();
    render_table_row(["Crate", "Version"], &mut table);
    render_table_row(["-", "-"], &mut table);
    for (crate_name, version_metadata) in &crate_version_metadata_map {
        render_table_row([crate_name, &version_metadata.version], &mut table);
    }

    render_details("Click to expand to view crate versions...", &table, out);
    out.push('\n');
}

/// Convert a list of changelog entries and crate versions into markdown.
/// Returns (header, body)
fn render(
    entries: &[ChangelogEntry],
    crate_version_metadata_map: CrateVersionMetadataMap,
    release_header: &str,
) -> (String, String) {
    let mut header = String::new();
    header.push_str(release_header);
    header.push('\n');
    for _ in 0..release_header.len() {
        header.push('=');
    }
    header.push('\n');

    let mut out = String::new();
    render_handauthored(
        entries.iter().filter_map(ChangelogEntry::hand_authored),
        &mut out,
    );
    render_sdk_model_entries(
        entries.iter().filter_map(ChangelogEntry::aws_sdk_model),
        &mut out,
    );
    render_external_contributors(entries, &mut out);
    render_crate_versions(crate_version_metadata_map, &mut out);

    (header, out)
}
@@ -399,11 +477,15 @@ fn render(entries: &[ChangelogEntry], release_header: &str) -> (String, String)
#[cfg(test)]
mod test {
    use super::{date_based_release_metadata, render, Changelog, ChangelogEntries, ChangelogEntry};
    use smithy_rs_tool_common::changelog::SdkAffected;
    use smithy_rs_tool_common::{
        changelog::SdkAffected,
        package::PackageCategory,
        versions_manifest::{CrateVersion, CrateVersionMetadataMap},
    };
    use time::OffsetDateTime;

    fn render_full(entries: &[ChangelogEntry], release_header: &str) -> String {
        let (header, body) = render(entries, release_header);
        let (header, body) = render(entries, CrateVersionMetadataMap::new(), release_header);
        format!("{header}{body}")
    }

@@ -494,6 +576,7 @@ v0.3.0 (January 4th, 2022)
Thank you for your contributions! ❤
- @another-contrib ([smithy-rs#200](https://github.com/awslabs/smithy-rs/issues/200))
- @external-contrib ([smithy-rs#446](https://github.com/awslabs/smithy-rs/issues/446))

"#
        .trim_start();
        pretty_assertions::assert_str_eq!(smithy_rs_expected, smithy_rs_rendered);
@@ -518,6 +601,7 @@ v0.1.0 (January 4th, 2022)
**Contributors**
Thank you for your contributions! ❤
- @external-contrib ([smithy-rs#446](https://github.com/awslabs/smithy-rs/issues/446))

"#
        .trim_start();
        pretty_assertions::assert_str_eq!(aws_sdk_expected, aws_sdk_rust_rendered);
@@ -592,9 +676,69 @@ author = "rcoh"
    #[test]
    fn test_empty_render() {
        let smithy_rs = Vec::<ChangelogEntry>::new();
        let (release_title, release_notes) = render(&smithy_rs, "some header");
        let (release_title, release_notes) =
            render(&smithy_rs, CrateVersionMetadataMap::new(), "some header");

        assert_eq!(release_title, "some header\n===========\n");
        assert_eq!(release_notes, "");
    }

    #[test]
    fn test_crate_versions() {
        let mut crate_version_metadata_map = CrateVersionMetadataMap::new();
        crate_version_metadata_map.insert(
            "aws-config".to_owned(),
            CrateVersion {
                category: PackageCategory::AwsRuntime,
                version: "0.54.1".to_owned(),
                source_hash: "e93380cfbd05e68d39801cbf0113737ede552a5eceb28f4c34b090048d539df9"
                    .to_owned(),
                model_hash: None,
            },
        );
        crate_version_metadata_map.insert(
            "aws-sdk-accessanalyzer".to_owned(),
            CrateVersion {
                category: PackageCategory::AwsSdk,
                version: "0.24.0".to_owned(),
                source_hash: "a7728756b41b33d02f68a5865d3456802b7bc3949ec089790bc4e726c0de8539"
                    .to_owned(),
                model_hash: Some(
                    "71f1f130504ebd55396c3166d9441513f97e49b281a5dd420fd7e2429860b41b".to_owned(),
                ),
            },
        );
        crate_version_metadata_map.insert(
            "aws-smithy-async".to_owned(),
            CrateVersion {
                category: PackageCategory::SmithyRuntime,
                version: "0.54.1".to_owned(),
                source_hash: "8ced52afc783cbb0df47ee8b55260b98e9febdc95edd796ed14c43db5199b0a9"
                    .to_owned(),
                model_hash: None,
            },
        );
        let (release_title, release_notes) = render(
            &Vec::<ChangelogEntry>::new(),
            crate_version_metadata_map,
            "some header",
        );

        assert_eq!(release_title, "some header\n===========\n");
        let expected_body = r#"
**Crate Versions**
<details>
<summary>Click to expand to view crate versions...</summary>

|Crate|Version|
|-|-|
|aws-config|0.54.1|
|aws-sdk-accessanalyzer|0.24.0|
|aws-smithy-async|0.54.1|
</details>

"#
        .trim_start();
        pretty_assertions::assert_str_eq!(release_notes, expected_body);
    }
}
+129 −8
Original line number Diff line number Diff line
@@ -45,6 +45,37 @@ const SDK_MODEL_SOURCE_TOML: &str = r#"
    message = "Some API change"
"#;

const VERSIONS_TOML: &str = r#"
    smithy_rs_revision = '41ca31b85b4ba8c0ad680fe62a230266cc52cc44'
    aws_doc_sdk_examples_revision = '97a177aab8c3d2fef97416cb66e4b4d0da840138'

    [manual_interventions]
    crates_to_remove = []
    [crates.aws-config]
    category = 'AwsRuntime'
    version = '0.54.1'
    source_hash = 'e93380cfbd05e68d39801cbf0113737ede552a5eceb28f4c34b090048d539df9'

    [crates.aws-sdk-accessanalyzer]
    category = 'AwsSdk'
    version = '0.24.0'
    source_hash = 'a7728756b41b33d02f68a5865d3456802b7bc3949ec089790bc4e726c0de8539'
    model_hash = '71f1f130504ebd55396c3166d9441513f97e49b281a5dd420fd7e2429860b41b'

    [crates.aws-smithy-async]
    category = 'SmithyRuntime'
    version = '0.54.1'
    source_hash = '8ced52afc783cbb0df47ee8b55260b98e9febdc95edd796ed14c43db5199b0a9'

    [release]
    tag = 'release-2023-01-26'

    [release.crates]
    aws-config = "0.54.1"
    aws-sdk-accessanalyzer = '0.24.0'
    aws-smithy-async = '0.54.1'
"#;

fn create_fake_repo_root(
    path: &Path,
    smithy_rs_version: &str,
@@ -98,7 +129,7 @@ fn create_fake_repo_root(
}

#[test]
fn split_aws_sdk_test() {
fn split_aws_sdk() {
    let tmp_dir = TempDir::new().unwrap();
    let source_path = tmp_dir.path().join("source.toml");
    let dest_path = tmp_dir.path().join("dest.toml");
@@ -226,7 +257,7 @@ fn split_aws_sdk_test() {
}

#[test]
fn render_smithy_rs_test() {
fn render_smithy_rs() {
    let tmp_dir = TempDir::new().unwrap();
    let source_path = tmp_dir.path().join("source.toml");
    let dest_path = tmp_dir.path().join("dest.md");
@@ -253,6 +284,7 @@ fn render_smithy_rs_test() {
        changelog_output: dest_path.clone(),
        release_manifest_output: Some(tmp_dir.path().into()),
        date_override: Some(OffsetDateTime::UNIX_EPOCH),
        current_release_versions_manifest: None,
        previous_release_versions_manifest: None,
        smithy_rs_location: Some(tmp_dir.path().into()),
    })
@@ -274,6 +306,7 @@ January 1st, 1970
Thank you for your contributions! ❤
- @another-dev ([smithy-rs#1234](https://github.com/awslabs/smithy-rs/issues/1234))


v0.41.0 (Some date in the past)
=========

@@ -285,7 +318,7 @@ Old entry contents
        r#"{
  "tagName": "release-1970-01-01",
  "name": "January 1st, 1970",
  "body": "**New this release:**\n- (all, [smithy-rs#1234](https://github.com/awslabs/smithy-rs/issues/1234), @another-dev) Another change\n\n**Contributors**\nThank you for your contributions! ❤\n- @another-dev ([smithy-rs#1234](https://github.com/awslabs/smithy-rs/issues/1234))\n",
  "body": "**New this release:**\n- (all, [smithy-rs#1234](https://github.com/awslabs/smithy-rs/issues/1234), @another-dev) Another change\n\n**Contributors**\nThank you for your contributions! ❤\n- @another-dev ([smithy-rs#1234](https://github.com/awslabs/smithy-rs/issues/1234))\n\n",
  "prerelease": true
}"#,
        release_manifest
@@ -293,13 +326,13 @@ Old entry contents
}

#[test]
fn render_aws_sdk_test() {
fn render_aws_sdk() {
    let tmp_dir = TempDir::new().unwrap();
    let source1_path = tmp_dir.path().join("source1.toml");
    let source2_path = tmp_dir.path().join("source2.toml");
    let dest_path = tmp_dir.path().join("dest.md");
    let release_manifest_path = tmp_dir.path().join("aws-sdk-rust-release-manifest.json");
    let 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) =
        create_fake_repo_root(tmp_dir.path(), "0.42.0", "0.12.0");
@@ -322,7 +355,7 @@ fn render_aws_sdk_test() {
    .unwrap();
    fs::write(&release_manifest_path, "overwrite-me").unwrap();
    fs::write(
        &versions_manifest_path,
        &previous_versions_manifest_path,
        format!(
            "smithy_rs_revision = '{release_1_commit}'
             aws_doc_sdk_examples_revision = 'not-relevant'
@@ -339,7 +372,8 @@ fn render_aws_sdk_test() {
        changelog_output: dest_path.clone(),
        release_manifest_output: Some(tmp_dir.path().into()),
        date_override: Some(OffsetDateTime::UNIX_EPOCH),
        previous_release_versions_manifest: Some(versions_manifest_path),
        current_release_versions_manifest: None,
        previous_release_versions_manifest: Some(previous_versions_manifest_path),
        smithy_rs_location: Some(tmp_dir.path().into()),
    })
    .unwrap();
@@ -368,6 +402,7 @@ January 1st, 1970
Thank you for your contributions! ❤
- @test-dev ([aws-sdk-rust#234](https://github.com/awslabs/aws-sdk-rust/issues/234), [smithy-rs#567](https://github.com/awslabs/smithy-rs/issues/567))


v0.41.0 (Some date in the past)
=========

@@ -379,7 +414,7 @@ Old entry contents
        r#"{
  "tagName": "release-1970-01-01",
  "name": "January 1st, 1970",
  "body": "**New this release:**\n- 🐛 ([aws-sdk-rust#234](https://github.com/awslabs/aws-sdk-rust/issues/234), [smithy-rs#567](https://github.com/awslabs/smithy-rs/issues/567), @test-dev) Some other change\n\n**Service Features:**\n- `aws-sdk-ec2` (0.12.0): Some API change\n\n**Contributors**\nThank you for your contributions! ❤\n- @test-dev ([aws-sdk-rust#234](https://github.com/awslabs/aws-sdk-rust/issues/234), [smithy-rs#567](https://github.com/awslabs/smithy-rs/issues/567))\n",
  "body": "**New this release:**\n- 🐛 ([aws-sdk-rust#234](https://github.com/awslabs/aws-sdk-rust/issues/234), [smithy-rs#567](https://github.com/awslabs/smithy-rs/issues/567), @test-dev) Some other change\n\n**Service Features:**\n- `aws-sdk-ec2` (0.12.0): Some API change\n\n**Contributors**\nThank you for your contributions! ❤\n- @test-dev ([aws-sdk-rust#234](https://github.com/awslabs/aws-sdk-rust/issues/234), [smithy-rs#567](https://github.com/awslabs/smithy-rs/issues/567))\n\n",
  "prerelease": true
}"#,
        release_manifest
@@ -460,6 +495,7 @@ author = "LukeMathWalker"
        changelog_output: dest_path.clone(),
        release_manifest_output: Some(tmp_dir.path().into()),
        date_override: Some(OffsetDateTime::UNIX_EPOCH),
        current_release_versions_manifest: None,
        previous_release_versions_manifest: None,
        smithy_rs_location: Some(tmp_dir.path().into()),
    })
@@ -487,6 +523,7 @@ Thank you for your contributions! ❤
- @another-dev ([smithy-rs#2](https://github.com/awslabs/smithy-rs/issues/2))
- @server-dev ([smithy-rs#1](https://github.com/awslabs/smithy-rs/issues/1))


v0.41.0 (Some date in the past)
=========

@@ -569,6 +606,7 @@ author = "rcoh"
        changelog_output: dest_path,
        release_manifest_output: Some(tmp_dir.path().into()),
        date_override: Some(OffsetDateTime::UNIX_EPOCH),
        current_release_versions_manifest: None,
        previous_release_versions_manifest: None,
        smithy_rs_location: Some(tmp_dir.path().into()),
    });
@@ -582,3 +620,86 @@ author = "rcoh"
        panic!("This should have been error that aws-sdk-rust has a target entry");
    }
}

#[test]
fn render_crate_versions() {
    let tmp_dir = TempDir::new().unwrap();
    let source_path = tmp_dir.path().join("source.toml");
    let dest_path = tmp_dir.path().join("dest.md");
    let release_manifest_path = tmp_dir.path().join("smithy-rs-release-manifest.json");
    let current_versions_manifest_path = tmp_dir.path().join("versions.toml");

    create_fake_repo_root(tmp_dir.path(), "0.54.1", "0.24.0");

    fs::write(&source_path, SOURCE_TOML).unwrap();
    fs::write(
        &dest_path,
        format!(
            "{}\nv0.54.0 (Some date in the past)\n=========\n\nOld entry contents\n",
            USE_UPDATE_CHANGELOGS
        ),
    )
    .unwrap();
    fs::write(&release_manifest_path, "overwrite-me").unwrap();
    fs::write(&current_versions_manifest_path, VERSIONS_TOML).unwrap();

    subcommand_render(&RenderArgs {
        change_set: ChangeSet::SmithyRs,
        independent_versioning: true,
        source: vec![source_path.clone()],
        source_to_truncate: source_path.clone(),
        changelog_output: dest_path.clone(),
        release_manifest_output: Some(tmp_dir.path().into()),
        date_override: Some(OffsetDateTime::UNIX_EPOCH),
        current_release_versions_manifest: Some(current_versions_manifest_path),
        previous_release_versions_manifest: None,
        smithy_rs_location: Some(tmp_dir.path().into()),
    })
    .unwrap();

    let source = fs::read_to_string(&source_path).unwrap();
    let dest = fs::read_to_string(&dest_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.trim(), source);
    pretty_assertions::assert_str_eq!(
        r#"<!-- Do not manually edit this file. Use the `changelogger` tool. -->
January 1st, 1970
=================
**New this release:**
- (all, [smithy-rs#1234](https://github.com/awslabs/smithy-rs/issues/1234), @another-dev) Another change

**Contributors**
Thank you for your contributions! ❤
- @another-dev ([smithy-rs#1234](https://github.com/awslabs/smithy-rs/issues/1234))

**Crate Versions**
<details>
<summary>Click to expand to view crate versions...</summary>

|Crate|Version|
|-|-|
|aws-config|0.54.1|
|aws-sdk-accessanalyzer|0.24.0|
|aws-smithy-async|0.54.1|
</details>


v0.54.0 (Some date in the past)
=========

Old entry contents
"#,
        dest
    );
    pretty_assertions::assert_str_eq!(
        r#"{
  "tagName": "release-1970-01-01",
  "name": "January 1st, 1970",
  "body": "**New this release:**\n- (all, [smithy-rs#1234](https://github.com/awslabs/smithy-rs/issues/1234), @another-dev) Another change\n\n**Contributors**\nThank you for your contributions! ❤\n- @another-dev ([smithy-rs#1234](https://github.com/awslabs/smithy-rs/issues/1234))\n\n**Crate Versions**\n<details>\n<summary>Click to expand to view crate versions...</summary>\n\n|Crate|Version|\n|-|-|\n|aws-config|0.54.1|\n|aws-sdk-accessanalyzer|0.24.0|\n|aws-smithy-async|0.54.1|\n</details>\n\n",
  "prerelease": true
}"#,
        release_manifest
    );
}
+3 −1
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@ use std::fs;
use std::path::Path;
use std::str::FromStr;

pub type CrateVersionMetadataMap = BTreeMap<String, CrateVersion>;

/// Root struct representing a `versions.toml` manifest
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
pub struct VersionsManifest {
@@ -31,7 +33,7 @@ pub struct VersionsManifest {
    pub manual_interventions: ManualInterventions,

    /// All SDK crate version metadata
    pub crates: BTreeMap<String, CrateVersion>,
    pub crates: CrateVersionMetadataMap,

    /// Crate versions that were a part of this SDK release.
    /// Releases may not release every single crate, which can happen if a crate has no changes.