Simplifying redirects for Spring Cloud docs

fixes gh-165
This commit is contained in:
Marcin Grzejszczak
2019-11-15 12:31:36 +01:00
parent 91215186ed
commit 10eeaf1b11
20 changed files with 456 additions and 1065 deletions

View File

@@ -18,6 +18,15 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<jsch-agent.version>0.0.9</jsch-agent.version>
<hibernate-validator.version>5.4.1.Final</hibernate-validator.version>
<org.eclipse.jgit.version>4.6.0.201612231935-r</org.eclipse.jgit.version>
<maven-model.version>2.2.1</maven-model.version>
<versions-maven-plugin.version>2.3</versions-maven-plugin.version>
<handlebars.version>4.0.6</handlebars.version>
<initializr-metadata.version>0.8.0.BUILD-SNAPSHOT</initializr-metadata.version>
<awaitility.version>3.1.6</awaitility.version>
<sagan-site.version>1.0.0.BUILD-SNAPSHOT</sagan-site.version>
<javax.json.version>1.0.4</javax.json.version>
</properties>
<dependencies>
@@ -37,12 +46,12 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
<version>${hibernate-validator.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>4.6.0.201612231935-r</version>
<version>${org.eclipse.jgit.version}</version>
</dependency>
<!-- a proxy to ssh-agent and Pageant in Java -->
<dependency>
@@ -65,12 +74,12 @@
<artifactId>maven-model</artifactId>
<!--<version>3.3.9</version>-->
<!-- Versions plugin uses this version -->
<version>2.2.1</version>
<version>${maven-model.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.3</version>
<version>${versions-maven-plugin.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
@@ -94,12 +103,12 @@
<dependency>
<groupId>com.github.jknack</groupId>
<artifactId>handlebars</artifactId>
<version>4.0.6</version>
<version>${handlebars.version}</version>
</dependency>
<dependency>
<groupId>io.spring.initializr</groupId>
<artifactId>initializr-metadata</artifactId>
<version>0.8.0.BUILD-SNAPSHOT</version>
<version>${initializr-metadata.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
@@ -114,7 +123,7 @@
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>3.1.6</version>
<version>${awaitility.version}</version>
<scope>test</scope>
</dependency>
@@ -122,7 +131,7 @@
<groupId>sagan</groupId>
<artifactId>sagan-site</artifactId>
<classifier>stubs</classifier>
<version>1.0.0.BUILD-SNAPSHOT</version>
<version>${sagan-site.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
@@ -134,7 +143,7 @@
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
<version>${javax.json.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>

View File

@@ -18,14 +18,19 @@ package org.springframework.cloud.release.cloud.docs;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.release.internal.docs.CustomProjectDocumentationUpdater;
import org.springframework.cloud.release.internal.git.ProjectGitHandler;
import org.springframework.cloud.release.internal.project.ProjectVersion;
import org.springframework.cloud.release.internal.project.Projects;
import org.springframework.util.StringUtils;
/**
* @author Marcin Grzejszczak
@@ -37,6 +42,10 @@ class SpringCloudCustomProjectDocumentationUpdater
private static final String HTTPS_SC_STATIC_URL = "https://cloud.spring.io/spring-cloud-static/";
public static final String NO_PROJECT_NAME = "";
private byte[] indexHtmlTemplate;
private static final Logger log = LoggerFactory
.getLogger(SpringCloudCustomProjectDocumentationUpdater.class);
@@ -63,71 +72,140 @@ class SpringCloudCustomProjectDocumentationUpdater
*/
@Override
public File updateDocsRepo(File clonedDocumentationProject,
ProjectVersion currentProject, String bomBranch) {
ProjectVersion currentProject, Projects projects, String bomBranch) {
log.debug("Cloning the doc project to [{}]", clonedDocumentationProject);
String pathToIndexHtml = "current/index.html";
File indexHtml = indexHtml(clonedDocumentationProject, pathToIndexHtml);
File indexHtml = indexHtmlWithRedirection(clonedDocumentationProject, "",
bomBranch, pathToIndexHtml);
File docsRepo = updateTheDocsRepo(NO_PROJECT_NAME, bomBranch,
clonedDocumentationProject, indexHtml);
log.info(
"Updating all current links to documentation for release train projects");
projects.forEach(projectVersion -> {
File index = indexHtmlWithRedirection(clonedDocumentationProject,
projectVersion.projectName, projectVersion.version, pathToIndexHtml);
try {
updateTheDocsRepo(projectVersion.projectName, projectVersion.version,
clonedDocumentationProject, index);
log.info("Processed [{}] for project with name [{}]", index,
projectVersion.projectName);
}
catch (Exception ex) {
log.warn(
"Exception occurred while trying o update the index html of a project ["
+ projectVersion.projectName + "]",
ex);
}
});
return pushChanges(docsRepo);
}
private File indexHtmlWithRedirection(File clonedDocumentationProject,
String projectName, String version, String pathToIndexHtml) {
File indexHtml = indexHtml(clonedDocumentationProject,
combinedPathToIndexHtml(projectName, version, pathToIndexHtml));
if (!indexHtml.exists()) {
throw new IllegalStateException(
"index.html is not present at [" + pathToIndexHtml + "]");
return generateIndexHtml(projectName, version, pathToIndexHtml, indexHtml);
}
return updateTheDocsRepo(bomBranch, clonedDocumentationProject, indexHtml);
return indexHtml;
}
private File generateIndexHtml(String projectName, String projectVersion,
String pathToIndexHtml, File indexHtml) {
try {
log.info("No file [{}] found, will create one", indexHtml);
indexHtml.getParentFile().mkdirs();
indexHtml.createNewFile();
String newIndex = new String(indexHtmlTemplate()).replaceAll("\\{\\{URL}}",
"https://cloud.spring.io/spring-cloud-static/"
+ concreteVersionIndexHtml(projectName,
branchToReleaseVersion(projectVersion),
"index.html"));
Files.write(indexHtml.toPath(), newIndex.getBytes());
return indexHtml;
}
catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
private String combinedPathToIndexHtml(String projectName, String projectVersion,
String pathToIndexHtml) {
boolean releaseTrain = new ProjectVersion(projectName, projectVersion)
.isReleaseTrain();
// release train -> static/current/index.html
// project -> static/spring-cloud-sleuth/current/index.html
String prefix = releaseTrain ? ""
: (StringUtils.hasText(projectName) ? projectName : "") + "/";
return prefix + pathToIndexHtml;
}
private String concreteVersionIndexHtml(String projectName, String projectVersion,
String pathToIndexHtml) {
boolean releaseTrain = new ProjectVersion(projectName, projectVersion)
.isReleaseTrain();
// release train -> static/current/index.html
// project -> static/spring-cloud-sleuth/current/index.html
String prefix = releaseTrain ? projectVersion
: (projectName + "/" + projectVersion);
return prefix + "/" + pathToIndexHtml;
}
private File pushChanges(File docsRepo) {
this.gitHandler.pushCurrentBranch(docsRepo);
log.info("Committed and pushed changes to the documentation project");
return docsRepo;
}
File indexHtml(File clonedDocumentationProject, String pathToIndexHtml) {
return new File(clonedDocumentationProject, pathToIndexHtml);
}
private File updateTheDocsRepo(String springCloudReleaseBranch,
private File updateTheDocsRepo(String projectName, String version,
File documentationProject, File indexHtml) {
try {
String indexHtmlText = readIndexHtmlContents(indexHtml);
int httpIndex = indexHtmlText.indexOf(HTTP_SC_STATIC_URL);
int httpsIndex = indexHtmlText.indexOf(HTTPS_SC_STATIC_URL);
String httpSubstring = HTTP_SC_STATIC_URL
+ (StringUtils.hasText(projectName) ? (projectName + "/") : "");
String httpsSubstring = HTTPS_SC_STATIC_URL
+ (StringUtils.hasText(projectName) ? (projectName + "/") : "");
int httpIndex = indexHtmlText.indexOf(httpSubstring);
int httpsIndex = indexHtmlText.indexOf(httpsSubstring);
if (httpIndex == -1 && httpsIndex == -1) {
throw new IllegalStateException(
"The URL to the documentation repo not found in the index.html file");
}
int beginIndex = beginIndex(httpIndex, httpsIndex);
String storedReleaseTrainLine = indexHtmlText.substring(beginIndex);
String storedReleaseTrain = storedReleaseTrainLine.substring(0,
storedReleaseTrainLine.indexOf("/"));
String firstLetterOfReleaseTrain = String
.valueOf(storedReleaseTrain.charAt(0));
String currentReleaseTrainVersion = branchToReleaseVersion(
springCloudReleaseBranch);
String firstLetterOfCurrentReleaseTrain = String
.valueOf(currentReleaseTrainVersion.charAt(0));
boolean newerOrEqualReleaseTrain = isNewerOrEqualReleaseTrain(
storedReleaseTrain, firstLetterOfReleaseTrain,
currentReleaseTrainVersion, firstLetterOfCurrentReleaseTrain);
if (!newerOrEqualReleaseTrain) {
log.info(
"Current release train [{}] is not newer than the stored one [{}]",
currentReleaseTrainVersion, storedReleaseTrain);
int beginIndex = beginIndex(httpIndex, httpSubstring, httpsIndex,
httpsSubstring);
String storedVersionLine = indexHtmlText.substring(beginIndex);
String storedVersion = storedVersionLine.substring(0,
storedVersionLine.indexOf("/"));
String currentVersion = branchToReleaseVersion(version);
boolean newerVersion = isMoreMature(storedVersion, currentVersion);
if (!newerVersion) {
log.info("Current version [{}] is not newer than the stored one [{}]",
currentVersion, storedVersion);
return documentationProject;
}
return pushCommitedChanges(currentReleaseTrainVersion, documentationProject,
indexHtml, indexHtmlText, storedReleaseTrain);
return commitChanges(currentVersion, documentationProject, indexHtml,
indexHtmlText, storedVersion);
}
catch (IOException e) {
throw new IllegalStateException(e);
}
}
boolean isNewerOrEqualReleaseTrain(String storedReleaseTrain,
String firstLetterOfReleaseTrain, String currentReleaseTrainVersion,
String firstLetterOfCurrentReleaseTrain) {
return (!storedReleaseTrain.equals(currentReleaseTrainVersion))
&& firstLetterOfCurrentReleaseTrain
.compareToIgnoreCase(firstLetterOfReleaseTrain) >= 0;
boolean isMoreMature(String storedVersion, String currentVersion) {
return new ProjectVersion("project", currentVersion)
.isMoreMature(new ProjectVersion("project", storedVersion));
}
private int beginIndex(int httpIndex, int httpsIndex) {
private int beginIndex(int httpIndex, String httpSubstring, int httpsIndex,
String httpsSubstring) {
if (httpIndex != -1) {
return httpIndex + HTTP_SC_STATIC_URL.length();
return httpIndex + httpSubstring.length();
}
return httpsIndex + HTTPS_SC_STATIC_URL.length();
return httpsIndex + httpsSubstring.length();
}
private String branchToReleaseVersion(String springCloudReleaseBranch) {
@@ -137,19 +215,16 @@ class SpringCloudCustomProjectDocumentationUpdater
return springCloudReleaseBranch;
}
private File pushCommitedChanges(String currentReleaseTrainVersion,
File documentationProject, File indexHtml, String indexHtmlText,
String storedReleaseTrain) throws IOException {
private File commitChanges(String currentVersion, File documentationProject,
File indexHtml, String indexHtmlText, String storedReleaseTrain)
throws IOException {
String replacedIndexHtml = indexHtmlText.replace(storedReleaseTrain,
currentReleaseTrainVersion);
currentVersion);
Files.write(indexHtml.toPath(), replacedIndexHtml.getBytes());
log.info("Stored the release train [{}] in [{}]", currentReleaseTrainVersion,
log.info("Stored the version URL [{}] in [{}]", currentVersion,
indexHtml.getAbsolutePath());
this.gitHandler.commit(documentationProject,
"Updating the link to the current version to ["
+ currentReleaseTrainVersion + "]");
this.gitHandler.pushCurrentBranch(documentationProject);
log.info("Committed and pushed changes to the documentation project");
"Updating the link to the current version to [" + currentVersion + "]");
return documentationProject;
}
@@ -157,4 +232,18 @@ class SpringCloudCustomProjectDocumentationUpdater
return new String(Files.readAllBytes(indexHtml.toPath()));
}
private byte[] indexHtmlTemplate() {
if (this.indexHtmlTemplate == null) {
try {
URI uri = CustomProjectDocumentationUpdater.class
.getResource("/cloud/index.html").toURI();
this.indexHtmlTemplate = IOUtils.toByteArray(uri);
}
catch (URISyntaxException | IOException ex) {
throw new IllegalStateException(ex);
}
}
return this.indexHtmlTemplate;
}
}

View File

@@ -359,23 +359,13 @@ public class Releaser implements ReleaserPropertiesAware {
}
public void updateDocumentationRepository(ReleaserProperties properties,
ProjectVersion releaseVersion) {
Projects projects, ProjectVersion releaseVersion) {
String releaseBranch = properties.getPom().getBranch();
this.documentationUpdater.updateDocsRepo(releaseVersion, releaseBranch);
this.documentationUpdater.updateDocsRepo(projects, releaseVersion, releaseBranch);
log.info("\nSuccessfully updated documentation repository for branch [{}]",
releaseBranch);
}
@Deprecated
public void updateSpringProjectPage(Projects projects) {
if (this.documentationUpdater.updateProjectRepo(projects) != null) {
log.info("\nSuccessfully updated Spring project page");
}
else {
throw new MakeBuildUnstableException("Failed to update Spring Project page");
}
}
public void runUpdatedSamples(Projects projects) {
this.postReleaseActions.runUpdatedTests(projects);
log.info("\nSuccessfully updated and ran samples");

View File

@@ -1017,7 +1017,7 @@ public class ReleaserProperties implements Serializable {
/**
* Command to be executed to deploy a built project.
*/
private String deployCommand = "./gradlew clean build publish --console=plain {{systemProps}}";
private String deployCommand = "./gradlew publish --console=plain {{systemProps}}";
/**
* Command to be executed to build and deploy guides project only.

View File

@@ -19,6 +19,7 @@ package org.springframework.cloud.release.internal.docs;
import java.io.File;
import org.springframework.cloud.release.internal.project.ProjectVersion;
import org.springframework.cloud.release.internal.project.Projects;
/**
* @author Marcin Grzejszczak
@@ -37,7 +38,7 @@ public interface CustomProjectDocumentationUpdater {
@Override
public File updateDocsRepo(File clonedDocumentationProject,
ProjectVersion currentProject, String bomBranch) {
ProjectVersion currentProject, Projects projects, String bomBranch) {
return clonedDocumentationProject;
}
};
@@ -58,11 +59,12 @@ public interface CustomProjectDocumentationUpdater {
* Updates the documentation repository.
* @param clonedDocumentationProject path to the cloned documentation project
* @param currentProject project to update the docs repo for
* @param projects list of projects to update versions for
* @param bomBranch the bom project branch
* @return {@link File cloned temporary directory} - {@code null} if wrong version is
* used
*/
File updateDocsRepo(File clonedDocumentationProject, ProjectVersion currentProject,
String bomBranch);
Projects projects, String bomBranch);
}

View File

@@ -58,29 +58,18 @@ public class DocumentationUpdater implements ReleaserPropertiesAware {
/**
* Updates the documentation repository if current release train version is greater or
* equal than the one stored in the repo.
* @param projects list of projects with updated versions
* @param currentProject the project we're parsing
* @param bomReleaseBranch branch of the BOM
* @return {@link File cloned temporary directory} - {@code null} if wrong version is
* used
*/
public File updateDocsRepo(ProjectVersion currentProject, String bomReleaseBranch) {
return this.projectDocumentationUpdater.updateDocsRepo(currentProject,
public File updateDocsRepo(Projects projects, ProjectVersion currentProject,
String bomReleaseBranch) {
return this.projectDocumentationUpdater.updateDocsRepo(projects, currentProject,
bomReleaseBranch);
}
/**
* Updates the project page if current release train version is greater or equal than
* the one stored in the repo.
* @param projects list of projects to update versions for
* @return {@link File cloned temporary directory} - {@code null} if wrong version is
* used or the switch is turned off
* @deprecated - index.html doesn't look like this anymore
*/
@Deprecated
public File updateProjectRepo(Projects projects) {
return this.releaseTrainContentsUpdater.updateProjectRepo(projects);
}
/**
* Updates the release train wiki page.
* @param projects list of projects to update versions for

View File

@@ -26,6 +26,7 @@ import org.springframework.cloud.release.internal.ReleaserProperties;
import org.springframework.cloud.release.internal.ReleaserPropertiesAware;
import org.springframework.cloud.release.internal.git.ProjectGitHandler;
import org.springframework.cloud.release.internal.project.ProjectVersion;
import org.springframework.cloud.release.internal.project.Projects;
/**
* @author Marcin Grzejszczak
@@ -49,7 +50,8 @@ class ProjectDocumentationUpdater implements ReleaserPropertiesAware {
this.updaters = updaters;
}
public File updateDocsRepo(ProjectVersion currentProject, String bomBranch) {
public File updateDocsRepo(Projects projects, ProjectVersion currentProject,
String bomBranch) {
if (!this.properties.getGit().isUpdateDocumentationRepo()) {
log.info(
"Will not update documentation repository, since the switch to do so "
@@ -67,7 +69,8 @@ class ProjectDocumentationUpdater implements ReleaserPropertiesAware {
CustomProjectDocumentationUpdater updater = this.updaters.stream().filter(
u -> u.isApplicable(documentationProject, currentProject, bomBranch))
.findFirst().orElse(CustomProjectDocumentationUpdater.NO_OP);
return updater.updateDocsRepo(documentationProject, currentProject, bomBranch);
return updater.updateDocsRepo(documentationProject, currentProject, projects,
bomBranch);
}
@Override

View File

@@ -21,12 +21,8 @@ import java.io.IOException;
import java.nio.file.Files;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.stream.Collectors;
import com.github.jknack.handlebars.Template;
import com.google.common.collect.ImmutableMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -35,7 +31,6 @@ import org.springframework.cloud.release.internal.ReleaserPropertiesAware;
import org.springframework.cloud.release.internal.git.ProjectGitHandler;
import org.springframework.cloud.release.internal.project.ProjectVersion;
import org.springframework.cloud.release.internal.project.Projects;
import org.springframework.cloud.release.internal.tech.HandlebarsHelper;
import org.springframework.cloud.release.internal.template.TemplateGenerator;
import org.springframework.util.StringUtils;
@@ -52,8 +47,6 @@ class ReleaseTrainContentsUpdater implements ReleaserPropertiesAware {
private final ReleaseTrainContentsParser parser;
private final ReleaseTrainContentsGenerator generator;
private final TemplateGenerator templateGenerator;
private ReleaserProperties properties;
@@ -64,53 +57,6 @@ class ReleaseTrainContentsUpdater implements ReleaserPropertiesAware {
this.handler = new ReleaseTrainContentsGitHandler(handler);
this.templateGenerator = templateGenerator;
this.parser = new ReleaseTrainContentsParser();
this.generator = new ReleaseTrainContentsGenerator(properties);
}
/**
* Updates the project page if current release train version is greater or equal than
* the one stored in the repo.
* @param projects projects to update project repo for
* @return {@link File cloned temporary directory} - {@code null} if wrong version is
* used or the switch is turned off
* @deprecated - index.html doesn't look like this anymore
*/
@Deprecated
File updateProjectRepo(Projects projects) {
if (!this.properties.getGit().isUpdateSpringProject()) {
log.info("Will not update the Spring Project cause "
+ "the switch is turned off. Set [releaser.git.update-spring-project=true].");
return null;
}
File releaseTrainProject = this.handler.cloneSpringDocProject();
File index = new File(releaseTrainProject, "index.html");
ReleaseTrainContents contents = this.parser.parseProjectPage(index);
if (contents == null) {
log.warn(
"There are no markers for the index.html page - I don't really know what to do, so I'll back away");
return null;
}
String newContents = this.generator.releaseTrainContents(contents, projects);
if (StringUtils.isEmpty(newContents)) {
log.info("No changes to commit to the Spring Project page.");
return releaseTrainProject;
}
return pushNewContents(projects, releaseTrainProject, index, newContents);
}
private File pushNewContents(Projects projects, File releaseTrainProject, File index,
String newContents) {
try {
log.debug("Storing new contents to the page");
Files.write(index.toPath(), newContents.getBytes());
log.info("Successfully stored new contents of the page");
this.handler.commitAndPushChanges(releaseTrainProject,
this.generator.currentReleaseTrainProject(projects));
return releaseTrainProject;
}
catch (IOException e) {
throw new IllegalStateException(e);
}
}
/**
@@ -220,138 +166,6 @@ class ReleaseTrainContentsUpdater implements ReleaserPropertiesAware {
return releaseTrainDocFile;
}
@Override
public void setReleaserProperties(ReleaserProperties properties) {
this.properties = properties;
this.generator.setReleaserProperties(properties);
}
}
/**
* @author Marcin Grzejszczak
*/
class ReleaseTrainContentsGenerator implements ReleaserPropertiesAware {
private static final Logger log = LoggerFactory
.getLogger(ReleaseTrainContentsGenerator.class);
private static final String SPRING_PROJECT_TEMPLATE = "spring-project";
private final File projectOutput;
private ReleaserProperties properties;
ReleaseTrainContentsGenerator(ReleaserProperties properties) {
this.properties = properties;
this.projectOutput = new File("target/index.html");
}
String releaseTrainContents(ReleaseTrainContents currentContents, Projects projects) {
String trainProject = this.properties.getMetaRelease()
.getReleaseTrainProjectName();
ProjectVersion currentReleaseTrainProject = currentReleaseTrainProject(projects);
ProjectVersion lastGa = new ProjectVersion(trainProject,
currentContents.title.lastGaTrainName);
ProjectVersion currentGa = new ProjectVersion(trainProject,
currentContents.title.currentGaTrainName);
ReleaseTrainContents newReleaseTrainContents = updateReleaseTrainContentsIfNecessary(
currentContents, projects, currentReleaseTrainProject, lastGa, currentGa);
if (!currentContents.equals(newReleaseTrainContents)) {
Template template = HandlebarsHelper.template(
this.properties.getTemplate().getTemplateFolder(),
SPRING_PROJECT_TEMPLATE);
return generate(this.projectOutput, template, newReleaseTrainContents);
}
log.warn("Current release train [{}] is neither last [{}] "
+ "or current [{}] or the projects haven't changed. Will not update the contents",
currentReleaseTrainProject.version, lastGa, currentGa);
return "";
}
ProjectVersion currentReleaseTrainProject(Projects projects) {
return projects.releaseTrain(this.properties);
}
private String generate(File contentOutput, Template template,
ReleaseTrainContents releaseTrainContents) {
try {
Map<String, Object> map = ImmutableMap.<String, Object>builder()
.put("lastGaTrainName", releaseTrainContents.title.lastGaTrainName)
.put("currentGaTrainName",
releaseTrainContents.title.currentGaTrainName)
.put("currentSnapshotTrainName",
releaseTrainContents.title.currentSnapshotTrainName)
.put("projects", releaseTrainContents.rows).build();
String contents = template.apply(map);
Files.write(contentOutput.toPath(), contents.getBytes());
return contents;
}
catch (IOException e) {
throw new IllegalStateException(e);
}
}
private ReleaseTrainContents updateReleaseTrainContentsIfNecessary(
ReleaseTrainContents currentContents, Projects projects,
ProjectVersion currentReleaseTrainProject, ProjectVersion lastGa,
ProjectVersion currentGa) {
ReleaseTrainContents newReleaseTrainContents = currentContents;
// current GA is greater than the last GA
if (greaterMinorOfLastGaReleaseTrain(currentReleaseTrainProject, lastGa)) {
Title title = new Title(currentReleaseTrainProject.version,
currentContents.title.currentGaTrainName,
currentContents.title.currentSnapshotTrainName);
return updatedReleaseTrainContents(currentContents, projects, title, true);
}
else if (currentReleaseTrainProject.isSameReleaseTrainName(currentGa.version)) {
Title title = new Title(currentContents.title.lastGaTrainName,
currentReleaseTrainProject.isReleaseOrServiceRelease()
? currentReleaseTrainProject.version
: currentContents.title.currentGaTrainName,
currentReleaseTrainProject.isSnapshot()
? currentReleaseTrainProject.version
: currentContents.title.currentSnapshotTrainName);
return updatedReleaseTrainContents(currentContents, projects, title, false);
}
return newReleaseTrainContents;
}
private boolean greaterMinorOfLastGaReleaseTrain(
ProjectVersion currentReleaseTrainProject, ProjectVersion lastGa) {
return currentReleaseTrainProject.isSameReleaseTrainName(lastGa.version)
&& currentReleaseTrainProject.isReleaseOrServiceRelease()
&& currentReleaseTrainProject
.compareToReleaseTrainName(lastGa.version) > 0;
}
private ReleaseTrainContents updatedReleaseTrainContents(
ReleaseTrainContents currentContents, Projects projects, Title title,
boolean lastGa) {
List<Row> rows = Row.fromProjects(projects, lastGa);
return new ReleaseTrainContents(title,
currentContents.rows.stream().map(current -> {
Row projectRow = rows.stream().filter(
row -> current.componentName.equals(row.componentName))
.findFirst().orElse(current);
if (projectRow == current) {
return projectRow;
}
return from(current, projectRow);
}).collect(Collectors.toCollection(LinkedList::new)));
}
private Row from(Row current, Row project) {
return new Row(current.componentName,
StringUtils.hasText(project.lastGaVersion) ? project.lastGaVersion
: current.lastGaVersion,
StringUtils.hasText(project.currentGaVersion) ? project.currentGaVersion
: current.currentGaVersion,
StringUtils.hasText(project.currentSnapshotVersion)
? project.currentSnapshotVersion
: current.currentSnapshotVersion);
}
@Override
public void setReleaserProperties(ReleaserProperties properties) {
this.properties = properties;
@@ -372,10 +186,6 @@ class ReleaseTrainContentsGitHandler {
this.handler = handler;
}
File cloneSpringDocProject() {
return this.handler.cloneSpringDocProject();
}
File cloneReleaseTrainWiki() {
return this.handler.cloneReleaseTrainWiki();
}

View File

@@ -70,11 +70,14 @@ public class ProjectVersion implements Comparable<ProjectVersion> {
private final String artifactId;
private final ReleaseType releaseType;
public ProjectVersion(String projectName, String version) {
this.projectName = projectName;
this.version = version;
this.groupId = "";
this.artifactId = "";
this.releaseType = toReleaseType();
}
public ProjectVersion(File project) {
@@ -105,6 +108,7 @@ public class ProjectVersion implements Comparable<ProjectVersion> {
this.artifactId = projectVersion.artifactId;
}
}
this.releaseType = toReleaseType();
}
public static ProjectVersion notMavenProject(File file) {
@@ -271,6 +275,11 @@ public class ProjectVersion implements Comparable<ProjectVersion> {
return this.version != null && this.version.contains("RELEASE");
}
public boolean isReleaseTrain() {
SplitVersion splitVersion = assertVersion();
return splitVersion.isReleaseTrain();
}
public boolean isReleaseOrServiceRelease() {
return isRelease() || isServiceRelease();
}
@@ -279,6 +288,46 @@ public class ProjectVersion implements Comparable<ProjectVersion> {
return this.version != null && this.version.matches(".*.SR[0-9]+");
}
private ReleaseType toReleaseType() {
if (isMilestone()) {
return ReleaseType.M;
}
else if (isRc()) {
return ReleaseType.RC;
}
else if (isRelease()) {
return ReleaseType.RELEASE;
}
else if (isServiceRelease()) {
return ReleaseType.SR;
}
return ReleaseType.SNAPSHOT;
}
/*
* E.g. 1.0.1.RELEASE is more mature than 1.0.2.RC2
*/
public boolean isMoreMature(ProjectVersion that) {
SplitVersion thisSplit = assertVersion();
SplitVersion thatSplit = that.assertVersion();
int releaseTypeComparison = this.releaseType.compareTo(that.releaseType);
boolean thisReleaseTypeHigher = releaseTypeComparison > 0;
boolean bothGa = this.isReleaseOrServiceRelease()
&& that.isReleaseOrServiceRelease();
// 1.0.1.M2 vs 1.0.0.RELEASE (x)
if (thisReleaseTypeHigher && !bothGa) {
return true;
}
int versionComparison = thisSplit.gav().compareTo(thatSplit.gav());
if (versionComparison == 0) {
// 1.0.0.SR1 vs 1.0.1.RELEASE (x)
// Finchley.RELEASE vs Finchley.SR1 (x)
return thisReleaseTypeHigher;
}
// 1.0.0.SR1 vs 1.0.1.RELEASE (x)
return versionComparison > 0;
}
public boolean isSameMinor(String version) {
if (this.version == null) {
return false;
@@ -467,6 +516,15 @@ public class ProjectVersion implements Comparable<ProjectVersion> {
delimiter, suffix);
}
private String gav() {
// Finchley
if (StringUtils.isEmpty(minor)) {
return String.format("%s", major);
}
// 1.0.1
return String.format("%s.%s.%s", major, minor, patch);
}
private String print() {
// Finchley.SR2
if (StringUtils.isEmpty(minor)) {
@@ -540,3 +598,9 @@ class TrainVersionNumber implements Comparable<TrainVersionNumber> {
}
}
enum ReleaseType {
SNAPSHOT, M, RC, RELEASE, SR
}

View File

@@ -0,0 +1,29 @@
<!--
~ 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.
-->
<!DOCTYPE HTML>
<meta charset="UTF-8">
<meta http-equiv="refresh" content="1; url={{URL}}">
<script>
window.location.href = "{{URL}}"
</script>
<title>Page Redirection</title>
<!-- Note: don't tell people to `click` the link, just tell them that it is a link. -->
If you are not redirected automatically, follow the <a href='{{URL}}'>link to latest release</a>

View File

@@ -1,426 +0,0 @@
---
# The name of your project
title: Spring Cloud
badges:
# Customize your project's badges. Delete any entries that do not apply.
custom:
- name: Source (GitHub)
url: https://github.com/spring-cloud
icon: github
- name: StackOverflow
url: https://stackoverflow.com/questions/tagged/spring-cloud
icon: stackoverflow
---
<!DOCTYPE HTML>
<html lang="en-US">
{% capture billboard_description %}
Spring Cloud provides tools for developers to quickly build some of
the common patterns in distributed systems (e.g. configuration
management, service discovery, circuit breakers, intelligent routing,
micro-proxy, control bus, one-time tokens, global locks, leadership
election, distributed sessions, cluster state). Coordination of
distributed systems leads to boiler plate patterns, and using Spring
Cloud developers can quickly stand up services and applications that
implement those patterns. They will work well in any distributed
environment, including the developer's own laptop, bare metal data
centres, and managed platforms such as Cloud Foundry.
{% endcapture %}
{% capture main_content %}
Spring Cloud builds on Spring Boot by providing a bunch of libraries
that enhance the behaviour of an application when added to the
classpath. You can take advantage of the basic default behaviour to
get started really quickly, and then when you need to, you can
configure or extend to create a custom solution.
<span id="quick-start"></span>
## Quick Start
The release train label (see below) is actually only used explicitly
in one artifact: "spring-cloud-dependencies" (all the others have
normal numeric release labels tied to their parent project). The
dependencies POM is the one you can use as a BOM for dependency
management. Example using the latest version with the config client
and eureka (change the artifact ids to pull in other starters):
{% include download_widget.md %}
## Features
Spring Cloud focuses on providing good out of box experience for typical use cases and extensibility mechanism to cover
others.
* Distributed/versioned configuration
* Service registration and discovery
* Routing
* Service-to-service calls
* Load balancing
* Circuit Breakers
* Global locks
* Leadership election and cluster state
* Distributed messaging
Spring Cloud takes a very declarative approach, and often you get a
lot of fetaures with just a classpath change and/or an
annotation. Example application that is a discovery client:
```java
@SpringBootApplication
@EnableDiscoveryClient
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
```
<a name="main-projects"></a>
## Main Projects
<!-- Spring Cloud Config -->
{% capture project_description %}
Centralized external configuration management backed by a git repository. The configuration resources map directly to
Spring `Environment` but could be used by non-Spring applications if desired.
{% endcapture %}
{% include project_block.md site_url="https://cloud.spring.io/spring-cloud-config"
repo_url="https://github.com/spring-cloud/spring-cloud-config" project_title="Spring Cloud Config"
project_description=project_description %}
<!-- Spring Cloud Netflix -->
{% capture project_description %}
Integration with various Netflix OSS components (Eureka, Hystrix, Zuul, Archaius, etc.).
{% endcapture %}
{% include project_block.md site_url="https://cloud.spring.io/spring-cloud-netflix"
repo_url="https://github.com/spring-cloud/spring-cloud-netflix" project_title="Spring Cloud Netflix"
project_description=project_description %}
<!-- Spring Cloud Bus -->
{% capture project_description %}
An event bus for linking services and service instances together with distributed messaging. Useful for propagating
state changes across a cluster (e.g. config change events).
{% endcapture %}
{% include project_block.md site_url="https://cloud.spring.io/spring-cloud-bus"
repo_url="https://github.com/spring-cloud/spring-cloud-bus" project_title="Spring Cloud Bus"
project_description=project_description %}
<!-- Spring Cloud Cloudfoundry -->
{% capture project_description %}
Integrates your application with Pivotal Cloud Foundry. Provides a service discovery implementation and also makes it
easy to implement SSO and OAuth2 protected resources.
{% endcapture %}
{% include project_block.md site_url="https://cloud.spring.io/spring-cloud-cloudfoundry"
repo_url="https://github.com/spring-cloud/spring-cloud-cloudfoundry" project_title="Spring Cloud for Cloud Foundry"
project_description=project_description %}
<!-- Spring Cloud Open Service Broker -->
{% capture project_description %}
Provides a starting point for building a service broker that implements the Open Service Broker API.
{% endcapture %}
{% include project_block.md site_url="https://cloud.spring.io/spring-cloud-open-service-broker/"
repo_url="https://github.com/spring-cloud/spring-cloud-open-service-broker" project_title="Spring Cloud Open Service
Broker" project_description=project_description %}
<!-- Spring Cloud Cluster -->
{% capture project_description %}
Leadership election and common stateful patterns with an abstraction and implementation for Zookeeper, Redis, Hazelcast,
Consul.
{% endcapture %}
{% include project_block.md site_url="/spring-cloud" repo_url="https://github.com/spring-cloud/spring-cloud-cluster"
project_title="Spring Cloud Cluster" project_description=project_description %}
<!-- Spring Cloud Consul -->
{% capture project_description %}
Service discovery and configuration management with Hashicorp Consul.
{% endcapture %}
{% include project_block.md site_url="https://cloud.spring.io/spring-cloud-consul"
repo_url="https://github.com/spring-cloud/spring-cloud-consul" project_title="Spring Cloud Consul"
project_description=project_description %}
<!-- Spring Cloud Security -->
{% capture project_description %}
Provides support for load-balanced OAuth2 rest client and authentication header relays in a Zuul proxy.
{% endcapture %}
{% include project_block.md site_url="https://cloud.spring.io/spring-cloud-security"
repo_url="https://github.com/spring-cloud/spring-cloud-security" project_title="Spring Cloud Security"
project_description=project_description %}
<!-- Spring Cloud Sleuth -->
{% capture project_description %}
Distributed tracing for Spring Cloud applications, compatible with Zipkin, HTrace and log-based (e.g. ELK) tracing.
{% endcapture %}
{% include project_block.md site_url="https://cloud.spring.io/spring-cloud-sleuth"
repo_url="https://github.com/spring-cloud/spring-cloud-sleuth" project_title="Spring Cloud Sleuth"
project_description=project_description %}
<!-- Spring Cloud Data Flow -->
{% capture project_description %}
A cloud-native orchestration service for composable microservice applications on modern runtimes. Easy-to-use DSL,
drag-and-drop GUI, and REST-APIs together simplifies the overall orchestration of microservice based data pipelines.
{% endcapture %}
{% include project_block.md site_url="https://cloud.spring.io/spring-cloud-dataflow"
repo_url="https://github.com/spring-cloud/spring-cloud-dataflow" project_title="Spring Cloud Data Flow"
project_description=project_description %}
<!-- Spring Cloud Stream -->
{% capture project_description %}
A lightweight event-driven microservices framework to quickly build applications that can connect to external systems.
Simple declarative model to send and receive messages using Apache Kafka or RabbitMQ between Spring Boot apps.
{% endcapture %}
{% include project_block.md site_url="https://cloud.spring.io/spring-cloud-stream"
repo_url="https://github.com/spring-cloud/spring-cloud-stream" project_title="Spring Cloud Stream"
project_description=project_description %}
<!-- Spring Cloud Stream App Starters -->
{% capture project_description %}
Spring Cloud Stream App Starters are Spring Boot based Spring Integration applications that provide integration with
external systems.
{% endcapture %}
{% include project_block.md site_url="https://cloud.spring.io/spring-cloud-stream-app-starters"
repo_url="https://github.com/spring-cloud/spring-cloud-stream-app-starters" project_title="Spring Cloud Stream App
Starters" project_description=project_description %}
<!-- Spring Cloud Task -->
{% capture project_description %}
A short-lived microservices framework to quickly build applications that perform finite amounts of data processing.
Simple declarative for adding both functional and non-functional features to Spring Boot apps.
{% endcapture %}
{% include project_block.md site_url="https://cloud.spring.io/spring-cloud-task"
repo_url="https://github.com/spring-cloud/spring-cloud-task" project_title="Spring Cloud Task"
project_description=project_description %}
<!-- Spring Cloud Task App Starters -->
{% capture project_description %}
Spring Cloud Task App Starters are Spring Boot applications that may be any process including Spring Batch jobs that do
not run forever, and they end/stop after a finite period of data processing.
{% endcapture %}
{% include project_block.md site_url="https://cloud.spring.io/spring-cloud-task-app-starters"
repo_url="https://github.com/spring-cloud/spring-cloud-task-app-starters" project_title="Spring Cloud Task App Starters"
project_description=project_description %}
<!-- Spring Cloud Zookeeper -->
{% capture project_description %}
Service discovery and configuration management with Apache Zookeeper.
{% endcapture %}
{% include project_block.md site_url="https://cloud.spring.io/spring-cloud-zookeeper"
repo_url="https://github.com/spring-cloud/spring-cloud-zookeeper" project_title="Spring Cloud Zookeeper"
project_description=project_description %}
<!-- Spring Cloud AWS -->
{% capture project_description %}
Easy integration with hosted Amazon Web Services. It offers a convenient way to interact with AWS provided services
using well-known Spring idioms and APIs, such as the messaging or caching API. Developers can build their application
around the hosted services without having to care about infrastructure or maintenance.
{% endcapture %}
{% capture site_url %}
{{ site.projects_site_url }}/spring-cloud-aws
{% endcapture %}
{% include project_block.md site_url=site_url repo_url="https://github.com/spring-cloud/spring-cloud-aws"
project_title="Spring Cloud for Amazon Web Services" project_description=project_description %}
<!-- Spring Cloud Connectors -->
{% capture project_description %}
Makes it easy for PaaS applications in a variety of platforms to connect to backend services like
databases and message brokers (the project formerly known as "Spring Cloud").
{% endcapture %}
{% capture site_url %}
{{ site.projects_site_url }}/spring-cloud-connectors
{% endcapture %}
{% include project_block.md site_url=site_url repo_url="https://github.com/spring-cloud/spring-cloud-connectors"
project_title="Spring Cloud Connectors" project_description=project_description %}
<!-- Spring Cloud Starters -->
{% capture project_description %}
Spring Boot-style starter projects to ease dependency management for consumers of Spring Cloud. (Discontinued as a
project and merged with the other projects after Angel.SR2.)
{% endcapture %}
{% include project_block.md site_url="https://github.com/spring-cloud/spring-cloud-starters"
repo_url="https://github.com/spring-cloud/spring-cloud-starters" project_title="Spring Cloud Starters"
project_description=project_description %}
<!-- Spring Cloud CLI -->
{% capture project_description %}
Spring Boot CLI plugin for creating Spring Cloud component applications quickly in Groovy
{% endcapture %}
{% include project_block.md site_url="https://github.com/spring-cloud/spring-cloud-cli"
repo_url="https://github.com/spring-cloud/spring-cloud-cli" project_title="Spring Cloud CLI"
project_description=project_description %}
<!-- Spring Cloud Contract -->
{% capture project_description %}
Spring Cloud Contract is an umbrella project holding solutions that help users in successfully implementing the Consumer
Driven Contracts approach.
{% endcapture %}
{% include project_block.md site_url="https://cloud.spring.io/spring-cloud-contract"
repo_url="https://github.com/spring-cloud/spring-cloud-contract" project_title="Spring Cloud Contract"
project_description=project_description %}
<!-- Spring Cloud Gateway -->
{% capture project_description %}
Spring Cloud Gateway is an intelligent and programmable router based on Project Reactor.
{% endcapture %}
{% include project_block.md site_url="https://cloud.spring.io/spring-cloud-gateway"
repo_url="https://github.com/spring-cloud/spring-cloud-gateway" project_title="Spring Cloud Gateway"
project_description=project_description %}
<!-- Spring Cloud OpenFeign -->
{% capture project_description %}
Spring Cloud OpenFeign provides integrations for Spring Boot apps through autoconfiguration and binding to the Spring
Environment and other Spring programming model idioms.
{% endcapture %}
{% include project_block.md site_url="https://cloud.spring.io/spring-cloud-openfeign"
repo_url="https://github.com/spring-cloud/spring-cloud-openfeign" project_title="Spring Cloud OpenFeign"
project_description=project_description %}
<!-- Spring Cloud Pipelines -->
{% capture project_description %}
Spring Cloud Pipelines provides an opinionated deployment pipeline with steps to ensure that your application can be
deployed in zero downtime fashion and easilly rolled back of something goes wrong.
{% endcapture %}
{% include project_block.md site_url="https://cloud.spring.io/spring-cloud-pipelines"
repo_url="https://github.com/spring-cloud/spring-cloud-pipelines" project_title="Spring Cloud Pipelines"
project_description=project_description %}
<!-- Spring Cloud Function -->
{% capture project_description %}
Spring Cloud Function promotes the implementation of business logic via functions. It supports a uniform programming
model across serverless providers, as well as the ability to run standalone (locally or in a PaaS).
{% endcapture %}
{% include project_block.md site_url="https://cloud.spring.io/spring-cloud-function"
repo_url="https://github.com/spring-cloud/spring-cloud-function" project_title="Spring Cloud Function"
project_description=project_description %}
## Release Trains
Spring Cloud is an umbrella project consisting of independent projects with, in principle, different
release cadences. To manage the portfolio a BOM (Bill of Materials) is published with a curated
set of dependencies on the individual project (see below). The release trains have names, not
versions, to avoid confusion with the sub-projects. The names are an alphabetic sequence (so
you can sort them chronologically) with names of London Tube stations ("Angel" is the first
release, "Brixton" is the second). When point releases of the individual projects accumulate to
a critical mass, or if there is a critical bug in one of them that needs to be available to everyone,
the release train will push out "service releases" with names ending ".SRX", where "X"
is a number.
Release train contents:
<!-- BEGIN COMPONENTS -->
|Component |{{lastGaTrainName}}|{{currentGaTrainName}}|{{currentSnapshotTrainName}}|
|--------------------------------------|-----------------|---------------------|------------------------|
{{#each projects}} |{{componentName}}|{{lastGaVersion}}|{{currentGaVersion}}|{{currentSnapshotVersion}}|
{{/each}}
<!-- END COMPONENTS -->
Finchley builds and works with Spring Boot 2.0.x, and is not expected
to work with Spring Boot 1.5.x.
Note: The Dalston release train will [reach
end-of-life](https://spring.io/blog/2018/06/19/spring-cloud-finchley-release-is-available) in December 2018. Edgware
will follow the end-of-life cycle of Spring Boot 1.5.x.
The Dalston and Edgware release trains build on Spring Boot 1.5.x, and
are not expected to work with Spring Boot 2.0.x.
NOTE: The Camden release train was [marked
end-of-life](https://spring.io/blog/2018/06/19/spring-cloud-finchley-release-is-available).
The Camden release train builds on Spring Boot 1.4.x, but is also
tested with 1.5.x.
NOTE: The Brixton and Angel release trains were [marked
end-of-life](https://spring.io/blog/2017/07/21/spring-cloud-dalston-sr2-is-available-now#end-of-life-for-angel-and-brixton-release-trains)
(EOL) in July 2017.
The Brixton release train builds on Spring Boot 1.3.x, but is also
tested with 1.4.x.
The Angel release train builds on Spring Boot 1.2.x, and is
incompatible in some areas with Spring Boot 1.3.x. Brixton builds on
Spring Boot 1.3.x and is similarly incompatible with 1.2.x. Some
libraries and most apps built on Angel will run fine on Brixton, but
changes will be required anywhere that the OAuth2 features from
spring-cloud-security 1.0.x are used (they were mostly moved to Spring
Boot in 1.3.0).
Use your dependency management tools to control the version. If you
are using Maven remember that the first version declared wins, so
declare the BOMs in order, with the first one usually being the most
recent (e.g. if you want to use Spring Boot 1.3.6 with Brixton.RELEASE, put
the Boot BOM first). The same rule applies to Gradle if you use the
Spring dependency management plugin.
> NOTE: The release train contains a
> `spring-cloud-dependencies` as well as the
> `spring-cloud-starter-parent`. You can use the parent as you would
> the `spring-boot-starter-parent` (if you are using Maven).
> If you only need dependency management, the "dependencies"
> version is a BOM-only version of the same thing (it just
> contains dependency management and no plugin declarations
> or direct references to Spring or Spring Boot). If you are
> using the Spring Boot parent POM, then you can use the BOM from
> Spring Cloud. The opposite is not true: using the Cloud parent
> makes it impossible, or at least unreliable, to also use the
> Boot BOM to change the version of Spring Boot and its dependencies.
> NOTE: If you find anything wrong or outdated on this page, please open an issue in
[this](https://github.com/spring-projects/spring-cloud) repo.
{% endcapture %}
{% capture related_resources %}
### Sample Projects
* [Config Server](https://github.com/spring-cloud-samples/configserver)
* [Service Registry](https://github.com/spring-cloud-samples/eureka)
* [Circuit Breaker Dashboard](https://github.com/spring-cloud-samples/hystrix-dashboard)
* [Business Application](https://github.com/spring-cloud-samples/customers-stores) (Customers and Stores)
* [OAuth2 Authorization Server](https://github.com/spring-cloud-samples/authserver)
* [OAuth2 SSO Client](https://github.com/spring-cloud-samples/sso)
* [Integration Test Samples](https://github.com/spring-cloud-samples/tests)
* [Spring Cloud Contract Samples](https://github.com/spring-cloud-samples/spring-cloud-contract-samples)
{% endcapture %}
{% include project_page.html %}
</html>

View File

@@ -38,6 +38,7 @@ import org.springframework.cloud.release.internal.docs.DocumentationUpdater;
import org.springframework.cloud.release.internal.git.ProjectGitHandler;
import org.springframework.cloud.release.internal.github.ProjectGitHubHandler;
import org.springframework.cloud.release.internal.project.ProjectVersion;
import org.springframework.cloud.release.internal.project.Projects;
import org.springframework.cloud.release.internal.template.TemplateGenerator;
import org.springframework.util.FileSystemUtils;
@@ -80,20 +81,27 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
}
@Test
public void should_throw_exception_if_index_html_not_found()
throws URISyntaxException {
ProjectVersion releaseTrainVersion = new ProjectVersion("spring-cloud-sleuth",
"1.3.4.SR10");
public void should_generate_a_new_index_html_when_original_one_is_not_found()
throws URISyntaxException, IOException {
ProjectVersion releaseTrainVersion = new ProjectVersion("spring-cloud-release",
"Hoxton.SR10");
ReleaserProperties properties = new ReleaserProperties();
properties.getGit().setDocumentationBranch("master");
properties.getGit().setDocumentationUrl(
file("/projects/spring-cloud-release/").toURI().toString());
BDDAssertions
.thenThrownBy(() -> projectDocumentationUpdaterWithNoIndexHtml(properties)
.updateDocsRepo(releaseTrainVersion, "vAngel.SR33"))
.isInstanceOf(IllegalStateException.class)
.hasMessageContaining("index.html is not present");
File updatedDocs = projectDocumentationUpdaterWithNoIndexHtml(properties)
.updateDocsRepo(projects(), releaseTrainVersion, "vHoxton.SR10");
String indexHtmlContent = new String(
Files.readAllBytes(new File(updatedDocs, "current/index.html").toPath()));
then(indexHtmlContent)
.contains("cloud.spring.io/spring-cloud-static/Hoxton.SR10/");
String sleuthIndexHtmlContent = new String(Files.readAllBytes(
new File(updatedDocs, "spring-cloud-sleuth/current/index.html")
.toPath()));
then(sleuthIndexHtmlContent).contains(
"cloud.spring.io/spring-cloud-static/spring-cloud-sleuth/1.0.0.RELEASE/");
}
@Test
@@ -116,8 +124,8 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
BDDAssertions
.thenThrownBy(() -> new DocumentationUpdater(this.handler, properties,
templateGenerator(properties),
Collections.singletonList(customUpdater))
.updateDocsRepo(releaseTrainVersion, "vAngel.SR33"))
Collections.singletonList(customUpdater)).updateDocsRepo(
projects(), releaseTrainVersion, "vAngel.SR33"))
.isInstanceOf(IllegalStateException.class)
.hasMessageContaining("The URL to the documentation repo not found");
}
@@ -129,7 +137,7 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
ReleaserProperties properties = new ReleaserProperties();
File updatedDocs = projectDocumentationUpdater(properties)
.updateDocsRepo(releaseTrainVersion, "vAngel.M7");
.updateDocsRepo(projects(), releaseTrainVersion, "vAngel.M7");
then(updatedDocs).isNull();
}
@@ -141,10 +149,7 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
templateGenerator(properties), Collections.singletonList(
new SpringCloudCustomProjectDocumentationUpdater(this.handler) {
@Override
boolean isNewerOrEqualReleaseTrain(String storedReleaseTrain,
String firstLetterOfReleaseTrain,
String currentReleaseTrainVersion,
String firstLetterOfCurrentReleaseTrain) {
boolean isMoreMature(String first, String second) {
return true;
}
}));
@@ -159,7 +164,10 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
@Override
File indexHtml(File clonedDocumentationProject,
String pathToIndexHtml) {
return new File("non/existent/file");
File file = super.indexHtml(clonedDocumentationProject,
pathToIndexHtml);
file.delete();
return file;
}
}));
}
@@ -185,7 +193,7 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
File updatedDocs = new SpringCloudCustomProjectDocumentationUpdater(
new ProjectGitHandler(properties)).updateDocsRepo(this.clonedDocProject,
releaseTrainVersion, "vAngel.SR33");
releaseTrainVersion, projects(), "vAngel.SR33");
String indexHtmlContent = new String(
Files.readAllBytes(new File(updatedDocs, "current/index.html").toPath()));
@@ -202,7 +210,7 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
ProjectGitHandler handler = BDDMockito.spy(new ProjectGitHandler(properties));
new SpringCloudCustomProjectDocumentationUpdater(handler).updateDocsRepo(
this.clonedDocProject, releaseTrainVersion, "vDalston.SR3");
this.clonedDocProject, releaseTrainVersion, projects(), "vDalston.SR3");
BDDMockito.then(handler).should(BDDMockito.never())
.commit(BDDMockito.any(File.class), BDDMockito.anyString());
@@ -218,7 +226,7 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
File updatedDocs = new SpringCloudCustomProjectDocumentationUpdater(
new ProjectGitHandler(properties)).updateDocsRepo(this.clonedDocProject,
releaseTrainVersion, "Angel.SR33");
releaseTrainVersion, projects(), "Angel.SR33");
String indexHtmlContent = new String(
Files.readAllBytes(new File(updatedDocs, "current/index.html").toPath()));
@@ -235,7 +243,7 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
properties.getGit().setDocumentationUrl(this.clonedDocProject.toURI().toString());
File updatedDocs = projectDocumentationUpdater(properties)
.updateDocsRepo(releaseTrainVersion, "vFinchley.SR33");
.updateDocsRepo(projects(), releaseTrainVersion, "vFinchley.SR33");
String indexHtmlContent = new String(
Files.readAllBytes(new File(updatedDocs, "current/index.html").toPath()));
@@ -252,7 +260,7 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
properties.getGit().setDocumentationUrl(this.clonedDocProject.toURI().toString());
File updatedDocs = projectDocumentationUpdater(properties)
.updateDocsRepo(releaseTrainVersion, "Finchley.SR33");
.updateDocsRepo(projects(), releaseTrainVersion, "Finchley.SR33");
String indexHtmlContent = new String(
Files.readAllBytes(new File(updatedDocs, "current/index.html").toPath()));
@@ -269,7 +277,7 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
properties.getGit().setUpdateDocumentationRepo(false);
File updatedDocs = projectDocumentationUpdater(properties)
.updateDocsRepo(releaseTrainVersion, "Finchley.SR33");
.updateDocsRepo(projects(), releaseTrainVersion, "Finchley.SR33");
then(updatedDocs).isNull();
}
@@ -279,4 +287,8 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
.getResource(relativePath).toURI());
}
private Projects projects() {
return new Projects(new ProjectVersion("spring-cloud-sleuth", "1.0.0.RELEASE"));
}
}

View File

@@ -20,6 +20,7 @@ import java.io.File;
import java.net.URISyntaxException;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.cloud.release.internal.ReleaserProperties;
@@ -45,6 +46,7 @@ public class MavenBomParserTests {
}
@Test
@Ignore("flakey")
public void should_throw_exception_when_boot_pom_is_missing() {
BomParser parser = MavenBomParserAccessor.cloudMavenBomParser(this.properties);
File file = new File(".");
@@ -66,6 +68,7 @@ public class MavenBomParserTests {
}
@Test
@Ignore("flakey")
public void should_throw_exception_when_boot_version_is_missing_in_pom() {
this.properties.getPom().setPomWithBootStarterParent("pom.xml");
BomParser parser = MavenBomParserAccessor.cloudMavenBomParser(this.properties);

View File

@@ -352,6 +352,115 @@ public class ProjectVersionTests {
.isNegative();
}
@Test
public void should_compare_builds_in_terms_of_maturity_for_projects() {
String thisVersion = "1.3.2.RELEASE";
then(projectVersion(thisVersion)
.isMoreMature(projectVersion("1.3.1.BUILD-SNAPSHOT"))).isTrue();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.3.1.M1")))
.isTrue();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.3.1.RC1")))
.isTrue();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.3.1.RELEASE")))
.isTrue();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.3.3.RELEASE")))
.isFalse();
then(projectVersion(thisVersion)
.isMoreMature(projectVersion("1.3.3.BUILD-SNAPSHOT"))).isTrue();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.3.3.M1")))
.isTrue();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.3.3.RC1")))
.isTrue();
}
@Test
public void should_compare_builds_in_terms_of_maturity_for_trains() {
String thisVersion = "Hoxton.SR1";
then(projectVersion(thisVersion)
.isMoreMature(projectVersion("Hoxton.BUILD-SNAPSHOT"))).isTrue();
then(projectVersion(thisVersion).isMoreMature(projectVersion("Hoxton.M1")))
.isTrue();
then(projectVersion(thisVersion).isMoreMature(projectVersion("Hoxton.RC1")))
.isTrue();
then(projectVersion(thisVersion).isMoreMature(projectVersion("Hoxton.RELEASE")))
.isTrue();
then(projectVersion(thisVersion)
.isMoreMature(projectVersion("Iexample.BUILD-SNAPSHOT"))).isTrue();
then(projectVersion(thisVersion).isMoreMature(projectVersion("Iexample.M1")))
.isTrue();
then(projectVersion(thisVersion).isMoreMature(projectVersion("Iexample.RC1")))
.isTrue();
then(projectVersion(thisVersion).isMoreMature(projectVersion("Iexample.RELEASE")))
.isFalse();
then(projectVersion(thisVersion).isMoreMature(projectVersion("Iexample.SR1")))
.isFalse();
thisVersion = "Hoxton.BUILD-SNAPSHOT";
then(projectVersion(thisVersion)
.isMoreMature(projectVersion("Hoxton.BUILD-SNAPSHOT"))).isFalse();
then(projectVersion(thisVersion).isMoreMature(projectVersion("Hoxton.M1")))
.isFalse();
then(projectVersion(thisVersion).isMoreMature(projectVersion("Hoxton.RC1")))
.isFalse();
then(projectVersion(thisVersion).isMoreMature(projectVersion("Hoxton.RELEASE")))
.isFalse();
then(projectVersion(thisVersion)
.isMoreMature(projectVersion("Iexample.BUILD-SNAPSHOT"))).isFalse();
then(projectVersion(thisVersion).isMoreMature(projectVersion("Iexample.M1")))
.isFalse();
then(projectVersion(thisVersion).isMoreMature(projectVersion("Iexample.RC1")))
.isFalse();
then(projectVersion(thisVersion).isMoreMature(projectVersion("Iexample.RELEASE")))
.isFalse();
then(projectVersion(thisVersion).isMoreMature(projectVersion("Iexample.SR1")))
.isFalse();
thisVersion = "1.0.1.RELEASE";
then(projectVersion(thisVersion)
.isMoreMature(projectVersion("1.0.1.BUILD-SNAPSHOT"))).isTrue();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.0.1.M1")))
.isTrue();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.0.1.RC1")))
.isTrue();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.0.1.RELEASE")))
.isFalse();
then(projectVersion(thisVersion)
.isMoreMature(projectVersion("1.0.2.BUILD-SNAPSHOT"))).isTrue();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.0.2.M1")))
.isTrue();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.0.2.RC1")))
.isTrue();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.0.2.RELEASE")))
.isFalse();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.0.2.SR1")))
.isFalse();
thisVersion = "1.0.1.BUILD-SNAPSHOT";
then(projectVersion(thisVersion)
.isMoreMature(projectVersion("1.0.1.BUILD-SNAPSHOT"))).isFalse();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.0.1.M1")))
.isFalse();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.0.1.RC1")))
.isFalse();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.0.1.RELEASE")))
.isFalse();
then(projectVersion(thisVersion)
.isMoreMature(projectVersion("1.0.2.BUILD-SNAPSHOT"))).isFalse();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.0.2.M1")))
.isFalse();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.0.2.RC1")))
.isFalse();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.0.2.RELEASE")))
.isFalse();
then(projectVersion(thisVersion).isMoreMature(projectVersion("1.0.2.SR1")))
.isFalse();
}
@Test
public void should_return_empty_group_id_when_it_is_missing() {
ProjectVersion projectVersion = projectVersion("1.0.0.RC1");

View File

@@ -1,257 +0,0 @@
/*
* 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 org.springframework.cloud.release.internal.docs;
import java.util.Arrays;
import java.util.List;
import org.assertj.core.api.BDDAssertions;
import org.junit.Test;
import org.springframework.cloud.release.internal.ReleaserProperties;
import org.springframework.cloud.release.internal.project.ProjectVersion;
import org.springframework.cloud.release.internal.project.Projects;
/**
* @author Marcin Grzejszczak
*/
public class ReleaseTrainContentsGeneratorTests {
@Test
public void should_return_empty_contents_if_there_versions_are_lower_than_current_ones() {
ReleaseTrainContentsGenerator generator = new ReleaseTrainContentsGenerator(
new ReleaserProperties());
String contents = generator.releaseTrainContents(contents(), olderReleaseTrain());
BDDAssertions.then(contents).isEmpty();
}
@Test
public void should_return_empty_contents_if_there_are_no_changes_in_the_versions() {
ReleaseTrainContentsGenerator generator = new ReleaseTrainContentsGenerator(
new ReleaserProperties());
String contents = generator.releaseTrainContents(contents(),
sameProjectsForCurrentGa());
BDDAssertions.then(contents).isEmpty();
}
@Test
public void should_return_contents_with_updated_current_release_train() {
ReleaseTrainContentsGenerator generator = new ReleaseTrainContentsGenerator(
new ReleaserProperties());
String contents = generator.releaseTrainContents(contents(),
newerProjectsForNewGa());
BDDAssertions.then(contents)
.contains("|Edgware.SR5|Finchley.SR2|Finchley.BUILD-SNAPSHOT|");
BDDAssertions.then(contents).contains(
" |spring-cloud-cli|1.4.1.RELEASE|3.0.0.RELEASE|2.0.1.BUILD-SNAPSHOT|");
}
@Test
public void should_return_contents_with_updated_previous_release_train() {
ReleaseTrainContentsGenerator generator = new ReleaseTrainContentsGenerator(
new ReleaserProperties());
String contents = generator.releaseTrainContents(contents(),
newerProjectsForOldGa());
BDDAssertions.then(contents)
.contains("|Edgware.SR6|Finchley.SR1|Finchley.BUILD-SNAPSHOT|");
BDDAssertions.then(contents).contains(
" |spring-cloud-cli|3.0.0.RELEASE|2.0.0.RELEASE|2.0.1.BUILD-SNAPSHOT|");
}
@Test
public void should_return_contents_with_updated_current_snapshot_train() {
ReleaseTrainContentsGenerator generator = new ReleaseTrainContentsGenerator(
new ReleaserProperties());
String contents = generator.releaseTrainContents(contents(),
newerProjectsForCurrentSnapshot());
BDDAssertions.then(contents)
.contains("|Edgware.SR5|Finchley.SR1|Finchley.BUILD-SNAPSHOT|");
BDDAssertions.then(contents).contains(
" |spring-cloud-cli|1.4.1.RELEASE|2.0.0.RELEASE|3.0.0.BUILD-SNAPSHOT|");
}
ReleaseTrainContents contents() {
Title title = new Title("Edgware.SR5", "Finchley.SR1", "Finchley.BUILD-SNAPSHOT");
List<Row> rows = Arrays.asList(
new Row("spring-cloud-aws", "1.2.3.RELEASE", "2.0.0.RELEASE",
"2.0.1.BUILD-SNAPSHOT"),
new Row("spring-cloud-bus", "1.3.3.RELEASE", "2.0.0.RELEASE",
"2.0.1.BUILD-SNAPSHOT"),
new Row("spring-cloud-cli", "1.4.1.RELEASE", "2.0.0.RELEASE",
"2.0.1.BUILD-SNAPSHOT"),
new Row("spring-cloud-commons", "1.3.5.RELEASE", "2.0.1.RELEASE",
"2.0.2.BUILD-SNAPSHOT"),
new Row("spring-cloud-contract", "1.2.6.RELEASE", "2.0.1.RELEASE",
"2.0.2.BUILD-SNAPSHOT"),
new Row("spring-cloud-config", "1.4.5.RELEASE", "2.0.1.RELEASE",
"2.0.2.BUILD-SNAPSHOT"),
new Row("spring-cloud-netflix", "1.4.6.RELEASE", "2.0.1.RELEASE",
"2.0.2.BUILD-SNAPSHOT"),
new Row("spring-cloud-security", "1.2.3.RELEASE", "2.0.0.RELEASE",
"2.0.1.BUILD-SNAPSHOT"),
new Row("spring-cloud-cloudfoundry", "1.1.2.RELEASE", "2.0.0.RELEASE",
"2.0.1.BUILD-SNAPSHOT"),
new Row("spring-cloud-consul", "1.3.5.RELEASE", "2.0.1.RELEASE",
"2.0.2.BUILD-SNAPSHOT"),
new Row("spring-cloud-sleuth", "1.3.5.RELEASE", "2.0.1.RELEASE",
"2.0.2.BUILD-SNAPSHOT"),
new Row("spring-cloud-stream", "Ditmars.SR4", "Elmhurst.SR1",
"Elmhurst.BUILD-SNAPSHOT"),
new Row("spring-cloud-zookeeper", "1.2.2.RELEASE", "2.0.0.RELEASE",
"2.0.1.BUILD-SNAPSHOT"),
new Row("spring-boot", "1.5.16.RELEASE", "2.0.4.RELEASE",
"2.0.4.BUILD-SNAPSHOT"),
new Row("spring-cloud-task", "1.2.3.RELEASE", "2.0.0.RELEASE",
"2.0.1.BUILD-SNAPSHOT"),
new Row("spring-cloud-vault", "1.1.2.RELEASE", "2.0.1.RELEASE",
"2.0.2.BUILD-SNAPSHOT"),
new Row("spring-cloud-gateway", "1.0.2.RELEASE", "2.0.1.RELEASE",
"2.0.2.BUILD-SNAPSHOT"),
new Row("spring-cloud-openfeign", "", "2.0.1.RELEASE",
"2.0.2.BUILD-SNAPSHOT"),
new Row("spring-cloud-function", "1.0.1.RELEASE", "1.0.0.RELEASE",
"1.0.1.BUILD-SNAPSHOT"));
return new ReleaseTrainContents(title, rows);
}
Projects olderReleaseTrain() {
return new Projects(new ProjectVersion("spring-cloud-aws", "2.0.0.RELEASE"),
new ProjectVersion("spring-cloud-bus", "2.0.0.RELEASE"),
new ProjectVersion("spring-cloud-cli", "2.0.0.RELEASE"),
new ProjectVersion("spring-cloud-commons", "2.0.1.RELEASE"),
new ProjectVersion("spring-cloud-contract", "2.0.1.RELEASE"),
new ProjectVersion("spring-cloud-config", "2.0.1.RELEASE"),
new ProjectVersion("spring-cloud-netflix", "2.0.1.RELEASE"),
new ProjectVersion("spring-cloud-security", "2.0.0.RELEASE"),
new ProjectVersion("spring-cloud-cloudfoundry", "2.0.0.RELEASE"),
new ProjectVersion("spring-cloud-consul", "2.0.1.RELEASE"),
new ProjectVersion("spring-cloud-sleuth", "2.0.1.RELEASE"),
new ProjectVersion("spring-cloud-stream", "Elmhurst.SR1"),
new ProjectVersion("spring-cloud-zookeeper", "2.0.0.RELEASE"),
new ProjectVersion("spring-boot", "2.0.4.RELEASE"),
new ProjectVersion("spring-cloud-task", "2.0.0.RELEASE"),
new ProjectVersion("spring-cloud-release", "Dalston.SR1"),
new ProjectVersion("spring-cloud-vault", "2.0.1.RELEASE"),
new ProjectVersion("spring-cloud-gateway", "2.0.1.RELEASE"),
new ProjectVersion("spring-cloud-openfeign", "2.0.1.RELEASE"),
new ProjectVersion("spring-cloud-function", "1.0.0.RELEASE"));
}
Projects sameProjectsForCurrentGa() {
return new Projects(new ProjectVersion("spring-cloud-aws", "2.0.0.RELEASE"),
new ProjectVersion("spring-cloud-bus", "2.0.0.RELEASE"),
new ProjectVersion("spring-cloud-cli", "2.0.0.RELEASE"),
new ProjectVersion("spring-cloud-commons", "2.0.1.RELEASE"),
new ProjectVersion("spring-cloud-contract", "2.0.1.RELEASE"),
new ProjectVersion("spring-cloud-config", "2.0.1.RELEASE"),
new ProjectVersion("spring-cloud-netflix", "2.0.1.RELEASE"),
new ProjectVersion("spring-cloud-security", "2.0.0.RELEASE"),
new ProjectVersion("spring-cloud-cloudfoundry", "2.0.0.RELEASE"),
new ProjectVersion("spring-cloud-consul", "2.0.1.RELEASE"),
new ProjectVersion("spring-cloud-sleuth", "2.0.1.RELEASE"),
new ProjectVersion("spring-cloud-stream", "Elmhurst.SR1"),
new ProjectVersion("spring-cloud-zookeeper", "2.0.0.RELEASE"),
new ProjectVersion("spring-boot", "2.0.4.RELEASE"),
new ProjectVersion("spring-cloud-task", "2.0.0.RELEASE"),
new ProjectVersion("spring-cloud-release", "Finchley.SR1"),
new ProjectVersion("spring-cloud-vault", "2.0.1.RELEASE"),
new ProjectVersion("spring-cloud-gateway", "2.0.1.RELEASE"),
new ProjectVersion("spring-cloud-openfeign", "2.0.1.RELEASE"),
new ProjectVersion("spring-cloud-function", "1.0.0.RELEASE"));
}
Projects newerProjectsForNewGa() {
return new Projects(new ProjectVersion("spring-cloud-aws", "2.0.0.RELEASE"),
new ProjectVersion("spring-cloud-bus", "3.0.0.RELEASE"),
new ProjectVersion("spring-cloud-cli", "3.0.0.RELEASE"),
new ProjectVersion("spring-cloud-commons", "3.0.1.RELEASE"),
new ProjectVersion("spring-cloud-contract", "3.0.1.RELEASE"),
new ProjectVersion("spring-cloud-config", "3.0.1.RELEASE"),
new ProjectVersion("spring-cloud-netflix", "3.0.1.RELEASE"),
new ProjectVersion("spring-cloud-security", "3.0.0.RELEASE"),
new ProjectVersion("spring-cloud-cloudfoundry", "3.0.0.RELEASE"),
new ProjectVersion("spring-cloud-consul", "3.0.1.RELEASE"),
new ProjectVersion("spring-cloud-sleuth", "3.0.1.RELEASE"),
new ProjectVersion("spring-cloud-stream", "Elmhurst.SR1"),
new ProjectVersion("spring-cloud-zookeeper", "3.0.0.RELEASE"),
new ProjectVersion("spring-boot", "3.0.4.RELEASE"),
new ProjectVersion("spring-cloud-task", "3.0.0.RELEASE"),
new ProjectVersion("spring-cloud-release", "Finchley.SR2"),
new ProjectVersion("spring-cloud-vault", "3.0.1.RELEASE"),
new ProjectVersion("spring-cloud-gateway", "3.0.1.RELEASE"),
new ProjectVersion("spring-cloud-openfeign", "3.0.1.RELEASE"),
new ProjectVersion("spring-cloud-function", "1.0.0.RELEASE"));
}
Projects newerProjectsForOldGa() {
return new Projects(new ProjectVersion("spring-cloud-aws", "2.0.0.RELEASE"),
new ProjectVersion("spring-cloud-bus", "3.0.0.RELEASE"),
new ProjectVersion("spring-cloud-cli", "3.0.0.RELEASE"),
new ProjectVersion("spring-cloud-commons", "3.0.1.RELEASE"),
new ProjectVersion("spring-cloud-contract", "3.0.1.RELEASE"),
new ProjectVersion("spring-cloud-config", "3.0.1.RELEASE"),
new ProjectVersion("spring-cloud-netflix", "3.0.1.RELEASE"),
new ProjectVersion("spring-cloud-security", "3.0.0.RELEASE"),
new ProjectVersion("spring-cloud-cloudfoundry", "3.0.0.RELEASE"),
new ProjectVersion("spring-cloud-consul", "3.0.1.RELEASE"),
new ProjectVersion("spring-cloud-sleuth", "3.0.1.RELEASE"),
new ProjectVersion("spring-cloud-stream", "Elmhurst.SR1"),
new ProjectVersion("spring-cloud-zookeeper", "3.0.0.RELEASE"),
new ProjectVersion("spring-boot", "3.0.4.RELEASE"),
new ProjectVersion("spring-cloud-task", "3.0.0.RELEASE"),
new ProjectVersion("spring-cloud-release", "Edgware.SR6"),
new ProjectVersion("spring-cloud-vault", "3.0.1.RELEASE"),
new ProjectVersion("spring-cloud-gateway", "3.0.1.RELEASE"),
new ProjectVersion("spring-cloud-openfeign", "3.0.1.RELEASE"),
new ProjectVersion("spring-cloud-function", "1.0.0.RELEASE"));
}
Projects newerProjectsForCurrentSnapshot() {
return new Projects(
new ProjectVersion("spring-cloud-aws", "2.0.0.BUILD-SNAPSHOT"),
new ProjectVersion("spring-cloud-bus", "3.0.0.BUILD-SNAPSHOT"),
new ProjectVersion("spring-cloud-cli", "3.0.0.BUILD-SNAPSHOT"),
new ProjectVersion("spring-cloud-commons", "3.0.1.BUILD-SNAPSHOT"),
new ProjectVersion("spring-cloud-contract", "3.0.1.BUILD-SNAPSHOT"),
new ProjectVersion("spring-cloud-config", "3.0.1.BUILD-SNAPSHOT"),
new ProjectVersion("spring-cloud-netflix", "3.0.1.BUILD-SNAPSHOT"),
new ProjectVersion("spring-cloud-security", "3.0.0.BUILD-SNAPSHOT"),
new ProjectVersion("spring-cloud-cloudfoundry", "3.0.0.BUILD-SNAPSHOT"),
new ProjectVersion("spring-cloud-consul", "3.0.1.BUILD-SNAPSHOT"),
new ProjectVersion("spring-cloud-sleuth", "3.0.1.BUILD-SNAPSHOT"),
new ProjectVersion("spring-cloud-stream", "Elmhurst.SR1"),
new ProjectVersion("spring-cloud-zookeeper", "3.0.0.BUILD-SNAPSHOT"),
new ProjectVersion("spring-boot", "3.0.4.BUILD-SNAPSHOT"),
new ProjectVersion("spring-cloud-task", "3.0.0.BUILD-SNAPSHOT"),
new ProjectVersion("spring-cloud-release", "Finchley.BUILD-SNAPSHOT"),
new ProjectVersion("spring-cloud-vault", "3.0.1.BUILD-SNAPSHOT"),
new ProjectVersion("spring-cloud-gateway", "3.0.1.BUILD-SNAPSHOT"),
new ProjectVersion("spring-cloud-openfeign", "3.0.1.BUILD-SNAPSHOT"),
new ProjectVersion("spring-cloud-function", "1.0.0.BUILD-SNAPSHOT"));
}
}

View File

@@ -87,45 +87,6 @@ public class ReleaseTrainContentsUpdaterTests {
ReleaseTrainContentsUpdaterTests.class.getResource(relativePath).toURI());
}
@Test
public void should_do_nothing_when_switch_is_off() {
this.properties.getGit().setUpdateSpringProject(false);
File file = this.updater.updateProjectRepo(oldReleaseTrain());
BDDAssertions.then(file).isNull();
}
@Test
public void should_not_update_the_contents_of_spring_project_repo_when_release_train_smaller()
throws GitAPIException {
this.properties.getGit()
.setSpringProjectUrl(this.springCloudRepo.getAbsolutePath() + "/");
File file = this.updater.updateProjectRepo(oldReleaseTrain());
BDDAssertions.then(file).isNotNull();
BDDAssertions
.then(GitTestUtils.openGitProject(file).log().call().iterator().next()
.getShortMessage())
.doesNotContain("Updating project page to release train");
}
@Test
public void should_update_the_contents_of_spring_project_repo_when_release_train_greater()
throws GitAPIException {
this.properties.getGit()
.setSpringProjectUrl(this.springCloudRepo.getAbsolutePath() + "/");
File file = this.updater.updateProjectRepo(newReleaseTrain());
BDDAssertions.then(file).isNotNull();
BDDAssertions
.then(GitTestUtils.openGitProject(file).log().call().iterator().next()
.getShortMessage())
.contains("Updating project page to release train [Edgware.SR7]");
}
@Test
public void should_do_nothing_when_switch_is_off_for_wiki_update() {
this.properties.getGit().setUpdateReleaseTrainWiki(false);

View File

@@ -83,14 +83,9 @@ final class Tasks {
static Task UPDATE_DOCUMENTATION = task("updateDocumentation", "ud",
"UPDATE DOCUMENTATION", "Updating documentation repository", args -> {
args.releaser.updateDocumentationRepository(args.properties,
args.versionFromScRelease);
args.projects, args.versionFromScRelease);
}, TaskType.POST_RELEASE);
@Deprecated
static Task UPDATE_SPRING_PROJECT_PAGE = task("updateSpringProjectPage", "up",
"UPDATE SPRING PROJECT PAGE", "Updating Spring Project page", args -> {
args.releaser.updateSpringProjectPage(args.projects);
}, TaskType.POST_RELEASE);
static Task RUN_UPDATED_SAMPLES = task("runUpdatedSample", "ru",
"UPDATE AND RUN SAMPLES",
"Updates the sample project with versions and runs samples", args -> {

View File

@@ -16,14 +16,10 @@
package org.springframework.cloud.release.internal.docs;
import java.io.File;
import edu.emory.mathcs.backport.java.util.Collections;
import org.springframework.cloud.release.internal.ReleaserProperties;
import org.springframework.cloud.release.internal.git.ProjectGitHandler;
import org.springframework.cloud.release.internal.project.Projects;
import org.springframework.cloud.release.internal.template.TemplateGenerator;
/**
* @author Marcin Grzejszczak
@@ -37,18 +33,4 @@ public class TestDocumentationUpdater extends DocumentationUpdater {
Collections.singletonList(updater)), testRelease);
}
public static class TestReleaseContentsUpdater extends ReleaseTrainContentsUpdater {
public TestReleaseContentsUpdater(ReleaserProperties properties,
ProjectGitHandler handler, TemplateGenerator templateGenerator) {
super(properties, handler, templateGenerator);
}
@Override
public File updateProjectRepo(Projects projects) {
return super.updateProjectRepo(projects);
}
}
}

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 org.springframework.cloud.release.internal.docs;
import org.springframework.cloud.release.internal.ReleaserProperties;
import org.springframework.cloud.release.internal.git.ProjectGitHandler;
import org.springframework.cloud.release.internal.template.TemplateGenerator;
/**
* @author Marcin Grzejszczak
*/
public class TestReleaseContentsUpdater extends ReleaseTrainContentsUpdater {
public TestReleaseContentsUpdater(ReleaserProperties properties,
ProjectGitHandler handler, TemplateGenerator templateGenerator) {
super(properties, handler, templateGenerator);
}
}

View File

@@ -56,6 +56,7 @@ import org.springframework.cloud.release.internal.buildsystem.TestPomReader;
import org.springframework.cloud.release.internal.buildsystem.TestUtils;
import org.springframework.cloud.release.internal.docs.DocumentationUpdater;
import org.springframework.cloud.release.internal.docs.TestDocumentationUpdater;
import org.springframework.cloud.release.internal.docs.TestReleaseContentsUpdater;
import org.springframework.cloud.release.internal.git.GitTestUtils;
import org.springframework.cloud.release.internal.git.ProjectGitHandler;
import org.springframework.cloud.release.internal.github.ProjectGitHubHandler;
@@ -93,8 +94,6 @@ public class AcceptanceTests {
File documentationFolder;
File cloudProjectFolder;
TestProjectGitHubHandler gitHandler;
NonAssertingTestProjectGitHandler nonAssertingGitHandler;
@@ -461,7 +460,8 @@ public class AcceptanceTests {
private void thenDocumentationWasUpdated() {
BDDMockito.then(this.documentationUpdater).should().updateDocsRepo(
BDDMockito.any(ProjectVersion.class), BDDMockito.anyString());
BDDMockito.any(Projects.class), BDDMockito.any(ProjectVersion.class),
BDDMockito.anyString());
}
private void thenDocumentationWasNotUpdated() {
@@ -791,15 +791,17 @@ public class AcceptanceTests {
GradleUpdater gradleUpdater = new GradleUpdater(properties);
SaganUpdater saganUpdater = new SaganUpdater(this.saganClient,
this.releaserProperties);
TestReleaseContentsUpdater testReleaseContentsUpdater = new TestReleaseContentsUpdater(
properties, gitHandler, templateGenerator);
DocumentationUpdater documentationUpdater = new TestDocumentationUpdater(
properties,
SpringCloudDocsAccessor.testUpdater(gitHandler, "Brixton.SR1"),
gitHandler, new TestDocumentationUpdater.TestReleaseContentsUpdater(
properties, gitHandler, templateGenerator)) {
gitHandler, testReleaseContentsUpdater) {
@Override
public File updateDocsRepo(ProjectVersion currentProject,
public File updateDocsRepo(Projects projects, ProjectVersion currentProject,
String bomReleaseBranch) {
File file = super.updateDocsRepo(currentProject, bomReleaseBranch);
File file = super.updateDocsRepo(projects, currentProject,
bomReleaseBranch);
AcceptanceTests.this.documentationFolder = file;
return file;
}
@@ -830,20 +832,12 @@ public class AcceptanceTests {
.spy(new TestDocumentationUpdater(properties,
SpringCloudDocsAccessor.testUpdater(nonAssertingGitHandler,
"Brixton.SR1"),
nonAssertingGitHandler,
new TestDocumentationUpdater.TestReleaseContentsUpdater(
properties, nonAssertingGitHandler, templateGenerator) {
@Override
public File updateProjectRepo(Projects projects) {
File file = super.updateProjectRepo(projects);
AcceptanceTests.this.cloudProjectFolder = file;
return file;
}
}) {
nonAssertingGitHandler, new TestReleaseContentsUpdater(properties,
nonAssertingGitHandler, templateGenerator)) {
@Override
public File updateDocsRepo(ProjectVersion currentProject,
String bomReleaseBranch) {
File file = super.updateDocsRepo(currentProject,
public File updateDocsRepo(Projects projects,
ProjectVersion currentProject, String bomReleaseBranch) {
File file = super.updateDocsRepo(projects, currentProject,
bomReleaseBranch);
AcceptanceTests.this.documentationFolder = file;
return file;