Generate Release Train Docs; fixes gh-91

This commit is contained in:
Marcin Grzejszczak
2018-10-25 17:45:37 +02:00
parent a39c179b34
commit 0ff2b4a2b8
11 changed files with 220 additions and 27 deletions

View File

@@ -285,14 +285,17 @@ The following properties are used for both meta release and a release of an indi
- `releaser.git.release-train-bom-url` - URL to a project containing a BOM. Defaults to Spring Cloud Release Git repository: `https://github.com/spring-cloud/spring-cloud-release`.
- `releaser.git.documentation-url` - URL to the documentation Git repository. Defaults to `https://github.com/spring-cloud/spring-cloud-static`.
- `releaser.git.documentation-branch` - Branch to check out for the documentation project. Defaults to `gh-pages`.
- `releaser.git.update-documentation-repo` - If `true` then will update documentation repository with the `current` URL. Defaults to `true`.
- `releaser.git.spring-project-url` - URL to the documentation Git repository. Defaults to `https://github.com/spring-projects/spring-cloud`.
- `releaser.git.spring-project-branch` - Branch to check out for the documentation project. Defaults to `gh-pages`.
- `releaser.git.update-spring-project` - If `true` then will update Spring Project page with the current release train values. Defaults to `true`.
- `releaser.git.test-samples-project-url` - URL to the test samples to be checked against the given release train. Defaults to `https://github.com/spring-cloud/spring-cloud-core-tests`.
- `releaser.git.test-samples-project-branch` - Branch to check out for test samples. Defaults to `master`.
- `releaser.git.run-updated-samples` - If `true` then will update samples and run the the build. Defaults to `true`.
- `releaser.git.update-documentation-repo` - If `true` then will update documentation repository with the `current` URL. Defaults to `true`.
- `releaser.git.release-train-docs-url` - URL to the release train documentation. Defaults to `https://github.com/spring-cloud-sample/scripts`.
- `releaser.git.release-train-docs-branch` - Branch to check out for release train documentation. Defaults to `master`.
- `releaser.git.update-release-train-docs` - If `true` then will update the release train documentation project and run the generation. Defaults to `true`.
- `releaser.git.update-spring-guides` - If `true` then will update Spring Guides with the current release train. Defaults to `true`.
- `releaser.git.update-spring-project` - If `true` then will update Spring Project page with the current release train values. Defaults to `true`.
- `releaser.git.oauth-token` - GitHub OAuth token to be used to interact with GitHub repo.
- `releaser.git.username` - Optional Git username. If not passed keys will be used for authentication.
- `releaser.git.password` - Optional Git password. If not passed keys will be used for authentication.

View File

@@ -275,14 +275,17 @@ The following properties are used for both meta release and a release of an indi
- `releaser.git.release-train-bom-url` - URL to a project containing a BOM. Defaults to Spring Cloud Release Git repository: `https://github.com/spring-cloud/spring-cloud-release`.
- `releaser.git.documentation-url` - URL to the documentation Git repository. Defaults to `https://github.com/spring-cloud/spring-cloud-static`.
- `releaser.git.documentation-branch` - Branch to check out for the documentation project. Defaults to `gh-pages`.
- `releaser.git.update-documentation-repo` - If `true` then will update documentation repository with the `current` URL. Defaults to `true`.
- `releaser.git.spring-project-url` - URL to the documentation Git repository. Defaults to `https://github.com/spring-projects/spring-cloud`.
- `releaser.git.spring-project-branch` - Branch to check out for the documentation project. Defaults to `gh-pages`.
- `releaser.git.update-spring-project` - If `true` then will update Spring Project page with the current release train values. Defaults to `true`.
- `releaser.git.test-samples-project-url` - URL to the test samples to be checked against the given release train. Defaults to `https://github.com/spring-cloud/spring-cloud-core-tests`.
- `releaser.git.test-samples-project-branch` - Branch to check out for test samples. Defaults to `master`.
- `releaser.git.run-updated-samples` - If `true` then will update samples and run the the build. Defaults to `true`.
- `releaser.git.update-documentation-repo` - If `true` then will update documentation repository with the `current` URL. Defaults to `true`.
- `releaser.git.release-train-docs-url` - URL to the release train documentation. Defaults to `https://github.com/spring-cloud-sample/scripts`.
- `releaser.git.release-train-docs-branch` - Branch to check out for release train documentation. Defaults to `master`.
- `releaser.git.update-release-train-docs` - If `true` then will update the release train documentation project and run the generation. Defaults to `true`.
- `releaser.git.update-spring-guides` - If `true` then will update Spring Guides with the current release train. Defaults to `true`.
- `releaser.git.update-spring-project` - If `true` then will update Spring Project page with the current release train values. Defaults to `true`.
- `releaser.git.oauth-token` - GitHub OAuth token to be used to interact with GitHub repo.
- `releaser.git.username` - Optional Git username. If not passed keys will be used for authentication.
- `releaser.git.password` - Optional Git password. If not passed keys will be used for authentication.

