Refactoring to batch (#181)

The rationale of this pull request is to

* have more maintainable and granular code
* not maintain the custom made job engine
* allow the users to customize the defaults of the releaser more easy
* allow the users to create their own steps without the need to change any existing code
* allow the users to fully change the flows and tasks logic
* abstract underlying batch mechanism (Spring Batch) so it doesn't leak to production code
* allow parallelization of the release process and release tasks
This commit is contained in:
Marcin Grzejszczak
2019-12-23 13:49:58 +01:00
committed by GitHub
parent ea85372e05
commit 8992e45321
2130 changed files with 12441 additions and 6429 deletions

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2013-2019 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 releaser.cloud.buildsystem;
/**
* @author Marcin Grzejszczak
*/
final class SpringCloudBomConstants {
// boot
static final String SPRING_BOOT = "spring-boot";
static final String BOOT_STARTER_ARTIFACT_ID = "spring-boot-starter";
static final String BOOT_STARTER_PARENT_ARTIFACT_ID = BOOT_STARTER_ARTIFACT_ID
+ "-parent";
static final String BOOT_DEPENDENCIES_ARTIFACT_ID = "spring-boot-dependencies";
// sc-build
static final String CLOUD_DEPENDENCIES_PARENT_ARTIFACT_ID = "spring-cloud-dependencies-parent";
static final String BUILD_ARTIFACT_ID = "spring-cloud-build";
// sc-release
static final String CLOUD_DEPENDENCIES_ARTIFACT_ID = "spring-cloud-dependencies";
static final String CLOUD_ARTIFACT_ID = "spring-cloud";
static final String CLOUD_RELEASE_ARTIFACT_ID = "spring-cloud-release";
static final String CLOUD_STARTER_ARTIFACT_ID = "spring-cloud-starter";
static final String CLOUD_STARTER_PARENT_ARTIFACT_ID = "spring-cloud-starter-parent";
private SpringCloudBomConstants() {
throw new IllegalStateException("Don't instantiate a utility class");
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2013-2019 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 releaser.cloud.buildsystem;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
class SpringCloudBuildsystemConfiguration {
@Bean
SpringCloudMavenBomParser springCloudMavenBomParser() {
return new SpringCloudMavenBomParser();
}
}

View File

@@ -0,0 +1,202 @@
/*
* Copyright 2013-2019 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 releaser.cloud.buildsystem;
import java.io.File;
import java.util.LinkedHashSet;
import java.util.Set;
import org.apache.maven.model.Model;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import releaser.internal.ReleaserProperties;
import releaser.internal.buildsystem.CustomBomParser;
import releaser.internal.buildsystem.VersionsFromBom;
import releaser.internal.buildsystem.VersionsFromBomBuilder;
import releaser.internal.project.Project;
import releaser.internal.tech.PomReader;
import org.springframework.util.StringUtils;
import static releaser.cloud.buildsystem.SpringCloudBomConstants.BOOT_DEPENDENCIES_ARTIFACT_ID;
import static releaser.cloud.buildsystem.SpringCloudBomConstants.BOOT_STARTER_ARTIFACT_ID;
import static releaser.cloud.buildsystem.SpringCloudBomConstants.BOOT_STARTER_PARENT_ARTIFACT_ID;
import static releaser.cloud.buildsystem.SpringCloudBomConstants.BUILD_ARTIFACT_ID;
import static releaser.cloud.buildsystem.SpringCloudBomConstants.CLOUD_ARTIFACT_ID;
import static releaser.cloud.buildsystem.SpringCloudBomConstants.CLOUD_DEPENDENCIES_ARTIFACT_ID;
import static releaser.cloud.buildsystem.SpringCloudBomConstants.CLOUD_DEPENDENCIES_PARENT_ARTIFACT_ID;
import static releaser.cloud.buildsystem.SpringCloudBomConstants.CLOUD_RELEASE_ARTIFACT_ID;
import static releaser.cloud.buildsystem.SpringCloudBomConstants.CLOUD_STARTER_ARTIFACT_ID;
import static releaser.cloud.buildsystem.SpringCloudBomConstants.CLOUD_STARTER_PARENT_ARTIFACT_ID;
import static releaser.cloud.buildsystem.SpringCloudBomConstants.SPRING_BOOT;
class SpringCloudMavenBomParser implements CustomBomParser {
private static final Logger log = LoggerFactory
.getLogger(SpringCloudMavenBomParser.class);
@Override
public VersionsFromBom parseBom(File root, ReleaserProperties properties) {
VersionsFromBom springCloudBuild = springCloudBuild(root, properties);
VersionsFromBom boot = bootVersion(root, properties);
log.debug("Added Spring Cloud Build [{}] and boot versions [{}]",
springCloudBuild, boot);
return new VersionsFromBomBuilder().thisProjectRoot(root)
.releaserProperties(properties).projects(springCloudBuild, boot).merged();
}
private VersionsFromBom springCloudBuild(File root, ReleaserProperties properties) {
String buildVersion = buildVersion(root, properties);
if (StringUtils.isEmpty(buildVersion)) {
return VersionsFromBom.EMPTY_VERSION;
}
VersionsFromBom scBuild = new VersionsFromBomBuilder().thisProjectRoot(root)
.releaserProperties(properties).merged();
scBuild.add(BUILD_ARTIFACT_ID, buildVersion);
scBuild.add(CLOUD_DEPENDENCIES_PARENT_ARTIFACT_ID, buildVersion);
return scBuild;
}
private String buildVersion(File root, ReleaserProperties properties) {
String buildVersion = properties.getFixedVersions().get(BUILD_ARTIFACT_ID);
if (StringUtils.hasText(buildVersion)) {
return buildVersion;
}
File pom = new File(root, properties.getPom().getThisTrainBom());
if (!pom.exists()) {
return "";
}
Model model = PomReader.pom(root, properties.getPom().getThisTrainBom());
String buildArtifact = model.getParent().getArtifactId();
log.debug("[{}] artifact id is equal to [{}]",
CLOUD_DEPENDENCIES_PARENT_ARTIFACT_ID, buildArtifact);
if (!CLOUD_DEPENDENCIES_PARENT_ARTIFACT_ID.equals(buildArtifact)) {
throw new IllegalStateException(
"The pom doesn't have a [spring-cloud-dependencies-parent] artifact id");
}
buildVersion = model.getParent().getVersion();
log.debug("Spring Cloud Build version is equal to [{}]", buildVersion);
return buildVersion;
}
private String boot(File root, ReleaserProperties properties) {
String bootVersion = properties.getFixedVersions().get(SPRING_BOOT);
if (StringUtils.hasText(bootVersion)) {
return bootVersion;
}
String pomWithBootStarterParent = properties.getPom()
.getPomWithBootStarterParent();
File pom = new File(root, pomWithBootStarterParent);
if (!pom.exists()) {
return "";
}
Model model = PomReader.pom(root, pomWithBootStarterParent);
if (model == null) {
return "";
}
String bootArtifactId = model.getParent().getArtifactId();
log.debug("Boot artifact id is equal to [{}]", bootArtifactId);
if (!BOOT_STARTER_PARENT_ARTIFACT_ID.equals(bootArtifactId)) {
if (log.isDebugEnabled()) {
throw new IllegalStateException("The pom doesn't have a ["
+ BOOT_STARTER_PARENT_ARTIFACT_ID + "] artifact id");
}
return "";
}
return model.getParent().getVersion();
}
VersionsFromBom bootVersion(File root, ReleaserProperties properties) {
String bootVersion = boot(root, properties);
if (StringUtils.isEmpty(bootVersion)) {
return VersionsFromBom.EMPTY_VERSION;
}
log.debug("Boot version is equal to [{}]", bootVersion);
VersionsFromBom versionsFromBom = new VersionsFromBomBuilder()
.thisProjectRoot(root).releaserProperties(properties).merged();
versionsFromBom.add(SPRING_BOOT, bootVersion);
versionsFromBom.add(BOOT_STARTER_PARENT_ARTIFACT_ID, bootVersion);
versionsFromBom.add(BOOT_DEPENDENCIES_ARTIFACT_ID, bootVersion);
return versionsFromBom;
}
@Override
public Set<Project> setVersion(Set<Project> projects, String projectName,
String version) {
Set<Project> newProjects = new LinkedHashSet<>(projects);
switch (projectName) {
case SPRING_BOOT:
case BOOT_STARTER_ARTIFACT_ID:
case BOOT_STARTER_PARENT_ARTIFACT_ID:
case BOOT_DEPENDENCIES_ARTIFACT_ID:
updateBootVersions(newProjects, version);
break;
case BUILD_ARTIFACT_ID:
case CLOUD_DEPENDENCIES_PARENT_ARTIFACT_ID:
updateBuildVersions(newProjects, version);
break;
case CLOUD_ARTIFACT_ID:
case CLOUD_DEPENDENCIES_ARTIFACT_ID:
case CLOUD_RELEASE_ARTIFACT_ID:
case CLOUD_STARTER_ARTIFACT_ID:
case CLOUD_STARTER_PARENT_ARTIFACT_ID:
updateSpringCloudVersions(newProjects, version);
break;
}
return newProjects;
}
private void updateBootVersions(Set<Project> newProjects, String version) {
remove(newProjects, SPRING_BOOT);
remove(newProjects, BOOT_STARTER_ARTIFACT_ID);
remove(newProjects, BOOT_STARTER_PARENT_ARTIFACT_ID);
remove(newProjects, BOOT_DEPENDENCIES_ARTIFACT_ID);
add(newProjects, SPRING_BOOT, version);
add(newProjects, BOOT_STARTER_ARTIFACT_ID, version);
add(newProjects, BOOT_STARTER_PARENT_ARTIFACT_ID, version);
add(newProjects, BOOT_DEPENDENCIES_ARTIFACT_ID, version);
}
private void updateBuildVersions(Set<Project> newProjects, String version) {
remove(newProjects, BUILD_ARTIFACT_ID);
remove(newProjects, CLOUD_DEPENDENCIES_PARENT_ARTIFACT_ID);
add(newProjects, BUILD_ARTIFACT_ID, version);
add(newProjects, CLOUD_DEPENDENCIES_PARENT_ARTIFACT_ID, version);
}
private void updateSpringCloudVersions(Set<Project> newProjects, String version) {
remove(newProjects, CLOUD_DEPENDENCIES_ARTIFACT_ID);
remove(newProjects, CLOUD_ARTIFACT_ID);
remove(newProjects, CLOUD_RELEASE_ARTIFACT_ID);
remove(newProjects, CLOUD_STARTER_ARTIFACT_ID);
remove(newProjects, CLOUD_STARTER_PARENT_ARTIFACT_ID);
add(newProjects, CLOUD_DEPENDENCIES_ARTIFACT_ID, version);
add(newProjects, CLOUD_ARTIFACT_ID, version);
add(newProjects, CLOUD_RELEASE_ARTIFACT_ID, version);
add(newProjects, CLOUD_STARTER_ARTIFACT_ID, version);
add(newProjects, CLOUD_STARTER_PARENT_ARTIFACT_ID, version);
}
private void add(Set<Project> projects, String key, String value) {
projects.add(new Project(key, value));
}
private void remove(Set<Project> projects, String expectedProjectName) {
projects.removeIf(project -> expectedProjectName.equals(project.name));
}
}

View File

@@ -0,0 +1,223 @@
/*
* Copyright 2013-2019 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 releaser.cloud.docs;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import releaser.internal.ReleaserProperties;
import releaser.internal.docs.CustomProjectDocumentationUpdater;
import releaser.internal.git.ProjectGitHandler;
import releaser.internal.project.ProjectVersion;
import releaser.internal.project.Projects;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.StringUtils;
/**
* @author Marcin Grzejszczak
*/
class SpringCloudCustomProjectDocumentationUpdater
implements CustomProjectDocumentationUpdater {
private static final Logger log = LoggerFactory
.getLogger(SpringCloudCustomProjectDocumentationUpdater.class);
private final ProjectGitHandler gitHandler;
private final ReleaserProperties releaserProperties;
SpringCloudCustomProjectDocumentationUpdater(ProjectGitHandler gitHandler,
ReleaserProperties releaserProperties) {
this.gitHandler = gitHandler;
this.releaserProperties = releaserProperties;
}
/**
* Updates the documentation repository if current release train version is greater or
* equal than the one stored in the repo.
* @param currentProject project to update the docs repo for
* @param bomBranch the bom project branch
* @return {@link File cloned temporary directory} - {@code null} if wrong version is
* used
*/
@Override
public File updateDocsRepoForReleaseTrain(File clonedDocumentationProject,
ProjectVersion currentProject, Projects projects, String bomBranch) {
log.debug("Cloning the doc project to [{}]", clonedDocumentationProject);
ProjectVersion releaseTrainProject = new ProjectVersion(
this.releaserProperties.getMetaRelease().getReleaseTrainProjectName(),
branchToReleaseVersion(bomBranch));
File currentReleaseFolder = new File(clonedDocumentationProject, currentFolder(
releaseTrainProject.projectName, releaseTrainProject.version));
// remove the old way
removeAFolderWithRedirection(currentReleaseFolder);
File docsRepo = updateTheDocsRepo(releaseTrainProject, clonedDocumentationProject,
currentReleaseFolder);
return pushChanges(docsRepo);
}
/**
* Updates the documentation repository if current release train version is greater or
* equal than the one stored in the repo.
* @param currentProject project to update the docs repo for
* @return {@link File cloned temporary directory} - {@code null} if wrong version is
* used
*/
@Override
public File updateDocsRepoForSingleProject(File clonedDocumentationProject,
ProjectVersion currentProject, Projects projects) {
if (!projects.containsProject(currentProject.projectName)) {
log.warn(
"Can't update the documentation repo for project [{}] cause it's not present on the projects list {}",
currentProject.projectName, projects);
return clonedDocumentationProject;
}
log.info("Updating link to documentation for project [{}]",
currentProject.projectName);
ProjectVersion projectVersion = projects.forName(currentProject.projectName);
File currentProjectReleaseFolder = new File(clonedDocumentationProject,
currentFolder(projectVersion.projectName, projectVersion.version));
removeAFolderWithRedirection(currentProjectReleaseFolder);
try {
updateTheDocsRepo(projectVersion, clonedDocumentationProject,
currentProjectReleaseFolder);
log.info("Processed [{}] for project with name [{}]",
currentProjectReleaseFolder, projectVersion.projectName);
}
catch (Exception ex) {
log.warn("Exception occurred while trying o update the symlink of a project ["
+ projectVersion.projectName + "]", ex);
}
return pushChanges(clonedDocumentationProject);
}
private void removeAFolderWithRedirection(File currentReleaseFolder) {
if (!isSymbolinkLink(currentReleaseFolder)) {
FileSystemUtils.deleteRecursively(currentReleaseFolder);
}
}
private boolean isSymbolinkLink(File currentFolder) {
return Files.isSymbolicLink(currentFolder.toPath());
}
private String currentFolder(String projectName, String projectVersion) {
boolean releaseTrain = new ProjectVersion(projectName, projectVersion)
.isReleaseTrain();
// release train -> static/current
// project -> static/spring-cloud-sleuth/current
return releaseTrain ? "current"
: (StringUtils.hasText(projectName) ? projectName : "") + "/current";
}
String linkToVersion(File file) {
if (Files.isSymbolicLink(file.toPath())) {
try {
Path path = Files.readSymbolicLink(file.toPath());
// current -> Hoxton.SR2
// spring-cloud-sleuth/current -> spring-cloud-sleuth/1.2.3.RELEASE
return folderName(path.toString());
}
catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
return "";
}
private String folderName(String path) {
int last = path.lastIndexOf(File.separator);
return last > 0 ? path.substring(last + 1) : path;
}
private String concreteVersionFolder(ProjectVersion projectVersion) {
String projectName = projectVersion.projectName;
boolean releaseTrain = projectVersion.isReleaseTrain();
// release train -> static/Hoxton.SR2/
// project -> static/spring-cloud-sleuth/1.2.3.RELEASE/
String prefix = releaseTrain ? projectVersion.version
: (projectName + "/" + projectVersion.version);
return prefix + "/";
}
private File pushChanges(File docsRepo) {
this.gitHandler.pushCurrentBranch(docsRepo);
log.info("Committed and pushed changes to the documentation project");
return docsRepo;
}
private File updateTheDocsRepo(ProjectVersion projectVersion,
File documentationProject, File currentVersionFolder) {
try {
String storedVersion = linkToVersion(currentVersionFolder);
String currentVersion = projectVersion.version;
boolean newerVersion = StringUtils.isEmpty(storedVersion)
|| isMoreMature(storedVersion, currentVersion);
if (!newerVersion) {
log.info("Current version [{}] is not newer than the stored one [{}]",
currentVersion, storedVersion);
return documentationProject;
}
boolean deleted = Files.deleteIfExists(currentVersionFolder.toPath())
|| FileSystemUtils.deleteRecursively(currentVersionFolder.toPath());
if (deleted) {
log.info("Deleted current version folder link at [{}]",
currentVersionFolder);
}
boolean creatingParentDirs = currentVersionFolder.getParentFile().mkdirs();
if (!creatingParentDirs) {
log.warn("Failed to create parent directory of [{}]",
currentVersionFolder);
}
File newTarget = new File(projectVersion.version);
Files.createSymbolicLink(currentVersionFolder.toPath(), newTarget.toPath());
log.info("Updated the link [{}] to point to [{}]",
currentVersionFolder.toPath(),
Files.readSymbolicLink(currentVersionFolder.toPath()));
return commitChanges(currentVersion, documentationProject);
}
catch (IOException e) {
throw new IllegalStateException(e);
}
}
private boolean isMoreMature(String storedVersion, String currentVersion) {
return new ProjectVersion("project", currentVersion)
.isMoreMature(new ProjectVersion("project", storedVersion));
}
private String branchToReleaseVersion(String branch) {
if (branch.startsWith("v")) {
return branch.substring(1);
}
return branch;
}
private File commitChanges(String currentVersion, File documentationProject)
throws IOException {
log.info("Updated the symbolic links");
this.gitHandler.commit(documentationProject,
"Updating the link to the current version to [" + currentVersion + "]");
return documentationProject;
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2013-2019 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 releaser.cloud.docs;
import releaser.internal.ReleaserProperties;
import releaser.internal.git.ProjectGitHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
class SpringCloudDocsConfiguration {
@Bean
SpringCloudCustomProjectDocumentationUpdater springCloudCustomProjectDocumentationUpdater(
ProjectGitHandler handler, ReleaserProperties releaserProperties) {
return new SpringCloudCustomProjectDocumentationUpdater(handler,
releaserProperties);
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2013-2019 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 releaser.cloud.github;
import releaser.internal.ReleaserProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
class SpringCloudGithubConfiguration {
@Bean
SpringCloudGithubIssues springCloudGithubIssues(
ReleaserProperties releaserProperties) {
return new SpringCloudGithubIssues(releaserProperties);
}
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright 2013-2019 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 releaser.cloud.github;
import com.jcabi.github.Github;
import releaser.internal.ReleaserProperties;
import releaser.internal.github.CustomGithubIssues;
import releaser.internal.github.GithubIssueFiler;
import releaser.internal.project.ProjectVersion;
import releaser.internal.project.Projects;
import org.springframework.util.StringUtils;
class SpringCloudGithubIssues implements CustomGithubIssues {
private static final String GITHUB_ISSUE_TITLE = "Upgrade to Spring Cloud %s";
private final GithubIssueFiler githubIssueFiler;
private final ReleaserProperties properties;
SpringCloudGithubIssues(ReleaserProperties properties) {
this.githubIssueFiler = new GithubIssueFiler(properties);
this.properties = properties;
}
SpringCloudGithubIssues(Github github, ReleaserProperties properties) {
this.githubIssueFiler = new GithubIssueFiler(github, properties);
this.properties = properties;
}
@Override
public void fileIssueInSpringGuides(Projects projects, ProjectVersion version) {
String user = "spring-guides";
String repo = "getting-started-guides";
this.githubIssueFiler.fileAGitHubIssue(user, repo, version, issueTitle(),
guidesIssueText(projects));
}
@Override
public void fileIssueInStartSpringIo(Projects projects, ProjectVersion version) {
String user = "spring-io";
String repo = "start.spring.io";
this.githubIssueFiler.fileAGitHubIssue(user, repo, version, issueTitle(),
startSpringIoIssueText(projects));
}
private String issueTitle() {
return String.format(GITHUB_ISSUE_TITLE, StringUtils.capitalize(parsedVersion()));
}
private String parsedVersion() {
String version = this.properties.getPom().getBranch();
if (version.startsWith("v")) {
return version.substring(1);
}
return version;
}
private String startSpringIoIssueText(Projects projects) {
String springBootVersion = projects.containsProject("spring-boot")
? projects.forName("spring-boot").version : "";
return "Release train ["
+ this.properties.getMetaRelease().getReleaseTrainProjectName()
+ "] in version [" + parsedVersion()
+ "] released with the Spring Boot version [`" + springBootVersion + "`]";
}
private String guidesIssueText(Projects projects) {
StringBuilder builder = new StringBuilder().append("Release train [")
.append(this.properties.getMetaRelease().getReleaseTrainProjectName())
.append("] in version [").append(parsedVersion())
.append("] released with the following projects:").append("\n\n");
projects.forEach(project -> builder.append(project.projectName).append(" : ")
.append("`").append(project.version).append("`").append("\n"));
return builder.toString();
}
}