Browse Source

Fix changelog generator missing directly removed properties

The changelog generator did not detect properties that were added to a new
version with error-level deprecation (indicating immediate removal). This
commonly occurs when upgrading dependencies like Flyway 10, where properties
are removed without prior deprecation.

Modified the computeDifferences method to detect properties that only exist
in the new metadata with error-level deprecation and properly mark them as
DELETED in the changelog.

See gh-45267

Signed-off-by: yybmion <yunyubin54@gmail.com>
pull/45382/head
yybmion 9 months ago committed by Andy Wilkinson
parent
commit
30a679872c
  1. 24
      spring-boot-project/spring-boot-tools/spring-boot-configuration-metadata-changelog-generator/src/main/java/org/springframework/boot/configurationmetadata/changelog/Changelog.java
  2. 11
      spring-boot-project/spring-boot-tools/spring-boot-configuration-metadata-changelog-generator/src/test/java/org/springframework/boot/configurationmetadata/changelog/ChangelogTests.java
  3. 13
      spring-boot-project/spring-boot-tools/spring-boot-configuration-metadata-changelog-generator/src/test/resources/sample-2.0.json
  4. 4
      spring-boot-project/spring-boot-tools/spring-boot-configuration-metadata-changelog-generator/src/test/resources/sample.adoc

24
spring-boot-project/spring-boot-tools/spring-boot-configuration-metadata-changelog-generator/src/main/java/org/springframework/boot/configurationmetadata/changelog/Changelog.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,6 +21,7 @@ import java.util.List; @@ -21,6 +21,7 @@ import java.util.List;
import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;
import org.springframework.boot.configurationmetadata.ConfigurationMetadataRepository;
import org.springframework.boot.configurationmetadata.Deprecation;
/**
* A changelog containing differences computed from two repositories of configuration
@ -32,6 +33,7 @@ import org.springframework.boot.configurationmetadata.ConfigurationMetadataRepos @@ -32,6 +33,7 @@ import org.springframework.boot.configurationmetadata.ConfigurationMetadataRepos
* @author Stephane Nicoll
* @author Andy Wilkinson
* @author Phillip Webb
* @author Yoobin Yoon
*/
record Changelog(String oldVersionNumber, String newVersionNumber, List<Difference> differences) {
@ -48,14 +50,24 @@ record Changelog(String oldVersionNumber, String newVersionNumber, List<Differen @@ -48,14 +50,24 @@ record Changelog(String oldVersionNumber, String newVersionNumber, List<Differen
String id = oldProperty.getId();
seenIds.add(id);
ConfigurationMetadataProperty newProperty = newMetadata.getAllProperties().get(id);
Difference difference = Difference.compute(oldProperty, newProperty);
if (difference != null) {
differences.add(difference);
if (newProperty == null) {
differences.add(new Difference(DifferenceType.DELETED, oldProperty, null));
}
else {
Difference difference = Difference.compute(oldProperty, newProperty);
if (difference != null) {
differences.add(difference);
}
}
}
for (ConfigurationMetadataProperty newProperty : newMetadata.getAllProperties().values()) {
if ((!seenIds.contains(newProperty.getId())) && (!newProperty.isDeprecated())) {
differences.add(new Difference(DifferenceType.ADDED, null, newProperty));
if (!seenIds.contains(newProperty.getId())) {
if (newProperty.isDeprecated() && newProperty.getDeprecation().getLevel() == Deprecation.Level.ERROR) {
differences.add(new Difference(DifferenceType.DELETED, null, newProperty));
}
else if (!newProperty.isDeprecated()) {
differences.add(new Difference(DifferenceType.ADDED, null, newProperty));
}
}
}
return List.copyOf(differences);

11
spring-boot-project/spring-boot-tools/spring-boot-configuration-metadata-changelog-generator/src/test/java/org/springframework/boot/configurationmetadata/changelog/ChangelogTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -29,6 +29,7 @@ import static org.assertj.core.api.Assertions.assertThat; @@ -29,6 +29,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Stephane Nicoll
* @author Andy Wilkinson
* @author Yoobin Yoon
*/
class ChangelogTests {
@ -38,7 +39,7 @@ class ChangelogTests { @@ -38,7 +39,7 @@ class ChangelogTests {
assertThat(differences).isNotNull();
assertThat(differences.oldVersionNumber()).isEqualTo("1.0");
assertThat(differences.newVersionNumber()).isEqualTo("2.0");
assertThat(differences.differences()).hasSize(4);
assertThat(differences.differences()).hasSize(5);
List<Difference> added = differences.differences()
.stream()
.filter((difference) -> difference.type() == DifferenceType.ADDED)
@ -49,10 +50,12 @@ class ChangelogTests { @@ -49,10 +50,12 @@ class ChangelogTests {
.stream()
.filter((difference) -> difference.type() == DifferenceType.DELETED)
.toList();
assertThat(deleted).hasSize(2)
assertThat(deleted).hasSize(3)
.anySatisfy((entry) -> assertProperty(entry.oldProperty(), "test.delete", String.class, "delete"))
.anySatisfy(
(entry) -> assertProperty(entry.newProperty(), "test.delete.deprecated", String.class, "delete"));
(entry) -> assertProperty(entry.newProperty(), "test.delete.deprecated", String.class, "delete"))
.anySatisfy((entry) -> assertProperty(entry.newProperty(), "test.removed.directly", String.class,
"directlyRemoved"));
List<Difference> deprecated = differences.differences()
.stream()
.filter((difference) -> difference.type() == DifferenceType.DEPRECATED)

13
spring-boot-project/spring-boot-tools/spring-boot-configuration-metadata-changelog-generator/src/test/resources/sample-2.0.json

@ -31,6 +31,17 @@ @@ -31,6 +31,17 @@
"replacement": "test.add",
"reason": "it was just bad"
}
},
{
"name": "test.removed.directly",
"type": "java.lang.String",
"description": "Test property removed without prior deprecation.",
"defaultValue": "directlyRemoved",
"deprecation": {
"level": "error",
"replacement": "test.new.property",
"reason": "Removed in Upgrade 10"
}
}
]
}
}

4
spring-boot-project/spring-boot-tools/spring-boot-configuration-metadata-changelog-generator/src/test/resources/sample.adoc

@ -32,4 +32,8 @@ _None_. @@ -32,4 +32,8 @@ _None_.
| `test.delete.deprecated`
| `test.add`
| it was just bad
| `test.removed.directly`
| `test.new.property`
| Removed in Upgrade 10
|======================

Loading…
Cancel
Save