Upgrade to Flyway 11.13.0

Closes gh-47239
This commit is contained in:
Stéphane Nicoll 2025-09-17 08:17:17 +02:00
parent 7ada32ca77
commit 297b4dfe70
6 changed files with 41 additions and 4 deletions

View File

@ -234,6 +234,11 @@ public final class FlywayAutoConfiguration {
.resolveLocations(properties.getLocations()) .resolveLocations(properties.getLocations())
.toArray(new String[0]); .toArray(new String[0]);
configuration.locations(locations); configuration.locations(locations);
map.from(properties.getCallbackLocations())
.when((callbackLocations) -> !ObjectUtils.isEmpty(callbackLocations))
.to((callbackLocations) -> configuration.callbackLocations(
new LocationResolver(configuration.getDataSource()).resolveLocations(callbackLocations)
.toArray(new String[0])));
map.from(properties.isFailOnMissingLocations()) map.from(properties.isFailOnMissingLocations())
.to((failOnMissingLocations) -> configuration.failOnMissingLocations(failOnMissingLocations)); .to((failOnMissingLocations) -> configuration.failOnMissingLocations(failOnMissingLocations));
map.from(properties.getEncoding()).to((encoding) -> configuration.encoding(encoding)); map.from(properties.getEncoding()).to((encoding) -> configuration.encoding(encoding));

View File

@ -60,6 +60,15 @@ public class FlywayProperties {
*/ */
private List<String> locations = new ArrayList<>(Collections.singletonList("classpath:db/migration")); private List<String> locations = new ArrayList<>(Collections.singletonList("classpath:db/migration"));
/**
* Locations of callbacks. Can contain the special "{vendor}" placeholder to use
* vendor-specific callbacks. Unprefixed locations or locations starting with
* "classpath:" point to a package on the classpath and may contain both SQL and
* Java-based callbacks. Locations starting with "filesystem:" point to a directory on
* the filesystem, may only contain SQL callbacks.
*/
private List<String> callbackLocations = new ArrayList<>();
/** /**
* Encoding of SQL migrations. * Encoding of SQL migrations.
*/ */
@ -365,6 +374,14 @@ public class FlywayProperties {
this.locations = locations; this.locations = locations;
} }
public List<String> getCallbackLocations() {
return this.callbackLocations;
}
public void setCallbackLocations(List<String> callbackLocations) {
this.callbackLocations = callbackLocations;
}
public Charset getEncoding() { public Charset getEncoding() {
return this.encoding; return this.encoding;
} }

View File

@ -35,8 +35,8 @@ class NativeImageResourceProviderCustomizer extends ResourceProviderCustomizer {
@Override @Override
public void customize(FluentConfiguration configuration) { public void customize(FluentConfiguration configuration) {
if (configuration.getResourceProvider() == null) { if (configuration.getResourceProvider() == null) {
Scanner<JavaMigration> scanner = new Scanner<>(JavaMigration.class, false, new ResourceNameCache(), Scanner<JavaMigration> scanner = new Scanner<>(JavaMigration.class, new ResourceNameCache(),
new LocationScannerCache(), configuration); new LocationScannerCache(), configuration, configuration.getLocations());
NativeImageResourceProvider resourceProvider = new NativeImageResourceProvider(scanner, NativeImageResourceProvider resourceProvider = new NativeImageResourceProvider(scanner,
configuration.getClassLoader(), Arrays.asList(configuration.getLocations()), configuration.getClassLoader(), Arrays.asList(configuration.getLocations()),
configuration.getEncoding(), configuration.isFailOnMissingLocations()); configuration.getEncoding(), configuration.isFailOnMissingLocations());

View File

@ -560,6 +560,19 @@ class FlywayAutoConfigurationTests {
}); });
} }
@Test
@WithResource(name = "com/example/h2/beforeEachMigrate.sql", content = "DROP TABLE IF EXISTS TEMP;")
void useOneCallbackLocationWithVendorSpecificPackage() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.flyway.callback-locations=classpath:com.example.{vendor}")
.run((context) -> {
assertThat(context).hasSingleBean(Flyway.class);
Flyway flyway = context.getBean(Flyway.class);
assertThat(flyway.getConfiguration().getCallbackLocations())
.containsExactly(new Location("classpath:com.example.h2"));
});
}
@Test @Test
void callbacksAreConfiguredAndOrderedByName() { void callbacksAreConfiguredAndOrderedByName() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class, CallbackConfiguration.class) this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class, CallbackConfiguration.class)

View File

@ -54,6 +54,8 @@ class FlywayPropertiesTests {
assertThat(properties.isFailOnMissingLocations()).isEqualTo(configuration.isFailOnMissingLocations()); assertThat(properties.isFailOnMissingLocations()).isEqualTo(configuration.isFailOnMissingLocations());
assertThat(properties.getLocations().stream().map(Location::new).toArray(Location[]::new)) assertThat(properties.getLocations().stream().map(Location::new).toArray(Location[]::new))
.isEqualTo(configuration.getLocations()); .isEqualTo(configuration.getLocations());
assertThat(properties.getCallbackLocations().stream().map(Location::new).toArray(Location[]::new))
.isEqualTo(configuration.getCallbackLocations());
assertThat(properties.getEncoding()).isEqualTo(configuration.getEncoding()); assertThat(properties.getEncoding()).isEqualTo(configuration.getEncoding());
assertThat(properties.getConnectRetries()).isEqualTo(configuration.getConnectRetries()); assertThat(properties.getConnectRetries()).isEqualTo(configuration.getConnectRetries());
assertThat(properties.getConnectRetriesInterval()).extracting(Duration::getSeconds) assertThat(properties.getConnectRetriesInterval()).extracting(Duration::getSeconds)
@ -130,7 +132,7 @@ class FlywayPropertiesTests {
"environmentProvisionMode", "provisionMode", "cleanOnValidationError"); "environmentProvisionMode", "provisionMode", "cleanOnValidationError");
// Handled by the conversion service // Handled by the conversion service
ignoreProperties(configuration, "baselineVersionAsString", "encodingAsString", "locationsAsStrings", ignoreProperties(configuration, "baselineVersionAsString", "encodingAsString", "locationsAsStrings",
"targetAsString"); "callbackLocationsAsStrings", "targetAsString");
// Handled as initSql array // Handled as initSql array
ignoreProperties(configuration, "initSql"); ignoreProperties(configuration, "initSql");
ignoreProperties(properties, "initSqls"); ignoreProperties(properties, "initSqls");

View File

@ -375,7 +375,7 @@ bom {
javadoc("elasticsearch-java", version -> "https://javadoc.io/doc/co.elastic.clients/elasticsearch-java/%s/index.html".formatted(version), "co.elastic.clients.elasticsearch", "co.elastic.clients.transport") javadoc("elasticsearch-java", version -> "https://javadoc.io/doc/co.elastic.clients/elasticsearch-java/%s/index.html".formatted(version), "co.elastic.clients.elasticsearch", "co.elastic.clients.transport")
} }
} }
library("Flyway", "11.12.0") { library("Flyway", "11.13.0") {
group("org.flywaydb") { group("org.flywaydb") {
modules = [ modules = [
"flyway-commandline", "flyway-commandline",