Support for commercial releases.
This commit is contained in:
1
Jenkinsfile
vendored
1
Jenkinsfile
vendored
@@ -54,6 +54,7 @@ pipeline {
|
||||
GITHUB = credentials('3a20bcaa-d8ad-48e3-901d-9fbc941376ee')
|
||||
GITHUB_TOKEN = credentials('7b3ebbea-7001-479b-8578-b8c464dab973')
|
||||
REPO_SPRING_IO = credentials('repo_spring_io-jenkins-release-token')
|
||||
COMMERCIAL = credentials('repo_spring_vmware_com-jenkins-token')
|
||||
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
|
||||
STAGING_PROFILE_ID = credentials('spring-data-release-deployment-maven-central-staging-profile-id')
|
||||
MAVEN_SIGNING_KEY = credentials('spring-gpg-private-key')
|
||||
|
||||
@@ -18,5 +18,15 @@
|
||||
<username>${env.ARTIFACTORY_USR}</username>
|
||||
<password>${env.ARTIFACTORY_PSW}</password>
|
||||
</server>
|
||||
<server>
|
||||
<id>spring-commercial-snapshot</id>
|
||||
<username>${env.COMMERCIAL_USR}</username>
|
||||
<password>${env.COMMERCIAL_PSW}</password>
|
||||
</server>
|
||||
<server>
|
||||
<id>spring-commercial-release</id>
|
||||
<username>${env.COMMERCIAL_USR}</username>
|
||||
<password>${env.COMMERCIAL_PSW}</password>
|
||||
</server>
|
||||
</servers>
|
||||
</settings>
|
||||
|
||||
@@ -19,10 +19,8 @@ import java.util.List;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.plugin.core.OrderAwarePluginRegistry;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.plugin.core.PluginRegistry;
|
||||
|
||||
import org.xmlbeam.XBProjector;
|
||||
import org.xmlbeam.XBProjector.Flags;
|
||||
import org.xmlbeam.config.DefaultXMLFactoriesConfig;
|
||||
@@ -37,8 +35,8 @@ import org.xmlbeam.config.DefaultXMLFactoriesConfig.NamespacePhilosophy;
|
||||
class BuildConfiguration {
|
||||
|
||||
@Bean
|
||||
public PluginRegistry<BuildSystem, Project> buildSystems(List<? extends BuildSystem> buildSystems) {
|
||||
return OrderAwarePluginRegistry.create(buildSystems);
|
||||
public PluginRegistry<BuildSystem, SupportedProject> buildSystems(List<? extends BuildSystem> buildSystems) {
|
||||
return PluginRegistry.of(buildSystems);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -35,16 +35,15 @@ import java.util.function.BiFunction;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import org.springframework.data.release.infra.InfrastructureOperations;
|
||||
import org.springframework.data.release.io.Workspace;
|
||||
import org.springframework.data.release.model.JavaVersion;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.model.ProjectAware;
|
||||
import org.springframework.data.release.utils.ListWrapperCollector;
|
||||
import org.springframework.data.util.Streamable;
|
||||
@@ -61,8 +60,7 @@ import org.springframework.util.Assert;
|
||||
@RequiredArgsConstructor
|
||||
class BuildExecutor {
|
||||
|
||||
private final @NonNull PluginRegistry<BuildSystem, Project> buildSystems;
|
||||
private final MavenProperties mavenProperties;
|
||||
private final @NonNull PluginRegistry<BuildSystem, SupportedProject> buildSystems;
|
||||
private final ExecutorService executor;
|
||||
private final Workspace workspace;
|
||||
|
||||
@@ -121,13 +119,14 @@ class BuildExecutor {
|
||||
|
||||
if (futureResult == null) {
|
||||
|
||||
if (!iteration.stream().map(ProjectAware::getProject).anyMatch(project -> project.equals(dependency))) {
|
||||
throw new IllegalStateException(moduleIteration.getProject().getName() + " requires "
|
||||
if (!iteration.stream().map(ProjectAware::getSupportedProject)
|
||||
.anyMatch(project -> project.equals(dependency))) {
|
||||
throw new IllegalStateException(moduleIteration.getSupportedProject().getName() + " requires "
|
||||
+ dependency.getName() + " which is not part of the Iteration. Please fix Projects/Iterations setup");
|
||||
}
|
||||
|
||||
throw new IllegalStateException("No future result for " + dependency.getName() + ", required by "
|
||||
+ moduleIteration.getProject().getName());
|
||||
+ moduleIteration.getSupportedProject().getName());
|
||||
}
|
||||
|
||||
futureResult.join();
|
||||
@@ -156,16 +155,18 @@ class BuildExecutor {
|
||||
.collect(toSummaryCollector());
|
||||
}
|
||||
|
||||
private <T, M extends ProjectAware> CompletableFuture<T> run(M module, BiFunction<BuildSystem, M, T> function) {
|
||||
private <T, M extends ProjectAware> CompletableFuture<T> run(M module,
|
||||
BiFunction<BuildSystem, M, T> function) {
|
||||
|
||||
Assert.notNull(module, "Module must not be null!");
|
||||
|
||||
CompletableFuture<T> result = new CompletableFuture<>();
|
||||
Supplier<IllegalStateException> exception = () -> new IllegalStateException(
|
||||
String.format("No build system plugin found for project %s!", module.getProject()));
|
||||
String.format("No build system plugin found for project %s!", module.getSupportedProject()));
|
||||
|
||||
BuildSystem buildSystem = buildSystems.getPluginFor(module.getProject(), exception)
|
||||
.withJavaVersion(detectJavaVersion(module.getProject()));
|
||||
BuildSystem buildSystem = buildSystems //
|
||||
.getPluginFor(module.getSupportedProject(), exception) //
|
||||
.withJavaVersion(detectJavaVersion(module.getSupportedProject()));
|
||||
|
||||
Runnable runnable = () -> {
|
||||
|
||||
@@ -183,7 +184,7 @@ class BuildExecutor {
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public JavaVersion detectJavaVersion(Project project) {
|
||||
public JavaVersion detectJavaVersion(SupportedProject project) {
|
||||
|
||||
File ciProperties = workspace.getFile(InfrastructureOperations.CI_PROPERTIES, project);
|
||||
|
||||
|
||||
@@ -29,12 +29,11 @@ import java.util.stream.Collectors;
|
||||
import org.assertj.core.util.VisibleForTesting;
|
||||
import org.springframework.data.release.deployment.DeploymentInformation;
|
||||
import org.springframework.data.release.deployment.StagingRepository;
|
||||
import org.springframework.data.release.model.Iteration;
|
||||
import org.springframework.data.release.model.Module;
|
||||
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.Projects;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.model.Train;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
@@ -52,7 +51,7 @@ import org.springframework.util.Assert;
|
||||
@RequiredArgsConstructor
|
||||
public class BuildOperations {
|
||||
|
||||
private final @NonNull PluginRegistry<BuildSystem, Project> buildSystems;
|
||||
private final @NonNull PluginRegistry<BuildSystem, SupportedProject> buildSystems;
|
||||
private final @NonNull Logger logger;
|
||||
private final @NonNull MavenProperties properties;
|
||||
private final @NonNull BuildExecutor executor;
|
||||
@@ -117,7 +116,7 @@ public class BuildOperations {
|
||||
*/
|
||||
public void open(ModuleIteration iteration) {
|
||||
|
||||
doWithBuildSystem(iteration, (buildSystem, moduleIteration) -> buildSystem.open());
|
||||
doWithBuildSystem(iteration, (buildSystem, moduleIteration) -> buildSystem.open(iteration.getTrain()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,8 +130,10 @@ public class BuildOperations {
|
||||
Assert.notNull(stagingRepository, "StagingRepository must not be null");
|
||||
Assert.isTrue(stagingRepository.isPresent(), "StagingRepository must be present");
|
||||
|
||||
Train train = iteration.getTrain();
|
||||
|
||||
doWithBuildSystem(iteration, (buildSystem, moduleIteration) -> {
|
||||
buildSystem.close(stagingRepository);
|
||||
buildSystem.close(train, stagingRepository);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
@@ -145,7 +146,7 @@ public class BuildOperations {
|
||||
*/
|
||||
public void build(TrainIteration iteration) {
|
||||
|
||||
executor.doWithBuildSystemOrdered(iteration, BuildSystem::triggerBuild);
|
||||
executor.doWithBuildSystemOrdered(iteration, (it, l) -> it.triggerBuild(l));
|
||||
|
||||
logger.log(iteration, "Build finished");
|
||||
}
|
||||
@@ -156,11 +157,11 @@ public class BuildOperations {
|
||||
* @param iteration
|
||||
* @return
|
||||
*/
|
||||
public StagingRepository openStagingRepository(Iteration iteration) {
|
||||
public StagingRepository openStagingRepository(TrainIteration iteration) {
|
||||
|
||||
BuildSystem orchestrator = buildSystems.getRequiredPluginFor(Projects.BUILD);
|
||||
BuildSystem orchestrator = buildSystems.getRequiredPluginFor(iteration.getSupportedProject(Projects.BUILD));
|
||||
|
||||
return iteration.isPublic() ? orchestrator.open() : StagingRepository.EMPTY;
|
||||
return iteration.isPublic() ? orchestrator.open(iteration.getTrain()) : StagingRepository.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -169,27 +170,28 @@ public class BuildOperations {
|
||||
* @param stagingRepository
|
||||
* @return
|
||||
*/
|
||||
public void closeStagingRepository(StagingRepository stagingRepository) {
|
||||
public void closeStagingRepository(Train train, StagingRepository stagingRepository) {
|
||||
|
||||
BuildSystem orchestrator = buildSystems.getRequiredPluginFor(Projects.BUILD);
|
||||
BuildSystem orchestrator = buildSystems.getRequiredPluginFor(train.getSupportedProject(Projects.BUILD));
|
||||
|
||||
if (stagingRepository.isPresent()) {
|
||||
orchestrator.close(stagingRepository);
|
||||
orchestrator.close(train, stagingRepository);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Promote the staging repository.
|
||||
*
|
||||
* @param stagingRepository
|
||||
* @param train must not be {@literal null}.
|
||||
* @param stagingRepository must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public void releaseStagingRepository(StagingRepository stagingRepository) {
|
||||
public void releaseStagingRepository(Train train, StagingRepository stagingRepository) {
|
||||
|
||||
BuildSystem orchestrator = buildSystems.getRequiredPluginFor(Projects.BUILD);
|
||||
BuildSystem orchestrator = buildSystems.getRequiredPluginFor(train.getSupportedProject(Projects.BUILD));
|
||||
|
||||
if (stagingRepository.isPresent()) {
|
||||
orchestrator.release(stagingRepository);
|
||||
orchestrator.release(train, stagingRepository);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,16 +217,19 @@ public class BuildOperations {
|
||||
*/
|
||||
public void release(ModuleIteration iteration, StagingRepository stagingRepository) {
|
||||
|
||||
Train train = iteration.getTrain();
|
||||
|
||||
doWithBuildSystem(iteration, (buildSystem, moduleIteration) -> {
|
||||
buildSystem.release(stagingRepository);
|
||||
buildSystem.release(train, stagingRepository);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public void buildDocumentation(TrainIteration iteration) {
|
||||
|
||||
executor.doWithBuildSystemOrdered(Streamable.of(iteration.getModulesExcept(BOM, COMMONS, BUILD)),
|
||||
BuildSystem::triggerDocumentationBuild);
|
||||
Streamable<ModuleIteration> of = Streamable.of(iteration.getModulesExcept(BOM, COMMONS, BUILD));
|
||||
|
||||
executor.doWithBuildSystemOrdered(of, BuildSystem::triggerDocumentationBuild);
|
||||
|
||||
logger.log(iteration, "Documentation build finished");
|
||||
}
|
||||
@@ -244,14 +249,17 @@ public class BuildOperations {
|
||||
*/
|
||||
public List<DeploymentInformation> performRelease(TrainIteration iteration) {
|
||||
|
||||
Iteration it = iteration.getIteration();
|
||||
StagingRepository stagingRepository = it.isPublic() ? openStagingRepository(it) : StagingRepository.EMPTY;
|
||||
StagingRepository stagingRepository = iteration.isPublic() //
|
||||
? openStagingRepository(iteration) //
|
||||
: StagingRepository.EMPTY;
|
||||
|
||||
BuildExecutor.Summary<DeploymentInformation> summary = executor.doWithBuildSystemOrdered(iteration,
|
||||
(buildSystem, moduleIteration) -> buildSystem.deploy(moduleIteration, stagingRepository));
|
||||
|
||||
Train train = iteration.getTrain();
|
||||
|
||||
if (stagingRepository.isPresent()) {
|
||||
closeStagingRepository(stagingRepository);
|
||||
closeStagingRepository(train, stagingRepository);
|
||||
}
|
||||
|
||||
smokeTests(iteration, stagingRepository);
|
||||
@@ -259,10 +267,12 @@ public class BuildOperations {
|
||||
logger.log(iteration, "Release: %s", summary);
|
||||
|
||||
if (stagingRepository.isPresent()) {
|
||||
releaseStagingRepository(stagingRepository);
|
||||
releaseStagingRepository(train, stagingRepository);
|
||||
}
|
||||
|
||||
return summary.getExecutions().stream().map(BuildExecutor.ExecutionResult::getResult).collect(Collectors.toList());
|
||||
return summary.getExecutions().stream()
|
||||
.map(BuildExecutor.ExecutionResult::getResult)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -296,8 +306,7 @@ public class BuildOperations {
|
||||
|
||||
Assert.notNull(train, "Train must not be null!");
|
||||
|
||||
BuildExecutor.Summary<Module> summary = executor.doWithBuildSystemAnyOrder(train,
|
||||
BuildSystem::triggerDistributionBuild);
|
||||
BuildExecutor.Summary<?> summary = executor.doWithBuildSystemAnyOrder(train, BuildSystem::triggerDistributionBuild);
|
||||
|
||||
logger.log(train, "Distribution build: %s", summary);
|
||||
}
|
||||
@@ -357,24 +366,30 @@ public class BuildOperations {
|
||||
|
||||
/**
|
||||
* Verifies Java version presence and that the project can be build using Maven.
|
||||
*
|
||||
* @param train must not be {@literal null}.
|
||||
*/
|
||||
public void verify() {
|
||||
public void verify(Train train) {
|
||||
|
||||
Project project = Projects.BUILD;
|
||||
SupportedProject project = train.getSupportedProject(Projects.BUILD);
|
||||
BuildSystem buildSystem = buildSystems.getRequiredPluginFor(project);
|
||||
|
||||
buildSystem.withJavaVersion(executor.detectJavaVersion(project)).verify();
|
||||
buildSystem.verify(train);
|
||||
// buildSystem.withJavaVersion(executor.detectJavaVersion(project)).verify(train);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies Maven staging authentication.
|
||||
*
|
||||
* @param train must not be {@literal null}.
|
||||
*/
|
||||
public void verifyStagingAuthentication() {
|
||||
public void verifyStagingAuthentication(Train train) {
|
||||
|
||||
Project project = Projects.BUILD;
|
||||
SupportedProject project = train.getSupportedProject(Projects.BUILD);
|
||||
BuildSystem buildSystem = buildSystems.getRequiredPluginFor(project);
|
||||
|
||||
buildSystem.withJavaVersion(executor.detectJavaVersion(project)).verifyStagingAuthentication();
|
||||
buildSystem.verifyStagingAuthentication(train);
|
||||
// buildSystem.withJavaVersion(executor.detectJavaVersion(project)).verifyStagingAuthentication(train);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -385,15 +400,17 @@ public class BuildOperations {
|
||||
* @param function must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
private <T> T doWithBuildSystem(ModuleIteration module, BiFunction<BuildSystem, ModuleIteration, T> function) {
|
||||
private <T, S extends ProjectAware> T doWithBuildSystem(S module,
|
||||
BiFunction<BuildSystem, S, T> function) {
|
||||
|
||||
Assert.notNull(module, "ModuleIteration must not be null!");
|
||||
|
||||
Supplier<IllegalStateException> exception = () -> new IllegalStateException(
|
||||
String.format("No build system plugin found for project %s!", module.getProject()));
|
||||
String.format("No build system plugin found for project %s!", module.getSupportedProject()));
|
||||
|
||||
BuildSystem buildSystem = buildSystems.getPluginFor(module.getProject(), exception);
|
||||
BuildSystem buildSystem = buildSystems.getPluginFor(module.getSupportedProject(), exception);
|
||||
|
||||
return function.apply(buildSystem.withJavaVersion(executor.detectJavaVersion(module.getProject())), module);
|
||||
return function.apply(buildSystem.withJavaVersion(executor.detectJavaVersion(module.getSupportedProject())),
|
||||
module);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,9 @@ import org.springframework.data.release.deployment.StagingRepository;
|
||||
import org.springframework.data.release.model.JavaVersion;
|
||||
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.SupportedProject;
|
||||
import org.springframework.data.release.model.ProjectAware;
|
||||
import org.springframework.data.release.model.Train;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.plugin.core.Plugin;
|
||||
|
||||
@@ -32,7 +33,7 @@ import org.springframework.plugin.core.Plugin;
|
||||
* @author Mark Paluch
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
interface BuildSystem extends Plugin<Project> {
|
||||
interface BuildSystem extends Plugin<SupportedProject> {
|
||||
|
||||
/**
|
||||
* Updates the project descriptors for the given {@link ModuleIteration} using the given {@link UpdateInformation}.
|
||||
@@ -61,18 +62,24 @@ interface BuildSystem extends Plugin<Project> {
|
||||
|
||||
/**
|
||||
* Open a remote repository for staging artifacts.
|
||||
*
|
||||
* @param train must not be {@literal null}.
|
||||
*/
|
||||
StagingRepository open();
|
||||
StagingRepository open(Train train);
|
||||
|
||||
/**
|
||||
* Close a remote repository for staging artifacts.
|
||||
*
|
||||
* @param train must not be {@literal null}.
|
||||
*/
|
||||
void close(StagingRepository stagingRepository);
|
||||
void close(Train train, StagingRepository stagingRepository);
|
||||
|
||||
/**
|
||||
* Release a remote repository of staged artifacts.
|
||||
*
|
||||
* @param train must not be {@literal null}.
|
||||
*/
|
||||
void release(StagingRepository stagingRepository);
|
||||
void release(Train train, StagingRepository stagingRepository);
|
||||
|
||||
<M extends ProjectAware> M triggerBuild(M module);
|
||||
|
||||
@@ -113,13 +120,17 @@ interface BuildSystem extends Plugin<Project> {
|
||||
|
||||
/**
|
||||
* Verify general functionality and correctness of the build setup.
|
||||
*
|
||||
* @param train must not be {@literal null}.
|
||||
*/
|
||||
void verify();
|
||||
void verify(Train train);
|
||||
|
||||
/**
|
||||
* Verify general functionality and correctness of the build setup.
|
||||
*
|
||||
* @param train must not be {@literal null}.
|
||||
*/
|
||||
void verifyStagingAuthentication();
|
||||
void verifyStagingAuthentication(Train train);
|
||||
|
||||
/**
|
||||
* Prepare the build system with a Java version.
|
||||
|
||||
@@ -47,7 +47,7 @@ public class MavenArtifact {
|
||||
|
||||
Assert.notNull(module, "Module iteration must not be null!");
|
||||
|
||||
this.project = module.getModule().getProject();
|
||||
this.project = module.getProject();
|
||||
this.version = ArtifactVersion.of(module);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,18 +48,11 @@ import org.springframework.data.release.build.Pom.Artifact;
|
||||
import org.springframework.data.release.deployment.DefaultDeploymentInformation;
|
||||
import org.springframework.data.release.deployment.DeploymentInformation;
|
||||
import org.springframework.data.release.deployment.DeploymentProperties;
|
||||
import org.springframework.data.release.deployment.DeploymentProperties.Authentication;
|
||||
import org.springframework.data.release.deployment.DeploymentProperties.MavenCentral;
|
||||
import org.springframework.data.release.deployment.StagingRepository;
|
||||
import org.springframework.data.release.io.Workspace;
|
||||
import org.springframework.data.release.model.ArtifactVersion;
|
||||
import org.springframework.data.release.model.Gpg;
|
||||
import org.springframework.data.release.model.JavaVersion;
|
||||
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.data.release.model.Version;
|
||||
import org.springframework.data.release.model.*;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -107,17 +100,18 @@ class MavenBuildSystem implements BuildSystem {
|
||||
@Override
|
||||
public <M extends ProjectAware> M updateProjectDescriptors(M module, UpdateInformation information) {
|
||||
|
||||
PomUpdater updater = new PomUpdater(logger, information, module.getProject());
|
||||
PomUpdater updater = new PomUpdater(logger, information, module.getSupportedProject());
|
||||
TrainIteration train = information.getTrain();
|
||||
|
||||
if (updater.isBuildProject()) {
|
||||
|
||||
if (information.isBomInBuildProject()) {
|
||||
updateBom(updater, information, "bom/pom.xml", BUILD);
|
||||
updateBom(updater, information, "bom/pom.xml", train.getSupportedProject(BUILD));
|
||||
}
|
||||
|
||||
updateParentPom(updater, information);
|
||||
} else if (updater.isBomProject()) {
|
||||
updateBom(updater, information, "bom/pom.xml", BOM);
|
||||
updateBom(updater, information, "bom/pom.xml", train.getSupportedProject(BOM));
|
||||
} else {
|
||||
|
||||
doWithProjection(workspace.getFile(POM_XML, updater.getProject()), pom -> {
|
||||
@@ -138,12 +132,12 @@ class MavenBuildSystem implements BuildSystem {
|
||||
@Override
|
||||
public ModuleIteration prepareVersion(ModuleIteration module, Phase phase) {
|
||||
|
||||
Project project = module.getProject();
|
||||
SupportedProject project = module.getSupportedProject();
|
||||
UpdateInformation information = UpdateInformation.of(module.getTrainIteration(), phase);
|
||||
|
||||
CommandLine goals = CommandLine.of(goal("versions:set"), goal("versions:commit"));
|
||||
|
||||
if (BOM.equals(project)) {
|
||||
if (BOM.equals(module.getProject())) {
|
||||
|
||||
mvn.execute(project, goals.and(arg("newVersion").withValue(information.getReleaseTrainVersion())) //
|
||||
.and(arg("generateBackupPoms").withValue("false")));
|
||||
@@ -154,11 +148,12 @@ class MavenBuildSystem implements BuildSystem {
|
||||
.and(Argument.of("-pl").withValue("bom")));
|
||||
|
||||
} else {
|
||||
mvn.execute(project, goals.and(arg("newVersion").withValue(information.getProjectVersionToSet(project)))
|
||||
.and(arg("generateBackupPoms").withValue("false")));
|
||||
mvn.execute(project,
|
||||
goals.and(arg("newVersion").withValue(information.getProjectVersionToSet(project.getProject())))
|
||||
.and(arg("generateBackupPoms").withValue("false")));
|
||||
}
|
||||
|
||||
if (BUILD.equals(project)) {
|
||||
if (BUILD.equals(module.getProject())) {
|
||||
|
||||
if (!module.getTrain().usesCalver()) {
|
||||
mvn.execute(project, goals.and(arg("newVersion").withValue(information.getReleaseTrainVersion())) //
|
||||
@@ -179,7 +174,7 @@ class MavenBuildSystem implements BuildSystem {
|
||||
*/
|
||||
public <M extends ProjectAware> M triggerPreReleaseCheck(M module) {
|
||||
|
||||
mvn.execute(module.getProject(), CommandLine.of(Goal.CLEAN, Goal.VALIDATE, profile("pre-release")));
|
||||
mvn.execute(module.getSupportedProject(), CommandLine.of(Goal.CLEAN, Goal.VALIDATE, profile("pre-release")));
|
||||
|
||||
return module;
|
||||
}
|
||||
@@ -188,7 +183,7 @@ class MavenBuildSystem implements BuildSystem {
|
||||
* Perform a {@literal nexus-staging:rc-open} and extract the {@code stagingProfileId} from the results.
|
||||
*/
|
||||
@Override
|
||||
public StagingRepository open() {
|
||||
public StagingRepository open(Train train) {
|
||||
|
||||
Assert.notNull(properties.getMavenCentral(), "Maven Central properties must not be null");
|
||||
Assert.hasText(properties.getMavenCentral().getStagingProfileId(), "Staging Profile Identifier must not be empty");
|
||||
@@ -199,7 +194,7 @@ class MavenBuildSystem implements BuildSystem {
|
||||
arg("openedRepositoryMessageFormat").withValue("'" + REPO_OPENING_TAG + "%s" + REPO_CLOSING_TAG + "'"))
|
||||
.andIf(!ObjectUtils.isEmpty(properties.getSettingsXml()), () -> settingsXml(properties.getSettingsXml()));
|
||||
|
||||
MavenRuntime.MavenInvocationResult invocationResult = mvn.execute(BUILD, arguments);
|
||||
MavenRuntime.MavenInvocationResult invocationResult = mvn.execute(train.getSupportedProject(BUILD), arguments);
|
||||
|
||||
List<String> rcOpenLogContents = invocationResult.getLog();
|
||||
|
||||
@@ -220,7 +215,7 @@ class MavenBuildSystem implements BuildSystem {
|
||||
* Perform a {@literal nexus-staging:rc-close}.
|
||||
*/
|
||||
@Override
|
||||
public void close(StagingRepository stagingRepository) {
|
||||
public void close(Train train, StagingRepository stagingRepository) {
|
||||
|
||||
Assert.notNull(stagingRepository, "StagingRepository must not be null");
|
||||
Assert.isTrue(stagingRepository.isPresent(), "StagingRepository must be present");
|
||||
@@ -230,7 +225,7 @@ class MavenBuildSystem implements BuildSystem {
|
||||
arg("stagingRepositoryId").withValue(stagingRepository.getId()))
|
||||
.andIf(!ObjectUtils.isEmpty(properties.getSettingsXml()), () -> settingsXml(properties.getSettingsXml()));
|
||||
|
||||
mvn.execute(BUILD, arguments);
|
||||
mvn.execute(train.getSupportedProject(BUILD), arguments);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -241,10 +236,10 @@ class MavenBuildSystem implements BuildSystem {
|
||||
public <M extends ProjectAware> M triggerBuild(M module) {
|
||||
|
||||
CommandLine arguments = CommandLine.of(Goal.CLEAN, Goal.INSTALL)//
|
||||
.and(profile("ci,release")).andIf(module.getProject().skipTests(), SKIP_TESTS)
|
||||
.and(profile("ci,release")).andIf(module.getSupportedProject().getProject().skipTests(), SKIP_TESTS)
|
||||
.andIf(!ObjectUtils.isEmpty(properties.getSettingsXml()), settingsXml(properties.getSettingsXml()));
|
||||
|
||||
mvn.execute(module.getProject(), arguments);
|
||||
mvn.execute(module.getSupportedProject(), arguments);
|
||||
|
||||
return module;
|
||||
}
|
||||
@@ -299,24 +294,31 @@ class MavenBuildSystem implements BuildSystem {
|
||||
Assert.notNull(module, "Module iteration must not be null!");
|
||||
Assert.notNull(information, "Deployment information must not be null!");
|
||||
|
||||
if (!module.getIteration().isPreview()) {
|
||||
logger.log(module, "Not a preview version (milestone or release candidate). Skipping Artifactory deployment.");
|
||||
boolean isCommercialRelease = module.isCommercial();
|
||||
|
||||
if (!module.getIteration().isPreview() && !isCommercialRelease) {
|
||||
logger.log(module,
|
||||
"Not a preview version (milestone or release candidate) or commercial release. Skipping Artifactory deployment.");
|
||||
return;
|
||||
}
|
||||
|
||||
logger.log(module, "Deploying artifacts to Spring Artifactory…");
|
||||
logger.log(module,
|
||||
String.format("Deploying artifacts to Spring %sArtifactory…", isCommercialRelease ? "Commercial " : ""));
|
||||
|
||||
Authentication authentication = properties.getAuthentication(module);
|
||||
|
||||
CommandLine arguments = CommandLine.of(Goal.CLEAN, Goal.DEPLOY, //
|
||||
profile("ci,release,artifactory"), //
|
||||
SKIP_TESTS, //
|
||||
arg("artifactory.server").withValue(properties.getServer().getUri()),
|
||||
arg("artifactory.staging-repository").withValue(properties.getStagingRepository()),
|
||||
arg("artifactory.username").withValue(properties.getUsername()),
|
||||
arg("artifactory.password").withValue(properties.getPassword()),
|
||||
arg("artifactory.server").withValue(authentication.getServer().getUri()),
|
||||
arg("artifactory.staging-repository").withValue(authentication.getStagingRepository()),
|
||||
arg("artifactory.username").withValue(authentication.getUsername()),
|
||||
arg("artifactory.password").withValue(authentication.getPassword()),
|
||||
arg("artifactory.build-name").withQuotedValue(information.getBuildName()),
|
||||
arg("artifactory.build-number").withValue(information.getBuildNumber()));
|
||||
arg("artifactory.build-number").withValue(information.getBuildNumber()),
|
||||
arg("artifactory.project").withValue(information.getProject()));
|
||||
|
||||
mvn.execute(module.getProject(), arguments);
|
||||
mvn.execute(module.getSupportedProject(), arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -331,9 +333,8 @@ class MavenBuildSystem implements BuildSystem {
|
||||
Assert.notNull(module, "Module iteration must not be null!");
|
||||
Assert.notNull(deploymentInformation, "DeploymentInformation iteration must not be null!");
|
||||
|
||||
if (!module.getIteration().isPublic()) {
|
||||
|
||||
logger.log(module, "Skipping deployment to Maven Central as it's not a public version!");
|
||||
if (!module.isPublic()) {
|
||||
logger.log(module, "Skipping deployment to Maven Central as it's not a public version or a commercial release!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -352,7 +353,7 @@ class MavenBuildSystem implements BuildSystem {
|
||||
() -> arg("stagingRepositoryId").withValue(deploymentInformation.getStagingRepositoryId()))
|
||||
.andIf(gpg.hasSecretKeyring(), () -> arg("gpg.secretKeyring").withValue(gpg.getSecretKeyring()));
|
||||
|
||||
mvn.execute(module.getProject(), arguments);
|
||||
mvn.execute(module.getSupportedProject(), arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -363,12 +364,13 @@ class MavenBuildSystem implements BuildSystem {
|
||||
|
||||
logger.log(iteration, "🚬 Running smoke test…");
|
||||
|
||||
boolean mavenCentral = iteration.getIteration().isPublic();
|
||||
boolean mavenCentral = iteration.isPublic();
|
||||
String profile = mavenCentral ? "maven-central" : "artifactory";
|
||||
|
||||
ModuleIteration module = iteration.getModule(BUILD);
|
||||
|
||||
doWithProjection(workspace.getFile(POM_XML, SMOKE_TESTS), pom -> {
|
||||
SupportedProject smokeTests = iteration.getSupportedProject(SMOKE_TESTS);
|
||||
doWithProjection(workspace.getFile(POM_XML, smokeTests), pom -> {
|
||||
|
||||
Version version = module.getVersion();
|
||||
String targetBootVersion = version.getMajor() == 2 ? "2.7.8" : "3.0.2";
|
||||
@@ -381,7 +383,7 @@ class MavenBuildSystem implements BuildSystem {
|
||||
arg("spring-data-bom.version").withValue(iteration.getReleaseTrainNameAndVersion())) //
|
||||
.andIf(mavenCentral, arg("stagingRepository").withValue(stagingRepository.getId()));
|
||||
|
||||
mvn.execute(SMOKE_TESTS, arguments);
|
||||
mvn.execute(smokeTests, arguments);
|
||||
|
||||
logger.log(iteration, "✅ Smoke tests passed. Do not smoke 🚭. It's unhealthy.");
|
||||
}
|
||||
@@ -390,7 +392,7 @@ class MavenBuildSystem implements BuildSystem {
|
||||
* Perform a {@literal nexus-staging:rc-release}.
|
||||
*/
|
||||
@Override
|
||||
public void release(StagingRepository stagingRepository) {
|
||||
public void release(Train train, StagingRepository stagingRepository) {
|
||||
|
||||
Assert.notNull(stagingRepository, "StagingRepository must not be null");
|
||||
Assert.isTrue(stagingRepository.isPresent(), "StagingRepository must be present");
|
||||
@@ -400,17 +402,17 @@ class MavenBuildSystem implements BuildSystem {
|
||||
arg("stagingRepositoryId").withValue(stagingRepository.getId()))
|
||||
.andIf(!ObjectUtils.isEmpty(properties.getSettingsXml()), () -> settingsXml(properties.getSettingsXml()));
|
||||
|
||||
mvn.execute(BUILD, arguments);
|
||||
mvn.execute(train.getSupportedProject(BUILD), arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <M extends ProjectAware> M triggerDocumentationBuild(M module) {
|
||||
|
||||
Project project = module.getProject();
|
||||
SupportedProject project = module.getSupportedProject();
|
||||
|
||||
mvn.execute(project, CommandLine.of(Goal.CLEAN, Goal.INSTALL, SKIP_TESTS, profile("distribute")));
|
||||
|
||||
logger.log(project, "Successfully finished documentation build.");
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
@@ -431,33 +433,38 @@ class MavenBuildSystem implements BuildSystem {
|
||||
return module;
|
||||
}
|
||||
|
||||
if (!isMavenProject(project)) {
|
||||
SupportedProject supportedProject = module.getSupportedProject();
|
||||
|
||||
if (!isMavenProject(supportedProject)) {
|
||||
logger.log(project, "Skipping project as no pom.xml could be found in the working directory!");
|
||||
return module;
|
||||
}
|
||||
|
||||
logger.log(project, "Triggering distribution build…");
|
||||
|
||||
mvn.execute(project, CommandLine.of(Goal.CLEAN, Goal.DEPLOY, //
|
||||
SKIP_TESTS, profile("distribute"), Argument.of("-B"),
|
||||
arg("artifactory.server").withValue(properties.getServer().getUri()),
|
||||
arg("artifactory.distribution-repository").withValue(properties.getDistributionRepository()),
|
||||
arg("artifactory.username").withValue(properties.getUsername()),
|
||||
arg("artifactory.password").withValue(properties.getPassword())));
|
||||
Authentication authentication = properties.getAuthentication(module);
|
||||
|
||||
mvn.execute(project, CommandLine.of(Goal.CLEAN, Goal.DEPLOY, //
|
||||
mvn.execute(supportedProject, CommandLine.of(Goal.CLEAN, Goal.DEPLOY, //
|
||||
SKIP_TESTS, profile("distribute"), Argument.of("-B"),
|
||||
arg("artifactory.server").withValue(authentication.getServer().getUri()),
|
||||
arg("artifactory.distribution-repository").withValue(authentication.getDistributionRepository()),
|
||||
arg("artifactory.username").withValue(authentication.getUsername()),
|
||||
arg("artifactory.password").withValue(authentication.getPassword())));
|
||||
|
||||
mvn.execute(supportedProject, CommandLine.of(Goal.CLEAN, Goal.DEPLOY, //
|
||||
SKIP_TESTS, profile("distribute-schema"), Argument.of("-B"),
|
||||
arg("artifactory.server").withValue(properties.getServer().getUri()),
|
||||
arg("artifactory.distribution-repository").withValue(properties.getDistributionRepository()),
|
||||
arg("artifactory.username").withValue(properties.getUsername()),
|
||||
arg("artifactory.password").withValue(properties.getPassword())));
|
||||
arg("artifactory.server").withValue(authentication.getServer().getUri()),
|
||||
arg("artifactory.distribution-repository").withValue(authentication.getDistributionRepository()),
|
||||
arg("artifactory.username").withValue(authentication.getUsername()),
|
||||
arg("artifactory.password").withValue(authentication.getPassword())));
|
||||
|
||||
logger.log(project, "Successfully finished distribution build!");
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
private void updateBom(PomUpdater updater, UpdateInformation updateInformation, String file, Project project) {
|
||||
private void updateBom(PomUpdater updater, UpdateInformation updateInformation, String file,
|
||||
SupportedProject project) {
|
||||
|
||||
TrainIteration iteration = updateInformation.getTrain();
|
||||
|
||||
@@ -506,23 +513,22 @@ class MavenBuildSystem implements BuildSystem {
|
||||
private void updateParentPom(PomUpdater updater, UpdateInformation information) {
|
||||
|
||||
// Fix version of shared resources to to-be-released version.
|
||||
doWithProjection(workspace.getFile("parent/pom.xml", BUILD), ParentPom.class, pom -> {
|
||||
doWithProjection(workspace.getFile("parent/pom.xml", information.getSupportedProject(BUILD)), ParentPom.class,
|
||||
pom -> {
|
||||
|
||||
logger.log(BUILD, "Setting shared resources version to %s.", information.getParentVersionToSet());
|
||||
pom.setSharedResourcesVersion(information.getParentVersionToSet());
|
||||
logger.log(BUILD, "Setting shared resources version to %s.", information.getParentVersionToSet());
|
||||
pom.setSharedResourcesVersion(information.getParentVersionToSet());
|
||||
|
||||
logger.log(BUILD, "Setting releasetrain property to %s.", information.getReleaseTrainVersion());
|
||||
pom.setReleaseTrain(information.getReleaseTrainVersion());
|
||||
logger.log(BUILD, "Setting releasetrain property to %s.", information.getReleaseTrainVersion());
|
||||
pom.setReleaseTrain(information.getReleaseTrainVersion());
|
||||
|
||||
updater.updateRepository(pom);
|
||||
});
|
||||
updater.updateRepository(pom);
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isMavenProject(ModuleIteration module) {
|
||||
|
||||
Project project = module.getProject();
|
||||
|
||||
if (!isMavenProject(project)) {
|
||||
if (!isMavenProject(module.getSupportedProject())) {
|
||||
logger.log(module, "No pom.xml file found, skipping project.");
|
||||
return false;
|
||||
}
|
||||
@@ -535,7 +541,7 @@ class MavenBuildSystem implements BuildSystem {
|
||||
* @see org.springframework.data.release.build.BuildSystem#verify()
|
||||
*/
|
||||
@Override
|
||||
public void verify() {
|
||||
public void verify(Train train) {
|
||||
|
||||
logger.log(BUILD, "Verifying Maven Build System…");
|
||||
|
||||
@@ -549,21 +555,26 @@ class MavenBuildSystem implements BuildSystem {
|
||||
arg("gpg.passphrase").withValue(gpg.getPassphrase())) //
|
||||
.andIf(gpg.hasSecretKeyring(), () -> arg("gpg.secretKeyring").withValue(gpg.getSecretKeyring()));
|
||||
|
||||
mvn.execute(BUILD, arguments);
|
||||
mvn.execute(train.getSupportedProject(BUILD), arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void verifyStagingAuthentication() {
|
||||
public void verifyStagingAuthentication(Train train) {
|
||||
|
||||
logger.log(BUILD, "Verifying Maven Staging Authentication…");
|
||||
if (train.isOpenSource()) {
|
||||
|
||||
mvn.execute(BUILD, CommandLine.of(goal("nexus-staging:rc-list-profiles"), //
|
||||
profile("central")));
|
||||
logger.log(BUILD, "Verifying Maven Staging Authentication…");
|
||||
|
||||
Assert.notNull(properties.getMavenCentral(),
|
||||
"Maven Central properties are not set (deployment.maven-central.staging-profile-id=…)");
|
||||
Assert.hasText(properties.getMavenCentral().getStagingProfileId(),
|
||||
"Staging Profile Id is not set (deployment.maven-central.staging-profile-id=…)");
|
||||
mvn.execute(train.getSupportedProject(BUILD), //
|
||||
CommandLine.of(goal("nexus-staging:rc-list-profiles"), //
|
||||
profile("central")));
|
||||
|
||||
Assert.notNull(properties.getMavenCentral(),
|
||||
"Maven Central properties are not set (deployment.maven-central.staging-profile-id=…)");
|
||||
Assert.hasText(properties.getMavenCentral().getStagingProfileId(),
|
||||
"Staging Profile Id is not set (deployment.maven-central.staging-profile-id=…)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -571,11 +582,11 @@ class MavenBuildSystem implements BuildSystem {
|
||||
* @see org.springframework.plugin.core.Plugin#supports(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean supports(Project project) {
|
||||
public boolean supports(SupportedProject project) {
|
||||
return isMavenProject(project);
|
||||
}
|
||||
|
||||
private boolean isMavenProject(Project project) {
|
||||
private boolean isMavenProject(SupportedProject project) {
|
||||
return workspace.getFile(POM_XML, project).exists();
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.release.io.JavaRuntimes;
|
||||
import org.springframework.data.release.io.Workspace;
|
||||
import org.springframework.data.release.model.JavaVersion;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.Named;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.shell.support.util.StringUtils;
|
||||
@@ -155,8 +156,7 @@ public class MavenRuntime {
|
||||
return matcher.group(1);
|
||||
}
|
||||
|
||||
public MavenInvocationResult execute(Project project, CommandLine arguments) {
|
||||
|
||||
public MavenInvocationResult execute(SupportedProject project, CommandLine arguments) {
|
||||
|
||||
logger.log(project, "📦 Executing mvn %s", arguments.toString());
|
||||
|
||||
@@ -173,7 +173,8 @@ public class MavenRuntime {
|
||||
mavenLogger.info(String.format("Java Home: %s", jdk));
|
||||
mavenLogger.info(String.format("Executing: mvn %s", arguments));
|
||||
|
||||
CommandLine disabledGradleBuildCache = arguments.and(arg("gradle.cache.local.enabled=false")).and(arg("gradle.cache.remote.enabled=false"));
|
||||
CommandLine disabledGradleBuildCache = arguments.and(arg("gradle.cache.local.enabled=false"))
|
||||
.and(arg("gradle.cache.remote.enabled=false"));
|
||||
|
||||
mvn.setGoals(disabledGradleBuildCache.toCommandLine(it -> properties.getFullyQualifiedPlugin(it.getGoal())));
|
||||
});
|
||||
@@ -221,7 +222,7 @@ public class MavenRuntime {
|
||||
return jdk.getHome().getAbsoluteFile();
|
||||
}
|
||||
|
||||
private MavenLogger getLogger(Project project, List<CommandLine.Goal> goals) {
|
||||
private MavenLogger getLogger(Named project, List<CommandLine.Goal> goals) {
|
||||
|
||||
if (this.properties.isConsoleLogger()) {
|
||||
return new SlfLogger(log, project);
|
||||
@@ -258,7 +259,7 @@ public class MavenRuntime {
|
||||
private final String logPrefix;
|
||||
private final List<String> contents;
|
||||
|
||||
SlfLogger(org.slf4j.Logger logger, Project project) {
|
||||
SlfLogger(org.slf4j.Logger logger, Named project) {
|
||||
this.logger = logger;
|
||||
this.logPrefix = StringUtils.padRight(project.getName(), 10);
|
||||
this.contents = new ArrayList<>();
|
||||
@@ -295,7 +296,7 @@ public class MavenRuntime {
|
||||
private final FileOutputStream outputStream;
|
||||
private final List<String> contents = new ArrayList<>();
|
||||
|
||||
FileLogger(org.slf4j.Logger logger, Project project, File logsDirectory, List<CommandLine.Goal> goals) {
|
||||
FileLogger(org.slf4j.Logger logger, Named project, File logsDirectory, List<CommandLine.Goal> goals) {
|
||||
|
||||
if (!logsDirectory.exists()) {
|
||||
logsDirectory.mkdirs();
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.util.List;
|
||||
|
||||
import org.springframework.data.release.build.Pom.RepositoryElementFactory;
|
||||
import org.springframework.data.release.model.ArtifactVersion;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -37,26 +37,26 @@ class PomUpdater {
|
||||
|
||||
private final Logger logger;
|
||||
private final UpdateInformation information;
|
||||
private final @Getter Project project;
|
||||
private final @Getter SupportedProject project;
|
||||
|
||||
public boolean isBuildProject() {
|
||||
return BUILD.equals(project);
|
||||
return BUILD.equals(project.getProject());
|
||||
}
|
||||
|
||||
public boolean isBomProject() {
|
||||
return BOM.equals(project);
|
||||
return BOM.equals(project.getProject());
|
||||
}
|
||||
|
||||
public void updateArtifactVersion(Pom pom) {
|
||||
|
||||
ArtifactVersion version = information.getProjectVersionToSet(project);
|
||||
ArtifactVersion version = information.getProjectVersionToSet(project.getProject());
|
||||
logger.log(project, "Updated project version to %s.", version);
|
||||
pom.setVersion(version);
|
||||
}
|
||||
|
||||
public void updateDependencyProperties(Pom pom) {
|
||||
|
||||
project.getDependencies().forEach(dependency -> {
|
||||
project.getProject().getDependencies().forEach(dependency -> {
|
||||
|
||||
String dependencyProperty = dependency.getDependencyProperty();
|
||||
|
||||
|
||||
@@ -27,9 +27,12 @@ public class Repository {
|
||||
static Repository SNAPSHOT = new Repository("spring-snapshot", "https://repo.spring.io/snapshot", true, false);
|
||||
static Repository MILESTONE = new Repository("spring-milestone", "https://repo.spring.io/milestone", null, null);
|
||||
|
||||
static Repository COMMERCIAL_SNAPSHOT = new Repository("spring-commercial-snapshot",
|
||||
"https://repo.spring.vmware.com/artifactory/spring-commercial-snapshot-local", true, false);
|
||||
static Repository COMMERCIAL_RELEASE = new Repository("spring-commercial-release",
|
||||
"https://repo.spring.vmware.com/artifactory/spring-commercial", false, true);
|
||||
|
||||
String id, url;
|
||||
Boolean snapshots;
|
||||
Boolean releases;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.springframework.data.release.model.ArtifactVersion;
|
||||
import org.springframework.data.release.model.Iteration;
|
||||
import org.springframework.data.release.model.Phase;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -93,16 +94,20 @@ public class UpdateInformation {
|
||||
if (phase == Phase.PREPARE) {
|
||||
|
||||
Iteration iteration = train.getIteration();
|
||||
|
||||
if (iteration.isMilestone() || iteration.isReleaseCandidate()) {
|
||||
return Collections.singletonList(Repository.MILESTONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (phase == Phase.CLEANUP || phase == Phase.MAINTENANCE) {
|
||||
return Arrays.asList(Repository.SNAPSHOT, Repository.MILESTONE);
|
||||
|
||||
return train.isCommercial()
|
||||
? Arrays.asList(Repository.COMMERCIAL_SNAPSHOT, Repository.COMMERCIAL_RELEASE)
|
||||
: Arrays.asList(Repository.SNAPSHOT, Repository.MILESTONE);
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
return train.isCommercial() ? Arrays.asList(Repository.COMMERCIAL_RELEASE) : Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,4 +147,8 @@ public class UpdateInformation {
|
||||
public boolean isBomInBuildProject() {
|
||||
return !train.getTrain().usesCalver();
|
||||
}
|
||||
|
||||
public SupportedProject getSupportedProject(Project project) {
|
||||
return train.getSupportedProject(project);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.release.cli;
|
||||
|
||||
import static org.springframework.data.release.model.Projects.*;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -36,13 +34,10 @@ import org.springframework.data.release.git.GitOperations;
|
||||
import org.springframework.data.release.issues.IssueTrackerCommands;
|
||||
import org.springframework.data.release.issues.github.GitHubCommands;
|
||||
import org.springframework.data.release.misc.ReleaseOperations;
|
||||
import org.springframework.data.release.model.ArtifactVersion;
|
||||
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.Projects;
|
||||
import org.springframework.data.release.model.ReleaseTrains;
|
||||
import org.springframework.data.release.model.Train;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.shell.core.annotation.CliCommand;
|
||||
import org.springframework.shell.core.annotation.CliOption;
|
||||
@@ -64,14 +59,6 @@ class ReleaseCommands extends TimedCommand {
|
||||
@NonNull IssueTrackerCommands tracker;
|
||||
@NonNull GitHubCommands gitHub;
|
||||
|
||||
@CliCommand("release predict")
|
||||
public String predictTrainAndIteration() {
|
||||
|
||||
return git.getTags(COMMONS).getLatest().toArtifactVersion().//
|
||||
map(ReleaseCommands::getTrainNameForCommonsVersion).//
|
||||
orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Composite command to prepare a release.
|
||||
*
|
||||
@@ -140,7 +127,7 @@ class ReleaseCommands extends TimedCommand {
|
||||
@CliCommand(value = "repository open")
|
||||
public void repositoryOpen(@CliOption(key = "", mandatory = true) TrainIteration iteration) {
|
||||
|
||||
if (iteration.getIteration().isPublic()) {
|
||||
if (iteration.isPublic()) {
|
||||
build.open(iteration.getModule(Projects.BUILD));
|
||||
}
|
||||
}
|
||||
@@ -149,7 +136,7 @@ class ReleaseCommands extends TimedCommand {
|
||||
public void repositoryClose(@CliOption(key = "", mandatory = true) TrainIteration iteration,
|
||||
@CliOption(key = "stagingRepositoryId", mandatory = true) String stagingRepositoryId) {
|
||||
|
||||
if (iteration.getIteration().isPublic()) {
|
||||
if (iteration.isPublic()) {
|
||||
build.close(iteration.getModule(Projects.BUILD), StagingRepository.of(stagingRepositoryId));
|
||||
}
|
||||
}
|
||||
@@ -158,7 +145,7 @@ class ReleaseCommands extends TimedCommand {
|
||||
public void repositoryRelease(@CliOption(key = "", mandatory = true) TrainIteration iteration,
|
||||
@CliOption(key = "stagingRepositoryId", mandatory = true) String stagingRepositoryId) {
|
||||
|
||||
if (iteration.getIteration().isPublic()) {
|
||||
if (iteration.isPublic()) {
|
||||
build.release(iteration.getModule(Projects.BUILD), StagingRepository.of(stagingRepositoryId));
|
||||
}
|
||||
}
|
||||
@@ -169,8 +156,8 @@ class ReleaseCommands extends TimedCommand {
|
||||
|
||||
git.checkout(iteration);
|
||||
|
||||
if (!iteration.getIteration().isPublic()) {
|
||||
deployment.verifyAuthentication();
|
||||
if (!iteration.isPublic()) {
|
||||
deployment.verifyAuthentication(iteration);
|
||||
}
|
||||
|
||||
if (projectName != null) {
|
||||
@@ -293,11 +280,4 @@ class ReleaseCommands extends TimedCommand {
|
||||
build.distributeResources(iteration);
|
||||
}
|
||||
}
|
||||
|
||||
private static String getTrainNameForCommonsVersion(ArtifactVersion version) {
|
||||
|
||||
return ReleaseTrains.TRAINS.stream().//
|
||||
filter(train -> version.toString().startsWith(train.getModule(COMMONS).getVersion().toString())).//
|
||||
findFirst().map(Train::getName).orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.springframework.data.release.git.VersionTags;
|
||||
import org.springframework.data.release.model.ArtifactVersion;
|
||||
import org.springframework.data.release.model.DocumentationMetadata;
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.Project;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
@@ -40,8 +39,7 @@ public class StaticResources {
|
||||
|
||||
this.metadata = DocumentationMetadata.of(module, ArtifactVersion.of(module), false);
|
||||
|
||||
Project project = module.getProject();
|
||||
GitProject gitProject = GitProject.of(project);
|
||||
GitProject gitProject = GitProject.of(module);
|
||||
Tag tag = VersionTags.empty(module.getProject()).createTag(module);
|
||||
|
||||
this.releaseUrl = String.format("%s/releases/tag/%s", gitProject.getProjectUri(), tag.getName());
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.springframework.data.release.build.BuildOperations;
|
||||
import org.springframework.data.release.deployment.DeploymentOperations;
|
||||
import org.springframework.data.release.git.GitOperations;
|
||||
import org.springframework.data.release.issues.github.GitHub;
|
||||
import org.springframework.data.release.model.Train;
|
||||
import org.springframework.data.release.projectservice.ProjectService;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
import org.springframework.shell.core.annotation.CliCommand;
|
||||
@@ -50,18 +51,20 @@ class VerifyCommands extends TimedCommand {
|
||||
@NonNull Logger logger;
|
||||
|
||||
@CliCommand("verify")
|
||||
public void verifyReleaseTools(@CliOption(key = "", mandatory = false) String mode) {
|
||||
public void verifyReleaseTools(
|
||||
@CliOption(key = "", mandatory = false) String mode,
|
||||
@CliOption(key = "train", mandatory = true) Train train) {
|
||||
|
||||
if ("local".equals(mode)) {
|
||||
|
||||
// Git checkout build
|
||||
git.verify();
|
||||
git.verify(train);
|
||||
|
||||
// Maven interaction
|
||||
build.verify();
|
||||
build.verify(train);
|
||||
|
||||
// GitHub verification
|
||||
github.verifyAuthentication();
|
||||
github.verifyAuthentication(train);
|
||||
|
||||
// Projects Service Verification
|
||||
projectService.verifyAuthentication();
|
||||
@@ -72,23 +75,23 @@ class VerifyCommands extends TimedCommand {
|
||||
|
||||
if (ObjectUtils.isEmpty(mode) || "git".equals(mode)) {
|
||||
// Git checkout build
|
||||
git.verify();
|
||||
git.verify(train);
|
||||
}
|
||||
|
||||
if (ObjectUtils.isEmpty(mode) || "build".equals(mode)) {
|
||||
// Maven interaction
|
||||
build.verify();
|
||||
build.verifyStagingAuthentication();
|
||||
build.verify(train);
|
||||
build.verifyStagingAuthentication(train);
|
||||
}
|
||||
|
||||
if (ObjectUtils.isEmpty(mode) || "deployment".equals(mode)) {
|
||||
// Artifactory verification
|
||||
deployment.verifyAuthentication();
|
||||
deployment.verifyAuthentication(train);
|
||||
}
|
||||
|
||||
if (ObjectUtils.isEmpty(mode) || "github".equals(mode)) {
|
||||
// GitHub verification
|
||||
github.verifyAuthentication();
|
||||
github.verifyAuthentication(train);
|
||||
}
|
||||
|
||||
if (ObjectUtils.isEmpty(mode) || "projects".equals(mode)) {
|
||||
@@ -98,5 +101,4 @@ class VerifyCommands extends TimedCommand {
|
||||
|
||||
logger.log("Verify", "All settings are verified. You can ship a release now.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,9 @@ import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.data.release.deployment.DeploymentProperties.Authentication;
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.SupportStatusAware;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
@@ -39,9 +41,9 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@RequiredArgsConstructor
|
||||
class ArtifactoryClient {
|
||||
|
||||
private final RestOperations template;
|
||||
private final Logger logger;
|
||||
private final DeploymentProperties properties;
|
||||
private final RestOperations operations;
|
||||
|
||||
/**
|
||||
* Triggers the promotion of the artifacts identified by the given {@link DeploymentInformation}.
|
||||
@@ -53,28 +55,35 @@ class ArtifactoryClient {
|
||||
Assert.notNull(information, "DeploymentInformation must not be null!");
|
||||
|
||||
ModuleIteration module = information.getModule();
|
||||
URI uri = properties.getServer().getPromotionResource(information);
|
||||
URI uri = information.getPromotionResource();
|
||||
|
||||
Authentication authentication = properties.getAuthentication(module);
|
||||
|
||||
logger.log(module, "Promoting %s %s from %s to %s.", information.getBuildName(), information.getBuildNumber(),
|
||||
properties.getStagingRepository(), information.getTargetRepository());
|
||||
authentication.getStagingRepository(), authentication.getTargetRepository());
|
||||
|
||||
try {
|
||||
template.postForEntity(uri,
|
||||
new PromotionRequest(information.getTargetRepository(), properties.getStagingRepository()), String.class);
|
||||
PromotionRequest request = new PromotionRequest(information.getTargetRepository(),
|
||||
authentication.getStagingRepository());
|
||||
operations.postForEntity(uri, request, String.class);
|
||||
|
||||
} catch (HttpClientErrorException o_O) {
|
||||
handle(message -> logger.warn(information.getModule(), message), "Promotion failed!", o_O);
|
||||
}
|
||||
}
|
||||
|
||||
public void verify() {
|
||||
public void verify(SupportStatusAware status) {
|
||||
|
||||
URI verificationResource = properties.getServer().getVerificationResource();
|
||||
URI verificationResource = properties
|
||||
.getAuthentication(status)
|
||||
.getServer()
|
||||
.getVerificationResource();
|
||||
|
||||
try {
|
||||
|
||||
logger.log("Artifactory", "Verifying authentication using a GET call to %s.", verificationResource);
|
||||
|
||||
template.getForEntity(verificationResource, String.class);
|
||||
operations.getForEntity(verificationResource, String.class);
|
||||
|
||||
logger.log("Artifactory", "Authentication verified!");
|
||||
|
||||
@@ -101,7 +110,8 @@ class ArtifactoryClient {
|
||||
}
|
||||
|
||||
public void deleteArtifacts(DeploymentInformation information) {
|
||||
template.delete(properties.getServer().getDeleteBuildResource(information));
|
||||
|
||||
operations.delete(information.getDeleteBuildResource());
|
||||
}
|
||||
|
||||
@Value
|
||||
|
||||
@@ -18,8 +18,11 @@ package org.springframework.data.release.deployment;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.data.release.CliComponent;
|
||||
import org.springframework.data.release.TimedCommand;
|
||||
import org.springframework.data.release.model.SupportStatus;
|
||||
import org.springframework.shell.core.annotation.CliCommand;
|
||||
|
||||
/**
|
||||
@@ -35,6 +38,8 @@ class ArtifactoryCommands extends TimedCommand {
|
||||
|
||||
@CliCommand(value = "artifactory verify", help = "Verifies authentication at Artifactory.")
|
||||
public void verify() {
|
||||
deployment.verifyAuthentication();
|
||||
|
||||
Stream.of(SupportStatus.OSS, SupportStatus.COMMERCIAL)
|
||||
.forEach(deployment::verifyAuthentication);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,11 +20,13 @@ import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.data.release.deployment.DeploymentProperties.Authentication;
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.web.util.UriTemplate;
|
||||
|
||||
@@ -44,6 +46,8 @@ public class DefaultDeploymentInformation implements DeploymentInformation {
|
||||
private final @Getter String buildNumber;
|
||||
private final @Getter StagingRepository stagingRepositoryId;
|
||||
|
||||
private final Authentication authentication;
|
||||
|
||||
public DefaultDeploymentInformation(ModuleIteration module, DeploymentProperties properties) {
|
||||
this(module, properties, StagingRepository.EMPTY);
|
||||
}
|
||||
@@ -51,17 +55,18 @@ public class DefaultDeploymentInformation implements DeploymentInformation {
|
||||
public DefaultDeploymentInformation(ModuleIteration module, DeploymentProperties properties,
|
||||
String stagingRepositoryId) {
|
||||
this(module, properties, String.valueOf(LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)),
|
||||
StagingRepository.of(stagingRepositoryId));
|
||||
StagingRepository.of(stagingRepositoryId), properties.getAuthentication(module));
|
||||
}
|
||||
|
||||
public DefaultDeploymentInformation(ModuleIteration module, DeploymentProperties properties,
|
||||
StagingRepository stagingRepository) {
|
||||
this(module, properties, String.valueOf(LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)), stagingRepository);
|
||||
this(module, properties, String.valueOf(LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)), stagingRepository,
|
||||
properties.getAuthentication(module));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeploymentInformation withModule(ModuleIteration module) {
|
||||
return new DefaultDeploymentInformation(module, properties, buildNumber, stagingRepositoryId);
|
||||
return new DefaultDeploymentInformation(module, properties, buildNumber, stagingRepositoryId, authentication);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -73,14 +78,22 @@ public class DefaultDeploymentInformation implements DeploymentInformation {
|
||||
return module.getProject().getFullName().concat(" - Release");
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.release.deployment.DeploymentInformation#getProject()
|
||||
*/
|
||||
@Override
|
||||
public String getProject() {
|
||||
return authentication.getProject();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.release.deployment.DeploymentInformation#getTargetRepository()
|
||||
*/
|
||||
@Override
|
||||
public String getTargetRepository() {
|
||||
return properties.getRepositoryPrefix()
|
||||
.concat(module.getIteration().isPublic() ? "libs-release-local" : "libs-milestone-local");
|
||||
return authentication.getRepositoryPrefix().concat(authentication.getTargetRepository());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -91,7 +104,7 @@ public class DefaultDeploymentInformation implements DeploymentInformation {
|
||||
public String getDeploymentTargetUrl() {
|
||||
|
||||
Map<String, Object> parameters = new HashMap<>();
|
||||
parameters.put("server", properties.getStagingRepositoryUrl());
|
||||
parameters.put("server", authentication.getTargetRepository());
|
||||
parameters.putAll(getBuildInfoParameters());
|
||||
|
||||
return REPOSITORY_TEMPLATE.expand(parameters).toString();
|
||||
@@ -110,4 +123,33 @@ public class DefaultDeploymentInformation implements DeploymentInformation {
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.release.deployment.DeploymentInformation#getPromotionResource()
|
||||
*/
|
||||
@Override
|
||||
public URI getPromotionResource() {
|
||||
return authentication.getServer().getPromotionResource(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.release.deployment.DeploymentInformation#getDeleteBuildResource()
|
||||
*/
|
||||
@Override
|
||||
public URI getDeleteBuildResource() {
|
||||
return authentication.getServer().getDeleteBuildResource(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.release.deployment.DeploymentInformation#isMavenCentral()
|
||||
*/
|
||||
@Override
|
||||
public boolean isMavenCentral() {
|
||||
|
||||
return !module.isCommercial()
|
||||
&& module.getIteration().isPublic();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,11 +18,12 @@ package org.springframework.data.release.deployment;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.release.deployment.DeploymentProperties.Authentication;
|
||||
import org.springframework.data.release.model.Password;
|
||||
import org.springframework.data.release.utils.HttpBasicCredentials;
|
||||
import org.springframework.data.release.utils.HttpComponentsClientHttpRequestFactoryBuilder;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
import org.springframework.web.client.RestOperations;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
@@ -36,23 +37,30 @@ class DeploymentConfiguration {
|
||||
@Autowired DeploymentProperties properties;
|
||||
|
||||
@Bean
|
||||
public ArtifactoryClient client(Logger logger, RestTemplate artifactoryRestTemplate) {
|
||||
return new ArtifactoryClient(artifactoryRestTemplate, logger, properties);
|
||||
ArtifactoryClient client(Logger logger, RestOperations operations) {
|
||||
return new ArtifactoryClient(logger, properties, operations);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RestTemplate artifactoryRestTemplate() {
|
||||
RestTemplate artifactoryRestTemplateFactory(DeploymentProperties properties, Logger logger) {
|
||||
|
||||
RestTemplate template = new RestTemplate();
|
||||
HttpComponentsClientHttpRequestFactoryBuilder builder = HttpComponentsClientHttpRequestFactoryBuilder.builder();
|
||||
|
||||
HttpComponentsClientHttpRequestFactory factory = HttpComponentsClientHttpRequestFactoryBuilder.builder()
|
||||
.withAuthentication(properties.getServer().getUri(),
|
||||
new HttpBasicCredentials(properties.getUsername(), Password.of(properties.getApiKey())))
|
||||
.build();
|
||||
for (Authentication authentication : properties.getAuthentications()) {
|
||||
|
||||
template.setRequestFactory(factory);
|
||||
String uri = authentication.getServer().getUri();
|
||||
|
||||
return template;
|
||||
if (authentication.hasCredentials()) {
|
||||
|
||||
HttpBasicCredentials credentials = new HttpBasicCredentials(authentication.getUsername(),
|
||||
Password.of(authentication.getApiKey()));
|
||||
builder = builder.withAuthentication(uri, credentials);
|
||||
|
||||
} else {
|
||||
logger.warn("Infrastructure", "No credentials configured for repository %s!", uri);
|
||||
}
|
||||
}
|
||||
|
||||
return new RestTemplate(builder.build());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.release.deployment;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
@@ -39,6 +40,14 @@ public interface DeploymentInformation {
|
||||
*/
|
||||
String getBuildNumber();
|
||||
|
||||
/**
|
||||
* A project assignment on the server. JFrog uses this to group different builds into build info repositories in
|
||||
* Artifactory.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getProject();
|
||||
|
||||
/**
|
||||
* Returns the full URL to be used as deployment target.
|
||||
*
|
||||
@@ -53,6 +62,10 @@ public interface DeploymentInformation {
|
||||
*/
|
||||
String getTargetRepository();
|
||||
|
||||
URI getPromotionResource();
|
||||
|
||||
URI getDeleteBuildResource();
|
||||
|
||||
/**
|
||||
* Staging repository identifier.
|
||||
*
|
||||
@@ -75,4 +88,6 @@ public interface DeploymentInformation {
|
||||
Map<String, Object> getBuildInfoParameters();
|
||||
|
||||
DeploymentInformation withModule(ModuleIteration module);
|
||||
|
||||
boolean isMavenCentral();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springframework.data.release.deployment;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.data.release.model.SupportStatusAware;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -34,8 +35,8 @@ public class DeploymentOperations {
|
||||
private final ArtifactoryClient client;
|
||||
private final Logger logger;
|
||||
|
||||
public void verifyAuthentication() {
|
||||
client.verify();
|
||||
public void verifyAuthentication(SupportStatusAware status) {
|
||||
client.verify(status);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,7 +48,7 @@ public class DeploymentOperations {
|
||||
|
||||
Assert.notNull(information, "DeploymentInformation must not be null!");
|
||||
|
||||
if (information.getModule().getIteration().isPublic()) {
|
||||
if (information.isMavenCentral()) {
|
||||
logger.log(information.getModule(),
|
||||
"Skipping build promotion as it's a public version and was staged to OSS Sonatype.");
|
||||
return;
|
||||
|
||||
@@ -15,18 +15,20 @@
|
||||
*/
|
||||
package org.springframework.data.release.deployment;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.data.release.model.Gpg;
|
||||
import org.springframework.data.release.model.Password;
|
||||
import org.springframework.data.release.utils.HttpBasicCredentials;
|
||||
import org.springframework.data.release.model.SupportStatusAware;
|
||||
import org.springframework.data.util.Streamable;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.util.UriTemplate;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
@@ -36,54 +38,16 @@ import lombok.Data;
|
||||
@ConfigurationProperties(prefix = "deployment")
|
||||
public class DeploymentProperties {
|
||||
|
||||
/**
|
||||
* The Artifactory host.
|
||||
*/
|
||||
private Server server;
|
||||
|
||||
/**
|
||||
* The deployer's username.
|
||||
*/
|
||||
private String username;
|
||||
|
||||
private String apiKey;
|
||||
|
||||
/**
|
||||
* The deployer's password.
|
||||
*/
|
||||
private Password password;
|
||||
|
||||
/**
|
||||
* The repository to deploy the artifacts to.
|
||||
*/
|
||||
private String stagingRepository;
|
||||
|
||||
/**
|
||||
* The repository to deploy docs/schemas to.
|
||||
*/
|
||||
private String distributionRepository;
|
||||
|
||||
private String settingsXml;
|
||||
|
||||
private String repositoryPrefix = "";
|
||||
|
||||
private MavenCentral mavenCentral;
|
||||
private Authentication opensource, commercial;
|
||||
|
||||
public String getStagingRepository() {
|
||||
return repositoryPrefix.concat(stagingRepository);
|
||||
public Authentication getAuthentication(SupportStatusAware status) {
|
||||
return status.isOpenSource() ? opensource : commercial;
|
||||
}
|
||||
|
||||
public String getDistributionRepository() {
|
||||
return repositoryPrefix.concat(distributionRepository);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URI of the staging repository.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getStagingRepositoryUrl() {
|
||||
return server.getUri().concat("/").concat(stagingRepository);
|
||||
public Streamable<Authentication> getAuthentications() {
|
||||
return Streamable.of(opensource, commercial);
|
||||
}
|
||||
|
||||
@Data
|
||||
@@ -91,9 +55,10 @@ public class DeploymentProperties {
|
||||
|
||||
private static final String PROMOTION_RESOURCE = "/api/build/promote/{buildName}/{buildNumber}";
|
||||
private static final String DELETE_BUILD_RESOURCE = "/api/build/{buildName}?buildNumbers={buildNumber}&artifacts=1";
|
||||
private static final String VERIFICATION_RESOURCE = "/api/storage/temp-private-local";
|
||||
private static final String VERIFICATION_RESOURCE = "/api/storage/{verificationResource}";
|
||||
|
||||
private String uri;
|
||||
private String verificationResource;
|
||||
|
||||
/**
|
||||
* Returns the URI to the resource that a promotion can be triggered at.
|
||||
@@ -114,7 +79,7 @@ public class DeploymentProperties {
|
||||
}
|
||||
|
||||
public URI getVerificationResource() {
|
||||
return URI.create(uri.concat(VERIFICATION_RESOURCE));
|
||||
return new UriTemplate(uri.concat(VERIFICATION_RESOURCE)).expand(verificationResource);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,4 +95,37 @@ public class DeploymentProperties {
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class Authentication {
|
||||
|
||||
Server server;
|
||||
String stagingRepository, targetRepository;
|
||||
String distributionRepository;
|
||||
String project;
|
||||
String username;
|
||||
Password password;
|
||||
String apiKey;
|
||||
String repositoryPrefix = "";
|
||||
|
||||
public boolean hasCredentials() {
|
||||
return StringUtils.hasText(username) && password != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URI of the staging repository.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getStagingRepositoryUrl() {
|
||||
return server.getUri().concat("/").concat(stagingRepository);
|
||||
}
|
||||
|
||||
public String getStagingRepository() {
|
||||
return repositoryPrefix.concat(stagingRepository);
|
||||
}
|
||||
|
||||
public String getDistributionRepository() {
|
||||
return repositoryPrefix.concat(distributionRepository);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ public class DocumentationCommands extends TimedCommand {
|
||||
if (preview) {
|
||||
buildOperations.buildDocumentation(module);
|
||||
|
||||
File projectDirectory = workspace.getProjectDirectory(module.getProject());
|
||||
File projectDirectory = workspace.getProjectDirectory(module.getSupportedProject());
|
||||
|
||||
if (!projectDirectory.exists()) {
|
||||
logger.warn(module, "Unable to locate project directory");
|
||||
@@ -171,9 +171,9 @@ public class DocumentationCommands extends TimedCommand {
|
||||
HttpStatus status = checkedLink.getResult();
|
||||
if (status.is2xxSuccessful()) {
|
||||
ansi.fg(Color.GREEN);
|
||||
} else if (status.is4xxClientError())
|
||||
} else if (status.is4xxClientError()) {
|
||||
ansi.fg(Color.RED);
|
||||
else if (status.is3xxRedirection()) {
|
||||
} else if (status.is3xxRedirection()) {
|
||||
ansi.fg(Color.YELLOW);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,8 @@ class BackportTargets implements Iterable<Branch> {
|
||||
|
||||
this.source = Branch.from(module);
|
||||
|
||||
Stream<Branch> branches = targets.stream().map(target -> target.getModuleIfAvailable(module.getProject()))//
|
||||
Stream<Branch> branches = targets.stream() //
|
||||
.map(target -> target.getModuleIfAvailable(module.getSupportedProject().getProject()))//
|
||||
.flatMap(o -> o.map(Stream::of).orElse(Stream.empty()))//
|
||||
.map(Branch::from);
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.Projects;
|
||||
import org.springframework.data.release.model.ReleaseTrains;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.model.Train;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.data.release.utils.ExecutionUtils;
|
||||
@@ -54,7 +55,7 @@ import org.springframework.util.StringUtils;
|
||||
@RequiredArgsConstructor
|
||||
class GitCommands extends TimedCommand {
|
||||
|
||||
private final PluginRegistry<IssueTracker, Project> trackers;
|
||||
private final PluginRegistry<IssueTracker, SupportedProject> trackers;
|
||||
private final @NonNull GitOperations git;
|
||||
private final @NonNull Executor executor;
|
||||
|
||||
@@ -75,11 +76,13 @@ class GitCommands extends TimedCommand {
|
||||
}
|
||||
|
||||
@CliCommand("git tags")
|
||||
public String tags(@CliOption(key = { "project" }, mandatory = true) String projectName) throws Exception {
|
||||
public String tags(
|
||||
@CliOption(key = { "project" }, mandatory = true) String projectName,
|
||||
@CliOption(key = { "", "train" }, mandatory = true) Train train) throws Exception {
|
||||
|
||||
Project project = ReleaseTrains.getProjectByName(projectName);
|
||||
|
||||
return StringUtils.collectionToDelimitedString(git.getTags(project).asList(), "\n");
|
||||
return StringUtils.collectionToDelimitedString(git.getTags(train.getSupportedProject(project)).asList(), "\n");
|
||||
}
|
||||
|
||||
@CliCommand("git previous")
|
||||
@@ -96,7 +99,7 @@ class GitCommands extends TimedCommand {
|
||||
if (StringUtils.hasText(moduleName)) {
|
||||
|
||||
ModuleIteration module = iteration.getModule(Projects.requiredByName(moduleName));
|
||||
List<TicketReference> ticketRefs = git.getTicketReferencesBetween(module.getProject(), previousIteration,
|
||||
List<TicketReference> ticketRefs = git.getTicketReferencesBetween(module.getSupportedProject(), previousIteration,
|
||||
iteration);
|
||||
|
||||
Changelog changelog = Changelog.of(module, toTickets(module, ticketRefs));
|
||||
@@ -105,15 +108,16 @@ class GitCommands extends TimedCommand {
|
||||
}
|
||||
|
||||
return ExecutionUtils
|
||||
.runAndReturn(executor, iteration, module -> changelog(iteration, module.getModule().getProject().getName())) //
|
||||
.runAndReturn(executor, iteration,
|
||||
module -> changelog(iteration, module.getModule().getProject().getName())) //
|
||||
.stream() //
|
||||
.collect(Collectors.joining("\n"));
|
||||
}
|
||||
|
||||
private Tickets toTickets(ModuleIteration module, List<TicketReference> ticketReferences) {
|
||||
|
||||
IssueTracker issueTracker = trackers.getRequiredPluginFor(module.getProject(),
|
||||
() -> String.format("No issue tracker found for project %s!", module.getProject()));
|
||||
IssueTracker issueTracker = trackers.getRequiredPluginFor(module.getSupportedProject(),
|
||||
() -> String.format("No issue tracker found for project %s!", module.getSupportedProject()));
|
||||
|
||||
List<String> ticketIds = ticketReferences.stream().map(TicketReference::getId).collect(Collectors.toList());
|
||||
|
||||
@@ -174,12 +178,14 @@ class GitCommands extends TimedCommand {
|
||||
* @throws Exception
|
||||
*/
|
||||
@CliCommand("git issuebranches")
|
||||
public Table issuebranches(@CliOption(key = { "" }, mandatory = true) String projectName,
|
||||
public Table issuebranches(
|
||||
@CliOption(key = "", mandatory = true) String projectName,
|
||||
@CliOption(key = "train", mandatory = true) Train train,
|
||||
@CliOption(key = "resolved", unspecifiedDefaultValue = "false", specifiedDefaultValue = "true") Boolean resolved)
|
||||
throws Exception {
|
||||
|
||||
Project project = ReleaseTrains.getProjectByName(projectName);
|
||||
TicketBranches ticketBranches = git.listTicketBranches(project);
|
||||
TicketBranches ticketBranches = git.listTicketBranches(train.getSupportedProject(project));
|
||||
|
||||
Table table = new Table();
|
||||
table.addHeader(1, new TableHeader("Branch"));
|
||||
|
||||
@@ -38,8 +38,10 @@ import org.eclipse.jgit.api.CheckoutCommand;
|
||||
import org.eclipse.jgit.api.CommitCommand;
|
||||
import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.GitCommand;
|
||||
import org.eclipse.jgit.api.LogCommand;
|
||||
import org.eclipse.jgit.api.ResetCommand.ResetType;
|
||||
import org.eclipse.jgit.api.TransportCommand;
|
||||
import org.eclipse.jgit.api.errors.EmptyCommitException;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.api.errors.RefNotFoundException;
|
||||
@@ -65,6 +67,7 @@ import org.springframework.data.release.issues.Ticket;
|
||||
import org.springframework.data.release.issues.TicketReference;
|
||||
import org.springframework.data.release.issues.TicketStatus;
|
||||
import org.springframework.data.release.model.*;
|
||||
import org.springframework.data.release.model.Module;
|
||||
import org.springframework.data.release.utils.ExecutionUtils;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
import org.springframework.data.util.Pair;
|
||||
@@ -92,20 +95,10 @@ public class GitOperations {
|
||||
Executor executor;
|
||||
Workspace workspace;
|
||||
Logger logger;
|
||||
PluginRegistry<IssueTracker, Project> issueTracker;
|
||||
PluginRegistry<IssueTracker, SupportedProject> issueTracker;
|
||||
GitProperties gitProperties;
|
||||
Gpg gpg;
|
||||
|
||||
/**
|
||||
* Returns the {@link GitProject} for the given {@link Project}.
|
||||
*
|
||||
* @param project
|
||||
* @return
|
||||
*/
|
||||
public GitProject getGitProject(Project project) {
|
||||
return new GitProject(project, server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the repositories for all modules of the given {@link Train}.
|
||||
*
|
||||
@@ -116,7 +109,7 @@ public class GitOperations {
|
||||
Assert.notNull(train, "Train must not be null!");
|
||||
|
||||
ExecutionUtils.run(executor, train, module -> {
|
||||
reset(module.getProject(), Branch.from(module));
|
||||
reset(module.getSupportedProject(), Branch.from(module));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -149,9 +142,9 @@ public class GitOperations {
|
||||
update(train);
|
||||
}
|
||||
|
||||
ExecutionUtils.run(executor, train, module -> {
|
||||
ExecutionUtils.run(executor, train.getModules(), module -> {
|
||||
|
||||
Project project = module.getProject();
|
||||
SupportedProject project = train.getSupportedProject(module);
|
||||
|
||||
doWithGit(project, git -> {
|
||||
|
||||
@@ -168,9 +161,9 @@ public class GitOperations {
|
||||
|
||||
}
|
||||
|
||||
private Branch getBranch(Train train, Module module, Project project) {
|
||||
private Branch getBranch(Train train, Module module, SupportedProject project) {
|
||||
|
||||
ModuleIteration gaIteration = train.getModuleIteration(project, Iteration.GA);
|
||||
ModuleIteration gaIteration = train.getModuleIteration(project.getProject(), Iteration.GA);
|
||||
Optional<Tag> gaTag = findTagFor(project, ArtifactVersion.of(gaIteration));
|
||||
|
||||
if (!gaTag.isPresent()) {
|
||||
@@ -180,7 +173,7 @@ public class GitOperations {
|
||||
return gaTag.isPresent() ? Branch.from(module) : Branch.MAIN;
|
||||
}
|
||||
|
||||
private void checkoutBranch(Project project, Git git, Branch branch) throws GitAPIException {
|
||||
private void checkoutBranch(SupportedProject project, Git git, Branch branch) throws GitAPIException {
|
||||
|
||||
CheckoutCommand command = git.checkout().setName(branch.toString()).setForced(true);
|
||||
|
||||
@@ -208,8 +201,9 @@ public class GitOperations {
|
||||
|
||||
ExecutionUtils.run(executor, iteration, module -> {
|
||||
|
||||
Project project = module.getProject();
|
||||
SupportedProject project = module.getSupportedProject();
|
||||
ArtifactVersion artifactVersion = ArtifactVersion.of(module);
|
||||
|
||||
Tag tag = findTagFor(project, artifactVersion).orElseThrow(() -> new IllegalStateException(
|
||||
String.format("No tag found for version %s of project %s, aborting.", artifactVersion, project)));
|
||||
|
||||
@@ -227,7 +221,7 @@ public class GitOperations {
|
||||
|
||||
ExecutionUtils.run(executor, iteration, module -> {
|
||||
|
||||
Project project = module.getProject();
|
||||
SupportedProject project = module.getSupportedProject();
|
||||
Branch branch = Branch.from(module);
|
||||
|
||||
update(project);
|
||||
@@ -238,9 +232,8 @@ public class GitOperations {
|
||||
doWithGit(project, git -> {
|
||||
|
||||
logger.log(project, "git pull origin %s", branch);
|
||||
git.pull()//
|
||||
.setRebase(true)//
|
||||
.call();
|
||||
|
||||
call(git.pull().setRebase(true));
|
||||
});
|
||||
|
||||
logger.log(project, "Pulling updates done!", branch);
|
||||
@@ -250,7 +243,7 @@ public class GitOperations {
|
||||
}
|
||||
|
||||
public void update(Train train) {
|
||||
ExecutionUtils.run(executor, train, module -> update(module.getProject()));
|
||||
ExecutionUtils.run(executor, train, this::update);
|
||||
}
|
||||
|
||||
public void push(TrainIteration iteration) {
|
||||
@@ -262,21 +255,21 @@ public class GitOperations {
|
||||
Branch branch = Branch.from(module);
|
||||
logger.log(module, "git push origin %s", branch);
|
||||
|
||||
if (!branchExists(module.getProject(), branch)) {
|
||||
SupportedProject project = module.getSupportedProject();
|
||||
|
||||
logger.log(module, "No branch %s in %s, skip push", branch, module.getProject().getName());
|
||||
if (!branchExists(project, branch)) {
|
||||
|
||||
logger.log(module, "No branch %s in %s, skip push", branch, project.getName());
|
||||
return;
|
||||
}
|
||||
|
||||
doWithGit(module.getProject(), git -> {
|
||||
doWithGit(project, git -> {
|
||||
|
||||
Ref ref = git.getRepository().findRef(branch.toString());
|
||||
|
||||
git.push()//
|
||||
.setRemote("origin")//
|
||||
.setRefSpecs(new RefSpec(ref.getName()))//
|
||||
.setCredentialsProvider(gitProperties.getCredentials())//
|
||||
.call();
|
||||
call(git.push() //
|
||||
.setRemote("origin") //
|
||||
.setRefSpecs(new RefSpec(ref.getName())));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -284,15 +277,15 @@ public class GitOperations {
|
||||
|
||||
ExecutionUtils.run(executor, train.getModules(), module -> {
|
||||
|
||||
logger.log(module.getProject(), "git push --tags origin");
|
||||
SupportedProject project = train.getSupportedProject(module);
|
||||
|
||||
doWithGit(module.getProject(), git -> {
|
||||
logger.log(project, "git push --tags origin");
|
||||
|
||||
git.push()//
|
||||
.setRemote("origin")//
|
||||
.setPushTags()//
|
||||
.setCredentialsProvider(gitProperties.getCredentials())//
|
||||
.call();
|
||||
doWithGit(project, git -> {
|
||||
|
||||
call(git.push() //
|
||||
.setRemote("origin") //
|
||||
.setPushTags());
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -303,16 +296,16 @@ public class GitOperations {
|
||||
*
|
||||
* @param project must not be {@literal null}.
|
||||
*/
|
||||
public void update(Project project) {
|
||||
public void update(SupportedProject project) {
|
||||
|
||||
Assert.notNull(project, "Project must not be null!");
|
||||
|
||||
logger.log(project, "Updating project…");
|
||||
|
||||
GitProject gitProject = new GitProject(project, server);
|
||||
GitProject gitProject = getGitProject(project);
|
||||
String repositoryName = gitProject.getRepositoryName();
|
||||
|
||||
doWithGit(project, git -> {
|
||||
doWithGit(gitProject.getProject(), git -> {
|
||||
|
||||
if (workspace.hasProjectDirectory(project)) {
|
||||
|
||||
@@ -321,10 +314,12 @@ public class GitOperations {
|
||||
checkout(project, Branch.MAIN);
|
||||
|
||||
logger.log(project, "git fetch --tags");
|
||||
git.fetch().setTagOpt(TagOpt.FETCH_TAGS).call();
|
||||
|
||||
call(git.fetch() //
|
||||
.setTagOpt(TagOpt.FETCH_TAGS));
|
||||
|
||||
} else {
|
||||
clone(project);
|
||||
clone(gitProject);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -336,35 +331,44 @@ public class GitOperations {
|
||||
*
|
||||
* @param project must not be {@literal null}.
|
||||
*/
|
||||
public void fetchTags(Project project) {
|
||||
public void fetchTags(Project project, Train train) {
|
||||
|
||||
Assert.notNull(project, "Project must not be null!");
|
||||
|
||||
logger.log(project, "Updating project tags…");
|
||||
|
||||
GitProject gitProject = new GitProject(project, server);
|
||||
GitProject gitProject = getGitProject(train.getSupportedProject(project));
|
||||
String repositoryName = gitProject.getRepositoryName();
|
||||
|
||||
doWithGit(project, git -> {
|
||||
doWithGit(gitProject.getProject(), git -> {
|
||||
|
||||
if (workspace.hasProjectDirectory(project)) {
|
||||
if (workspace.hasProjectDirectory(train.getSupportedProject(project))) {
|
||||
|
||||
logger.log(project, "Found existing repository %s. Obtaining tags…", repositoryName);
|
||||
logger.log(project, "git fetch --tags");
|
||||
git.fetch().setTagOpt(TagOpt.FETCH_TAGS).call();
|
||||
|
||||
call(git.fetch() //
|
||||
.setTagOpt(TagOpt.FETCH_TAGS));
|
||||
|
||||
} else {
|
||||
clone(project);
|
||||
clone(gitProject);
|
||||
}
|
||||
});
|
||||
|
||||
logger.log(project, "Project tags update done!");
|
||||
}
|
||||
|
||||
public VersionTags getTags(Project project) {
|
||||
private GitProject getGitProject(SupportedProject project) {
|
||||
return new GitProject(project, server);
|
||||
}
|
||||
|
||||
public VersionTags getTags(SupportedProject project) {
|
||||
|
||||
return doWithGit(project, git -> {
|
||||
return new VersionTags(project, git.tagList().call().stream()//
|
||||
|
||||
git.tagList().call();
|
||||
|
||||
return new VersionTags(project.getProject(), git.tagList().call().stream()//
|
||||
.map(ref -> {
|
||||
|
||||
RevCommit commit = getCommit(git.getRepository(), ref);
|
||||
@@ -403,7 +407,7 @@ public class GitOperations {
|
||||
* @param project must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public TicketBranches listTicketBranches(Project project) {
|
||||
public TicketBranches listTicketBranches(SupportedProject project) {
|
||||
|
||||
Assert.notNull(project, "Project must not be null!");
|
||||
|
||||
@@ -415,7 +419,7 @@ public class GitOperations {
|
||||
update(project);
|
||||
|
||||
Map<String, Branch> ticketIds = getRemoteBranches(project)//
|
||||
.filter(branch -> branch.isIssueBranch(project.getTracker()))//
|
||||
.filter(branch -> branch.isIssueBranch(project.getProject().getTracker()))//
|
||||
.collect(Collectors.toMap(Branch::toString, branch -> branch));
|
||||
|
||||
Collection<Ticket> tickets = tracker.findTickets(project, ticketIds.keySet());
|
||||
@@ -442,7 +446,9 @@ public class GitOperations {
|
||||
return trainToUse.getIteration(Iteration.GA);
|
||||
}
|
||||
|
||||
Optional<TrainIteration> mostRecentBefore = getTags(Projects.BUILD) //
|
||||
SupportedProject build = trainIteration.getSupportedProject(Projects.BUILD);
|
||||
|
||||
Optional<TrainIteration> mostRecentBefore = getTags(build) //
|
||||
.filter((tag, ti) -> ti.getTrain().equals(trainIteration.getTrain())) //
|
||||
.find((tag, iteration) -> iteration.getIteration().compareTo(trainIteration.getIteration()) < 0,
|
||||
Pair::getSecond);
|
||||
@@ -451,7 +457,8 @@ public class GitOperations {
|
||||
"Cannot determine previous iteration for " + trainIteration.getReleaseTrainNameAndVersion()));
|
||||
}
|
||||
|
||||
public List<TicketReference> getTicketReferencesBetween(Project project, TrainIteration from, TrainIteration to) {
|
||||
public List<TicketReference> getTicketReferencesBetween(SupportedProject project, TrainIteration from,
|
||||
TrainIteration to) {
|
||||
|
||||
VersionTags tags = getTags(project);
|
||||
|
||||
@@ -459,8 +466,8 @@ public class GitOperations {
|
||||
|
||||
Repository repo = git.getRepository();
|
||||
|
||||
ModuleIteration toModuleIteration = to.getModule(project);
|
||||
ObjectId fromTag = resolveLowerBoundary(project, from, tags, repo);
|
||||
ModuleIteration toModuleIteration = to.getModule(project.getProject());
|
||||
ObjectId fromTag = resolveLowerBoundary(project.getProject(), from, tags, repo);
|
||||
ObjectId toTag = resolveUpperBoundary(toModuleIteration, tags, repo);
|
||||
|
||||
Iterable<RevCommit> commits = git.log().addRange(fromTag, toTag).call();
|
||||
@@ -526,9 +533,13 @@ public class GitOperations {
|
||||
}
|
||||
|
||||
private static String getFirstCommit(Repository repo) throws IOException {
|
||||
return getFirstCommit(repo, Branch.MAIN);
|
||||
}
|
||||
|
||||
private static String getFirstCommit(Repository repo, Branch branch) throws IOException {
|
||||
|
||||
try (RevWalk revWalk = new RevWalk(repo)) {
|
||||
return revWalk.parseCommit(repo.resolve("main")).getName();
|
||||
return revWalk.parseCommit(repo.resolve(branch.toString())).getName();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,10 +558,10 @@ public class GitOperations {
|
||||
}
|
||||
|
||||
private static boolean isGaOrFirstMilestone(Iteration iteration) {
|
||||
return iteration.isGAIteration() || (iteration.isMilestone() && iteration.getIterationValue() == 1);
|
||||
return iteration.isGAIteration() || iteration.isMilestone() && iteration.getIterationValue() == 1;
|
||||
}
|
||||
|
||||
private Stream<Branch> getRemoteBranches(Project project) {
|
||||
private Stream<Branch> getRemoteBranches(SupportedProject project) {
|
||||
|
||||
return doWithGit(project, git -> {
|
||||
|
||||
@@ -576,7 +587,7 @@ public class GitOperations {
|
||||
|
||||
ExecutionUtils.run(executor, iteration, module -> {
|
||||
|
||||
Project project = module.getProject();
|
||||
SupportedProject project = module.getSupportedProject();
|
||||
ObjectId hash = getReleaseHash(module);
|
||||
Tag tag = getTags(project).createTag(module);
|
||||
|
||||
@@ -646,7 +657,7 @@ public class GitOperations {
|
||||
Assert.notNull(module, "Module iteration must not be null!");
|
||||
Assert.hasText(summary, "Summary must not be null or empty!");
|
||||
|
||||
Project project = module.getProject();
|
||||
SupportedProject project = module.getSupportedProject();
|
||||
IssueTracker tracker = issueTracker.getRequiredPluginFor(project,
|
||||
() -> String.format("No issue tracker found for project %s!", project));
|
||||
Ticket ticket = tracker.getReleaseTicketFor(module);
|
||||
@@ -667,7 +678,7 @@ public class GitOperations {
|
||||
Assert.notNull(module, "Module iteration must not be null!");
|
||||
Assert.hasText(summary, "Summary must not be null or empty!");
|
||||
|
||||
Project project = module.getProject();
|
||||
SupportedProject project = module.getSupportedProject();
|
||||
IssueTracker tracker = issueTracker.getRequiredPluginFor(project,
|
||||
() -> String.format("No issue tracker found for project %s!", project));
|
||||
Ticket ticket = tracker.getReleaseTicketFor(module);
|
||||
@@ -683,11 +694,12 @@ public class GitOperations {
|
||||
* @param summary must not be {@literal null} or empty.
|
||||
* @param details can be {@literal null} or empty.
|
||||
*/
|
||||
public void commit(ProjectAware module, Ticket ticket, String summary, Optional<String> details, boolean all) {
|
||||
public void commit(ProjectAware module, Ticket ticket, String summary, Optional<String> details,
|
||||
boolean all) {
|
||||
|
||||
Assert.notNull(module, "ProjectAware must not be null!");
|
||||
|
||||
commit(module.getProject(), ticket, summary, details, all);
|
||||
commit(module.getSupportedProject(), ticket, summary, details, all);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -698,7 +710,7 @@ public class GitOperations {
|
||||
* @param summary must not be {@literal null} or empty.
|
||||
* @param details can be {@literal null} or empty.
|
||||
*/
|
||||
public void commit(Project project, Ticket ticket, String summary, Optional<String> details, boolean all) {
|
||||
public void commit(SupportedProject project, Ticket ticket, String summary, Optional<String> details, boolean all) {
|
||||
|
||||
Assert.notNull(project, "Project must not be null!");
|
||||
Assert.hasText(summary, "Summary must not be null or empty!");
|
||||
@@ -745,7 +757,7 @@ public class GitOperations {
|
||||
* @param project must not be {@literal null}.
|
||||
* @param filepattern must not be {@literal null} or empty.
|
||||
*/
|
||||
public void add(Project project, String filepattern) {
|
||||
public void add(SupportedProject project, String filepattern) {
|
||||
|
||||
Assert.notNull(project, "Project must not be null!");
|
||||
|
||||
@@ -761,14 +773,14 @@ public class GitOperations {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks out the given {@link Branch} of the given {@link Project}. If the given branch doesn't exist yet, a tracking
|
||||
* branch is created assuming the branch exists in the {@code origin} remote. Pulls the latest changes from the
|
||||
* checked out branch will be pulled to make sure we see them.
|
||||
* Checks out the given {@link Branch} of the given {@link SupportedProject}. If the given branch doesn't exist yet, a
|
||||
* tracking branch is created assuming the branch exists in the {@code origin} remote. Pulls the latest changes from
|
||||
* the checked out branch will be pulled to make sure we see them.
|
||||
*
|
||||
* @param project must not be {@literal null}.
|
||||
* @param branch must not be {@literal null}.
|
||||
*/
|
||||
public void checkout(Project project, Branch branch) {
|
||||
public void checkout(SupportedProject project, Branch branch) {
|
||||
checkout(project, branch, BranchCheckoutMode.CREATE_AND_UPDATE);
|
||||
}
|
||||
|
||||
@@ -782,7 +794,7 @@ public class GitOperations {
|
||||
* @param branch must not be {@literal null}.
|
||||
* @param mode must not be {@literal null}.
|
||||
*/
|
||||
private void checkout(Project project, Branch branch, BranchCheckoutMode mode) {
|
||||
private void checkout(SupportedProject project, Branch branch, BranchCheckoutMode mode) {
|
||||
|
||||
Assert.notNull(project, "Project must not be null!");
|
||||
Assert.notNull(branch, "Branch must not be null!");
|
||||
@@ -822,11 +834,11 @@ public class GitOperations {
|
||||
// Pull latest changes to make sure the branch is up to date
|
||||
logger.log(project, "git pull origin %s", branch);
|
||||
|
||||
git.pull()//
|
||||
.setRemote("origin")//
|
||||
call(git.pull() //
|
||||
.setRemote("origin") //
|
||||
.setRebase(true) //
|
||||
.setRemoteBranchName(branch.toString())//
|
||||
.call();
|
||||
.setRemoteBranchName(branch.toString()));
|
||||
|
||||
break;
|
||||
}
|
||||
});
|
||||
@@ -845,7 +857,7 @@ public class GitOperations {
|
||||
ExecutionUtils.run(executor, iteration, module -> {
|
||||
|
||||
Branch branch = createMaintenanceBranch(module);
|
||||
checkout(module.getProject(), branch, BranchCheckoutMode.CREATE_ONLY);
|
||||
checkout(module.getSupportedProject(), branch, BranchCheckoutMode.CREATE_ONLY);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -853,7 +865,7 @@ public class GitOperations {
|
||||
|
||||
ExecutionUtils.run(executor, iteration, module -> {
|
||||
|
||||
Project project = module.getProject();
|
||||
SupportedProject project = module.getSupportedProject();
|
||||
ArtifactVersion artifactVersion = ArtifactVersion.of(module);
|
||||
|
||||
Optional<Tag> tag = findTagFor(project, artifactVersion);
|
||||
@@ -875,10 +887,12 @@ public class GitOperations {
|
||||
* Verify general Git operations.
|
||||
*/
|
||||
@SneakyThrows
|
||||
public void verify() {
|
||||
public void verify(Train train) {
|
||||
|
||||
SupportedProject project = train.getSupportedProject(Projects.BUILD);
|
||||
|
||||
Project project = Projects.BUILD;
|
||||
File projectDirectory = workspace.getProjectDirectory(project);
|
||||
|
||||
if (projectDirectory.exists()) {
|
||||
FileUtils.deleteDirectory(projectDirectory);
|
||||
}
|
||||
@@ -891,7 +905,7 @@ public class GitOperations {
|
||||
reset(project, Branch.MAIN);
|
||||
}
|
||||
|
||||
private void commitRandomFile(Project project, File projectDirectory) throws IOException {
|
||||
private void commitRandomFile(SupportedProject project, File projectDirectory) throws IOException {
|
||||
|
||||
String randomFileName = UUID.randomUUID() + ".txt";
|
||||
File randomFile = new File(projectDirectory, randomFileName);
|
||||
@@ -925,7 +939,7 @@ public class GitOperations {
|
||||
|
||||
Branch branch = Branch.from(module.getVersion());
|
||||
|
||||
doWithGit(module.getProject(), git -> {
|
||||
doWithGit(module.getSupportedProject(), git -> {
|
||||
logger.log(module, "git checkout -b %s", branch);
|
||||
git.branchCreate().setName(branch.toString()).call();
|
||||
});
|
||||
@@ -952,14 +966,15 @@ public class GitOperations {
|
||||
Predicate<RevCommit> trigger = calculateFilter(module, summary);
|
||||
|
||||
return findCommit(module, summary).orElseThrow(() -> new IllegalStateException(String
|
||||
.format("Did not find a commit with summary starting with '%s' for project %s", module.getProject(), trigger)));
|
||||
.format("Did not find a commit with summary starting with '%s' for project %s", module.getSupportedProject(),
|
||||
trigger)));
|
||||
}
|
||||
|
||||
private Optional<ObjectId> findCommit(ModuleIteration module, String summary) {
|
||||
return findCommit(module.getProject(), calculateFilter(module, summary));
|
||||
return findCommit(module.getSupportedProject(), calculateFilter(module, summary));
|
||||
}
|
||||
|
||||
private Optional<ObjectId> findCommit(Project project, Predicate<RevCommit> filter) {
|
||||
private Optional<ObjectId> findCommit(SupportedProject project, Predicate<RevCommit> filter) {
|
||||
|
||||
return doWithGit(project, git -> {
|
||||
|
||||
@@ -976,7 +991,7 @@ public class GitOperations {
|
||||
|
||||
private Predicate<RevCommit> calculateFilter(ModuleIteration module, String summary) {
|
||||
|
||||
Project project = module.getProject();
|
||||
SupportedProject project = module.getSupportedProject();
|
||||
Ticket releaseTicket = issueTracker
|
||||
.getRequiredPluginFor(project, () -> String.format("No issue tracker found for project %s!", project))//
|
||||
.getReleaseTicketFor(module);
|
||||
@@ -999,14 +1014,14 @@ public class GitOperations {
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private Optional<Tag> findTagFor(Project project, ArtifactVersion version) {
|
||||
private Optional<Tag> findTagFor(SupportedProject project, ArtifactVersion version) {
|
||||
|
||||
return getTags(project).stream()//
|
||||
.filter(tag -> tag.toArtifactVersion().map(it -> it.equals(version)).orElse(false))//
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
private Repository getRepository(Project project) throws IOException {
|
||||
private Repository getRepository(SupportedProject project) throws IOException {
|
||||
|
||||
Repository repository = FileRepositoryBuilder.create(workspace.getFile(".git", project));
|
||||
|
||||
@@ -1017,25 +1032,24 @@ public class GitOperations {
|
||||
return repository;
|
||||
}
|
||||
|
||||
private void clone(Project project) throws Exception {
|
||||
private void clone(GitProject gitProject) throws Exception {
|
||||
|
||||
GitProject gitProject = getGitProject(project);
|
||||
SupportedProject project = gitProject.getProject();
|
||||
|
||||
logger.log(project, "No repository found! Cloning from %s…", gitProject.getProjectUri());
|
||||
|
||||
Git git = Git.cloneRepository()//
|
||||
.setURI(gitProject.getProjectUri())//
|
||||
.setDirectory(workspace.getProjectDirectory(project))//
|
||||
.call();
|
||||
Git git = call(Git.cloneRepository() //
|
||||
.setURI(gitProject.getProjectUri()) //
|
||||
.setDirectory(workspace.getProjectDirectory(project)));
|
||||
|
||||
git.checkout()//
|
||||
.setName(Branch.MAIN.toString())//
|
||||
git.checkout() //
|
||||
.setName(Branch.MAIN.toString()) //
|
||||
.call();
|
||||
|
||||
logger.log(project, "Cloning done!", project);
|
||||
}
|
||||
|
||||
private boolean branchExists(Project project, Branch branch) {
|
||||
private boolean branchExists(SupportedProject project, Branch branch) {
|
||||
|
||||
try (Git git = new Git(getRepository(project))) {
|
||||
|
||||
@@ -1046,7 +1060,7 @@ public class GitOperations {
|
||||
}
|
||||
}
|
||||
|
||||
private void reset(Project project, Branch branch) {
|
||||
private void reset(SupportedProject project, Branch branch) {
|
||||
|
||||
logger.log(project, "git reset --hard origin/%s", branch);
|
||||
|
||||
@@ -1063,7 +1077,7 @@ public class GitOperations {
|
||||
return summary.contains("%s") ? String.format(summary, module.getMediumVersionString()) : summary;
|
||||
}
|
||||
|
||||
private <T> T doWithGit(Project project, GitCallback<T> callback) {
|
||||
private <T> T doWithGit(SupportedProject project, GitCallback<T> callback) {
|
||||
|
||||
try (Git git = new Git(getRepository(project))) {
|
||||
return callback.doWithGit(git);
|
||||
@@ -1081,7 +1095,7 @@ public class GitOperations {
|
||||
}
|
||||
}
|
||||
|
||||
private void doWithGit(Project project, VoidGitCallback callback) {
|
||||
private void doWithGit(SupportedProject project, VoidGitCallback callback) {
|
||||
|
||||
doWithGit(project, (GitCallback<Void>) git -> {
|
||||
callback.doWithGit(git);
|
||||
@@ -1106,6 +1120,13 @@ public class GitOperations {
|
||||
return gpg;
|
||||
}
|
||||
|
||||
private <T, C extends GitCommand<T>> T call(TransportCommand<C, T> command) throws GitAPIException {
|
||||
|
||||
return command
|
||||
.setCredentialsProvider(gitProperties.getCredentials())
|
||||
.call();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link CredentialsProvider} for GPG Keys used with JGit Commit Signing.
|
||||
*/
|
||||
|
||||
@@ -17,35 +17,44 @@ package org.springframework.data.release.git;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.Projects;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@EqualsAndHashCode
|
||||
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
||||
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
public class GitProject {
|
||||
|
||||
private static final String PROJECT_PREFIX = "spring-data";
|
||||
|
||||
private final Project project;
|
||||
private final @Getter SupportedProject project;
|
||||
private final GitServer server;
|
||||
|
||||
public static GitProject of(Project project) {
|
||||
public static GitProject of(SupportedProject project) {
|
||||
return new GitProject(project, GitServer.INSTANCE);
|
||||
}
|
||||
|
||||
public static GitProject of(ModuleIteration module) {
|
||||
return new GitProject(module.getSupportedProject(), GitServer.INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the repository the project is using.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getRepositoryName() {
|
||||
return String.format("%s-%s", PROJECT_PREFIX,
|
||||
project == Projects.JDBC ? "relational" : project.getName().toLowerCase());
|
||||
|
||||
String logicalName = String.format("%s-%s", PROJECT_PREFIX,
|
||||
project.getProject() == Projects.JDBC ? "relational" : project.getName().toLowerCase());
|
||||
|
||||
return project.isCommercial() ? logicalName + "-commercial" : logicalName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -91,7 +91,7 @@ public class VersionTags implements Streamable<Tag> {
|
||||
|
||||
public Tag createTag(ModuleIteration iteration) {
|
||||
|
||||
if (iteration.getProject().equals(Projects.BOM)) {
|
||||
if (iteration.getSupportedProject().equals(Projects.BOM)) {
|
||||
return Tag.of(iteration.getTrainIteration().getReleaseTrainNameAndVersion());
|
||||
}
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ import org.springframework.data.release.TimedCommand;
|
||||
import org.springframework.data.release.git.GitOperations;
|
||||
import org.springframework.data.release.issues.Tickets;
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.Projects;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
import org.springframework.shell.core.annotation.CliCommand;
|
||||
@@ -79,13 +79,14 @@ public class DependencyCommands extends TimedCommand {
|
||||
|
||||
git.prepare(iteration);
|
||||
|
||||
List<Project> projects = Projects.all().stream()
|
||||
List<SupportedProject> projects = Projects.all().stream()
|
||||
.filter(it -> it != Projects.BOM && it != Projects.BUILD && it != Projects.COMMONS)
|
||||
.map(iteration::getSupportedProject)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Map<Dependency, DependencyVersion> dependencies = new TreeMap<>();
|
||||
|
||||
for (Project project : projects) {
|
||||
for (SupportedProject project : projects) {
|
||||
operations.getCurrentDependencies(project).forEach(dependencies::put);
|
||||
}
|
||||
|
||||
@@ -113,7 +114,7 @@ public class DependencyCommands extends TimedCommand {
|
||||
ModuleIteration module = iteration.getModule(Projects.BUILD);
|
||||
DependencyVersions dependencyVersions = loadDependencyUpgrades(module);
|
||||
|
||||
DependencyVersions upgradesToApply = operations.getDependencyUpgradesToApply(module.getProject(),
|
||||
DependencyVersions upgradesToApply = operations.getDependencyUpgradesToApply(module.getSupportedProject(),
|
||||
dependencyVersions);
|
||||
|
||||
if (upgradesToApply.isEmpty()) {
|
||||
@@ -151,12 +152,14 @@ public class DependencyCommands extends TimedCommand {
|
||||
|
||||
String propertiesFile = "dependency-upgrade-modules.properties";
|
||||
|
||||
List<Project> projects = Projects.all().stream().filter(it -> it != Projects.BOM && it != Projects.BUILD)
|
||||
List<SupportedProject> projects = Projects.all().stream()
|
||||
.filter(it -> it != Projects.BOM && it != Projects.BUILD)
|
||||
.map(iteration::getSupportedProject)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
DependencyUpgradeProposals proposals = DependencyUpgradeProposals.empty();
|
||||
|
||||
for (Project project : projects) {
|
||||
for (SupportedProject project : projects) {
|
||||
proposals = proposals.mergeWith(operations.getDependencyUpgradeProposals(project, iteration.getIteration()));
|
||||
}
|
||||
|
||||
@@ -172,7 +175,8 @@ public class DependencyCommands extends TimedCommand {
|
||||
|
||||
String propertiesFile = BUILD_PROPERTIES;
|
||||
|
||||
DependencyUpgradeProposals proposals = operations.getDependencyUpgradeProposals(Projects.BUILD,
|
||||
SupportedProject project = iteration.getSupportedProject(Projects.BUILD);
|
||||
DependencyUpgradeProposals proposals = operations.getDependencyUpgradeProposals(project,
|
||||
iteration.getIteration());
|
||||
|
||||
Files.write(Paths.get(propertiesFile), proposals.asProperties(iteration).getBytes());
|
||||
|
||||
@@ -55,6 +55,7 @@ import org.springframework.data.release.model.Iteration;
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.Projects;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.data.release.utils.ExecutionUtils;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
@@ -65,7 +66,6 @@ import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.RestOperations;
|
||||
|
||||
import org.xmlbeam.ProjectionFactory;
|
||||
import org.xmlbeam.annotation.XBRead;
|
||||
import org.xmlbeam.io.FileIO;
|
||||
@@ -102,7 +102,7 @@ public class DependencyOperations {
|
||||
* @param iteration
|
||||
* @return
|
||||
*/
|
||||
public DependencyUpgradeProposals getDependencyUpgradeProposals(Project project, Iteration iteration) {
|
||||
public DependencyUpgradeProposals getDependencyUpgradeProposals(SupportedProject project, Iteration iteration) {
|
||||
|
||||
DependencyVersions currentDependencies = getCurrentDependencies(project);
|
||||
Map<Dependency, DependencyUpgradeProposal> proposals = Collections.synchronizedMap(new LinkedHashMap<>());
|
||||
@@ -132,10 +132,12 @@ public class DependencyOperations {
|
||||
for (ModuleIteration moduleIteration : iteration) {
|
||||
|
||||
// ensure we have Maven Wrapper for each project.
|
||||
getMavenWrapperVersion(moduleIteration.getProject());
|
||||
getMavenWrapperVersion(moduleIteration.getSupportedProject());
|
||||
}
|
||||
|
||||
return getDependencyUpgradeProposals(Projects.BUILD, DependencyUpgradePolicy.LATEST_STABLE, Dependencies.MAVEN,
|
||||
SupportedProject build = iteration.getSupportedProject(Projects.BUILD);
|
||||
|
||||
return getDependencyUpgradeProposals(build, DependencyUpgradePolicy.LATEST_STABLE, Dependencies.MAVEN,
|
||||
this::getMavenWrapperVersion);
|
||||
}
|
||||
|
||||
@@ -154,7 +156,7 @@ public class DependencyOperations {
|
||||
}
|
||||
|
||||
return doWithDependencyVersionsAndCommit(tickets, module, dependencyVersions, (dependency, version) -> {
|
||||
upgradeMavenWrapperVersion(module.getProject(), version);
|
||||
upgradeMavenWrapperVersion(module.getSupportedProject(), version);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -164,17 +166,17 @@ public class DependencyOperations {
|
||||
|
||||
for (ModuleIteration moduleIteration : iteration) {
|
||||
|
||||
DependencyVersion currentVersion = getMavenWrapperVersion(moduleIteration.getProject());
|
||||
DependencyVersion currentVersion = getMavenWrapperVersion(moduleIteration.getSupportedProject());
|
||||
|
||||
if (targetVersion.isNewer(currentVersion)) {
|
||||
projectsToUpgrade.add(moduleIteration.getProject());
|
||||
projectsToUpgrade.add(moduleIteration.getSupportedProject().getProject());
|
||||
}
|
||||
}
|
||||
|
||||
return projectsToUpgrade;
|
||||
}
|
||||
|
||||
private DependencyVersion getMavenWrapperVersion(Project project) {
|
||||
private DependencyVersion getMavenWrapperVersion(SupportedProject project) {
|
||||
|
||||
try {
|
||||
|
||||
@@ -191,8 +193,8 @@ public class DependencyOperations {
|
||||
}
|
||||
|
||||
Pattern versionPattern = Pattern.compile(".*/maven2/org/apache/maven/apache-maven/([\\d\\.]+)/.*");
|
||||
|
||||
Matcher matcher = versionPattern.matcher(distributionUrl);
|
||||
|
||||
if (!matcher.find()) {
|
||||
throw new IllegalStateException(
|
||||
String.format("Invalid distribution URL in %s: %s", project.getName(), distributionUrl));
|
||||
@@ -204,7 +206,7 @@ public class DependencyOperations {
|
||||
}
|
||||
}
|
||||
|
||||
private void upgradeMavenWrapperVersion(Project project, DependencyVersion dependencyVersion) {
|
||||
private void upgradeMavenWrapperVersion(SupportedProject project, DependencyVersion dependencyVersion) {
|
||||
|
||||
String distributionUrlTemplate = "https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/%s/apache-maven-%s-bin.zip";
|
||||
|
||||
@@ -229,7 +231,7 @@ public class DependencyOperations {
|
||||
}
|
||||
}
|
||||
|
||||
private File getMavenWrapperProperties(Project project) throws FileNotFoundException {
|
||||
private File getMavenWrapperProperties(SupportedProject project) throws FileNotFoundException {
|
||||
File file = workspace.getFile(".mvn/wrapper/maven-wrapper.properties", project);
|
||||
|
||||
if (!file.exists()) {
|
||||
@@ -238,8 +240,9 @@ public class DependencyOperations {
|
||||
return file;
|
||||
}
|
||||
|
||||
public DependencyUpgradeProposals getDependencyUpgradeProposals(Project project, DependencyUpgradePolicy policy,
|
||||
Dependency dependency, Function<Project, DependencyVersion> currentVersionExtractor) {
|
||||
public DependencyUpgradeProposals getDependencyUpgradeProposals(SupportedProject project,
|
||||
DependencyUpgradePolicy policy, Dependency dependency,
|
||||
Function<SupportedProject, DependencyVersion> currentVersionExtractor) {
|
||||
|
||||
DependencyVersions currentDependencies = new DependencyVersions(
|
||||
Collections.singletonMap(dependency, currentVersionExtractor.apply(project)));
|
||||
@@ -280,7 +283,7 @@ public class DependencyOperations {
|
||||
*/
|
||||
public Tickets upgradeDependencies(Tickets tickets, ModuleIteration module, DependencyVersions dependencyVersions) {
|
||||
|
||||
Project project = module.getProject();
|
||||
SupportedProject project = module.getSupportedProject();
|
||||
ProjectDependencies dependencies = ProjectDependencies.get(project);
|
||||
|
||||
if (dependencyVersions.isEmpty()) {
|
||||
@@ -290,7 +293,7 @@ public class DependencyOperations {
|
||||
return doWithDependencyVersionsAndCommit(tickets, module, dependencyVersions, (dependency, version) -> {
|
||||
|
||||
String versionProperty = dependencies.getVersionPropertyFor(dependency);
|
||||
File pom = getPomFile(project);
|
||||
File pom = getPomFile(module.getSupportedProject());
|
||||
update(pom, Pom.class, it -> {
|
||||
it.setProperty(versionProperty, version.getIdentifier());
|
||||
});
|
||||
@@ -333,7 +336,8 @@ public class DependencyOperations {
|
||||
this.tickets.closeTickets(module, tickets);
|
||||
}
|
||||
|
||||
public DependencyVersions getDependencyUpgradesToApply(Project project, DependencyVersions dependencyVersions) {
|
||||
public DependencyVersions getDependencyUpgradesToApply(SupportedProject project,
|
||||
DependencyVersions dependencyVersions) {
|
||||
|
||||
DependencyVersions currentDependencies = getCurrentDependencies(project);
|
||||
Map<Dependency, DependencyVersion> upgrades = new LinkedHashMap<>();
|
||||
@@ -452,14 +456,16 @@ public class DependencyOperations {
|
||||
.max(DependencyVersion::compareTo);
|
||||
}
|
||||
|
||||
DependencyVersions getCurrentDependencies(Project project) {
|
||||
DependencyVersions getCurrentDependencies(SupportedProject supportedProject) {
|
||||
|
||||
Project project = supportedProject.getProject();
|
||||
|
||||
if (!ProjectDependencies.containsProject(project)) {
|
||||
return DependencyVersions.empty();
|
||||
}
|
||||
|
||||
File pom = getPomFile(project);
|
||||
ProjectDependencies dependencies = ProjectDependencies.get(project);
|
||||
File pom = getPomFile(supportedProject);
|
||||
ProjectDependencies dependencies = ProjectDependencies.get(supportedProject);
|
||||
|
||||
return doWithPom(pom, Pom.class, it -> {
|
||||
|
||||
@@ -469,7 +475,7 @@ public class DependencyOperations {
|
||||
|
||||
Dependency dependency = projectDependency.getDependency();
|
||||
|
||||
if (!((project == Projects.MONGO_DB && projectDependency.getProperty().equals("mongo.reactivestreams"))
|
||||
if (!(project == Projects.MONGO_DB && projectDependency.getProperty().equals("mongo.reactivestreams")
|
||||
|| project == Projects.NEO4J || project == Projects.BUILD)) {
|
||||
|
||||
if (it.getDependencyVersion(dependency.getArtifactId()) == null
|
||||
@@ -489,8 +495,8 @@ public class DependencyOperations {
|
||||
});
|
||||
}
|
||||
|
||||
private File getPomFile(Project project) {
|
||||
return workspace.getFile(project == Projects.BUILD ? "parent/pom.xml" : "pom.xml", project);
|
||||
private File getPomFile(SupportedProject project) {
|
||||
return workspace.getFile(project.getProject().getProjectDescriptor(), project);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@@ -560,7 +566,7 @@ public class DependencyOperations {
|
||||
|
||||
try {
|
||||
|
||||
T pom = (T) io.read(type);
|
||||
T pom = io.read(type);
|
||||
return callback.apply(pom);
|
||||
|
||||
} catch (Exception o_O) {
|
||||
@@ -574,7 +580,7 @@ public class DependencyOperations {
|
||||
|
||||
try {
|
||||
|
||||
T pom = (T) io.read(type);
|
||||
T pom = io.read(type);
|
||||
callback.accept(pom);
|
||||
io.write(pom);
|
||||
|
||||
|
||||
@@ -30,16 +30,15 @@ import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import org.springframework.data.release.TimedCommand;
|
||||
import org.springframework.data.release.git.Branch;
|
||||
import org.springframework.data.release.git.GitOperations;
|
||||
import org.springframework.data.release.io.Workspace;
|
||||
import org.springframework.data.release.issues.Tickets;
|
||||
import org.springframework.data.release.model.Module;
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.Projects;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.model.Train;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.data.release.utils.ExecutionUtils;
|
||||
@@ -72,7 +71,7 @@ public class InfrastructureOperations extends TimedCommand {
|
||||
*/
|
||||
void distributeCiProperties(TrainIteration iteration) {
|
||||
|
||||
File master = workspace.getFile(CI_PROPERTIES, Projects.BUILD);
|
||||
File master = workspace.getFile(CI_PROPERTIES, iteration.getSupportedProject(Projects.BUILD));
|
||||
|
||||
if (!master.exists()) {
|
||||
throw new IllegalStateException(String.format("CI Properties file %s does not exist", master));
|
||||
@@ -80,7 +79,7 @@ public class InfrastructureOperations extends TimedCommand {
|
||||
|
||||
ExecutionUtils.run(executor, iteration, module -> {
|
||||
|
||||
Project project = module.getProject();
|
||||
SupportedProject project = module.getSupportedProject();
|
||||
Branch branch = Branch.from(module);
|
||||
|
||||
git.update(project);
|
||||
@@ -91,12 +90,12 @@ public class InfrastructureOperations extends TimedCommand {
|
||||
|
||||
ExecutionUtils.run(executor, Streamable.of(iteration.getModulesExcept(Projects.BUILD)), module -> {
|
||||
|
||||
File target = workspace.getFile(CI_PROPERTIES, module.getProject());
|
||||
File target = workspace.getFile(CI_PROPERTIES, module.getSupportedProject());
|
||||
target.delete();
|
||||
|
||||
FileUtils.copyFile(master, target);
|
||||
|
||||
git.add(module.getProject(), CI_PROPERTIES);
|
||||
git.add(module.getSupportedProject(), CI_PROPERTIES);
|
||||
git.commit(module, "Update CI properties.", Optional.empty(), false);
|
||||
git.push(module);
|
||||
});
|
||||
@@ -104,8 +103,9 @@ public class InfrastructureOperations extends TimedCommand {
|
||||
|
||||
private void verifyExistingPropertyFiles(Train train, File master) {
|
||||
|
||||
for (Module module : train) {
|
||||
File target = workspace.getFile(CI_PROPERTIES, module.getProject());
|
||||
for (SupportedProject project : train) {
|
||||
|
||||
File target = workspace.getFile(CI_PROPERTIES, project);
|
||||
|
||||
if (!target.exists()) {
|
||||
throw new IllegalStateException(String.format("CI Properties file %s does not exist", master));
|
||||
|
||||
@@ -38,7 +38,6 @@ import org.apache.commons.io.filefilter.AbstractFileFilter;
|
||||
import org.apache.commons.io.filefilter.IOFileFilter;
|
||||
import org.apache.commons.io.filefilter.NameFileFilter;
|
||||
import org.apache.commons.io.filefilter.NotFileFilter;
|
||||
|
||||
import org.springframework.data.release.CliComponent;
|
||||
import org.springframework.data.release.TimedCommand;
|
||||
import org.springframework.data.release.git.GitOperations;
|
||||
@@ -49,6 +48,7 @@ import org.springframework.data.release.issues.TicketOperations;
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.Projects;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.data.release.utils.ExecutionUtils;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
@@ -95,7 +95,7 @@ public class LicenseHeaderCommands extends TimedCommand {
|
||||
|
||||
if (projectName != null) {
|
||||
Project project = Projects.requiredByName(projectName);
|
||||
modules = modules.filter(it -> it.getProject().equals(project));
|
||||
modules = modules.filter(it -> it.getSupportedProject().equals(project));
|
||||
}
|
||||
|
||||
ExecutionUtils.run(executor, modules, module -> {
|
||||
@@ -110,7 +110,7 @@ public class LicenseHeaderCommands extends TimedCommand {
|
||||
|
||||
private int updateLicense(int year, ModuleIteration module) {
|
||||
|
||||
return replaceInFiles(module.getProject(), (file, content) -> {
|
||||
return replaceInFiles(module.getSupportedProject(), (file, content) -> {
|
||||
|
||||
String contentToUse = content;
|
||||
|
||||
@@ -154,7 +154,7 @@ public class LicenseHeaderCommands extends TimedCommand {
|
||||
* @param contentFunction
|
||||
* @return
|
||||
*/
|
||||
private int replaceInFiles(Project project, Function<String, String> contentFunction) {
|
||||
private int replaceInFiles(SupportedProject project, Function<String, String> contentFunction) {
|
||||
return replaceInFiles(project, (file, s) -> contentFunction.apply(s));
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ public class LicenseHeaderCommands extends TimedCommand {
|
||||
* @param contentFunction
|
||||
* @return
|
||||
*/
|
||||
private int replaceInFiles(Project project, BiFunction<File, String, String> contentFunction) {
|
||||
private int replaceInFiles(SupportedProject project, BiFunction<File, String, String> contentFunction) {
|
||||
|
||||
File projectDirectory = workspace.getProjectDirectory(project);
|
||||
IOFileFilter fileFilter = new AntPathFileFilter(projectDirectory, filePatterns);
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.List;
|
||||
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.Projects;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.util.Streamable;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
@@ -104,19 +105,19 @@ public class ProjectDependencies implements Streamable<ProjectDependencies.Proje
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve upgradable dependencies for a {@link Project}.
|
||||
* Retrieve upgradable dependencies for a {@link SupportedProject}.
|
||||
*
|
||||
* @param project
|
||||
* @return
|
||||
* @throws IllegalArgumentException if the project has no upgradable dependencies.
|
||||
*/
|
||||
public static ProjectDependencies get(Project project) {
|
||||
public static ProjectDependencies get(SupportedProject project) {
|
||||
|
||||
if (!containsProject(project)) {
|
||||
if (!containsProject(project.getProject())) {
|
||||
throw new IllegalArgumentException(String.format("No dependency configuration for %s!", project));
|
||||
}
|
||||
|
||||
return new ProjectDependencies(config.get(project));
|
||||
return new ProjectDependencies(config.get(project.getProject()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,8 +42,8 @@ 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.model.SupportedProject;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -149,11 +149,11 @@ public class Workspace {
|
||||
* @param project must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public File getProjectDirectory(Project project) {
|
||||
public File getProjectDirectory(SupportedProject project) {
|
||||
|
||||
Assert.notNull(project, "Project must not be null!");
|
||||
|
||||
if (project == Projects.SMOKE_TESTS) {
|
||||
if (project.getProject() == Projects.SMOKE_TESTS) {
|
||||
return new File("smoke-tests");
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ public class Workspace {
|
||||
* @param project must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public boolean hasProjectDirectory(Project project) {
|
||||
public boolean hasProjectDirectory(SupportedProject project) {
|
||||
|
||||
Assert.notNull(project, "Project must not be null!");
|
||||
return getProjectDirectory(project).exists();
|
||||
@@ -179,7 +179,7 @@ public class Workspace {
|
||||
* @param project must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public File getFile(String name, Project project) {
|
||||
public File getFile(String name, SupportedProject project) {
|
||||
|
||||
Assert.hasText(name, "Filename must not be null or empty!");
|
||||
Assert.notNull(project, "Project must not be null!");
|
||||
@@ -187,7 +187,7 @@ public class Workspace {
|
||||
return new File(getProjectDirectory(project), name);
|
||||
}
|
||||
|
||||
public Stream<File> getFiles(String pattern, Project project) {
|
||||
public Stream<File> getFiles(String pattern, SupportedProject project) {
|
||||
|
||||
File projectDirectory = getProjectDirectory(project);
|
||||
String patternToLookup = String.format("file:%s/%s", projectDirectory.getAbsolutePath(), pattern);
|
||||
@@ -199,7 +199,7 @@ public class Workspace {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean processFile(String filename, Project project, LineCallback callback) {
|
||||
public boolean processFile(String filename, SupportedProject project, LineCallback callback) {
|
||||
|
||||
File file = getFile(filename, project);
|
||||
|
||||
@@ -226,7 +226,7 @@ public class Workspace {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void writeContentToFile(String name, Project project, String content) throws IOException {
|
||||
private void writeContentToFile(String name, SupportedProject project, String content) throws IOException {
|
||||
|
||||
File file = getFile(name, project);
|
||||
Files.write(file.toPath(), Collections.singleton(content), UTF_8);
|
||||
|
||||
@@ -19,10 +19,8 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.data.release.model.Iteration;
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.Train;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.plugin.core.Plugin;
|
||||
|
||||
@@ -32,7 +30,7 @@ import org.springframework.plugin.core.Plugin;
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public interface IssueTracker extends Plugin<Project> {
|
||||
public interface IssueTracker extends Plugin<SupportedProject> {
|
||||
|
||||
/**
|
||||
* Reset internal state (cache, etc).
|
||||
@@ -80,7 +78,7 @@ public interface IssueTracker extends Plugin<Project> {
|
||||
* @param ticketIds collection of {@link Ticket#id ticket Ids}, must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
Collection<Ticket> findTickets(Project project, Collection<String> ticketIds);
|
||||
Collection<Ticket> findTickets(SupportedProject project, Collection<String> ticketIds);
|
||||
|
||||
/**
|
||||
* Query the issue tracker for multiple {@link Ticket#id ticket Ids}. Tickets that are not found are not returned. The
|
||||
@@ -133,7 +131,7 @@ public interface IssueTracker extends Plugin<Project> {
|
||||
* @param project must not be {@literal null}.
|
||||
* @param ticket must not be {@literal null}.
|
||||
*/
|
||||
Ticket assignTicketToMe(Project project, Ticket ticket);
|
||||
Ticket assignTicketToMe(SupportedProject project, Ticket ticket);
|
||||
|
||||
/**
|
||||
* Assigns the release ticket for the given {@link ModuleIteration} to the current user.
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.springframework.data.release.model.Module;
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.Projects;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.data.release.utils.ExecutionUtils;
|
||||
import org.springframework.data.util.Streamable;
|
||||
@@ -50,7 +51,7 @@ import org.springframework.util.StringUtils;
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
|
||||
public class IssueTrackerCommands extends TimedCommand {
|
||||
|
||||
@NonNull PluginRegistry<IssueTracker, Project> tracker;
|
||||
@NonNull PluginRegistry<IssueTracker, SupportedProject> tracker;
|
||||
@NonNull Executor executor;
|
||||
|
||||
@CliCommand("tracker evict")
|
||||
@@ -199,13 +200,19 @@ public class IssueTrackerCommands extends TimedCommand {
|
||||
}
|
||||
|
||||
private static Streamable<ModuleIteration> withReleaseProject(TrainIteration iteration) {
|
||||
|
||||
if (iteration.isCommercial()) {
|
||||
return iteration;
|
||||
}
|
||||
|
||||
ModuleIteration bom = iteration.getModule(Projects.BOM);
|
||||
|
||||
return iteration.and(new ModuleIteration(new Module(Projects.RELEASE, bom.getVersion()), iteration));
|
||||
}
|
||||
|
||||
private IssueTracker getTrackerFor(ModuleIteration moduleIteration) {
|
||||
|
||||
return tracker.getRequiredPluginFor(moduleIteration.getProject(),
|
||||
return tracker.getRequiredPluginFor(moduleIteration.getSupportedProject(),
|
||||
() -> String.format("No issue tracker found for module %s!", moduleIteration));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,22 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.release.issues;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.client.AuthCache;
|
||||
import org.apache.http.client.CredentialsProvider;
|
||||
import org.apache.http.client.protocol.HttpClientContext;
|
||||
import org.apache.http.impl.auth.BasicScheme;
|
||||
import org.apache.http.impl.client.BasicAuthCache;
|
||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.cache.CacheManager;
|
||||
@@ -39,16 +25,11 @@ import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.release.issues.github.GitHubProperties;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.utils.HttpBasicCredentials;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.utils.HttpComponentsClientHttpRequestFactoryBuilder;
|
||||
import org.springframework.data.util.Lazy;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.client.ClientHttpRequest;
|
||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.plugin.core.OrderAwarePluginRegistry;
|
||||
import org.springframework.plugin.core.PluginRegistry;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator.Mode;
|
||||
@@ -106,8 +87,8 @@ class IssueTrackerConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
PluginRegistry<IssueTracker, Project> issueTrackers(List<? extends IssueTracker> plugins) {
|
||||
return OrderAwarePluginRegistry.of(plugins);
|
||||
PluginRegistry<IssueTracker, SupportedProject> issueTrackers(List<? extends IssueTracker> plugins) {
|
||||
return PluginRegistry.of(plugins);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
import org.springframework.plugin.core.PluginRegistry;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -40,7 +40,7 @@ public class TicketOperations {
|
||||
|
||||
Logger logger;
|
||||
|
||||
PluginRegistry<IssueTracker, Project> tracker;
|
||||
PluginRegistry<IssueTracker, SupportedProject> tracker;
|
||||
|
||||
/**
|
||||
* Create or look up ticket with a particular summary.
|
||||
@@ -65,8 +65,7 @@ public class TicketOperations {
|
||||
public Tickets getOrCreateTicketsWithSummary(ModuleIteration module, IssueTracker.TicketType ticketType,
|
||||
List<String> summaries) {
|
||||
|
||||
Project project = module.getProject();
|
||||
|
||||
SupportedProject project = module.getSupportedProject();
|
||||
IssueTracker tracker = this.tracker.getRequiredPluginFor(project);
|
||||
Tickets tickets = tracker.getTicketsFor(module);
|
||||
List<Ticket> results = new ArrayList<>();
|
||||
@@ -109,7 +108,7 @@ public class TicketOperations {
|
||||
|
||||
public void closeTickets(ModuleIteration module, Tickets tickets) {
|
||||
|
||||
IssueTracker tracker = this.tracker.getRequiredPluginFor(module.getProject());
|
||||
IssueTracker tracker = this.tracker.getRequiredPluginFor(module.getSupportedProject());
|
||||
|
||||
for (Ticket ticket : tickets) {
|
||||
tracker.closeTicket(module, ticket);
|
||||
|
||||
@@ -36,14 +36,7 @@ import org.springframework.data.release.issues.IssueTracker;
|
||||
import org.springframework.data.release.issues.Ticket;
|
||||
import org.springframework.data.release.issues.Tickets;
|
||||
import org.springframework.data.release.issues.github.GitHubWorkflows.GitHubWorkflow;
|
||||
import org.springframework.data.release.model.ArtifactVersion;
|
||||
import org.springframework.data.release.model.DocumentationMetadata;
|
||||
import org.springframework.data.release.model.Iteration;
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.Projects;
|
||||
import org.springframework.data.release.model.Tracker;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.data.release.model.*;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@@ -128,7 +121,7 @@ public class GitHub extends GitHubSupport implements IssueTracker {
|
||||
*/
|
||||
@Override
|
||||
@Cacheable("tickets")
|
||||
public Collection<Ticket> findTickets(Project project, Collection<String> ticketIds) {
|
||||
public Collection<Ticket> findTickets(SupportedProject project, Collection<String> ticketIds) {
|
||||
|
||||
String repositoryName = GitProject.of(project).getRepositoryName();
|
||||
List<Ticket> tickets = new ArrayList<>();
|
||||
@@ -173,8 +166,8 @@ public class GitHub extends GitHubSupport implements IssueTracker {
|
||||
* @see org.springframework.plugin.core.Plugin#supports(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean supports(Project project) {
|
||||
return project.uses(Tracker.GITHUB);
|
||||
public boolean supports(SupportedProject project) {
|
||||
return project.getProject().uses(Tracker.GITHUB);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -196,7 +189,7 @@ public class GitHub extends GitHubSupport implements IssueTracker {
|
||||
}
|
||||
|
||||
Tickets tickets = trainIteration.stream(). //
|
||||
filter(moduleIteration -> supports(moduleIteration.getProject())). //
|
||||
filter(moduleIteration -> supports(moduleIteration.getSupportedProject())). //
|
||||
flatMap(moduleIteration -> getTicketsFor(moduleIteration, forCurrentUser).stream()). //
|
||||
collect(Tickets.toTicketsCollector());
|
||||
|
||||
@@ -212,7 +205,7 @@ public class GitHub extends GitHubSupport implements IssueTracker {
|
||||
|
||||
Assert.notNull(moduleIteration, "ModuleIteration must not be null.");
|
||||
|
||||
String repositoryName = GitProject.of(moduleIteration.getProject()).getRepositoryName();
|
||||
String repositoryName = GitProject.of(moduleIteration).getRepositoryName();
|
||||
Optional<Milestone> milestone = findMilestone(moduleIteration);
|
||||
|
||||
if (milestone.isPresent()) {
|
||||
@@ -271,7 +264,7 @@ public class GitHub extends GitHubSupport implements IssueTracker {
|
||||
private Ticket doCreateTicket(ModuleIteration moduleIteration, String text, TicketType ticketType,
|
||||
boolean assignToCurrentUser) {
|
||||
|
||||
String repositoryName = GitProject.of(moduleIteration.getProject()).getRepositoryName();
|
||||
String repositoryName = GitProject.of(moduleIteration).getRepositoryName();
|
||||
Milestone milestone = getMilestone(moduleIteration);
|
||||
|
||||
Label label = TICKET_LABELS.get(ticketType);
|
||||
@@ -298,10 +291,10 @@ public class GitHub extends GitHubSupport implements IssueTracker {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.release.jira.IssueTracker#assignTicketToMe(org.springframework.data.release.jira.Ticket)
|
||||
* @see org.springframework.data.release.issues.IssueTracker#assignTicketToMe(org.springframework.data.release.model.SupportedProject, org.springframework.data.release.issues.Ticket)
|
||||
*/
|
||||
@Override
|
||||
public Ticket assignTicketToMe(Project project, Ticket ticket) {
|
||||
public Ticket assignTicketToMe(SupportedProject project, Ticket ticket) {
|
||||
|
||||
Assert.notNull(ticket, "Ticket must not be null.");
|
||||
|
||||
@@ -332,7 +325,7 @@ public class GitHub extends GitHubSupport implements IssueTracker {
|
||||
|
||||
Assert.notNull(module, "ModuleIteration must not be null.");
|
||||
|
||||
return assignTicketToMe(module.getProject(), getReleaseTicketFor(module));
|
||||
return assignTicketToMe(module.getSupportedProject(), getReleaseTicketFor(module));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -362,7 +355,7 @@ public class GitHub extends GitHubSupport implements IssueTracker {
|
||||
|
||||
private GitHubReadIssue close(ModuleIteration module, Ticket ticket) {
|
||||
|
||||
String repositoryName = GitProject.of(module.getProject()).getRepositoryName();
|
||||
String repositoryName = GitProject.of(module).getRepositoryName();
|
||||
|
||||
Map<String, Object> parameters = newUrlTemplateVariables();
|
||||
parameters.put("repoName", repositoryName);
|
||||
@@ -390,10 +383,10 @@ public class GitHub extends GitHubSupport implements IssueTracker {
|
||||
Optional<Milestone> milestone = milestoneCache.get(moduleIteration);
|
||||
if (milestone == null) {
|
||||
|
||||
String repositoryName = GitProject.of(moduleIteration.getProject()).getRepositoryName();
|
||||
String repositoryName = GitProject.of(moduleIteration).getRepositoryName();
|
||||
milestone = doFindMilestone(moduleIteration, repositoryName, m -> m.matches(moduleIteration));
|
||||
|
||||
if(milestone.isPresent()) {
|
||||
if (milestone.isPresent()) {
|
||||
milestoneCache.put(moduleIteration, milestone);
|
||||
}
|
||||
}
|
||||
@@ -419,12 +412,12 @@ public class GitHub extends GitHubSupport implements IssueTracker {
|
||||
milestones -> {
|
||||
|
||||
Optional<Milestone> milestone = milestones.stream(). //
|
||||
filter(milestonePredicate). //
|
||||
findFirst(). //
|
||||
map(m -> {
|
||||
logger.log(moduleIteration, "Found milestone %s.", m);
|
||||
return m;
|
||||
});
|
||||
filter(milestonePredicate). //
|
||||
findFirst(). //
|
||||
map(m -> {
|
||||
logger.log(moduleIteration, "Found milestone %s.", m);
|
||||
return m;
|
||||
});
|
||||
|
||||
if (milestone.isPresent()) {
|
||||
milestoneRef.set(milestone.get());
|
||||
@@ -460,7 +453,7 @@ public class GitHub extends GitHubSupport implements IssueTracker {
|
||||
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
|
||||
GitProject project = GitProject.of(module.getProject());
|
||||
GitProject project = GitProject.of(module);
|
||||
|
||||
findMilestone(module) //
|
||||
.filter(Milestone::isOpen) //
|
||||
@@ -496,7 +489,7 @@ public class GitHub extends GitHubSupport implements IssueTracker {
|
||||
Map<String, GitHubReadIssue> issues = getIssuesFor(moduleIteration, false, true)
|
||||
.collect(Collectors.toMap(GitHubIssue::getId, Function.identity()));
|
||||
|
||||
String repositoryName = GitProject.of(moduleIteration.getProject()).getRepositoryName();
|
||||
String repositoryName = GitProject.of(moduleIteration).getRepositoryName();
|
||||
|
||||
logger.log(moduleIteration, "Looking up GitHub issues …");
|
||||
Collection<GitHubReadIssue> foundIssues = ticketIds.stream().filter(it -> it.startsWith("#")).flatMap(it -> {
|
||||
@@ -602,23 +595,23 @@ public class GitHub extends GitHubSupport implements IssueTracker {
|
||||
private String createParticipatingModules(TrainIteration iteration) {
|
||||
|
||||
Comparator<ModuleIteration> comparator = Comparator
|
||||
.comparing(moduleIteration -> moduleIteration.getProject().getName());
|
||||
.comparing(moduleIteration -> moduleIteration.getSupportedProject().getName());
|
||||
return iteration.stream().sorted(comparator).map(module -> {
|
||||
|
||||
Tag tag = VersionTags.empty(module.getProject()).createTag(module);
|
||||
return String.format("* [Spring Data %s %s](%s%s/releases/tag/%s)%n", module.getProject().getName(),
|
||||
tag.getName(), GitServer.INSTANCE.getUri(), module.getProject().getFolderName(), tag.getName());
|
||||
return String.format("* [Spring Data %s %s](%s%s/releases/tag/%s)%n", module.getSupportedProject().getName(),
|
||||
tag.getName(), GitServer.INSTANCE.getUri(), module.getSupportedProject().getFolderName(), tag.getName());
|
||||
}).collect(Collectors.joining());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify GitHub authentication.
|
||||
*/
|
||||
public void verifyAuthentication() {
|
||||
public void verifyAuthentication(Train train) {
|
||||
|
||||
logger.log("GitHub", "Verifying GitHub Authentication…");
|
||||
|
||||
String repositoryName = GitProject.of(Projects.BUILD).getRepositoryName();
|
||||
String repositoryName = GitProject.of(train.getSupportedProject(Projects.BUILD)).getRepositoryName();
|
||||
|
||||
Map<String, Object> parameters = newUrlTemplateVariables();
|
||||
parameters.put("repoName", repositoryName);
|
||||
@@ -693,7 +686,8 @@ public class GitHub extends GitHubSupport implements IssueTracker {
|
||||
String referenceDocUrl = documentation.getReferenceDocUrl();
|
||||
String apiDocUrl = documentation.getApiDocUrl();
|
||||
|
||||
String reference = String.format("* [%s %s Reference documentation](%s)", module.getProject().getFullName(),
|
||||
String reference = String.format("* [%s %s Reference documentation](%s)",
|
||||
module.getProject().getFullName(),
|
||||
module.getVersion().toString(), referenceDocUrl);
|
||||
|
||||
String apidoc = String.format("* [%s %s Javadoc](%s)", module.getProject().getFullName(),
|
||||
@@ -704,7 +698,7 @@ public class GitHub extends GitHubSupport implements IssueTracker {
|
||||
|
||||
private void createOrUpdateRelease(ModuleIteration module, String body) {
|
||||
|
||||
String repositoryName = GitProject.of(module.getProject()).getRepositoryName();
|
||||
String repositoryName = GitProject.of(module).getRepositoryName();
|
||||
Tag tag = VersionTags.empty(module.getProject()).createTag(module);
|
||||
logger.log(module, "Looking up GitHub Release …");
|
||||
|
||||
@@ -764,7 +758,7 @@ public class GitHub extends GitHubSupport implements IssueTracker {
|
||||
private Stream<GitHubReadIssue> getIssuesFor(ModuleIteration moduleIteration, boolean forCurrentUser,
|
||||
boolean ignoreMissingMilestone) {
|
||||
|
||||
String repositoryName = GitProject.of(moduleIteration.getProject()).getRepositoryName();
|
||||
String repositoryName = GitProject.of(moduleIteration).getRepositoryName();
|
||||
|
||||
Optional<Milestone> optionalMilestone = findMilestone(moduleIteration);
|
||||
|
||||
|
||||
@@ -31,7 +31,9 @@ import org.springframework.data.release.issues.IssueTracker;
|
||||
import org.springframework.data.release.issues.TicketReference;
|
||||
import org.springframework.data.release.model.Iteration;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.model.Tracker;
|
||||
import org.springframework.data.release.model.Train;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.data.release.utils.ExecutionUtils;
|
||||
import org.springframework.plugin.core.PluginRegistry;
|
||||
@@ -48,15 +50,17 @@ import org.springframework.shell.core.annotation.CliOption;
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
|
||||
public class GitHubCommands extends TimedCommand {
|
||||
|
||||
@NonNull PluginRegistry<IssueTracker, Project> tracker;
|
||||
@NonNull PluginRegistry<IssueTracker, SupportedProject> tracker;
|
||||
@NonNull GitHub gitHub;
|
||||
@NonNull GitOperations git;
|
||||
@NonNull GitHubLabels gitHubLabels;
|
||||
@NonNull Executor executor;
|
||||
|
||||
@CliCommand(value = "github update labels")
|
||||
public void createOrUpdateLabels(@CliOption(key = "", mandatory = true) Project project) {
|
||||
gitHubLabels.createOrUpdateLabels(project);
|
||||
public void createOrUpdateLabels(
|
||||
@CliOption(key = "", mandatory = true) Project project,
|
||||
@CliOption(key = "train", mandatory = true) Train train) {
|
||||
gitHubLabels.createOrUpdateLabels(train.getSupportedProject(project));
|
||||
}
|
||||
|
||||
@CliCommand(value = "github push")
|
||||
@@ -81,9 +85,9 @@ public class GitHubCommands extends TimedCommand {
|
||||
|
||||
ExecutionUtils.run(executor, iteration, it -> {
|
||||
|
||||
if (it.getProject().getTracker() == Tracker.GITHUB) {
|
||||
if (it.getSupportedProject().getProject().getTracker() == Tracker.GITHUB) {
|
||||
|
||||
List<String> ticketReferences = git.getTicketReferencesBetween(it.getProject(), previousIteration, iteration)
|
||||
List<String> ticketReferences = git.getTicketReferencesBetween(it.getSupportedProject(), previousIteration, iteration)
|
||||
.stream().map(TicketReference::getId).collect(Collectors.toList());
|
||||
gitHub.createOrUpdateRelease(iteration, it, ticketReferences);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.data.release.git.GitProject;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@@ -63,13 +63,15 @@ public class GitHubLabels extends GitHubSupport {
|
||||
*
|
||||
* @param project the project to process.
|
||||
*/
|
||||
public void createOrUpdateLabels(Project project) {
|
||||
public void createOrUpdateLabels(SupportedProject project) {
|
||||
|
||||
logger.log(project, "Obtaining labels…");
|
||||
Map<String, Object> parameters = Collections.singletonMap("repoName", GitProject.of(project).getRepositoryName());
|
||||
|
||||
Map<String, Object> parameters = Collections.singletonMap("repoName",
|
||||
GitProject.of(project).getRepositoryName());
|
||||
|
||||
List<Label> existsOnGitHub = getLabelsFromGitHub(parameters);
|
||||
LabelConfiguration configuration = ProjectLabelConfiguration.forProject(project);
|
||||
LabelConfiguration configuration = ProjectLabelConfiguration.forProject(project.getProject());
|
||||
List<Label> newLabels = configuration.getNewLabels(existsOnGitHub);
|
||||
List<Label> existingLabels = configuration.getExistingLabels(existsOnGitHub);
|
||||
List<Label> additionalLabels = configuration.getAdditionalLabels(existsOnGitHub);
|
||||
|
||||
@@ -41,7 +41,9 @@ class GithubMilestone {
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return module.getProject().isUseShortVersionMilestones() ? module.getReleaseVersionString()
|
||||
|
||||
return module.getSupportedProject().getProject().isUseShortVersionMilestones()
|
||||
? module.getReleaseVersionString()
|
||||
: module.getMediumVersionString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,11 +37,9 @@ class Milestone {
|
||||
|
||||
public boolean matches(ModuleIteration moduleIteration) {
|
||||
|
||||
if (moduleIteration.getProject().isUseShortVersionMilestones()) {
|
||||
return title.equals(moduleIteration.getReleaseVersionString());
|
||||
}
|
||||
|
||||
return title.contains(moduleIteration.getShortVersionString());
|
||||
return moduleIteration.getSupportedProject().getProject().isUseShortVersionMilestones()
|
||||
? title.equals(moduleIteration.getReleaseVersionString())
|
||||
: title.contains(moduleIteration.getShortVersionString());
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
|
||||
@@ -39,7 +39,7 @@ public class ReleaseOperations {
|
||||
|
||||
iteration.stream().forEach(module -> {
|
||||
|
||||
boolean processed = workspace.processFile("src/main/resources/notice.txt", module.getProject(),
|
||||
boolean processed = workspace.processFile("src/main/resources/notice.txt", module.getSupportedProject(),
|
||||
(line, number) -> Optional.of(number != 0 ? line : module.toString()));
|
||||
|
||||
if (processed) {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2024 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.release.model;
|
||||
|
||||
/**
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
public interface IterationAware {
|
||||
|
||||
Iteration getIteration();
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2024 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.release.model;
|
||||
|
||||
/**
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
public interface Lifecycle extends IterationAware, SupportStatusAware {
|
||||
|
||||
default boolean isPublic() {
|
||||
|
||||
return getIteration().isPublic()
|
||||
&& getSupportStatus().isOpenSource();
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
@Value
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class Module implements VersionAware, ProjectAware, Comparable<Module> {
|
||||
public class Module implements VersionAware, Comparable<Module> {
|
||||
|
||||
Project project;
|
||||
Version version;
|
||||
|
||||
@@ -25,7 +25,7 @@ import lombok.RequiredArgsConstructor;
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
public class ModuleIteration implements IterationVersion, ProjectAware {
|
||||
public class ModuleIteration implements IterationVersion, ProjectAware, Lifecycle {
|
||||
|
||||
private final @Getter Module module;
|
||||
private final @Getter TrainIteration trainIteration;
|
||||
@@ -42,8 +42,8 @@ public class ModuleIteration implements IterationVersion, ProjectAware {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Project getProject() {
|
||||
return module.getProject();
|
||||
public SupportedProject getSupportedProject() {
|
||||
return trainIteration.getSupportedProject(module);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -152,6 +152,10 @@ public class ModuleIteration implements IterationVersion, ProjectAware {
|
||||
return result.concat(" (").concat(trainIteration.toString()).concat(")");
|
||||
}
|
||||
|
||||
public SupportStatus getSupportStatus() {
|
||||
return getTrain().getSupportStatus();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2024 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.release.model;
|
||||
|
||||
/**
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
public interface Named {
|
||||
|
||||
String getName();
|
||||
}
|
||||
@@ -35,7 +35,7 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
public class Project implements Comparable<Project> {
|
||||
public class Project implements Comparable<Project>, Named {
|
||||
|
||||
private final @Getter ProjectKey key;
|
||||
private final @Getter String name;
|
||||
@@ -125,6 +125,10 @@ public class Project implements Comparable<Project> {
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public String getProjectDescriptor() {
|
||||
return this == Projects.BUILD ? "parent/pom.xml" : "pom.xml";
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Comparable#compareTo(java.lang.Object)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2022 the original author or authors.
|
||||
* Copyright 2019-2024 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.
|
||||
@@ -19,9 +19,13 @@ package org.springframework.data.release.model;
|
||||
* An object that is aware of a {@link Project}. Typically implemented by {@link Module} or {@link ModuleIteration}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
public interface ProjectAware {
|
||||
public interface ProjectAware extends SupportStatusAware {
|
||||
|
||||
Project getProject();
|
||||
SupportedProject getSupportedProject();
|
||||
|
||||
default Project getProject() {
|
||||
return getSupportedProject().getProject();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,20 +34,40 @@ public class ReleaseTrains {
|
||||
|
||||
static {
|
||||
|
||||
CODD = codd();
|
||||
DIJKSTRA = dijkstra();
|
||||
EVANS = DIJKSTRA.next("Evans", Transition.MINOR);
|
||||
FOWLER = EVANS.next("Fowler", Transition.MINOR);
|
||||
GOSLING = FOWLER.next("Gosling", Transition.MINOR, new Module(KEY_VALUE, "1.0"));
|
||||
HOPPER = GOSLING.next("Hopper", Transition.MINOR, new Module(SOLR, "2.0"), new Module(ENVERS, "1.0"),
|
||||
new Module(NEO4J, "4.1"), new Module(COUCHBASE, "2.1"), new Module(ELASTICSEARCH, "2.0"));
|
||||
INGALLS = HOPPER.next("Ingalls", Transition.MINOR, new Module(LDAP, "1.0"));
|
||||
CODD = codd()
|
||||
.withSupportStatus(SupportStatus.EOL);
|
||||
DIJKSTRA = dijkstra()
|
||||
.withSupportStatus(SupportStatus.EOL);
|
||||
EVANS = DIJKSTRA.next("Evans", Transition.MINOR)
|
||||
.withSupportStatus(SupportStatus.EOL);
|
||||
FOWLER = EVANS.next("Fowler", Transition.MINOR)
|
||||
.withSupportStatus(SupportStatus.EOL);
|
||||
GOSLING = FOWLER.next("Gosling", Transition.MINOR,
|
||||
new Module(KEY_VALUE, "1.0"))
|
||||
.withSupportStatus(SupportStatus.EOL);
|
||||
HOPPER = GOSLING.next("Hopper", Transition.MINOR,
|
||||
new Module(SOLR, "2.0"),
|
||||
new Module(ENVERS, "1.0"),
|
||||
new Module(NEO4J, "4.1"),
|
||||
new Module(COUCHBASE, "2.1"),
|
||||
new Module(ELASTICSEARCH, "2.0"))
|
||||
.withSupportStatus(SupportStatus.EOL);
|
||||
|
||||
KAY = INGALLS.next("Kay", Transition.MAJOR, new Module(GEODE, "2.0"));
|
||||
INGALLS = HOPPER.next("Ingalls", Transition.MINOR,
|
||||
new Module(LDAP, "1.0"))
|
||||
.withSupportStatus(SupportStatus.EOL);
|
||||
|
||||
LOVELACE = KAY.next("Lovelace", Transition.MINOR, new Module(JDBC, "1.0"), new Module(SOLR, "4.0"));
|
||||
KAY = INGALLS.next("Kay", Transition.MAJOR,
|
||||
new Module(GEODE, "2.0")) //
|
||||
.withSupportStatus(SupportStatus.EOL);
|
||||
|
||||
MOORE = LOVELACE.next("Moore", Transition.MINOR);
|
||||
LOVELACE = KAY.next("Lovelace", Transition.MINOR, //
|
||||
new Module(JDBC, "1.0"), //
|
||||
new Module(SOLR, "4.0")) //
|
||||
.withSupportStatus(SupportStatus.EOL);
|
||||
|
||||
MOORE = LOVELACE.next("Moore", Transition.MINOR)
|
||||
.withSupportStatus(SupportStatus.EOL);
|
||||
|
||||
NEUMANN = MOORE.next("Neumann", Transition.MINOR, //
|
||||
new Module(COUCHBASE, "4.0"), //
|
||||
@@ -56,21 +76,28 @@ public class ReleaseTrains {
|
||||
new Module(MONGO_DB, "3.0"), //
|
||||
new Module(JDBC, "2.0"), //
|
||||
new Module(R2DBC, "1.1")) //
|
||||
.filterModules(module -> !module.getProject().getName().equalsIgnoreCase("GemFire"));
|
||||
.filterModules(module -> !module.getProject().getName().equalsIgnoreCase("GemFire"))
|
||||
.withSupportStatus(SupportStatus.EOL);
|
||||
|
||||
OCKHAM = NEUMANN.next("Ockham", Transition.MINOR, //
|
||||
new Module(BOM, "2020.0.0"), //
|
||||
new Module(NEO4J, "6.0") //
|
||||
).withIterations(Train.Iterations.DEFAULT).withCalver("2020.0");
|
||||
).withIterations(Train.Iterations.DEFAULT)
|
||||
.withCalver("2020.0") //
|
||||
.withSupportStatus(SupportStatus.EOL);
|
||||
|
||||
PASCAL = OCKHAM.next("Pascal", Transition.MINOR) //
|
||||
.filterModules(module -> !module.getProject().equals(SOLR)).withCalver("2021.0");
|
||||
.filterModules(module -> !module.getProject().equals(SOLR)) //
|
||||
.withCalver("2021.0") //
|
||||
.withSupportStatus(SupportStatus.EOL);
|
||||
|
||||
Q = PASCAL.next("Q", Transition.MINOR) //
|
||||
.withCalver("2021.1");
|
||||
.withCalver("2021.1") //
|
||||
.withSupportStatus(SupportStatus.EOL);
|
||||
|
||||
RAJ = Q.next("Raj", Transition.MINOR) //
|
||||
.withCalver("2021.2");
|
||||
.withCalver("2021.2") //
|
||||
.withSupportStatus(SupportStatus.COMMERCIAL);
|
||||
|
||||
TURING = PASCAL.next("Turing", Transition.MAJOR, //
|
||||
new Module(RELATIONAL, "3.0")) //
|
||||
@@ -78,7 +105,8 @@ public class ReleaseTrains {
|
||||
.filterModules(module -> !module.getProject().equals(ENVERS))
|
||||
.filterModules(module -> !module.getProject().equals(GEODE))
|
||||
.filterModules(module -> !module.getProject().equals(R2DBC))
|
||||
.filterModules(module -> !module.getProject().equals(JDBC)); // filter "old" JDBC without R2DBC submodule
|
||||
.filterModules(module -> !module.getProject().equals(JDBC)) // filter "old" JDBC without R2DBC submodule
|
||||
.withSupportStatus(SupportStatus.COMMERCIAL);
|
||||
|
||||
ULLMAN = TURING.next("Ullman", Transition.MINOR) //
|
||||
.withCalver("2023.0");
|
||||
@@ -157,4 +185,8 @@ public class ReleaseTrains {
|
||||
public static List<Train> trains() {
|
||||
return TRAINS;
|
||||
}
|
||||
|
||||
public static Train latest() {
|
||||
return TRAINS.get(TRAINS.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2024 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.release.model;
|
||||
|
||||
/**
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
public enum SupportStatus implements SupportStatusAware {
|
||||
|
||||
OSS, COMMERCIAL, EOL;
|
||||
|
||||
public boolean isOpenSource() {
|
||||
return this == OSS;
|
||||
}
|
||||
|
||||
public boolean isCommercial() {
|
||||
return this == COMMERCIAL;
|
||||
}
|
||||
|
||||
public boolean isEndOfLife() {
|
||||
return this == EOL;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.release.model.SupportStatusAware#getSupportStatus()
|
||||
*/
|
||||
@Override
|
||||
public SupportStatus getSupportStatus() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2024 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.release.model;
|
||||
|
||||
/**
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
public interface SupportStatusAware {
|
||||
|
||||
SupportStatus getSupportStatus();
|
||||
|
||||
default boolean isOpenSource() {
|
||||
return getSupportStatus().isOpenSource();
|
||||
}
|
||||
|
||||
default boolean isCommercial() {
|
||||
return getSupportStatus().isCommercial();
|
||||
}
|
||||
|
||||
default boolean isEndOfLife() {
|
||||
return getSupportStatus().isEndOfLife();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2024 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.release.model;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
/**
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@Value(staticConstructor = "of")
|
||||
public class SupportedProject implements Named, ProjectAware {
|
||||
|
||||
Project project;
|
||||
SupportStatus status;
|
||||
|
||||
public String getFolderName() {
|
||||
return status.name().toLowerCase() + "/" + project.getFolderName();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return project.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return project.getFullName() + " (" + status.name() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public SupportedProject getSupportedProject() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.release.model.SupportStatusAware#getSupportStatus()
|
||||
*/
|
||||
@Override
|
||||
public SupportStatus getSupportStatus() {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@ import org.springframework.util.Assert;
|
||||
@Value
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
@EqualsAndHashCode(of = "name")
|
||||
public class Train implements Streamable<Module> {
|
||||
public class Train implements Streamable<SupportedProject>, SupportStatusAware {
|
||||
|
||||
private final String name;
|
||||
private final Modules modules;
|
||||
@@ -54,7 +54,7 @@ public class Train implements Streamable<Module> {
|
||||
private @With Iterations iterations;
|
||||
private @With boolean alwaysUseBranch;
|
||||
private JavaVersion javaVersion;
|
||||
|
||||
private @With SupportStatus supportStatus;
|
||||
private @With DocumentationFormat documentationFormat;
|
||||
|
||||
public Train(String name, Module... modules) {
|
||||
@@ -63,16 +63,7 @@ public class Train implements Streamable<Module> {
|
||||
|
||||
public Train(String name, Collection<Module> modules) {
|
||||
this(name, Modules.of(modules), null, Iterations.DEFAULT, false, JavaVersion.VERSION_1_8,
|
||||
DocumentationFormat.ASCIIDOC);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Iterable#iterator()
|
||||
*/
|
||||
@Override
|
||||
public Iterator<Module> iterator() {
|
||||
return modules.iterator();
|
||||
SupportStatus.OSS, DocumentationFormat.ASCIIDOC);
|
||||
}
|
||||
|
||||
public boolean contains(Project project) {
|
||||
@@ -107,7 +98,9 @@ public class Train implements Streamable<Module> {
|
||||
|
||||
Assert.notNull(project, "Project must not be null!");
|
||||
|
||||
return modules.stream().filter(module -> module.getProject().equals(project)).findFirst();
|
||||
return modules.stream() //
|
||||
.filter(module -> module.getProject().equals(project)) //
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,12 +120,13 @@ public class Train implements Streamable<Module> {
|
||||
(it, additionalModule) -> it.hasSameProjectAs(additionalModule) ? additionalModule : it))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return new Train(name, Modules.of(modules), calver, iterations, false, javaVersion, documentationFormat);
|
||||
return new Train(name, Modules.of(modules), calver, iterations, false, javaVersion, SupportStatus.OSS,
|
||||
documentationFormat);
|
||||
}
|
||||
|
||||
public Train filterModules(Predicate<Module> filterPredicate) {
|
||||
return new Train(name, Modules.of(getModules().stream().filter(filterPredicate).collect(Collectors.toList())),
|
||||
calver, iterations, alwaysUseBranch, javaVersion, documentationFormat);
|
||||
calver, iterations, alwaysUseBranch, javaVersion, supportStatus, documentationFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,7 +187,8 @@ public class Train implements Streamable<Module> {
|
||||
|
||||
}).collect(Collectors.toSet());
|
||||
|
||||
return new Train(name, Modules.of(modules), calver, iterations, alwaysUseBranch, javaVersion, documentationFormat);
|
||||
return new Train(name, Modules.of(modules), calver, iterations, alwaysUseBranch, javaVersion, supportStatus,
|
||||
documentationFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -256,10 +251,36 @@ public class Train implements Streamable<Module> {
|
||||
return doGetTrainIteration(iteration);
|
||||
}
|
||||
|
||||
public SupportedProject getSupportedProject(Project project) {
|
||||
return SupportedProject.of(project, supportStatus);
|
||||
}
|
||||
|
||||
public SupportedProject getSupportedProject(Module module) {
|
||||
return SupportedProject.of(module.getProject(), supportStatus);
|
||||
}
|
||||
|
||||
protected TrainIteration doGetTrainIteration(Iteration iteration) {
|
||||
return new TrainIteration(this, iteration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all {@link SupportedProject} instances part of the current {@link Train}.
|
||||
*
|
||||
* @return will never be {@literal null}.
|
||||
*/
|
||||
public Streamable<SupportedProject> allProjects() {
|
||||
return modules.map(this::getSupportedProject);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Iterable#iterator()
|
||||
*/
|
||||
@Override
|
||||
public Iterator<SupportedProject> iterator() {
|
||||
return modules.map(this::getSupportedProject).iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Value object to represent a set of {@link Iteration}s.
|
||||
*
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.springframework.data.util.Streamable;
|
||||
*/
|
||||
@Value
|
||||
@RequiredArgsConstructor
|
||||
public class TrainIteration implements Streamable<ModuleIteration> {
|
||||
public class TrainIteration implements Streamable<ModuleIteration>, Lifecycle {
|
||||
|
||||
private final Train train;
|
||||
private final Iteration iteration;
|
||||
@@ -84,11 +84,19 @@ public class TrainIteration implements Streamable<ModuleIteration> {
|
||||
return getCalver().toMajorMinorBugfix();
|
||||
}
|
||||
|
||||
if (iteration.isGAIteration()) {
|
||||
return String.format("%s-RELEASE", getTrain().getName());
|
||||
}
|
||||
String trainName = getTrain().getName();
|
||||
|
||||
return String.format("%s-%s", getTrain().getName(), iteration);
|
||||
return iteration.isGAIteration()
|
||||
? String.format("%s-RELEASE", trainName)
|
||||
: String.format("%s-%s", trainName, iteration);
|
||||
}
|
||||
|
||||
public SupportedProject getSupportedProject(Project project) {
|
||||
return train.getSupportedProject(project);
|
||||
}
|
||||
|
||||
public SupportedProject getSupportedProject(Module module) {
|
||||
return train.getSupportedProject(module);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -124,4 +132,13 @@ public class TrainIteration implements Streamable<ModuleIteration> {
|
||||
|
||||
return version.toMajorMinorBugfix();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.release.model.SupportStatusAware#getSupportStatus()
|
||||
*/
|
||||
@Override
|
||||
public SupportStatus getSupportStatus() {
|
||||
return train.getSupportStatus();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ class MaintainedVersion implements Comparable<MaintainedVersion> {
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s - %s - %s", project.getName(), train.getName(), version);
|
||||
}
|
||||
|
||||
@@ -19,9 +19,7 @@ import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
@@ -29,7 +27,6 @@ import java.util.stream.Stream;
|
||||
import org.springframework.data.release.CliComponent;
|
||||
import org.springframework.data.release.TimedCommand;
|
||||
import org.springframework.data.release.git.GitOperations;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.ReleaseTrains;
|
||||
import org.springframework.data.release.model.Train;
|
||||
import org.springframework.data.release.utils.ExecutionUtils;
|
||||
@@ -63,15 +60,10 @@ class ProjectServiceCommands extends TimedCommand {
|
||||
public void updateProjectInformation(@CliOption(key = "", mandatory = true) String trainNames) {
|
||||
|
||||
List<Train> trains = Stream.of(trainNames.split(","))//
|
||||
.map(ReleaseTrains::getTrainByName) //
|
||||
.map(ReleaseTrains::getTrainByName)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// ensure we have all git repositories available
|
||||
Set<Project> affectedProjects = new HashSet<>();
|
||||
trains.stream() //
|
||||
.flatMap(Streamable::stream) //
|
||||
.forEach(it -> affectedProjects.add(it.getProject()));
|
||||
ExecutionUtils.run(executor, Streamable.of(affectedProjects), git::update);
|
||||
ExecutionUtils.run(executor, Streamable.of(trains), git::update);
|
||||
|
||||
projects.updateProjectMetadata(trains);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.springframework.data.release.git.Tag;
|
||||
import org.springframework.data.release.model.Module;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.Projects;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.model.Train;
|
||||
import org.springframework.data.release.model.Version;
|
||||
import org.springframework.data.release.utils.ExecutionUtils;
|
||||
@@ -76,7 +77,15 @@ class ProjectServiceOperations {
|
||||
|
||||
Assert.notNull(trains, "Trains must not be null!");
|
||||
|
||||
Map<Project, MaintainedVersions> versions = findVersions(trains);
|
||||
List<Train> openSourceTrains = trains.stream()
|
||||
.filter(it -> it.getSupportStatus().isOpenSource())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (openSourceTrains.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<Project, MaintainedVersions> versions = findVersions(openSourceTrains);
|
||||
|
||||
Streamable<Entry<Project, MaintainedVersions>> stream = Streamable.of(versions.entrySet()) //
|
||||
.filter(entry -> {
|
||||
@@ -118,17 +127,21 @@ class ProjectServiceOperations {
|
||||
Assert.notNull(trains, "Trains must not be null!");
|
||||
|
||||
Map<Project, MaintainedVersions> versions = ExecutionUtils.runAndReturn(executor, Streamable.of(trains), train -> {
|
||||
|
||||
return ExecutionUtils.runAndReturn(executor,
|
||||
Streamable.of(() -> train.stream().filter(module -> !TO_FILTER.contains(module.getProject()))), module -> {
|
||||
return getLatestVersion(module, train);
|
||||
});
|
||||
}).stream().flatMap(Collection::stream).flatMap(Collection::stream).collect(
|
||||
Collectors.groupingBy(MaintainedVersion::getProject, ListWrapperCollector.collectInto(MaintainedVersions::of)));
|
||||
train.getModules().filter(module -> !TO_FILTER.contains(module.getProject())),
|
||||
module -> getLatestVersion(module, train));
|
||||
|
||||
}).stream()
|
||||
.flatMap(Collection::stream)
|
||||
.flatMap(Collection::stream)
|
||||
.collect(
|
||||
Collectors.groupingBy(MaintainedVersion::getProject,
|
||||
ListWrapperCollector.collectInto(MaintainedVersions::of)));
|
||||
|
||||
// Migration because of the R2DBC merge into Spring Data Relational and project rename to Relational
|
||||
versions.put(Projects.R2DBC, MaintainedVersions.of(getR2dbcVersions(versions)));
|
||||
versions.put(Projects.RELATIONAL, MaintainedVersions.of(getRelationalVersions(versions)));
|
||||
|
||||
versions.remove(Projects.JDBC);
|
||||
|
||||
return versions;
|
||||
@@ -181,12 +194,13 @@ class ProjectServiceOperations {
|
||||
|
||||
private List<MaintainedVersion> getLatestVersion(Module module, Train train) {
|
||||
|
||||
Project project = module.getProject();
|
||||
SupportedProject project = train.getSupportedProject(module);
|
||||
|
||||
List<MaintainedVersion> version = git.getTags(project).stream()//
|
||||
.filter(tag -> matches(tag, module.getVersion())).max(Comparator.naturalOrder()) //
|
||||
.map(it -> {
|
||||
MaintainedVersion maintainedVersion = MaintainedVersion.of(module.getProject(), it.toArtifactVersion().get(),
|
||||
MaintainedVersion maintainedVersion = MaintainedVersion.of(module.getProject(),
|
||||
it.toArtifactVersion().get(),
|
||||
train, it.getCreationDate().toLocalDate(), it.getCreationDate().toLocalDate());
|
||||
return Arrays.asList(maintainedVersion, maintainedVersion.nextDevelopmentVersion());
|
||||
}) //
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
package org.springframework.data.release.utils;
|
||||
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.Named;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.model.Train;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.shell.support.logging.HandlerUtils;
|
||||
@@ -34,7 +36,11 @@ public class Logger {
|
||||
private final java.util.logging.Logger LOGGER = HandlerUtils.getLogger(getClass());
|
||||
|
||||
public void log(ModuleIteration module, Object template, Object... args) {
|
||||
log(module.getProject(), template, args);
|
||||
log(module.getSupportedProject(), template, args);
|
||||
}
|
||||
|
||||
public void log(SupportedProject project, Object template, Object... args) {
|
||||
log(project.getProject(), template, args);
|
||||
}
|
||||
|
||||
public void log(Project project, Object template, Object... args) {
|
||||
@@ -54,10 +60,10 @@ public class Logger {
|
||||
}
|
||||
|
||||
public void warn(ModuleIteration module, Object template, Object... args) {
|
||||
warn(module.getProject(), template, args);
|
||||
warn(module.getSupportedProject(), template, args);
|
||||
}
|
||||
|
||||
public void warn(Project project, Object template, Object... args) {
|
||||
public void warn(Named project, Object template, Object... args) {
|
||||
warn(project.getName(), template, args);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,11 +6,17 @@ git.gpg.keyname=300E596E
|
||||
git.gpg.passphrase=${GIT_SIGNING_KEY_PASSWORD}
|
||||
#git.gpg.executable=/usr/bin/gpg
|
||||
|
||||
deployment.username=${REPO_SPRING_IO_USR}
|
||||
deployment.password=${REPO_SPRING_IO_PSW}
|
||||
deployment.api-key=${REPO_SPRING_IO_PSW}
|
||||
# Spring OpenSource Artifactory
|
||||
deployment.opensource.username=${REPO_SPRING_IO_USR}
|
||||
deployment.opensource.password=${REPO_SPRING_IO_PSW}
|
||||
deployment.opensource.api-key=${REPO_SPRING_IO_PSW}
|
||||
deployment.settings-xml=${SETTINGS_XML}
|
||||
|
||||
# Spring Commercial Artifactory
|
||||
deployment.commercial.username=${COMMERCIAL_USR}
|
||||
deployment.commercial.password=${COMMERCIAL_PSW}
|
||||
deployment.commercial.api-key=${COMMERCIAL_PSW}
|
||||
|
||||
deployment.maven-central.stagingProfileId=${STAGING_PROFILE_ID}
|
||||
|
||||
deployment.maven-central.gpg.keyname=003C0425
|
||||
|
||||
@@ -4,13 +4,41 @@ io.logs=logs
|
||||
|
||||
# Maven setup
|
||||
maven.local-repository=~/temp/spring-data-shell/repository
|
||||
maven.plugins.versions=org.codehaus.mojo:versions-maven-plugin:2.2
|
||||
maven.plugins.versions=org.codehaus.mojo:versions-maven-plugin:2.16.2
|
||||
maven.console-logger=true
|
||||
deployment.server.uri=https://repo.spring.io
|
||||
deployment.staging-repository=libs-staging-local
|
||||
deployment.distribution-repository=temp-private-local
|
||||
deployment.username=buildmaster
|
||||
#deployment.password <- local
|
||||
|
||||
# Spring OpenSource Artifactory
|
||||
deployment.opensource.server.uri=https://repo.spring.io
|
||||
deployment.opensource.server.verification-resource=temp-private-local
|
||||
deployment.opensource.staging-repository=libs-staging-local
|
||||
deployment.opensource.target-repository=libs-milestone-local
|
||||
deployment.opensource.distribution-repository=temp-private-local
|
||||
# deployment.opensource.username <- local, for build
|
||||
# deployment.opensource.password <- local, for build
|
||||
# deployment.opensource.api-key <- local, for promotion
|
||||
|
||||
# Spring Commercial Artifactory
|
||||
# Test
|
||||
# deployment.commercial.server.uri=https://repo.spring.vmware.com
|
||||
# deployment.commercial.staging-repository=test-staging-local
|
||||
# deployment.commercial.target-repository=test-release-local
|
||||
# deployment.commercial.project=test
|
||||
# deployment.commercial.distribution-repository=
|
||||
# deployment.commercial.username <- local, for build
|
||||
# deployment.commercial.password <- local, for build
|
||||
# deployment.commercial.api-key <- local, for promotion
|
||||
|
||||
# Prod
|
||||
deployment.commercial.server.uri=https://repo.spring.vmware.com
|
||||
deployment.commercial.server.verification-resource=test-staging-local
|
||||
deployment.commercial.staging-repository=spring-commercial-staging-local
|
||||
deployment.commercial.target-repository=spring-commercial-release-local
|
||||
deployment.commercial.project=spring
|
||||
# deployment.commercial.distribution-repository=
|
||||
# deployment.commercial.username <- local, for build
|
||||
# deployment.commercial.password <- local, for build
|
||||
# deployment.commercial.api-key <- local, for promotion
|
||||
|
||||
github.team=christophstrobl,gregturn,jxblum,mp911de,odrotbohm,schauder,meistermeier,michael-simons,sothawo,daschl,mikereiche,davidkelly,sxhinzvc
|
||||
# GPG setup
|
||||
gpg.executable=/usr/local/bin/gpg2
|
||||
|
||||
@@ -26,7 +26,6 @@ import java.net.URLConnection;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.data.release.AbstractIntegrationTests;
|
||||
@@ -34,7 +33,7 @@ import org.springframework.data.release.git.GitOperations;
|
||||
import org.springframework.data.release.io.Workspace;
|
||||
import org.springframework.data.release.model.ArtifactVersion;
|
||||
import org.springframework.data.release.model.Projects;
|
||||
|
||||
import org.springframework.data.release.model.ReleaseTrains;
|
||||
import org.xmlbeam.ProjectionFactory;
|
||||
import org.xmlbeam.evaluation.XPathEvaluator;
|
||||
import org.xmlbeam.io.FileIO;
|
||||
@@ -92,7 +91,7 @@ class MavenIntegrationTests extends AbstractIntegrationTests {
|
||||
@Test
|
||||
void findsSnapshotDependencies() throws Exception {
|
||||
|
||||
File file = workspace.getFile("pom.xml", Projects.BUILD);
|
||||
File file = workspace.getFile("pom.xml", ReleaseTrains.latest().getSupportedProject(Projects.BUILD));
|
||||
|
||||
assumeThat(file).exists();
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.release.cli;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.assertj.core.api.Assumptions.*;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -24,12 +23,9 @@ import java.net.URLConnection;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.release.AbstractIntegrationTests;
|
||||
import org.springframework.data.release.git.GitOperations;
|
||||
import org.springframework.data.release.model.ReleaseTrains;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
@@ -52,12 +48,4 @@ class ReleaseCommandsIntegrationTests extends AbstractIntegrationTests {
|
||||
assumeThat(false).as("Test requires connectivity to GitHub:" + e.toString()).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void predictsReleaseTrainCorrectly() throws Exception {
|
||||
|
||||
git.update(ReleaseTrains.MOORE);
|
||||
|
||||
assertThat(releaseCommands.predictTrainAndIteration()).isEqualTo("Neumann");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,12 +26,12 @@ import java.net.URLConnection;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.release.AbstractIntegrationTests;
|
||||
import org.springframework.data.release.model.Iteration;
|
||||
import org.springframework.data.release.model.ReleaseTrains;
|
||||
import org.springframework.data.release.model.TestReleaseTrains;
|
||||
import org.springframework.data.release.model.Train;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
|
||||
/**
|
||||
@@ -41,6 +41,8 @@ import org.springframework.data.release.model.TrainIteration;
|
||||
@Disabled
|
||||
class GitOperationsIntegrationTests extends AbstractIntegrationTests {
|
||||
|
||||
private static Train LATEST = ReleaseTrains.latest();
|
||||
|
||||
@Autowired GitOperations gitOperations;
|
||||
|
||||
@BeforeAll
|
||||
@@ -66,7 +68,7 @@ class GitOperationsIntegrationTests extends AbstractIntegrationTests {
|
||||
|
||||
gitOperations.update(TestReleaseTrains.SAMPLE);
|
||||
|
||||
assertThat(gitOperations.getTags(BUILD).asList()).isNotEmpty();
|
||||
assertThat(gitOperations.getTags(LATEST.getSupportedProject(BUILD)).asList()).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -76,7 +78,7 @@ class GitOperationsIntegrationTests extends AbstractIntegrationTests {
|
||||
|
||||
@Test
|
||||
void obtainsVersionTagsForRepoThatAlsoHasOtherTags() {
|
||||
gitOperations.getTags(MONGO_DB);
|
||||
gitOperations.getTags(LATEST.getSupportedProject(MONGO_DB));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -18,9 +18,7 @@ package org.springframework.data.release.git;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.data.release.model.Module;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.Projects;
|
||||
import org.springframework.data.release.model.ReleaseTrains;
|
||||
import org.springframework.data.release.model.Train;
|
||||
@@ -38,9 +36,8 @@ class GitProjectUnitTests {
|
||||
Train codd = ReleaseTrains.CODD;
|
||||
GitServer server = new GitServer();
|
||||
Module module = codd.getModule(Projects.COMMONS);
|
||||
Project project = module.getProject();
|
||||
|
||||
GitProject gitProject = new GitProject(project, server);
|
||||
GitProject gitProject = GitProject.of(codd.getSupportedProject(module));
|
||||
|
||||
String projectUri = gitProject.getProjectUri();
|
||||
|
||||
|
||||
@@ -26,13 +26,13 @@ import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.release.AbstractIntegrationTests;
|
||||
import org.springframework.data.release.git.GitOperations;
|
||||
import org.springframework.data.release.model.Iteration;
|
||||
import org.springframework.data.release.model.Projects;
|
||||
import org.springframework.data.release.model.ReleaseTrains;
|
||||
import org.springframework.data.release.model.Train;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link DependencyOperations}.
|
||||
@@ -42,6 +42,8 @@ import org.springframework.data.release.model.ReleaseTrains;
|
||||
@Disabled
|
||||
class DependencyOperationsIntegrationTests extends AbstractIntegrationTests {
|
||||
|
||||
private static final Train LATEST = ReleaseTrains.latest();
|
||||
|
||||
@Autowired GitOperations git;
|
||||
@Autowired DependencyOperations operations;
|
||||
|
||||
@@ -69,19 +71,22 @@ class DependencyOperationsIntegrationTests extends AbstractIntegrationTests {
|
||||
|
||||
@Test
|
||||
void shouldReportExistingDependencyVersions() {
|
||||
assertThat(operations.getCurrentDependencies(Projects.BUILD).isEmpty()).isFalse();
|
||||
assertThat(operations.getCurrentDependencies(LATEST.getSupportedProject(Projects.BUILD)).isEmpty()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReportExistingOptionalDependencies() {
|
||||
|
||||
assertThat(operations.getCurrentDependencies(Projects.CASSANDRA).getVersions()).hasSize(1);
|
||||
assertThat(operations.getCurrentDependencies(Projects.MONGO_DB).getVersions()).hasSize(2);
|
||||
assertThat(operations.getCurrentDependencies(Projects.NEO4J).getVersions()).hasSize(1);
|
||||
assertThat(operations.getCurrentDependencies(LATEST.getSupportedProject(Projects.CASSANDRA)).getVersions())
|
||||
.hasSize(1);
|
||||
assertThat(operations.getCurrentDependencies(LATEST.getSupportedProject(Projects.MONGO_DB)).getVersions())
|
||||
.hasSize(2);
|
||||
assertThat(operations.getCurrentDependencies(LATEST.getSupportedProject(Projects.NEO4J)).getVersions()).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUpgradeProposals() {
|
||||
System.out.println(operations.getDependencyUpgradeProposals(Projects.BUILD, Iteration.M1));
|
||||
System.out
|
||||
.println(operations.getDependencyUpgradeProposals(LATEST.getSupportedProject(Projects.BUILD), Iteration.M1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import java.util.Collections;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.release.AbstractIntegrationTests;
|
||||
import org.springframework.data.release.WireMockExtension;
|
||||
@@ -35,6 +34,7 @@ import org.springframework.data.release.model.Iteration;
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.Projects;
|
||||
import org.springframework.data.release.model.ReleaseTrains;
|
||||
import org.springframework.data.release.model.Train;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.util.UriComponents;
|
||||
@@ -55,6 +55,7 @@ class GitHubIssueTrackerIntegrationTests extends AbstractIntegrationTests {
|
||||
static final String MILESTONES_URI = "/repos/spring-projects/spring-data-build/milestones";
|
||||
static final ModuleIteration BUILD_HOPPER_RC1 = ReleaseTrains.HOPPER.getModuleIteration(Projects.BUILD,
|
||||
Iteration.RC1);
|
||||
static final Train LATEST = ReleaseTrains.latest();
|
||||
|
||||
@RegisterExtension WireMockExtension mockService = new WireMockExtension(
|
||||
wireMockConfig().port(8888).fileSource(new ClasspathFileSource("integration/github")));
|
||||
@@ -76,21 +77,25 @@ class GitHubIssueTrackerIntegrationTests extends AbstractIntegrationTests {
|
||||
|
||||
mockGetIssueWith("issue.json", 233);
|
||||
|
||||
Collection<Ticket> tickets = github.findTickets(Projects.BUILD, Collections.singletonList("233"));
|
||||
Collection<Ticket> tickets = github.findTickets(LATEST.getSupportedProject(Projects.BUILD),
|
||||
Collections.singletonList("233"));
|
||||
|
||||
assertThat(tickets).hasSize(1);
|
||||
}
|
||||
|
||||
@Test // #5
|
||||
void ignoresUnknownTicketsByTicketId() {
|
||||
|
||||
Collection<Ticket> tickets = github.findTickets(Projects.BUILD, Collections.singletonList("123"));
|
||||
Collection<Ticket> tickets = github.findTickets(LATEST.getSupportedProject(Projects.BUILD),
|
||||
Collections.singletonList("123"));
|
||||
assertThat(tickets).isEmpty();
|
||||
}
|
||||
|
||||
@Test // #5
|
||||
void emptyResultWithEmptyTicketIds() {
|
||||
|
||||
Collection<Ticket> tickets = github.findTickets(Projects.COMMONS, Collections.emptyList());
|
||||
Collection<Ticket> tickets = github.findTickets(LATEST.getSupportedProject(Projects.COMMONS),
|
||||
Collections.emptyList());
|
||||
assertThat(tickets).isEmpty();
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.release.AbstractIntegrationTests;
|
||||
import org.springframework.data.release.git.GitOperations;
|
||||
@@ -30,9 +29,9 @@ import org.springframework.data.release.issues.IssueTracker;
|
||||
import org.springframework.data.release.issues.TicketReference;
|
||||
import org.springframework.data.release.issues.Tickets;
|
||||
import org.springframework.data.release.model.Iteration;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.Projects;
|
||||
import org.springframework.data.release.model.ReleaseTrains;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.plugin.core.PluginRegistry;
|
||||
|
||||
@@ -44,7 +43,7 @@ import org.springframework.plugin.core.PluginRegistry;
|
||||
@Disabled("Requires changes to application-test.properties to enable remote GitHub/Jira access")
|
||||
class ReleaseOperationsIntegrationTests extends AbstractIntegrationTests {
|
||||
|
||||
@Autowired PluginRegistry<IssueTracker, Project> trackers;
|
||||
@Autowired PluginRegistry<IssueTracker, SupportedProject> trackers;
|
||||
|
||||
@Autowired GitOperations gitOperations;
|
||||
|
||||
@@ -54,8 +53,10 @@ class ReleaseOperationsIntegrationTests extends AbstractIntegrationTests {
|
||||
TrainIteration from = ReleaseTrains.OCKHAM.getIteration(Iteration.M1);
|
||||
TrainIteration to = ReleaseTrains.OCKHAM.getIteration(Iteration.M2);
|
||||
|
||||
List<TicketReference> ticketReferences = gitOperations.getTicketReferencesBetween(Projects.MONGO_DB, from, to);
|
||||
IssueTracker tracker = trackers.getRequiredPluginFor(Projects.MONGO_DB);
|
||||
SupportedProject project = from.getSupportedProject(Projects.MONGO_DB);
|
||||
|
||||
List<TicketReference> ticketReferences = gitOperations.getTicketReferencesBetween(project, from, to);
|
||||
IssueTracker tracker = trackers.getRequiredPluginFor(project);
|
||||
|
||||
Tickets tickets = tracker.findTickets(to.getModule(Projects.MONGO_DB),
|
||||
ticketReferences.stream().map(TicketReference::getId).collect(Collectors.toList()));
|
||||
@@ -69,8 +70,10 @@ class ReleaseOperationsIntegrationTests extends AbstractIntegrationTests {
|
||||
TrainIteration from = ReleaseTrains.OCKHAM.getIteration(Iteration.M1);
|
||||
TrainIteration to = ReleaseTrains.OCKHAM.getIteration(Iteration.M2);
|
||||
|
||||
List<TicketReference> ticketReferences = gitOperations.getTicketReferencesBetween(Projects.R2DBC, from, to);
|
||||
IssueTracker tracker = trackers.getRequiredPluginFor(Projects.R2DBC);
|
||||
SupportedProject project = from.getSupportedProject(Projects.R2DBC);
|
||||
|
||||
List<TicketReference> ticketReferences = gitOperations.getTicketReferencesBetween(project, from, to);
|
||||
IssueTracker tracker = trackers.getRequiredPluginFor(project);
|
||||
|
||||
Tickets tickets = tracker.findTickets(to.getModule(Projects.R2DBC),
|
||||
ticketReferences.stream().map(TicketReference::getId).collect(Collectors.toList()));
|
||||
|
||||
Reference in New Issue
Block a user