diff --git a/smoke-tests/.mvn/wrapper/maven-wrapper.jar b/smoke-tests/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000..c1dd12f Binary files /dev/null and b/smoke-tests/.mvn/wrapper/maven-wrapper.jar differ diff --git a/smoke-tests/.mvn/wrapper/maven-wrapper.properties b/smoke-tests/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..464d05a --- /dev/null +++ b/smoke-tests/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.0/apache-maven-3.9.0-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar diff --git a/smoke-tests/pom.xml b/smoke-tests/pom.xml index 1adbee3..4092e1c 100644 --- a/smoke-tests/pom.xml +++ b/smoke-tests/pom.xml @@ -1,7 +1,5 @@ - - + + 4.0.0 @@ -19,7 +17,6 @@ smoke-tests - 17 2023.0.0-M1 orgspringframework-2453 @@ -70,6 +67,7 @@ + maven-central @@ -82,13 +80,14 @@ + artifactory spring-libs-milestone - https://repo.spring.io/milestone/ + https://repo.spring.io/libs-staging-local/ diff --git a/smoke-tests/src/test/java/com/example/smoketests/SmokeTestsApplicationTests.java b/smoke-tests/src/test/java/com/example/smoketests/SmokeTestsApplicationTests.java new file mode 100644 index 0000000..6d3e5d4 --- /dev/null +++ b/smoke-tests/src/test/java/com/example/smoketests/SmokeTestsApplicationTests.java @@ -0,0 +1,50 @@ +package com.example.smoketests; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +import org.springframework.data.cassandra.core.mapping.CassandraMappingContext; +import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; +import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; +import org.springframework.data.jpa.domain.JpaSort; +import org.springframework.data.mongodb.core.mapping.MongoMappingContext; + +/** + * Smoke tests to bootstrap Spring module components to verify they are functional. + */ +class SmokeTestsApplicationTests { + + @Test + void cassandra() { + + CassandraMappingContext context = new CassandraMappingContext(); + assertThat(context).isNotNull(); + } + + @Test + void elasticsearch() { + + SimpleElasticsearchMappingContext context = new SimpleElasticsearchMappingContext(); + assertThat(context).isNotNull(); + } + + @Test + void mongo() { + + MongoMappingContext context = new MongoMappingContext(); + assertThat(context).isNotNull(); + } + + @Test + void jpa() { + assertThat(JpaSort.unsafe("hello")).isNotNull(); + } + + @Test + void jdbc() { + JdbcMappingContext context = new JdbcMappingContext(); + assertThat(context).isNotNull(); + } + +} diff --git a/src/main/java/org/springframework/data/release/build/BuildOperations.java b/src/main/java/org/springframework/data/release/build/BuildOperations.java index 922e013..519785c 100644 --- a/src/main/java/org/springframework/data/release/build/BuildOperations.java +++ b/src/main/java/org/springframework/data/release/build/BuildOperations.java @@ -148,6 +148,20 @@ public class BuildOperations { logger.log(iteration, "Build finished"); } + /** + * Run smoke tests for a {@link TrainIteration} against a {@link StagingRepository}. + * + * @param iteration + * @param stagingRepository + */ + public void smokeTests(TrainIteration iteration, StagingRepository stagingRepository) { + + doWithBuildSystem(iteration.getModule(BUILD), (buildSystem, moduleIteration) -> { + buildSystem.smokeTests(iteration, stagingRepository); + return null; + }); + } + public void buildDocumentation(TrainIteration iteration) { executor.doWithBuildSystemOrdered(Streamable.of(iteration.getModulesExcept(BOM, COMMONS, BUILD)), @@ -184,6 +198,8 @@ public class BuildOperations { orchestrator.close(stagingRepository); } + smokeTests(iteration, stagingRepository); + logger.log(iteration, "Release: %s", summary); return summary.getExecutions().stream().map(BuildExecutor.ExecutionResult::getResult).collect(Collectors.toList()); diff --git a/src/main/java/org/springframework/data/release/build/BuildSystem.java b/src/main/java/org/springframework/data/release/build/BuildSystem.java index 61a1503..a5cd5e1 100644 --- a/src/main/java/org/springframework/data/release/build/BuildSystem.java +++ b/src/main/java/org/springframework/data/release/build/BuildSystem.java @@ -22,6 +22,7 @@ import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.Phase; import org.springframework.data.release.model.Project; import org.springframework.data.release.model.ProjectAware; +import org.springframework.data.release.model.TrainIteration; import org.springframework.plugin.core.Plugin; /** @@ -57,7 +58,6 @@ interface BuildSystem extends Plugin { */ M triggerPreReleaseCheck(M module); - /** * Open a remote repository for staging artifacts. */ @@ -89,6 +89,14 @@ interface BuildSystem extends Plugin { */ DeploymentInformation deploy(ModuleIteration module); + /** + * Run smoke test against a {@link StagingRepository}. + * + * @param iteration + * @param stagingRepository + */ + void smokeTests(TrainIteration iteration, StagingRepository stagingRepository); + /** * Runs the distribution build. * diff --git a/src/main/java/org/springframework/data/release/build/MavenBuildSystem.java b/src/main/java/org/springframework/data/release/build/MavenBuildSystem.java index 9242301..f0075f8 100644 --- a/src/main/java/org/springframework/data/release/build/MavenBuildSystem.java +++ b/src/main/java/org/springframework/data/release/build/MavenBuildSystem.java @@ -59,6 +59,7 @@ import org.springframework.data.release.model.Phase; import org.springframework.data.release.model.Project; import org.springframework.data.release.model.ProjectAware; import org.springframework.data.release.model.TrainIteration; +import org.springframework.data.release.model.Version; import org.springframework.data.release.utils.Logger; import org.springframework.stereotype.Component; import org.springframework.util.Assert; @@ -355,6 +356,37 @@ class MavenBuildSystem implements BuildSystem { mvn.execute(module.getProject(), arguments); } + @Override + public void smokeTests(TrainIteration iteration, StagingRepository stagingRepository) { + + Assert.notNull(iteration, "Train iteration must not be null!"); + Assert.notNull(stagingRepository, "StagingRepository iteration must not be null!"); + + logger.log(iteration, "🚬 Running smoke test…"); + + boolean mavenCentral = iteration.getIteration().isPublic(); + String profile = mavenCentral ? "maven-central" : "artifactory"; + + ModuleIteration module = iteration.getModule(BUILD); + + doWithProjection(workspace.getFile(POM_XML, SMOKE_TESTS), pom -> { + + Version version = module.getVersion(); + String targetBootVersion = version.getMajor() == 2 ? "2.7.8" : "3.0.2"; + + pom.setParentVersion(ArtifactVersion.of(Version.parse(targetBootVersion), true)); + }); + + CommandLine arguments = CommandLine.of(Goal.CLEAN, VERIFY, // + profile(profile), // + arg("spring-data-bom.version").withValue(iteration.getReleaseTrainNameAndVersion())) // + .andIf(mavenCentral, arg("stagingRepository").withValue(stagingRepository.getId())); + + mvn.execute(SMOKE_TESTS, arguments); + + logger.log(iteration, "✅ Smoke tests passed. Do not smoke 🚭. It's unhealthy."); + } + @Override public M triggerDocumentationBuild(M module) { diff --git a/src/main/java/org/springframework/data/release/build/MavenRuntime.java b/src/main/java/org/springframework/data/release/build/MavenRuntime.java index e12199b..5e6b092 100644 --- a/src/main/java/org/springframework/data/release/build/MavenRuntime.java +++ b/src/main/java/org/springframework/data/release/build/MavenRuntime.java @@ -129,7 +129,6 @@ public class MavenRuntime { mavenLogger.info(String.format("Executing: mvn %s", arguments)); mvn.setGoals(arguments.toCommandLine(it -> properties.getFullyQualifiedPlugin(it.getGoal()))); - }); if (result.getExitCode() != 0) { diff --git a/src/main/java/org/springframework/data/release/cli/ReleaseCommands.java b/src/main/java/org/springframework/data/release/cli/ReleaseCommands.java index 92b05be..3cbb1f5 100644 --- a/src/main/java/org/springframework/data/release/cli/ReleaseCommands.java +++ b/src/main/java/org/springframework/data/release/cli/ReleaseCommands.java @@ -223,6 +223,19 @@ class ReleaseCommands extends TimedCommand { git.checkout(iteration); } + /** + * Triggers the smoke tests. + * + * @param iteration + * @throws Exception + */ + @CliCommand(value = "release smoke-tests") + public void runSmokeTests(@CliOption(key = "", mandatory = true) TrainIteration iteration, + @CliOption(key = "stagingRepository", mandatory = false) String stagingRepository) throws Exception { + build.smokeTests(iteration, + stagingRepository != null ? StagingRepository.of(stagingRepository) : StagingRepository.EMPTY); + } + /** * Triggers the distribution of release artifacts for all projects. * diff --git a/src/main/java/org/springframework/data/release/io/Workspace.java b/src/main/java/org/springframework/data/release/io/Workspace.java index e2cd713..e09b870 100644 --- a/src/main/java/org/springframework/data/release/io/Workspace.java +++ b/src/main/java/org/springframework/data/release/io/Workspace.java @@ -43,6 +43,7 @@ import javax.annotation.PostConstruct; import org.springframework.core.io.Resource; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.data.release.model.Project; +import org.springframework.data.release.model.Projects; import org.springframework.data.release.utils.Logger; import org.springframework.stereotype.Component; import org.springframework.util.Assert; @@ -151,6 +152,11 @@ public class Workspace { public File getProjectDirectory(Project project) { Assert.notNull(project, "Project must not be null!"); + + if (project == Projects.SMOKE_TESTS) { + return new File("smoke-tests"); + } + return new File(getWorkingDirectory(), project.getFolderName()); } diff --git a/src/main/java/org/springframework/data/release/model/ArtifactVersion.java b/src/main/java/org/springframework/data/release/model/ArtifactVersion.java index 3148959..2be48b0 100644 --- a/src/main/java/org/springframework/data/release/model/ArtifactVersion.java +++ b/src/main/java/org/springframework/data/release/model/ArtifactVersion.java @@ -70,7 +70,11 @@ public class ArtifactVersion implements Comparable { } public static ArtifactVersion of(Version version) { - return new ArtifactVersion(version, false, RELEASE_SUFFIX); + return of(version, false); + } + + public static ArtifactVersion of(Version version, boolean useModifierFormat) { + return new ArtifactVersion(version, useModifierFormat, RELEASE_SUFFIX); } /** diff --git a/src/main/java/org/springframework/data/release/model/Projects.java b/src/main/java/org/springframework/data/release/model/Projects.java index f6b640a..613a8c3 100644 --- a/src/main/java/org/springframework/data/release/model/Projects.java +++ b/src/main/java/org/springframework/data/release/model/Projects.java @@ -42,6 +42,7 @@ public class Projects { public static final Project BOM, COMMONS, BUILD, REST, JDBC, RELATIONAL, JPA, MONGO_DB, NEO4J, SOLR, COUCHBASE, CASSANDRA, ELASTICSEARCH, R2DBC, REDIS, KEY_VALUE, ENVERS, LDAP, GEODE; public static final List PROJECTS; + public static final Project SMOKE_TESTS = new Project("SMOKE_TESTS", "Smoke Tests", Tracker.GITHUB); static {