View File

@@ -232,4 +232,13 @@ public class Releaser {
log.warn("\nUnable to update and run samples", e);
}
}
public void generateReleaseTrainDocumentation(Projects projects) {
try {
this.postReleaseActions.generateReleaseTrainDocumentation(projects);
log.info("\nSuccessfully updated and generated release train documentation");
} catch (Exception e) {
log.warn("\nUnable to update and generate release train documentation", e);
}
}
}

View File

@@ -156,6 +156,11 @@ public class ReleaserProperties implements Serializable {
*/
private String testSamplesProjectUrl = "https://github.com/spring-cloud/spring-cloud-core-tests";
/**
* URL to the release train documentation
*/
private String releaseTrainDocsUrl = "https://github.com/spring-cloud-samples/scripts";
/**
* Branch to check out for the documentation project
*/
@@ -172,9 +177,9 @@ public class ReleaserProperties implements Serializable {
private String testSamplesBranch = "master";
/**
* If {@code false}, will not update the documentation repository.
* Branch to check out for the release train docs
*/
private boolean updateDocumentationRepo = true;
private String releaseTrainDocsBranch = "master";
/**
* Where should the Spring Cloud Release repo get cloned to. If {@code null} defaults to a temporary directory
@@ -207,6 +212,11 @@ public class ReleaserProperties implements Serializable {
*/
private Integer numberOfCheckedMilestones = 10;
/**
* If {@code false}, will not update the documentation repository.
*/
private boolean updateDocumentationRepo = true;
/**
* If set to {@code false}, will not update Spring Guides for a release train.
*/
@@ -223,6 +233,11 @@ public class ReleaserProperties implements Serializable {
*/
private boolean runUpdatedSamples = true;
/**
* If set to {@code false}, will not update the release train docs
*/
private boolean updateReleaseTrainDocs = true;
public String getReleaseTrainBomUrl() {
return this.releaseTrainBomUrl;
}
@@ -359,6 +374,30 @@ public class ReleaserProperties implements Serializable {
this.updateSpringProject = updateSpringProject;
}
public String getReleaseTrainDocsUrl() {
return releaseTrainDocsUrl;
}
public void setReleaseTrainDocsUrl(String releaseTrainDocsUrl) {
this.releaseTrainDocsUrl = releaseTrainDocsUrl;
}
public String getReleaseTrainDocsBranch() {
return releaseTrainDocsBranch;
}
public void setReleaseTrainDocsBranch(String releaseTrainDocsBranch) {
this.releaseTrainDocsBranch = releaseTrainDocsBranch;
}
public boolean isUpdateReleaseTrainDocs() {
return updateReleaseTrainDocs;
}
public void setUpdateReleaseTrainDocs(boolean updateReleaseTrainDocs) {
this.updateReleaseTrainDocs = updateReleaseTrainDocs;
}
@Override
public String toString() {
return "Git{" +
@@ -486,6 +525,11 @@ public class ReleaserProperties implements Serializable {
"./target/gh-pages.sh -v {{version}} -c"
};
/**
* Command to be executed to generate release train documentation
*/
private String generateReleaseTrainDocsCommand = "./release_train.sh --retrieveversions --version {{version}} --ghpages --auto";
public static final String SYSTEM_PROPS_PLACEHOLDER = "{{systemProps}}";
/**
@@ -527,6 +571,14 @@ public class ReleaserProperties implements Serializable {
return this.publishDocsCommands;
}
public String getGenerateReleaseTrainDocsCommand() {
return this.generateReleaseTrainDocsCommand;
}
public void setGenerateReleaseTrainDocsCommand(String generateReleaseTrainDocsCommand) {
this.generateReleaseTrainDocsCommand = generateReleaseTrainDocsCommand;
}
public void setPublishDocsCommands(String[] publishDocsCommands) {
this.publishDocsCommands = publishDocsCommands;
}
@@ -542,8 +594,9 @@ public class ReleaserProperties implements Serializable {
@Override public String toString() {
return "Maven{" + "buildCommand='" + this.buildCommand + '\'' + ", deployCommand='"
+ this.deployCommand + '\'' + ", publishDocsCommands=" + Arrays
.toString(this.publishDocsCommands) + ", waitTimeInMinutes="
+ this.waitTimeInMinutes + '}';
.toString(this.publishDocsCommands) +
"generateReleaseTrainDocsCommand='" + this.generateReleaseTrainDocsCommand + '\'' +
", waitTimeInMinutes=" + this.waitTimeInMinutes + '}';
}
}

View File

@@ -76,6 +76,11 @@ public class ProjectGitHandler implements ReleaserPropertiesAware {
return cloneProject(this.properties.getGit().getReleaseTrainBomUrl());
}
public File cloneReleaseTrainDocumentationProject() {
return cloneAndCheckOut(this.properties.getGit().getReleaseTrainDocsUrl(),
this.properties.getGit().getReleaseTrainDocsBranch());
}
public File cloneDocumentationProject() {
return cloneAndCheckOut(this.properties.getGit()
.getDocumentationUrl(), this.properties.getGit()

View File

@@ -36,7 +36,7 @@ public class PostReleaseActions {
/**
* Clones the test project, updates it and runs tests
*
* @param projects - set of project with versions to assert agains
* @param projects - set of project with versions to assert against
*/
public void runUpdatedTests(Projects projects) {
if (!this.properties.getGit().isRunUpdatedSamples() ||
@@ -47,16 +47,40 @@ public class PostReleaseActions {
}
File file = this.projectGitHandler.cloneTestSamplesProject();
ProjectVersion projectVersion = new ProjectVersion(file);
Projects newProjects = addVersionForTestsProject(projects, projectVersion);
String releaseTrainVersion =
projects.forName(this.properties.getMetaRelease().getReleaseTrainProjectName()).version;
Projects newProjects = addVersionForTestsProject(projects, projectVersion, releaseTrainVersion);
this.projectPomUpdater
.updateProjectFromReleaseTrain(file, newProjects, projectVersion, false);
this.projectBuilder.build(projectVersion, file.getAbsolutePath());
}
private Projects addVersionForTestsProject(Projects projects, ProjectVersion projectVersion) {
/**
* Clones the release train documentation project
*
* @param projects - set of project with versions to assert against
*/
public void generateReleaseTrainDocumentation(Projects projects) {
if (!this.properties.getGit().isUpdateReleaseTrainDocs() ||
!this.properties.getMetaRelease().isEnabled()) {
log.info("Will not update the release train documentation, since the switch to do so "
+ "is off. Set [releaser.git.update-release-train-docs] to [true] to change that");
return;
}
File file = this.projectGitHandler.cloneReleaseTrainDocumentationProject();
ProjectVersion projectVersion = new ProjectVersion(file);
String releaseTrainVersion =
projects.forName(this.properties.getMetaRelease().getReleaseTrainProjectName()).version;
Projects newProjects = addVersionForTestsProject(projects, projectVersion, releaseTrainVersion);
this.projectPomUpdater
.updateProjectFromReleaseTrain(file, newProjects, projectVersion, false);
this.projectBuilder.generateReleaseTrainDocs(releaseTrainVersion, file.getAbsolutePath());
}
private Projects addVersionForTestsProject(Projects projects, ProjectVersion projectVersion,
String releaseTrainVersion) {
Projects newProjects = new Projects(projects);
newProjects.add(new ProjectVersion(projectVersion.projectName,
projects.forName(this.properties.getMetaRelease().getReleaseTrainProjectName()).version));
newProjects.add(new ProjectVersion(projectVersion.projectName, releaseTrainVersion));
return newProjects;
}
}

View File

@@ -53,6 +53,18 @@ public class ProjectBuilder implements ReleaserPropertiesAware {
}
}
public void generateReleaseTrainDocs(String version, String projectRoot) {
try {
String updatedCommand =
this.properties.getMaven().getGenerateReleaseTrainDocsCommand().replace(VERSION_MUSTACHE, version);
runCommand(projectRoot, updatedCommand.split(" "));
assertNoHtmlFilesInDocsContainUnresolvedTags(this.properties.getWorkingDir());
log.info("No HTML files from docs contain unresolved tags");
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
private String commandWithSystemProps(String command,
ProjectVersion version) {
if (command.contains(ReleaserProperties.Maven.SYSTEM_PROPS_PLACEHOLDER)) {
@@ -184,13 +196,13 @@ class ProcessExecutor implements ReleaserPropertiesAware {
void runCommand(String[] commands, long waitTimeInMinutes) {
try {
String workingDir = this.workingDir;
log.debug("Will run the build from [{}] via {} and wait for result for [{}] minutes",
log.debug("Will run the command from [{}] via {} and wait for result for [{}] minutes",
workingDir, commands, waitTimeInMinutes);
ProcessBuilder builder = builder(commands, workingDir);
Process process = startProcess(builder);
boolean finished = process.waitFor(waitTimeInMinutes, TimeUnit.MINUTES);
if (!finished) {
log.error("The build hasn't managed to finish in [{}] minutes", waitTimeInMinutes);
log.error("The command hasn't managed to finish in [{}] minutes", waitTimeInMinutes);
process.destroyForcibly();
throw new IllegalStateException("Process waiting time of [" + waitTimeInMinutes + "] minutes exceeded");
}

View File

@@ -31,12 +31,18 @@ public class PostReleaseActionsTests {
File temporaryFolder;
TestPomReader testPomReader = new TestPomReader();
ReleaserProperties properties = new ReleaserProperties();
File clonedTestSamples;
File cloned;
ProjectGitHandler projectGitHandler = new ProjectGitHandler(this.properties) {
@Override
public File cloneTestSamplesProject() {
clonedTestSamples = super.cloneTestSamplesProject();
return clonedTestSamples;
cloned = super.cloneTestSamplesProject();
return cloned;
}
@Override
public File cloneReleaseTrainDocumentationProject() {
cloned = super.cloneTestSamplesProject();
return cloned;
}
};
ProjectPomUpdater updater = new ProjectPomUpdater(this.properties);
@@ -50,29 +56,29 @@ public class PostReleaseActionsTests {
}
@Test
public void should_do_nothing_when_is_not_meta_release() {
public void should_do_nothing_when_is_not_meta_release_and_update_test_is_called() {
this.properties.getMetaRelease().setEnabled(false);
PostReleaseActions actions = new PostReleaseActions(this.projectGitHandler,
this.updater, this.builder, this.properties);
actions.runUpdatedTests(currentGa());
BDDAssertions.then(clonedTestSamples).isNull();
BDDAssertions.then(cloned).isNull();
}
@Test
public void should_do_nothing_when_the_switch_for_sample_check_is_off() {
public void should_do_nothing_when_the_switch_for_sample_check_is_off_and_update_test_is_called() {
this.properties.getGit().setRunUpdatedSamples(false);
PostReleaseActions actions = new PostReleaseActions(this.projectGitHandler,
this.updater, this.builder, this.properties);
actions.runUpdatedTests(currentGa());
BDDAssertions.then(clonedTestSamples).isNull();
BDDAssertions.then(cloned).isNull();
}
@Test
public void should_update_project_and_run_tests() {
public void should_update_project_and_run_tests_and_update_test_is_called() {
this.properties.getMetaRelease().setEnabled(true);
this.properties.getGit().setTestSamplesProjectUrl(tmpFile("spring-cloud-core-tests/").getAbsolutePath() + "/");
this.properties.getMaven().setBuildCommand("touch build.log");
@@ -81,15 +87,54 @@ public class PostReleaseActionsTests {
actions.runUpdatedTests(currentGa());
Model rootPom = this.testPomReader.readPom(new File(clonedTestSamples, "pom.xml"));
Model rootPom = this.testPomReader.readPom(new File(cloned, "pom.xml"));
BDDAssertions.then(rootPom.getVersion()).isEqualTo("Finchley.SR1");
BDDAssertions.then(rootPom.getParent().getVersion()).isEqualTo("2.0.4.RELEASE");
BDDAssertions.then(sleuthParentPomVersion()).isEqualTo("2.0.4.RELEASE");
BDDAssertions.then(new File(clonedTestSamples, "build.log")).exists();
BDDAssertions.then(new File(cloned, "build.log")).exists();
}
@Test
public void should_do_nothing_when_is_not_meta_release_and_release_train_docs_generation_is_called() {
this.properties.getMetaRelease().setEnabled(false);
PostReleaseActions actions = new PostReleaseActions(this.projectGitHandler,
this.updater, this.builder, this.properties);
actions.generateReleaseTrainDocumentation(currentGa());
BDDAssertions.then(cloned).isNull();
}
@Test
public void should_do_nothing_when_the_switch_for_sample_check_is_off_and_release_train_docs_generation_is_called() {
this.properties.getGit().setUpdateReleaseTrainDocs(false);
PostReleaseActions actions = new PostReleaseActions(this.projectGitHandler,
this.updater, this.builder, this.properties);
actions.generateReleaseTrainDocumentation(currentGa());
BDDAssertions.then(cloned).isNull();
}
@Test
public void should_update_project_and_run_tests_and_release_train_docs_generation_is_called() {
this.properties.getMetaRelease().setEnabled(true);
this.properties.getGit().setReleaseTrainDocsUrl(tmpFile("spring-cloud-core-tests/").getAbsolutePath() + "/");
this.properties.getMaven().setGenerateReleaseTrainDocsCommand("touch generate.log");
PostReleaseActions actions = new PostReleaseActions(this.projectGitHandler,
this.updater, this.builder, this.properties);
actions.generateReleaseTrainDocumentation(currentGa());
Model rootPom = this.testPomReader.readPom(new File(cloned, "pom.xml"));
BDDAssertions.then(rootPom.getVersion()).isEqualTo("Finchley.SR1");
BDDAssertions.then(rootPom.getParent().getVersion()).isEqualTo("2.0.4.RELEASE");
BDDAssertions.then(sleuthParentPomVersion()).isEqualTo("2.0.4.RELEASE");
BDDAssertions.then(new File(cloned, "generate.log")).exists();
}
private String sleuthParentPomVersion() {
return this.testPomReader.readPom(new File(clonedTestSamples, "sleuth/pom.xml"))
return this.testPomReader.readPom(new File(cloned, "sleuth/pom.xml"))
.getParent().getVersion();
}

View File

@@ -383,6 +383,26 @@ public class ProjectBuilderTests {
.contains("1.1.0.RELEASE");
}
@Test
public void should_successfully_execute_an_update_docs_command_and_substitute_the_version() throws Exception {
ReleaserProperties properties = new ReleaserProperties();
properties.getMaven().setGenerateReleaseTrainDocsCommand("echo '{{version}}'");
File resolved = tmpFile("/builder/resolved");
properties.setWorkingDir(resolved.getPath());
TestProcessExecutor executor = testExecutor(properties.getWorkingDir());
ProjectBuilder builder = new ProjectBuilder(properties) {
@Override
ProcessExecutor executor(String workingDir) {
return executor;
}
};
builder.generateReleaseTrainDocs("1.1.0.RELEASE", resolved.getAbsolutePath());
then(asString(tmpFile("/builder/resolved/resolved.log")))
.contains("1.1.0.RELEASE");
}
@Test
public void should_throw_exception_when_publish_docs_command_took_too_long_to_execute() throws Exception {
ReleaserProperties properties = new ReleaserProperties();

View File

@@ -83,6 +83,12 @@ class Tasks {
args -> {
args.releaser.runUpdatedSamples(args.projects);
},TaskType.POST_RELEASE);
static Task UPDATE_RELEASE_TRAIN_DOCUMENTATION = task("updateReleaseTrainDocs", "ur",
"UPDATE RELEASE TRAIN DOCS",
"Update release train documentation",
args -> {
args.releaser.generateReleaseTrainDocumentation(args.projects);
},TaskType.POST_RELEASE);
static final List<Task> DEFAULT_TASKS_PER_PROJECT = Stream.of(
Tasks.UPDATING_POMS,
@@ -100,7 +106,7 @@ class Tasks {
Tasks.RUN_UPDATED_SAMPLES,
Tasks.CREATE_TEMPLATES,
Tasks.UPDATE_GUIDES,
// Generate docs
Tasks.UPDATE_RELEASE_TRAIN_DOCUMENTATION,
Tasks.UPDATE_DOCUMENTATION,
Tasks.UPDATE_SPRING_PROJECT_PAGE
).collect(Collectors.toList());

View File

@@ -213,6 +213,7 @@ public class AcceptanceTests {
BDDAssertions.then(gitProject(this.cloudProjectFolder).log().call().iterator().next().getShortMessage())
.contains("Updating project page to release train [Edgware.SR10]");
thenRunUpdatedTestsWereCalled();
thenUpdateReleaseTrainDocsWasCalled();
}
private void thenRunUpdatedTestsWereCalled() {
@@ -220,6 +221,11 @@ public class AcceptanceTests {
.runUpdatedTests(BDDMockito.any(Projects.class));
}
private void thenUpdateReleaseTrainDocsWasCalled() {
BDDMockito.then(this.postReleaseActions).should()
.generateReleaseTrainDocumentation(BDDMockito.any(Projects.class));
}
private Map<String, String> edgwareSr10() {
Map<String, String> versions = new LinkedHashMap<>();
versions.put("spring-boot", "1.5.16.RELEASE");
@@ -781,6 +787,13 @@ public class AcceptanceTests {
return file;
}
@Override
public File cloneReleaseTrainDocumentationProject() {
File file = super.cloneReleaseTrainDocumentationProject();
this.clonedProjects.add(file);
return file;
}
@Override public File cloneProjectFromOrg(String projectName) {
File file = super.cloneProjectFromOrg(projectName);
this.clonedProjects.add(file);