Add breaking changes section to changelog generator (#3255)

Fixes #3212

-------

* Add breaking changes section to changelog generator.

* re-design test of changelog

* format fix

* Update tools/changelog/tests/generate_yew_changelog_file.rs

Co-authored-by: Muhammad Hamza <muhammadhamza1311@gmail.com>

---------

Co-authored-by: jelly <jelly.zhao.42@gmail.com>
Co-authored-by: Muhammad Hamza <muhammadhamza1311@gmail.com>
This commit is contained in:
jelllly420 2023-08-19 03:43:59 +08:00 committed by GitHub
parent 41d42fb89d
commit a27076db86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 87 additions and 25 deletions

View File

@ -81,25 +81,38 @@ impl Cli {
let log_lines = create_log_lines(from_ref, to, package_labels, token)?;
// categorize logs
let (fixes, features): (Vec<_>, Vec<_>) = log_lines
let (breaking_changes, filtered_log_lines): (Vec<_>, Vec<_>) = log_lines
.into_iter()
.partition(|log_line| log_line.message.to_lowercase().contains("fix"));
.partition(|log_line| log_line.is_breaking_change);
let (fixes, features): (Vec<_>, Vec<_>) =
filtered_log_lines
.into_iter()
.partition(|filtered_log_line| {
filtered_log_line.message.to_lowercase().contains("fix")
});
// create displayable log lines
let fixes_logs = write_log_lines(fixes)?;
let features_logs = write_log_lines(features)?;
let breaking_changes_logs = write_log_lines(breaking_changes)?;
if !skip_file_write {
// create version changelog
let version_changelog =
write_changelog_file(&fixes_logs, &features_logs, package, next_version)?;
let version_changelog = write_changelog_file(
&fixes_logs,
&features_logs,
&breaking_changes_logs,
package,
next_version,
)?;
// write changelog
write_changelog(&changelog_path, &version_changelog)?;
}
// stdout changelog meant for tag description
stdout_tag_description_changelog(&fixes_logs, &features_logs)?;
stdout_tag_description_changelog(&fixes_logs, &features_logs, &breaking_changes_logs)?;
Ok(())
}

View File

@ -89,11 +89,15 @@ pub fn create_log_line(
}
return Ok(None);
}
let is_breaking_change = issue_labels
.iter()
.any(|label| label.to_lowercase().contains("breaking change"));
let log_line = LogLine {
message,
user: author_name.to_string(),
issue_id,
is_breaking_change,
};
println!("{log_line:?}");

View File

@ -3,4 +3,5 @@ pub struct LogLine {
pub message: String,
pub user: String,
pub issue_id: String,
pub is_breaking_change: bool,
}

View File

