From 297b4dfe70f4eff92c3397f73b1321fcdb8dd39d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Wed, 17 Sep 2025 08:17:17 +0200 Subject: [PATCH] Upgrade to Flyway 11.13.0 Closes gh-47239 --- .../autoconfigure/FlywayAutoConfiguration.java | 5 +++++ .../flyway/autoconfigure/FlywayProperties.java | 17 +++++++++++++++++ .../NativeImageResourceProviderCustomizer.java | 4 ++-- .../FlywayAutoConfigurationTests.java | 13 +++++++++++++ .../autoconfigure/FlywayPropertiesTests.java | 4 +++- platform/spring-boot-dependencies/build.gradle | 2 +- 6 files changed, 41 insertions(+), 4 deletions(-) diff --git a/module/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayAutoConfiguration.java b/module/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayAutoConfiguration.java index b3d789d237e..7da486cc0ef 100644 --- a/module/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayAutoConfiguration.java +++ b/module/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayAutoConfiguration.java @@ -234,6 +234,11 @@ public final class FlywayAutoConfiguration { .resolveLocations(properties.getLocations()) .toArray(new String[0]); 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()) .to((failOnMissingLocations) -> configuration.failOnMissingLocations(failOnMissingLocations)); map.from(properties.getEncoding()).to((encoding) -> configuration.encoding(encoding)); diff --git a/module/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayProperties.java b/module/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayProperties.java index e41b74fdb57..082e4339396 100644 --- a/module/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayProperties.java +++ b/module/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayProperties.java @@ -60,6 +60,15 @@ public class FlywayProperties { */ private List 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 callbackLocations = new ArrayList<>(); + /** * Encoding of SQL migrations. */ @@ -365,6 +374,14 @@ public class FlywayProperties { this.locations = locations; } + public List getCallbackLocations() { + return this.callbackLocations; + } + + public void setCallbackLocations(List callbackLocations) { + this.callbackLocations = callbackLocations; + } + public Charset getEncoding() { return this.encoding; } diff --git a/module/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/NativeImageResourceProviderCustomizer.java b/module/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/NativeImageResourceProviderCustomizer.java index d5714ef5a08..7efbc1180c3 100644 --- a/module/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/NativeImageResourceProviderCustomizer.java +++ b/module/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/NativeImageResourceProviderCustomizer.java @@ -35,8 +35,8 @@ class NativeImageResourceProviderCustomizer extends ResourceProviderCustomizer { @Override public void customize(FluentConfiguration configuration) { if (configuration.getResourceProvider() == null) { - Scanner scanner = new Scanner<>(JavaMigration.class, false, new ResourceNameCache(), - new LocationScannerCache(), configuration); + Scanner scanner = new Scanner<>(JavaMigration.class, new ResourceNameCache(), + new LocationScannerCache(), configuration, configuration.getLocations()); NativeImageResourceProvider resourceProvider = new NativeImageResourceProvider(scanner, configuration.getClassLoader(), Arrays.asList(configuration.getLocations()), configuration.getEncoding(), configuration.isFailOnMissingLocations()); diff --git a/module/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/FlywayAutoConfigurationTests.java b/module/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/FlywayAutoConfigurationTests.java index a99520476c1..1d8c4b95c22 100644 --- a/module/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/FlywayAutoConfigurationTests.java +++ b/module/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/FlywayAutoConfigurationTests.java @@ -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 void callbacksAreConfiguredAndOrderedByName() { this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class, CallbackConfiguration.class) diff --git a/module/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/FlywayPropertiesTests.java b/module/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/FlywayPropertiesTests.java index 3a85cfbecb5..3c1cfb13700 100644 --- a/module/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/FlywayPropertiesTests.java +++ b/module/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/FlywayPropertiesTests.java @@ -54,6 +54,8 @@ class FlywayPropertiesTests { assertThat(properties.isFailOnMissingLocations()).isEqualTo(configuration.isFailOnMissingLocations()); assertThat(properties.getLocations().stream().map(Location::new).toArray(Location[]::new)) .isEqualTo(configuration.getLocations()); + assertThat(properties.getCallbackLocations().stream().map(Location::new).toArray(Location[]::new)) + .isEqualTo(configuration.getCallbackLocations()); assertThat(properties.getEncoding()).isEqualTo(configuration.getEncoding()); assertThat(properties.getConnectRetries()).isEqualTo(configuration.getConnectRetries()); assertThat(properties.getConnectRetriesInterval()).extracting(Duration::getSeconds) @@ -130,7 +132,7 @@ class FlywayPropertiesTests { "environmentProvisionMode", "provisionMode", "cleanOnValidationError"); // Handled by the conversion service ignoreProperties(configuration, "baselineVersionAsString", "encodingAsString", "locationsAsStrings", - "targetAsString"); + "callbackLocationsAsStrings", "targetAsString"); // Handled as initSql array ignoreProperties(configuration, "initSql"); ignoreProperties(properties, "initSqls"); diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index f191ed51918..819d8ec996d 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -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") } } - library("Flyway", "11.12.0") { + library("Flyway", "11.13.0") { group("org.flywaydb") { modules = [ "flyway-commandline",