@ -2,13 +2,17 @@ use std::io::{stdout, Write};
use anyhow::Result;
pub fn stdout_tag_description_changelog(fixes_logs: &[u8], features_logs: &[u8]) -> Result<()> {
pub fn stdout_tag_description_changelog(
fixes_logs: &[u8],
features_logs: &[u8],
breaking_changes_logs: &[u8],
) -> Result<()> {
let mut tag_changelog = Vec::new();
writeln!(tag_changelog, "# Changelog")?;
writeln!(tag_changelog)?;
if fixes_logs.is_empty() && features_logs.is_empty() {
if fixes_logs.is_empty() && features_logs.is_empty() && breaking_changes_logs.is_empty() {
writeln!(tag_changelog, "No changes")?;
writeln!(tag_changelog)?;
}
@ -26,6 +30,12 @@ pub fn stdout_tag_description_changelog(fixes_logs: &[u8], features_logs: &[u8])
tag_changelog.extend(features_logs);
}
if !breaking_changes_logs.is_empty() {
writeln!(tag_changelog, "## 🚨 Breaking changes")?;
writeln!(tag_changelog)?;
tag_changelog.extend(breaking_changes_logs);
}
stdout().write_all(&tag_changelog)?;
Ok(())

View File

@ -9,7 +9,7 @@ pub fn write_changelog(changelog_path: &str, version_changelog: &[u8]) -> Result
.context(format!("could not open {changelog_path} for reading"))?;
let old_changelog_reader = BufReader::new(old_changelog);
let changelog_path_new = &format!("../{changelog_path}.new");
let changelog_path_new = &format!("{changelog_path}.new");
let mut new_changelog = fs::OpenOptions::new()
.write(true)

View File

@ -10,6 +10,7 @@ pub fn write_log_lines(log_lines: Vec<LogLine>) -> Result<Vec<u8>> {
message,
user,
issue_id,
..
} in log_lines
{
writeln!(

View File

@ -8,6 +8,7 @@ use crate::yew_package::YewPackage;
pub fn write_changelog_file(
fixes_logs: &[u8],
features_logs: &[u8],
breaking_changes_logs: &[u8],
package: YewPackage,
next_version: Version,
) -> Result<Vec<u8>> {
@ -25,7 +26,7 @@ pub fn write_changelog_file(
)?;
writeln!(version_only_changelog)?;
if fixes_logs.is_empty() && features_logs.is_empty() {
if fixes_logs.is_empty() && features_logs.is_empty() && breaking_changes_logs.is_empty() {
writeln!(version_only_changelog, "No changes")?;
writeln!(version_only_changelog)?;
}
@ -44,5 +45,12 @@ pub fn write_changelog_file(
writeln!(version_only_changelog)?;
}
if !breaking_changes_logs.is_empty() {
writeln!(version_only_changelog, "### 🚨 Breaking changes")?;
writeln!(version_only_changelog)?;
version_only_changelog.extend(breaking_changes_logs);
writeln!(version_only_changelog)?;
}
Ok(version_only_changelog)
}

View File

@ -17,6 +17,23 @@ impl Drop for FileDeleteOnDrop {
}
}
fn _generate_yew_changelog_file(from: &str, to: &str) -> Result<()> {
let cli_args = Cli {
package: YewPackage::from_str("yew").unwrap(),
new_version_level: NewVersionLevel::Minor,
from: Some(from.to_string()),
to: to.to_string(),
changelog_path: "tests/test_changelog.md".to_string(),
skip_file_write: false,
skip_get_bump_version: true,
token: None,
};
cli_args.run().unwrap();
Ok(())
}
#[test]
fn generate_yew_changelog_file() -> Result<()> {
// Setup
@ -25,18 +42,15 @@ fn generate_yew_changelog_file() -> Result<()> {
fs::copy("tests/test_base.md", "tests/test_changelog.md")?;
// Run
let cli_args = Cli {
package: YewPackage::from_str("yew").unwrap(),
new_version_level: NewVersionLevel::Minor,
from: Some("abeb8bc3f1ffabc8a58bd9ba4430cd091a06335a".to_string()),
to: "d8ec50150ed27e2835bb1def26d2371a8c2ab750".to_string(),
changelog_path: "tests/test_changelog.md".to_string(),
skip_file_write: false,
skip_get_bump_version: true,
token: None,
};
_generate_yew_changelog_file(
"abeb8bc3f1ffabc8a58bd9ba4430cd091a06335a",
"d8ec50150ed27e2835bb1def26d2371a8c2ab750",
)?;
cli_args.run().unwrap();
_generate_yew_changelog_file(
"8086a73a217a099a46138f4363411827b18d1cb0",
"934aedbc8815fd77fc6630b644cfea4f9a071236",
)?;
// Check
let expected = File::open("tests/test_expected.md")?;
@ -48,13 +62,13 @@ fn generate_yew_changelog_file() -> Result<()> {
let lines = expected_reader_lines.zip(after_reader_lines);
for (i, (expected_line, after_line)) in lines.enumerate() {
if i == 2 {
// third line has dynamic things that may break the tests
let expected_third_line = expected_line?.replace(
if i == 2 || i == 13 {
// these lines have dynamic things that may break the tests
let expected_line_updated = expected_line?.replace(
"date_goes_here",
Utc::now().format("%Y-%m-%d").to_string().as_str(),
);
assert_eq!(expected_third_line, after_line?);
assert_eq!(expected_line_updated, after_line?);
} else {
assert_eq!(expected_line?, after_line?);
}

View File

@ -2,9 +2,20 @@
## ✨ yew **0.0.0** *(date_goes_here)* Changelog
### ⚡️ Features
- Incremental performance improvements to element creation. [[@Greg Johnston](https://github.com/Greg Johnston), [#3169](https://github.com/yewstack/yew/pull/3169)]
### 🚨 Breaking changes
- Enable PartialEq for all virtual dom types. [[@Kaede Hoshikawa](https://github.com/Kaede Hoshikawa), [#3206](https://github.com/yewstack/yew/pull/3206)]
- Pass hook dependencies as the first function argument. [[@Arniu Tseng](https://github.com/Arniu Tseng), [#2861](https://github.com/yewstack/yew/pull/2861)]
## ✨ yew **0.0.0** *(date_goes_here)* Changelog
### 🛠 Fixes
- Fix defaulted type parameter.. [[@futursolo](https://github.com/futursolo), [#2284](https://github.com/yewstack/yew/pull/2284)]
- Fix defaulted type parameter.. [[@Kaede Hoshikawa](https://github.com/Kaede Hoshikawa), [#2284](https://github.com/yewstack/yew/pull/2284)]
### ⚡️ Features