Refactoring to batch (#181)
The rationale of this pull request is to * have more maintainable and granular code * not maintain the custom made job engine * allow the users to customize the defaults of the releaser more easy * allow the users to create their own steps without the need to change any existing code * allow the users to fully change the flows and tasks logic * abstract underlying batch mechanism (Spring Batch) so it doesn't leak to production code * allow parallelization of the release process and release tasks
This commit is contained in:
committed by
GitHub
parent
ea85372e05
commit
8992e45321
0
releaser-spring/.jdk8
Normal file
0
releaser-spring/.jdk8
Normal file
109
releaser-spring/pom.xml
Normal file
109
releaser-spring/pom.xml
Normal file
@@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>releaser-spring</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud.internal</groupId>
|
||||
<artifactId>releaser-parent</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud.internal</groupId>
|
||||
<artifactId>releaser-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jgit</groupId>
|
||||
<artifactId>org.eclipse.jgit</artifactId>
|
||||
<version>${org.eclipse.jgit-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.jopt-simple</groupId>
|
||||
<artifactId>jopt-simple</artifactId>
|
||||
<version>${jopt-simple.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-yaml</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jakewharton.fliptables</groupId>
|
||||
<artifactId>fliptables</artifactId>
|
||||
<version>${fliptables.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-batch</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>sonar</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>pre-unit-test</id>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<propertyName>surefireArgLine</propertyName>
|
||||
<destFile>${project.build.directory}/jacoco.exec</destFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>post-unit-test</id>
|
||||
<phase>test</phase>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<!-- Sets the path to the file which contains the execution data. -->
|
||||
<dataFile>${project.build.directory}/jacoco.exec</dataFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<!-- Sets the VM argument line used when unit tests are run. -->
|
||||
<argLine>${surefireArgLine}</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser;
|
||||
|
||||
import releaser.internal.options.Options;
|
||||
import releaser.internal.options.Parser;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.spring.ExecutionResultHandler;
|
||||
import releaser.internal.spring.SpringReleaser;
|
||||
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
|
||||
public class ReleaserCommandLineRunner implements CommandLineRunner {
|
||||
|
||||
private final SpringReleaser releaser;
|
||||
|
||||
private final ExecutionResultHandler executionResultHandler;
|
||||
|
||||
private final Parser parser;
|
||||
|
||||
public ReleaserCommandLineRunner(SpringReleaser releaser,
|
||||
ExecutionResultHandler executionResultHandler, Parser parser) {
|
||||
this.releaser = releaser;
|
||||
this.executionResultHandler = executionResultHandler;
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... strings) {
|
||||
// TODO:
|
||||
// * Check out Spring Shell - maybe move interactive stuff out of it
|
||||
// * Spring Shell would spit out the options at the end
|
||||
// * Check why I can't run a composite job as a batch job (transaction not
|
||||
// committed exception)
|
||||
Options options = this.parser.parse(strings);
|
||||
ExecutionResult executionResult = this.releaser.release(options);
|
||||
this.executionResultHandler.accept(executionResult);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.buildsystem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import releaser.internal.ReleaserProperties;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
class BuildsystemConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
BomParser mavenBomParser(ReleaserProperties releaserProperties,
|
||||
@Autowired(required = false) List<CustomBomParser> customBomParsers) {
|
||||
return new MavenBomParser(releaserProperties, customBomParsers(customBomParsers));
|
||||
}
|
||||
|
||||
private List<CustomBomParser> customBomParsers(
|
||||
List<CustomBomParser> customBomParsers) {
|
||||
return customBomParsers == null ? new ArrayList<>() : customBomParsers;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
BomParser gradleBomParser(ReleaserProperties releaserProperties,
|
||||
@Autowired(required = false) List<CustomBomParser> customBomParsers) {
|
||||
return new GradleBomParser(releaserProperties,
|
||||
customBomParsers(customBomParsers));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
ProjectPomUpdater pomUpdater(ReleaserProperties releaserProperties,
|
||||
List<BomParser> bomParsers) {
|
||||
return new ProjectPomUpdater(releaserProperties, bomParsers);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.options;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class Options implements Serializable {
|
||||
|
||||
/**
|
||||
* Is meta release set.
|
||||
*/
|
||||
public Boolean metaRelease;
|
||||
|
||||
/**
|
||||
* Is full release set.
|
||||
*/
|
||||
public Boolean fullRelease;
|
||||
|
||||
/**
|
||||
* Is interactive mode set.
|
||||
*/
|
||||
public Boolean interactive;
|
||||
|
||||
/**
|
||||
* Is dry run set.
|
||||
*/
|
||||
public Boolean dryRun;
|
||||
|
||||
/**
|
||||
* List of task names to release.
|
||||
*/
|
||||
public List<String> taskNames;
|
||||
|
||||
/**
|
||||
* Name of the task / projects to start from.
|
||||
*/
|
||||
public String startFrom = "";
|
||||
|
||||
/**
|
||||
* Range of task / projects to release.
|
||||
*/
|
||||
public String range = "";
|
||||
|
||||
Options(Boolean metaRelease, Boolean fullRelease, Boolean interactive, Boolean dryRun,
|
||||
List<String> taskNames, String startFrom, String range) {
|
||||
this.metaRelease = metaRelease;
|
||||
this.fullRelease = fullRelease;
|
||||
this.interactive = interactive;
|
||||
this.dryRun = dryRun;
|
||||
this.taskNames = taskNames.stream().map(this::removeQuotingChars)
|
||||
.collect(Collectors.toList());
|
||||
this.startFrom = removeQuotingChars(startFrom);
|
||||
this.range = removeQuotingChars(range);
|
||||
}
|
||||
|
||||
private String removeQuotingChars(String string) {
|
||||
if (string != null && string.startsWith("'") && string.endsWith("'")) {
|
||||
return string.substring(1, string.length() - 1);
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Options{" + "metaRelease=" + this.metaRelease + ", fullRelease="
|
||||
+ this.fullRelease + ", interactive=" + this.interactive + ", dryRun="
|
||||
+ this.dryRun + ", taskNames=" + this.taskNames + ", startFrom='"
|
||||
+ this.startFrom + '\'' + ", range='" + this.range + '\'' + '}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.options;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class OptionsBuilder {
|
||||
|
||||
private Boolean metaRelease = false;
|
||||
|
||||
private Boolean fullRelease = false;
|
||||
|
||||
private Boolean interactive = true;
|
||||
|
||||
private Boolean dryRun = false;
|
||||
|
||||
private List<String> taskNames = new ArrayList<>();
|
||||
|
||||
private String startFrom = "";
|
||||
|
||||
private String range = "";
|
||||
|
||||
public OptionsBuilder metaRelease(Boolean metaRelease) {
|
||||
this.metaRelease = metaRelease;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OptionsBuilder fullRelease(Boolean fullRelease) {
|
||||
this.fullRelease = fullRelease;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OptionsBuilder interactive(Boolean interactive) {
|
||||
this.interactive = interactive;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OptionsBuilder dryRun(Boolean dryRun) {
|
||||
this.dryRun = dryRun;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OptionsBuilder taskNames(List<String> taskNames) {
|
||||
this.taskNames = taskNames;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OptionsBuilder startFrom(String startFrom) {
|
||||
this.startFrom = startFrom;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OptionsBuilder range(String range) {
|
||||
this.range = range;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Options options() {
|
||||
return new Options(this.metaRelease, this.fullRelease, this.interactive,
|
||||
this.dryRun, this.taskNames, this.startFrom, this.range);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.options;
|
||||
|
||||
/**
|
||||
* Converts input arguments to a {@link Options}.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public interface Parser {
|
||||
|
||||
Options parse(String[] args);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.sagan;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import releaser.internal.ReleaserProperties;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@Configuration
|
||||
class SaganConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(value = "releaser.sagan.update-sagan", matchIfMissing = true)
|
||||
SaganClient saganClient(ReleaserProperties properties) {
|
||||
RestTemplate restTemplate = restTemplate(properties);
|
||||
return new RestTemplateSaganClient(restTemplate, properties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(value = "releaser.sagan.update-sagan", havingValue = "false")
|
||||
SaganClient noOpSaganClient() {
|
||||
return new SaganClient() {
|
||||
@Override
|
||||
public Project getProject(String projectName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Release getRelease(String projectName, String releaseVersion) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Release deleteRelease(String projectName, String releaseVersion) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Project updateRelease(String projectName,
|
||||
List<ReleaseUpdate> releaseUpdate) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Project patchProject(Project project) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private RestTemplate restTemplate(ReleaserProperties properties) {
|
||||
Assert.hasText(properties.getGit().getOauthToken(),
|
||||
"In order to connect to Sagan you need to pass the Github OAuth token. "
|
||||
+ "You can do it via the [--releaser.git.oauth-token=...] "
|
||||
+ "command line argument or an env variable [export RELEASER_GIT_OAUTH_TOKEN=...].");
|
||||
return new RestTemplateBuilder()
|
||||
.basicAuthentication(properties.getGit().getOauthToken(), "").build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.options.Options;
|
||||
import releaser.internal.project.ProcessedProject;
|
||||
import releaser.internal.project.ProjectVersion;
|
||||
import releaser.internal.project.Projects;
|
||||
|
||||
/**
|
||||
* Arguments for a task.
|
||||
*/
|
||||
public final class Arguments implements Serializable {
|
||||
|
||||
/**
|
||||
* Cloned location of the project.
|
||||
*/
|
||||
public final File project;
|
||||
|
||||
/**
|
||||
* All projects taken from the BOM.
|
||||
*/
|
||||
public final Projects projects;
|
||||
|
||||
/**
|
||||
* Original version of this project before any manipulations.
|
||||
*/
|
||||
public final ProjectVersion originalVersion;
|
||||
|
||||
/**
|
||||
* Version of this project from the BOM.
|
||||
*/
|
||||
public final ProjectVersion versionFromBom;
|
||||
|
||||
/**
|
||||
* Releaser properties updated for this project.
|
||||
*/
|
||||
public final ReleaserProperties properties;
|
||||
|
||||
/**
|
||||
* Options updated for this project.
|
||||
*/
|
||||
public final Options options;
|
||||
|
||||
/**
|
||||
* Current project to run.
|
||||
*/
|
||||
public final ProjectToRun projectToRun;
|
||||
|
||||
/**
|
||||
* List of processed projects.
|
||||
*/
|
||||
public final List<ProcessedProject> processedProjects;
|
||||
|
||||
private Arguments(ProjectToRun thisProject, Projects projects,
|
||||
ProjectVersion currentProjectFromBom) {
|
||||
this.project = thisProject.thisProjectFolder;
|
||||
this.projects = projects;
|
||||
this.originalVersion = thisProject.originalVersion;
|
||||
this.versionFromBom = currentProjectFromBom;
|
||||
this.properties = thisProject.thisProjectReleaserProperties;
|
||||
this.options = thisProject.options;
|
||||
this.projectToRun = thisProject;
|
||||
this.processedProjects = new LinkedList<>(Collections.singletonList(
|
||||
new ProcessedProject(thisProject.thisProjectReleaserProperties,
|
||||
this.versionFromBom, this.originalVersion)));
|
||||
}
|
||||
|
||||
// in this case the project will be the BOM
|
||||
private Arguments(ProjectToRun thisProject,
|
||||
List<ProcessedProject> processedProjects) {
|
||||
this.project = thisProject.thisProjectFolder;
|
||||
this.projects = new Projects(processedProjects.stream()
|
||||
.map(p -> p.newProjectVersion).collect(Collectors.toSet()));
|
||||
this.originalVersion = thisProject.originalVersion;
|
||||
this.versionFromBom = thisProject.thisProjectVersionFromBom;
|
||||
this.properties = thisProject.thisProjectReleaserProperties;
|
||||
this.options = thisProject.options;
|
||||
this.projectToRun = thisProject;
|
||||
this.processedProjects = processedProjects;
|
||||
}
|
||||
|
||||
public static Arguments forProject(ProjectToRun thisProject) {
|
||||
return new Arguments(thisProject,
|
||||
thisProject.allProjectsFromBom.allProjectVersionsFromBom,
|
||||
thisProject.allProjectsFromBom.currentProjectFromBom);
|
||||
}
|
||||
|
||||
public static Arguments forPostRelease(ReleaserProperties properties,
|
||||
ProjectsToRun projectsToRun) {
|
||||
List<ProjectToRun> projects = projectsToRun.stream()
|
||||
.map(ProjectToRun.ProjectToRunSupplier::get)
|
||||
.collect(Collectors.toCollection(LinkedList::new));
|
||||
List<ProcessedProject> processedProjects = projectsToRunToProcessedProject(
|
||||
projects);
|
||||
ProjectToRun releaseTrainProject = projects.stream()
|
||||
.filter(p -> isReleaseTrainProject(properties, p)).findFirst()
|
||||
.orElseThrow(
|
||||
() -> new IllegalStateException("Missing release train version"));
|
||||
return new Arguments(releaseTrainProject, processedProjects);
|
||||
}
|
||||
|
||||
private static boolean isReleaseTrainProject(ReleaserProperties properties,
|
||||
ProjectToRun p) {
|
||||
return p.originalVersion.projectName
|
||||
.equals(properties.getMetaRelease().getReleaseTrainProjectName())
|
||||
|| properties.getMetaRelease().getReleaseTrainDependencyNames()
|
||||
.contains(p.originalVersion.projectName)
|
||||
|| p.name()
|
||||
.equals(properties.getMetaRelease().getReleaseTrainProjectName());
|
||||
}
|
||||
|
||||
private static List<ProcessedProject> projectsToRunToProcessedProject(
|
||||
List<ProjectToRun> projects) {
|
||||
return projects.stream()
|
||||
.map(p -> new ProcessedProject(p.thisProjectReleaserProperties,
|
||||
p.thisProjectVersionFromBom, p.originalVersion))
|
||||
.collect(Collectors.toCollection(LinkedList::new));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.MapperFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import releaser.internal.ReleaserProperties;
|
||||
|
||||
import org.springframework.batch.core.configuration.annotation.BatchConfigurer;
|
||||
import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer;
|
||||
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
|
||||
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
|
||||
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
|
||||
import org.springframework.batch.core.explore.JobExplorer;
|
||||
import org.springframework.batch.core.explore.support.JobExplorerFactoryBean;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer;
|
||||
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
@Configuration
|
||||
@EnableBatchProcessing
|
||||
class BatchConfiguration {
|
||||
|
||||
@Bean
|
||||
TaskExecutor batchTaskExecutor() {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setCorePoolSize(4);
|
||||
executor.initialize();
|
||||
return executor;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
ExecutionResultHandler springBatchExecutionResultHandler(JobExplorer jobExplorer,
|
||||
ConfigurableApplicationContext context) {
|
||||
return new SpringBatchExecutionResultHandler(jobExplorer, context);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
FlowRunnerTaskExecutorSupplier defaultFlowRunnerTaskExecutorSupplier() {
|
||||
return new FlowRunnerTaskExecutorSupplier() {
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
FlowRunner flowRunner(StepBuilderFactory stepBuilderFactory,
|
||||
JobBuilderFactory jobBuilderFactory,
|
||||
ProjectsToRunFactory projectsToRunFactory, JobLauncher jobLauncher,
|
||||
FlowRunnerTaskExecutorSupplier flowRunnerTaskExecutorSupplier,
|
||||
ConfigurableApplicationContext context,
|
||||
ReleaserProperties releaserProperties) {
|
||||
return new SpringBatchFlowRunner(stepBuilderFactory, jobBuilderFactory,
|
||||
projectsToRunFactory, jobLauncher, flowRunnerTaskExecutorSupplier,
|
||||
context, releaserProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
Jackson2ExecutionContextStringSerializer myJackson2ExecutionContextStringSerializer() {
|
||||
Jackson2ExecutionContextStringSerializer serializer = new Jackson2ExecutionContextStringSerializer();
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false);
|
||||
// Needed to add this to serialize the exceptions
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
objectMapper.enableDefaultTyping();
|
||||
serializer.setObjectMapper(objectMapper);
|
||||
return serializer;
|
||||
}
|
||||
|
||||
// Needed to add this to serialize the exceptions
|
||||
@Bean
|
||||
BatchConfigurer myBatchConfigurer(DataSource dataSource,
|
||||
Jackson2ExecutionContextStringSerializer myJackson2ExecutionContextStringSerializer,
|
||||
PlatformTransactionManager transactionManager) {
|
||||
return new DefaultBatchConfigurer(dataSource) {
|
||||
@Override
|
||||
protected JobExplorer createJobExplorer() throws Exception {
|
||||
JobExplorerFactoryBean jobExplorerFactoryBean = new JobExplorerFactoryBean();
|
||||
jobExplorerFactoryBean.setDataSource(dataSource);
|
||||
jobExplorerFactoryBean
|
||||
.setSerializer(myJackson2ExecutionContextStringSerializer);
|
||||
jobExplorerFactoryBean.afterPropertiesSet();
|
||||
return jobExplorerFactoryBean.getObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JobRepository createJobRepository() throws Exception {
|
||||
JobRepositoryFactoryBean jobRepositoryFactoryBean = new JobRepositoryFactoryBean();
|
||||
jobRepositoryFactoryBean.setDataSource(dataSource);
|
||||
jobRepositoryFactoryBean
|
||||
.setSerializer(myJackson2ExecutionContextStringSerializer);
|
||||
jobRepositoryFactoryBean.setTransactionManager(transactionManager);
|
||||
jobRepositoryFactoryBean.afterPropertiesSet();
|
||||
return jobRepositoryFactoryBean.getObject();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.options.Options;
|
||||
import releaser.internal.options.OptionsBuilder;
|
||||
|
||||
/**
|
||||
* Releaser that gets input from console.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
class DefaultSpringReleaser implements SpringReleaser {
|
||||
|
||||
private final ReleaserProperties properties;
|
||||
|
||||
private final OptionsAndPropertiesFactory optionsAndPropertiesFactory;
|
||||
|
||||
private final ProjectsToRunFactory projectsToRunFactory;
|
||||
|
||||
private final TasksToRunFactory tasksToRunFactory;
|
||||
|
||||
private final FlowRunner flowRunner;
|
||||
|
||||
DefaultSpringReleaser(ReleaserProperties properties,
|
||||
OptionsAndPropertiesFactory optionsAndPropertiesFactory,
|
||||
ProjectsToRunFactory projectsToRunFactory,
|
||||
TasksToRunFactory tasksToRunFactory, FlowRunner flowRunner) {
|
||||
this.properties = properties;
|
||||
this.optionsAndPropertiesFactory = optionsAndPropertiesFactory;
|
||||
this.projectsToRunFactory = projectsToRunFactory;
|
||||
this.tasksToRunFactory = tasksToRunFactory;
|
||||
this.flowRunner = flowRunner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default behaviour - interactive mode.
|
||||
*/
|
||||
@Override
|
||||
public ExecutionResult release() {
|
||||
return release(new OptionsBuilder().options());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult release(Options options) {
|
||||
OptionsAndProperties optionsAndProperties = prepareOptionsAndProperties(options,
|
||||
this.properties);
|
||||
// order matters! Tasks will mutate options and properties
|
||||
TasksToRun releaseTasksToRun = releaseTasksFromOptions(optionsAndProperties);
|
||||
ProjectsToRun projectsToRun = releaseProjects(optionsAndProperties);
|
||||
ExecutionResult releaseTasksExecutionResult = runReleaseTasks(
|
||||
optionsAndProperties, projectsToRun, releaseTasksToRun);
|
||||
TasksToRun postReleaseTrainTasksToRun = postReleaseTrainTasksFromOptions(
|
||||
optionsAndProperties);
|
||||
ExecutionResult postReleaseTrainTasksExecutionResult = runPostReleaseTasks(
|
||||
optionsAndProperties, postReleaseTrainTasksToRun);
|
||||
return releaseTasksExecutionResult.merge(postReleaseTrainTasksExecutionResult);
|
||||
}
|
||||
|
||||
private OptionsAndProperties prepareOptionsAndProperties(Options options,
|
||||
ReleaserProperties properties) {
|
||||
return this.optionsAndPropertiesFactory.get(properties, options);
|
||||
}
|
||||
|
||||
private ProjectsToRun releaseProjects(OptionsAndProperties options) {
|
||||
return this.projectsToRunFactory.release(options);
|
||||
}
|
||||
|
||||
private TasksToRun releaseTasksFromOptions(OptionsAndProperties options) {
|
||||
return this.tasksToRunFactory.release(options);
|
||||
}
|
||||
|
||||
private TasksToRun postReleaseTrainTasksFromOptions(
|
||||
OptionsAndProperties optionsAndProperties) {
|
||||
return this.tasksToRunFactory.postRelease(optionsAndProperties.options);
|
||||
}
|
||||
|
||||
private ExecutionResult runReleaseTasks(OptionsAndProperties optionsAndProperties,
|
||||
ProjectsToRun projectsToRun, TasksToRun tasksToRun) {
|
||||
return this.flowRunner.runReleaseTasks(optionsAndProperties.options,
|
||||
optionsAndProperties.properties, projectsToRun, tasksToRun);
|
||||
}
|
||||
|
||||
private ExecutionResult runPostReleaseTasks(OptionsAndProperties optionsAndProperties,
|
||||
TasksToRun postReleaseTasksToRun) {
|
||||
return this.flowRunner.runPostReleaseTrainTasks(optionsAndProperties.options,
|
||||
optionsAndProperties.properties, "postRelease", postReleaseTasksToRun);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import releaser.internal.tech.BuildUnstableException;
|
||||
|
||||
/**
|
||||
* Task execution result. Contains a list of exceptions thrown while running the task.
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ExecutionResult implements Serializable {
|
||||
|
||||
private List<Exception> exceptions = new LinkedList<>();
|
||||
|
||||
public ExecutionResult() {
|
||||
}
|
||||
|
||||
public ExecutionResult(Exception throwable) {
|
||||
this.exceptions.add(throwable);
|
||||
}
|
||||
|
||||
public ExecutionResult(List<Exception> throwables) {
|
||||
this.exceptions.addAll(throwables);
|
||||
}
|
||||
|
||||
public static ExecutionResult success() {
|
||||
return new ExecutionResult();
|
||||
}
|
||||
|
||||
public static ExecutionResult failure(Exception throwable) {
|
||||
return new ExecutionResult(throwable);
|
||||
}
|
||||
|
||||
public static ExecutionResult unstable(Exception ex) {
|
||||
return new ExecutionResult(ex instanceof BuildUnstableException ? ex
|
||||
: new BuildUnstableException(ex));
|
||||
}
|
||||
|
||||
public RuntimeException foundExceptions() {
|
||||
if (this.exceptions.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (this.exceptions.size() == 1) {
|
||||
Throwable throwable = this.exceptions.get(0);
|
||||
return throwable instanceof RuntimeException ? (RuntimeException) throwable
|
||||
: new RuntimeException(throwable);
|
||||
}
|
||||
if (isUnstable()) {
|
||||
return new MergedUnstableThrowable(this.exceptions);
|
||||
}
|
||||
return new MergedThrowable(this.exceptions);
|
||||
}
|
||||
|
||||
public ExecutionResult merge(ExecutionResult other) {
|
||||
ExecutionResult merged = new ExecutionResult(this.exceptions);
|
||||
merged.exceptions.addAll(other.exceptions);
|
||||
return merged;
|
||||
}
|
||||
|
||||
public boolean isUnstable() {
|
||||
return !this.exceptions.isEmpty() && this.exceptions.stream()
|
||||
.allMatch(t -> t instanceof BuildUnstableException);
|
||||
}
|
||||
|
||||
public boolean isFailure() {
|
||||
return !this.exceptions.isEmpty() && this.exceptions.stream()
|
||||
.anyMatch(t -> !(t instanceof BuildUnstableException));
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return this.exceptions.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isFailureOrUnstable() {
|
||||
return !this.exceptions.isEmpty();
|
||||
}
|
||||
|
||||
public List<Exception> getExceptions() {
|
||||
return this.exceptions;
|
||||
}
|
||||
|
||||
public void setExceptions(List<Exception> exceptions) {
|
||||
this.exceptions = exceptions;
|
||||
}
|
||||
|
||||
private static final class MergedThrowable extends RuntimeException
|
||||
implements Serializable {
|
||||
|
||||
private MergedThrowable(List<Exception> throwables) {
|
||||
super("Failed due to the following exceptions " + throwables);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class MergedUnstableThrowable extends BuildUnstableException
|
||||
implements Serializable {
|
||||
|
||||
private MergedUnstableThrowable(List<Exception> throwables) {
|
||||
super("Unstable due to the following exceptions " + throwables);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Handles the result of the execution of the train or project release. Example: You can
|
||||
* print the results in a table, throw exceptions when the build was faulty or just log
|
||||
* them when it was unstable.
|
||||
*/
|
||||
public interface ExecutionResultHandler extends Consumer<ExecutionResult> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import releaser.internal.tasks.ReleaserTask;
|
||||
|
||||
/**
|
||||
* A report from running a task. Can be mapped to a row in a table for a single execution
|
||||
* of a release task.
|
||||
*/
|
||||
public class ExecutionResultReport {
|
||||
|
||||
private String projectName;
|
||||
|
||||
private String shortName;
|
||||
|
||||
private String description;
|
||||
|
||||
private Class<? extends ReleaserTask> releaserTaskType;
|
||||
|
||||
private String state;
|
||||
|
||||
private List<Throwable> exceptions;
|
||||
|
||||
ExecutionResultReport() {
|
||||
}
|
||||
|
||||
public ExecutionResultReport(String projectName, String shortName, String description,
|
||||
Class<? extends ReleaserTask> releaserTaskType, String state,
|
||||
List<Throwable> exceptions) {
|
||||
this.projectName = projectName;
|
||||
this.shortName = shortName;
|
||||
this.description = description;
|
||||
this.releaserTaskType = releaserTaskType;
|
||||
this.state = state;
|
||||
this.exceptions = exceptions;
|
||||
}
|
||||
|
||||
public String getProjectName() {
|
||||
return this.projectName;
|
||||
}
|
||||
|
||||
public void setProjectName(String projectName) {
|
||||
this.projectName = projectName;
|
||||
}
|
||||
|
||||
public String getShortName() {
|
||||
return this.shortName;
|
||||
}
|
||||
|
||||
public void setShortName(String shortName) {
|
||||
this.shortName = shortName;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Class<? extends ReleaserTask> getReleaserTaskType() {
|
||||
return this.releaserTaskType;
|
||||
}
|
||||
|
||||
public void setReleaserTaskType(Class<? extends ReleaserTask> releaserTaskType) {
|
||||
this.releaserTaskType = releaserTaskType;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public List<Throwable> getExceptions() {
|
||||
return this.exceptions;
|
||||
}
|
||||
|
||||
public void setExceptions(List<Throwable> exceptions) {
|
||||
this.exceptions = exceptions;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.options.Options;
|
||||
import releaser.internal.tasks.ReleaserTask;
|
||||
|
||||
/**
|
||||
* Knows how to run a flow of tasks.
|
||||
*/
|
||||
public interface FlowRunner {
|
||||
|
||||
/**
|
||||
* Decide what to do before running a task.
|
||||
* @param options - options prepared for the task
|
||||
* @param properties - specific releaser properties for this task
|
||||
* @param releaserTask - the task to run
|
||||
* @return the decision on what to do with the task
|
||||
*/
|
||||
default Decision beforeTask(Options options, ReleaserProperties properties,
|
||||
ReleaserTask releaserTask) {
|
||||
return Decision.CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decide what to do after running a task.
|
||||
* @param options - options prepared for the task
|
||||
* @param properties - specific releaser properties for this task
|
||||
* @param releaserTask - the task to run
|
||||
* @return the decision on what to do with the task
|
||||
*/
|
||||
default Decision afterTask(Options options, ReleaserProperties properties,
|
||||
ReleaserTask releaserTask) {
|
||||
return Decision.CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the release tasks.
|
||||
* @param options - options coming from the input
|
||||
* @param properties - releaser properties coming from the input
|
||||
* @param projectToRuns - set of projects to run (for a single release it's simple)
|
||||
* @param tasksToRun - set of release tasks to run for each project
|
||||
* @return the result of release execution
|
||||
*/
|
||||
ExecutionResult runReleaseTasks(Options options, ReleaserProperties properties,
|
||||
ProjectsToRun projectToRuns, TasksToRun tasksToRun);
|
||||
|
||||
/**
|
||||
* Runs the post release tasks.
|
||||
* @param options - options coming from the input
|
||||
* @param properties - releaser properties coming from the input
|
||||
* @param executingTaskName - name for the post release task
|
||||
* @param tasksToRun - set of post release tasks to run for each project
|
||||
* @return the result of release execution
|
||||
*/
|
||||
ExecutionResult runPostReleaseTrainTasks(Options options,
|
||||
ReleaserProperties properties, String executingTaskName,
|
||||
TasksToRun tasksToRun);
|
||||
|
||||
/**
|
||||
* Decision to be taken before and after running a task.
|
||||
*/
|
||||
enum Decision {
|
||||
|
||||
/**
|
||||
* Allows to continue to the next task.
|
||||
*/
|
||||
CONTINUE,
|
||||
|
||||
/**
|
||||
* Skips the current task and goes to the next one.
|
||||
*/
|
||||
SKIP,
|
||||
|
||||
/**
|
||||
* Aborts the execution of the whole release.
|
||||
*/
|
||||
ABORT
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
/**
|
||||
* Customizes the {@link TaskExecutor} for the flow runner.
|
||||
*/
|
||||
public interface FlowRunnerTaskExecutorSupplier extends Supplier<TaskExecutor> {
|
||||
|
||||
@Override
|
||||
default TaskExecutor get() {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setCorePoolSize(4);
|
||||
executor.initialize();
|
||||
return executor;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.options.Options;
|
||||
|
||||
class OptionsAndProperties {
|
||||
|
||||
final ReleaserProperties properties;
|
||||
|
||||
final Options options;
|
||||
|
||||
OptionsAndProperties(ReleaserProperties properties, Options options) {
|
||||
this.properties = properties;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.options.Options;
|
||||
|
||||
class OptionsAndPropertiesFactory {
|
||||
|
||||
OptionsAndProperties get(ReleaserProperties properties, Options options) {
|
||||
if (options.metaRelease) {
|
||||
properties.getGit().setFetchVersionsFromGit(false);
|
||||
properties.getMetaRelease().setEnabled(true);
|
||||
options.fullRelease = true;
|
||||
}
|
||||
return new OptionsAndProperties(properties, options);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import joptsimple.ArgumentAcceptingOptionSpec;
|
||||
import joptsimple.OptionParser;
|
||||
import joptsimple.OptionSet;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import releaser.internal.options.Options;
|
||||
import releaser.internal.options.OptionsBuilder;
|
||||
import releaser.internal.options.Parser;
|
||||
import releaser.internal.tasks.ReleaserTask;
|
||||
import releaser.internal.tasks.SingleProjectReleaserTask;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
class OptionsParser implements Parser {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(OptionsParser.class);
|
||||
|
||||
private final List<ReleaserTask> allTasks;
|
||||
|
||||
private final List<SingleProjectReleaserTask> singleProjectReleaserTasks;
|
||||
|
||||
private final ConfigurableApplicationContext context;
|
||||
|
||||
OptionsParser(List<ReleaserTask> allTasks,
|
||||
List<SingleProjectReleaserTask> singleProjectReleaserTasks,
|
||||
ConfigurableApplicationContext context) {
|
||||
this.allTasks = allTasks;
|
||||
this.singleProjectReleaserTasks = singleProjectReleaserTasks;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Options parse(String[] args) {
|
||||
OptionParser parser = new OptionParser();
|
||||
parser.allowsUnrecognizedOptions();
|
||||
log.info("Got following args <{}>", args);
|
||||
try {
|
||||
ArgumentAcceptingOptionSpec<Boolean> metaReleaseOpt = parser
|
||||
.acceptsAll(Arrays.asList("x", "meta-release"),
|
||||
"Do you want to do the meta release?")
|
||||
.withRequiredArg().ofType(Boolean.class).defaultsTo(false);
|
||||
ArgumentAcceptingOptionSpec<Boolean> fullReleaseOpt = parser
|
||||
.acceptsAll(Arrays.asList("f", "full-release"),
|
||||
"Do you want to do the full release of a single project?")
|
||||
.withOptionalArg().ofType(Boolean.class).defaultsTo(false);
|
||||
ArgumentAcceptingOptionSpec<Boolean> interactiveOpt = parser.acceptsAll(
|
||||
Arrays.asList("i", "interactive"),
|
||||
"Do you want to set the properties from the command line of a single project?")
|
||||
.withRequiredArg().ofType(Boolean.class).defaultsTo(true);
|
||||
ArgumentAcceptingOptionSpec<Boolean> dryRunOpt = parser.acceptsAll(
|
||||
Arrays.asList("dr", "dry-run"),
|
||||
"Do you want to do the release / meta release with build and install projects locally only?")
|
||||
.withRequiredArg().ofType(Boolean.class).defaultsTo(false);
|
||||
LinkedList<ReleaserTask> singleProjectReleaseTasks = this.allTasks.stream()
|
||||
.filter(releaserTask -> releaserTask instanceof SingleProjectReleaserTask)
|
||||
.collect(Collectors.toCollection(LinkedList::new));
|
||||
singleProjectReleaseTasks.forEach(task -> parser
|
||||
.acceptsAll(Arrays.asList(task.shortName(), task.name()),
|
||||
task.description())
|
||||
.withOptionalArg());
|
||||
ArgumentAcceptingOptionSpec<String> startFromOpt = parser.acceptsAll(
|
||||
Arrays.asList("a", "start-from"),
|
||||
"Starts all release task starting "
|
||||
+ "from the given task. Requires passing the task name (either one letter or the full name)")
|
||||
.withRequiredArg().ofType(String.class);
|
||||
ArgumentAcceptingOptionSpec<String> taskNamesOpt = parser
|
||||
.acceptsAll(Arrays.asList("tn", "task-names"),
|
||||
"Starts all release task for the given task names")
|
||||
.withRequiredArg().ofType(String.class).defaultsTo("");
|
||||
ArgumentAcceptingOptionSpec<String> rangeOpt = parser.acceptsAll(
|
||||
Arrays.asList("r", "range"),
|
||||
"Runs release tasks from the given range. Requires passing "
|
||||
+ "the task names with a hyphen. The first task is inclusive, "
|
||||
+ "the second inclusive. E.g. 's-m' would mean running 'snapshot', "
|
||||
+ "'push' and 'milestone' tasks")
|
||||
.withRequiredArg().ofType(String.class);
|
||||
parser.acceptsAll(Arrays.asList("h", "help")).withOptionalArg();
|
||||
OptionSet options = parser.parse(args);
|
||||
if (options.has("h")) {
|
||||
printHelpMessage(parser);
|
||||
SpringApplication.exit(this.context, () -> 0);
|
||||
System.exit(0);
|
||||
}
|
||||
Boolean metaRelease = options.valueOf(metaReleaseOpt);
|
||||
Boolean interactive = options.valueOf(interactiveOpt);
|
||||
Boolean dryRun = options.valueOf(dryRunOpt);
|
||||
Boolean fullRelease = options.has(fullReleaseOpt);
|
||||
List<String> providedTaskNames = StringUtils.hasText(options
|
||||
.valueOf(taskNamesOpt)) ? Arrays.asList(
|
||||
removeQuotingChars(options.valueOf(taskNamesOpt)).split(","))
|
||||
: new ArrayList<>();
|
||||
providedTaskNames = providedTaskNames.stream().map(this::removeQuotingChars)
|
||||
.collect(Collectors.toList());
|
||||
log.info("Passed tasks {} from command line", providedTaskNames);
|
||||
List<String> allTaskNames = singleProjectReleaseTasks.stream()
|
||||
.map(ReleaserTask::name).collect(Collectors.toList());
|
||||
List<String> tasksFromOptions = singleProjectReleaseTasks.stream().filter(
|
||||
task -> options.has(task.name()) || options.has(task.shortName()))
|
||||
.map(ReleaserTask::name).collect(Collectors.toList());
|
||||
if (providedTaskNames.isEmpty()) {
|
||||
providedTaskNames.addAll(tasksFromOptions.isEmpty() && !metaRelease
|
||||
? allTaskNames : tasksFromOptions);
|
||||
}
|
||||
List<String> taskNames = filterProvidedTaskNames(providedTaskNames,
|
||||
allTaskNames, metaRelease);
|
||||
String startFrom = options.valueOf(startFromOpt);
|
||||
String range = options.valueOf(rangeOpt);
|
||||
Options buildOptions = new OptionsBuilder().metaRelease(metaRelease)
|
||||
.fullRelease(fullRelease).interactive(interactive).dryRun(dryRun)
|
||||
.taskNames(taskNames).startFrom(startFrom).range(range).options();
|
||||
log.info(
|
||||
"\n\nWill use the following options to process the project\n\n{}\n\n",
|
||||
buildOptions);
|
||||
return buildOptions;
|
||||
}
|
||||
catch (Exception e) {
|
||||
printErrorMessage(e, parser);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
List<String> filterProvidedTaskNames(List<String> providedTaskNames,
|
||||
List<String> allTaskNames, boolean metaRelease) {
|
||||
if (metaRelease) {
|
||||
return providedTaskNames;
|
||||
}
|
||||
return allTaskNames.stream().filter(providedTaskNames::contains)
|
||||
.collect(Collectors.toCollection(LinkedList::new));
|
||||
}
|
||||
|
||||
private String removeQuotingChars(String string) {
|
||||
if (string.startsWith("'") && string.endsWith("'")) {
|
||||
return string.substring(1, string.length() - 1);
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
private void printErrorMessage(Exception e, OptionParser parser) {
|
||||
System.err.println("Following exception has occurred: ");
|
||||
System.err.println(e.getMessage());
|
||||
e.printStackTrace();
|
||||
System.err.println(intro());
|
||||
System.err.println(
|
||||
"java -jar releaser-spring-1.0.0.BUILD-SNAPSHOT.jar [options...] ");
|
||||
try {
|
||||
parser.printHelpOn(System.err);
|
||||
}
|
||||
catch (IOException e1) {
|
||||
throw new IllegalStateException(e1);
|
||||
}
|
||||
System.err.println(examples());
|
||||
}
|
||||
|
||||
private void printHelpMessage(OptionParser parser) {
|
||||
try {
|
||||
System.out.println(intro());
|
||||
parser.printHelpOn(System.out);
|
||||
System.out.println(examples());
|
||||
}
|
||||
catch (IOException e1) {
|
||||
throw new IllegalStateException(e1);
|
||||
}
|
||||
}
|
||||
|
||||
private String intro() {
|
||||
return "\nHere you can find the list of tasks in order for a single project\n\n["
|
||||
+ this.singleProjectReleaserTasks.stream().map(ReleaserTask::name)
|
||||
.collect(Collectors.joining(","))
|
||||
+ "]\n\n";
|
||||
}
|
||||
|
||||
private String examples() {
|
||||
return "\nExamples of usage:\n\n" + "Run 'build' & 'commit' & 'deploy'\n"
|
||||
+ "java -jar jar.jar -b -c -d\n\n" + "Start from 'push'\n"
|
||||
+ "java -jar releaser.jar -a push\n\n" + "Range 'docs' -> 'push'\n"
|
||||
+ "java -jar releaser.jar -r o-p\n\n" + "\n\n";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.options.Options;
|
||||
import releaser.internal.project.ProjectVersion;
|
||||
|
||||
/**
|
||||
* A single project to be released. Contains all the information necessary to release a
|
||||
* project.
|
||||
*/
|
||||
public class ProjectToRun implements Serializable {
|
||||
|
||||
/**
|
||||
* Cloned location of this project.
|
||||
*/
|
||||
public final File thisProjectFolder;
|
||||
|
||||
/**
|
||||
* All projects taken from the BOM.
|
||||
*/
|
||||
public final ProjectsFromBom allProjectsFromBom;
|
||||
|
||||
/**
|
||||
* The original version of the project.
|
||||
*/
|
||||
public final ProjectVersion originalVersion;
|
||||
|
||||
/**
|
||||
* The project version of this project taken from the BOM.
|
||||
*/
|
||||
public final ProjectVersion thisProjectVersionFromBom;
|
||||
|
||||
/**
|
||||
* {@link ReleaserProperties} updated for this project.
|
||||
*/
|
||||
public final ReleaserProperties thisProjectReleaserProperties;
|
||||
|
||||
/**
|
||||
* {@link Options} updated for this project.
|
||||
*/
|
||||
public final Options options;
|
||||
|
||||
public ProjectToRun(File thisProjectFolder, ProjectsFromBom allProjectsFromBom,
|
||||
ProjectVersion originalVersion,
|
||||
ReleaserProperties thisProjectReleaserProperties, Options options) {
|
||||
this.thisProjectFolder = thisProjectFolder;
|
||||
this.allProjectsFromBom = allProjectsFromBom;
|
||||
this.originalVersion = originalVersion;
|
||||
this.thisProjectReleaserProperties = thisProjectReleaserProperties;
|
||||
this.options = options;
|
||||
this.thisProjectVersionFromBom = allProjectsFromBom.currentProjectFromBom;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return this.thisProjectFolder.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ProjectToRun that = (ProjectToRun) o;
|
||||
return Objects.equals(originalVersion, that.originalVersion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(originalVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Supplier of a project to run. Since retrieval of a project may require cloning it,
|
||||
* we will cache the cloned location instead of cloning it each time.
|
||||
*/
|
||||
public static class ProjectToRunSupplier
|
||||
implements Supplier<ProjectToRun>, Closeable {
|
||||
|
||||
private static final Map<String, ProjectToRun> CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
private final String projectName;
|
||||
|
||||
private final Supplier<ProjectToRun> project;
|
||||
|
||||
public ProjectToRunSupplier(String projectName, Supplier<ProjectToRun> project) {
|
||||
this.projectName = projectName;
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectToRun get() {
|
||||
return CACHE.computeIfAbsent(this.projectName, s -> this.project.get());
|
||||
}
|
||||
|
||||
public String projectName() {
|
||||
return this.projectName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ProjectToRunSupplier that = (ProjectToRunSupplier) o;
|
||||
return Objects.equals(this.projectName, that.projectName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.projectName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
CACHE.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import releaser.internal.project.ProjectVersion;
|
||||
import releaser.internal.project.Projects;
|
||||
|
||||
/**
|
||||
* Class representing this and other projects retrieved from the BOM.
|
||||
*/
|
||||
public class ProjectsFromBom {
|
||||
|
||||
/**
|
||||
* All projects with versions taken from BOM.
|
||||
*/
|
||||
public final Projects allProjectVersionsFromBom;
|
||||
|
||||
/**
|
||||
* Current project retrieved from BOM.
|
||||
*/
|
||||
public final ProjectVersion currentProjectFromBom;
|
||||
|
||||
public ProjectsFromBom(Projects allProjectVersionsFromBom,
|
||||
ProjectVersion currentProjectFromBom) {
|
||||
this.allProjectVersionsFromBom = allProjectVersionsFromBom;
|
||||
this.currentProjectFromBom = currentProjectFromBom;
|
||||
}
|
||||
|
||||
public ProjectsFromBom(Projects allProjectVersionsFromBom) {
|
||||
this(allProjectVersionsFromBom, null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* List of projects to run. They will be fetched in a lazy fashion.
|
||||
*/
|
||||
public class ProjectsToRun extends LinkedList<ProjectToRun.ProjectToRunSupplier> {
|
||||
|
||||
public ProjectsToRun() {
|
||||
}
|
||||
|
||||
public ProjectsToRun(ProjectToRun.ProjectToRunSupplier projectToRun) {
|
||||
add(projectToRun);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.options.Options;
|
||||
import releaser.internal.project.ProjectVersion;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
class ProjectsToRunFactory implements Closeable {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ProjectsToRunFactory.class);
|
||||
|
||||
private final ProjectsToRun storedProjects = new ProjectsToRun();
|
||||
|
||||
private final VersionsToBumpFactory versionsToBumpFactory;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
private final ReleaserPropertiesUpdater updater;
|
||||
|
||||
ProjectsToRunFactory(VersionsToBumpFactory versionsToBumpFactory, Releaser releaser,
|
||||
ReleaserPropertiesUpdater updater) {
|
||||
this.versionsToBumpFactory = versionsToBumpFactory;
|
||||
this.releaser = releaser;
|
||||
this.updater = updater;
|
||||
}
|
||||
|
||||
ProjectsToRun release(OptionsAndProperties optionsAndProperties) {
|
||||
ProjectsToRun projectsToRun = doRelease(optionsAndProperties);
|
||||
this.storedProjects.addAll(projectsToRun);
|
||||
return projectsToRun;
|
||||
}
|
||||
|
||||
private ProjectsToRun doRelease(OptionsAndProperties optionsAndProperties) {
|
||||
Options options = optionsAndProperties.options;
|
||||
ReleaserProperties properties = optionsAndProperties.properties;
|
||||
if (!options.metaRelease) {
|
||||
log.info(
|
||||
"Single project release picked. Will release only the current project");
|
||||
File projectFolder = projectFolder(properties);
|
||||
ProjectVersion version = new ProjectVersion(projectFolder);
|
||||
ProjectsFromBom projectsFromBom = this.versionsToBumpFactory
|
||||
.withProject(projectFolder);
|
||||
return new ProjectsToRun(new ProjectToRun.ProjectToRunSupplier(
|
||||
version.projectName, () -> new ProjectToRun(projectFolder,
|
||||
projectsFromBom, version, properties, options)));
|
||||
}
|
||||
log.info("Meta release picked");
|
||||
return metaReleaseProjectsToRun(options, properties);
|
||||
}
|
||||
|
||||
ProjectsToRun postReleaseTrain(OptionsAndProperties optionsAndProperties) {
|
||||
ProjectsToRun projectsToRun = doPostRelease(optionsAndProperties);
|
||||
this.storedProjects.addAll(projectsToRun);
|
||||
return projectsToRun;
|
||||
}
|
||||
|
||||
private ProjectsToRun doPostRelease(OptionsAndProperties optionsAndProperties) {
|
||||
Options options = optionsAndProperties.options;
|
||||
ReleaserProperties properties = optionsAndProperties.properties;
|
||||
if (!options.metaRelease) {
|
||||
return new ProjectsToRun();
|
||||
}
|
||||
log.info("Meta release picked");
|
||||
return metaReleasePostReleaseProjectsToRun(options, properties);
|
||||
}
|
||||
|
||||
private File projectFolder(ReleaserProperties properties) {
|
||||
String workingDir = properties.getWorkingDir();
|
||||
return new File(workingDir);
|
||||
}
|
||||
|
||||
private ProjectsToRun metaReleaseProjectsToRun(Options options,
|
||||
ReleaserProperties originalProps) {
|
||||
return metaProjectsToRun(options, originalProps,
|
||||
metaReleaseProjects(options, originalProps));
|
||||
}
|
||||
|
||||
private ProjectsToRun metaReleasePostReleaseProjectsToRun(Options options,
|
||||
ReleaserProperties originalProps) {
|
||||
return metaProjectsToRun(options, originalProps,
|
||||
allButSkippedProjects(originalProps));
|
||||
}
|
||||
|
||||
private ProjectsToRun metaProjectsToRun(Options options,
|
||||
ReleaserProperties originalProps, List<String> projectNames) {
|
||||
return projectNames.stream()
|
||||
.map(project -> projectSupplier(options, originalProps, project))
|
||||
.collect(Collectors.toCollection(ProjectsToRun::new));
|
||||
}
|
||||
|
||||
private ProjectToRun.ProjectToRunSupplier projectSupplier(Options options,
|
||||
ReleaserProperties originalProps, String project) {
|
||||
return new ProjectToRun.ProjectToRunSupplier(project, () -> {
|
||||
File clonedProjectFromOrg = this.releaser.clonedProjectFromOrg(project);
|
||||
ReleaserProperties properties = updatePropertiesIfCustomConfigPresent(
|
||||
originalProps.copy(), clonedProjectFromOrg);
|
||||
log.info("Successfully cloned the project [{}] to [{}]", project,
|
||||
clonedProjectFromOrg);
|
||||
ProjectVersion originalVersion = new ProjectVersion(clonedProjectFromOrg);
|
||||
ProjectsFromBom projectsFromBom = this.versionsToBumpFactory
|
||||
.withProject(clonedProjectFromOrg);
|
||||
return new ProjectToRun(clonedProjectFromOrg, projectsFromBom,
|
||||
originalVersion, properties, options);
|
||||
});
|
||||
}
|
||||
|
||||
private ReleaserProperties updatePropertiesIfCustomConfigPresent(
|
||||
ReleaserProperties copy, File clonedProjectFromOrg) {
|
||||
return this.updater.updateProperties(copy, clonedProjectFromOrg);
|
||||
}
|
||||
|
||||
private List<String> metaReleaseProjects(Options options,
|
||||
ReleaserProperties properties) {
|
||||
List<String> filteredProjects = allButSkippedProjects(properties);
|
||||
if (StringUtils.hasText(options.startFrom)) {
|
||||
filteredProjects = filterStartFrom(options, filteredProjects);
|
||||
}
|
||||
else if (!options.taskNames.isEmpty()) {
|
||||
filteredProjects = filterTaskNames(options, filteredProjects);
|
||||
}
|
||||
log.info("\n\n\nFor meta-release, will release the projects {}\n\n\n",
|
||||
filteredProjects);
|
||||
return filteredProjects;
|
||||
}
|
||||
|
||||
private List<String> allButSkippedProjects(ReleaserProperties properties) {
|
||||
List<String> projects = new ArrayList<>(properties.getFixedVersions().keySet());
|
||||
log.info("List of projects that should not be cloned {}",
|
||||
properties.getMetaRelease().getProjectsToSkip());
|
||||
List<String> filteredProjects = filterProjectsToSkip(projects, properties);
|
||||
log.info("List of all projects to clone before filtering {}", filteredProjects);
|
||||
return filteredProjects;
|
||||
}
|
||||
|
||||
private List<String> allProjects(ReleaserProperties properties) {
|
||||
return new ArrayList<>(properties.getFixedVersions().keySet());
|
||||
}
|
||||
|
||||
private List<String> filterProjectsToSkip(List<String> projects,
|
||||
ReleaserProperties properties) {
|
||||
return projects
|
||||
.stream().filter(project -> !properties.getMetaRelease()
|
||||
.getProjectsToSkip().contains(project))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<String> filterStartFrom(Options options, List<String> filteredProjects) {
|
||||
log.info("Start from option provided [{}]", options.startFrom);
|
||||
int projectIndex = filteredProjects.indexOf(options.startFrom);
|
||||
if (projectIndex < 0) {
|
||||
throw new IllegalStateException(
|
||||
"Project [" + options.startFrom + "] not found");
|
||||
}
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Index of project [{}] is [{}]", options.startFrom, projectIndex);
|
||||
}
|
||||
filteredProjects = filteredProjects.subList(projectIndex,
|
||||
filteredProjects.size());
|
||||
options.startFrom = "";
|
||||
return filteredProjects;
|
||||
}
|
||||
|
||||
private List<String> filterTaskNames(Options options, List<String> filteredProjects) {
|
||||
log.info("Task names provided {}", options.taskNames);
|
||||
filteredProjects = filteredProjects.stream()
|
||||
.filter(project -> options.taskNames.contains(project))
|
||||
.collect(Collectors.toList());
|
||||
options.taskNames = new ArrayList<>();
|
||||
return filteredProjects;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
this.storedProjects.forEach(ProjectToRun.ProjectToRunSupplier::close);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.buildsystem.GradleUpdater;
|
||||
import releaser.internal.buildsystem.ProjectPomUpdater;
|
||||
import releaser.internal.docs.CustomProjectDocumentationUpdater;
|
||||
import releaser.internal.docs.DocumentationUpdater;
|
||||
import releaser.internal.git.ProjectGitHandler;
|
||||
import releaser.internal.github.CustomGithubIssues;
|
||||
import releaser.internal.github.ProjectGitHubHandler;
|
||||
import releaser.internal.options.Parser;
|
||||
import releaser.internal.postrelease.PostReleaseActions;
|
||||
import releaser.internal.project.ProjectCommandExecutor;
|
||||
import releaser.internal.sagan.SaganClient;
|
||||
import releaser.internal.sagan.SaganUpdater;
|
||||
import releaser.internal.tasks.ReleaserTask;
|
||||
import releaser.internal.tasks.SingleProjectReleaserTask;
|
||||
import releaser.internal.template.TemplateGenerator;
|
||||
import releaser.internal.versions.VersionsFetcher;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(ReleaserProperties.class)
|
||||
class ReleaserConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
OptionsAndPropertiesFactory optionsAndPropertiesFactory() {
|
||||
return new OptionsAndPropertiesFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
VersionsToBumpFactory versionsToBumpFactory(Releaser releaser,
|
||||
ReleaserProperties properties) {
|
||||
return new VersionsToBumpFactory(releaser, properties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
ProjectsToRunFactory projectsToRunFactory(VersionsToBumpFactory versionsToBumpFactory,
|
||||
Releaser releaser, ReleaserPropertiesUpdater updater) {
|
||||
return new ProjectsToRunFactory(versionsToBumpFactory, releaser, updater);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
TasksToRunFactory tasksToRunFactory(ApplicationContext context) {
|
||||
return new TasksToRunFactory(context);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
SpringReleaser springReleaser(OptionsAndPropertiesFactory optionsAndPropertiesFactory,
|
||||
ProjectsToRunFactory projectsToRunFactory,
|
||||
TasksToRunFactory tasksToRunFactory, FlowRunner flowRunner,
|
||||
ReleaserProperties properties) {
|
||||
return new DefaultSpringReleaser(properties, optionsAndPropertiesFactory,
|
||||
projectsToRunFactory, tasksToRunFactory, flowRunner);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
ProjectCommandExecutor projectBuilder(ReleaserProperties properties) {
|
||||
return new ProjectCommandExecutor(properties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
VersionsFetcher versionsFetcher(ProjectPomUpdater updater,
|
||||
ReleaserProperties properties) {
|
||||
return new VersionsFetcher(properties, updater);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
ProjectGitHandler projectGitHandler(ReleaserProperties properties) {
|
||||
return new ProjectGitHandler(properties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
ProjectGitHubHandler projectGitHubHandler(
|
||||
@Autowired(required = false) List<CustomGithubIssues> customGithubIssues,
|
||||
ReleaserProperties properties) {
|
||||
return new ProjectGitHubHandler(properties,
|
||||
customGithubIssues != null ? customGithubIssues : new ArrayList<>());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
TemplateGenerator templateGenerator(ProjectGitHubHandler handler,
|
||||
ReleaserProperties properties) {
|
||||
return new TemplateGenerator(properties, handler);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
GradleUpdater gradleUpdater(ReleaserProperties properties) {
|
||||
return new GradleUpdater(properties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
SaganUpdater saganUpdater(SaganClient saganClient,
|
||||
ReleaserProperties releaserProperties) {
|
||||
return new SaganUpdater(saganClient, releaserProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
PostReleaseActions postReleaseActions(ProjectGitHandler handler,
|
||||
ProjectPomUpdater pomUpdater, GradleUpdater gradleUpdater,
|
||||
ProjectCommandExecutor projectCommandExecutor,
|
||||
ReleaserProperties releaserProperties, VersionsFetcher versionsFetcher) {
|
||||
return new PostReleaseActions(handler, pomUpdater, gradleUpdater,
|
||||
projectCommandExecutor, releaserProperties, versionsFetcher);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
DocumentationUpdater documentationUpdater(ProjectGitHandler projectGitHandler,
|
||||
ReleaserProperties properties, TemplateGenerator templateGenerator,
|
||||
@Autowired(
|
||||
required = false) List<CustomProjectDocumentationUpdater> customProjectDocumentationUpdaters) {
|
||||
return new DocumentationUpdater(projectGitHandler, properties, templateGenerator,
|
||||
customProjectDocumentationUpdaters != null
|
||||
? customProjectDocumentationUpdaters : new ArrayList<>());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
Releaser releaser(ProjectPomUpdater projectPomUpdater,
|
||||
ProjectCommandExecutor projectCommandExecutor,
|
||||
ProjectGitHandler projectGitHandler,
|
||||
ProjectGitHubHandler projectGitHubHandler,
|
||||
TemplateGenerator templateGenerator, GradleUpdater gradleUpdater,
|
||||
SaganUpdater saganUpdater, DocumentationUpdater documentationUpdater,
|
||||
PostReleaseActions postReleaseActions,
|
||||
ReleaserProperties releaserProperties) {
|
||||
return new Releaser(releaserProperties, projectPomUpdater, projectCommandExecutor,
|
||||
projectGitHandler, projectGitHubHandler, templateGenerator, gradleUpdater,
|
||||
saganUpdater, documentationUpdater, postReleaseActions);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
ReleaserPropertiesUpdater releaserPropertiesUpdater(ApplicationContext context) {
|
||||
return new ReleaserPropertiesUpdater(context);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
Parser optionsParser(List<ReleaserTask> allTasks,
|
||||
List<SingleProjectReleaserTask> singleProjectReleaserTasks,
|
||||
ConfigurableApplicationContext context) {
|
||||
return new OptionsParser(allTasks, singleProjectReleaserTasks, context);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.ReleaserPropertiesAware;
|
||||
|
||||
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
class ReleaserPropertiesUpdater {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(ReleaserPropertiesUpdater.class);
|
||||
|
||||
private final ApplicationContext context;
|
||||
|
||||
ReleaserPropertiesUpdater(ApplicationContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
ReleaserProperties updateProperties(ReleaserProperties properties,
|
||||
File clonedProjectFromOrg) {
|
||||
ReleaserProperties props = updatePropertiesFromFile(properties,
|
||||
clonedProjectFromOrg);
|
||||
props.setWorkingDir(clonedProjectFromOrg.getAbsolutePath());
|
||||
log.trace("Updated properties [\n\n{}\n\n]", props);
|
||||
updateProperties(props);
|
||||
return props;
|
||||
}
|
||||
|
||||
void updateProperties(ReleaserProperties props) {
|
||||
Map<String, ReleaserPropertiesAware> beans = this.context
|
||||
.getBeansOfType(ReleaserPropertiesAware.class);
|
||||
beans.values().forEach(aware -> aware.setReleaserProperties(props));
|
||||
}
|
||||
|
||||
private ReleaserProperties updatePropertiesFromFile(ReleaserProperties copy,
|
||||
File clonedProjectFromOrg) {
|
||||
File releaserConfig = releaserConfig(clonedProjectFromOrg);
|
||||
if (releaserConfig.exists()) {
|
||||
try {
|
||||
YamlPropertiesFactoryBean yamlProcessor = new YamlPropertiesFactoryBean();
|
||||
yamlProcessor.setResources(new FileSystemResource(releaserConfig));
|
||||
Properties properties = yamlProcessor.getObject();
|
||||
ReleaserProperties releaserProperties = new Binder(
|
||||
new MapConfigurationPropertySource(properties.entrySet().stream()
|
||||
.collect(Collectors.toMap(e -> e.getKey().toString(),
|
||||
e -> e.getValue().toString()))))
|
||||
.bind("releaser",
|
||||
ReleaserProperties.class)
|
||||
.get();
|
||||
log.info("config/releaser.yml found. Will update the current properties");
|
||||
overrideProperties(releaserProperties, copy);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.info(
|
||||
"No config/releaser.yml found. Will NOT update the current properties");
|
||||
}
|
||||
log.info("Updating working directory to [{}]",
|
||||
clonedProjectFromOrg.getAbsolutePath());
|
||||
copy.setWorkingDir(clonedProjectFromOrg.getAbsolutePath());
|
||||
return copy;
|
||||
}
|
||||
|
||||
private void overrideProperties(ReleaserProperties fromProject,
|
||||
ReleaserProperties copy) {
|
||||
overrideCommandIfPresent(fromProject.getMaven(), copy.getMaven());
|
||||
overrideCommandIfPresent(fromProject.getGradle(), copy.getGradle());
|
||||
overrideMapIfPresent(() -> fromProject.getGradle().getGradlePropsSubstitution(),
|
||||
s -> copy.getGradle().setGradlePropsSubstitution(s));
|
||||
overrideListIfPresent(() -> fromProject.getGradle().getIgnoredGradleRegex(),
|
||||
s -> copy.getGradle().setIgnoredGradleRegex(s));
|
||||
overrideCommandIfPresent(fromProject.getBash(), copy.getBash());
|
||||
}
|
||||
|
||||
private void overrideCommandIfPresent(ReleaserProperties.Command fromProject,
|
||||
ReleaserProperties.Command commandCopy) {
|
||||
overrideStringIfPresent(fromProject::getBuildCommand,
|
||||
commandCopy::setBuildCommand);
|
||||
overrideStringIfPresent(fromProject::getDeployCommand,
|
||||
commandCopy::setDeployCommand);
|
||||
overrideStringIfPresent(fromProject::getGenerateReleaseTrainDocsCommand,
|
||||
commandCopy::setGenerateReleaseTrainDocsCommand);
|
||||
overrideArrayIfPresent(fromProject::getPublishDocsCommands,
|
||||
commandCopy::setPublishDocsCommands);
|
||||
overrideStringIfPresent(fromProject::getDeployGuidesCommand,
|
||||
commandCopy::setDeployGuidesCommand);
|
||||
overrideStringIfPresent(fromProject::getSystemProperties,
|
||||
commandCopy::setSystemProperties);
|
||||
}
|
||||
|
||||
private void overrideStringIfPresent(Supplier<String> predicate,
|
||||
Consumer<String> consumer) {
|
||||
if (StringUtils.hasText(predicate.get())) {
|
||||
consumer.accept(predicate.get());
|
||||
}
|
||||
}
|
||||
|
||||
private void overrideArrayIfPresent(Supplier<String[]> predicate,
|
||||
Consumer<String[]> consumer) {
|
||||
String[] strings = predicate.get();
|
||||
if (strings.length > 0) {
|
||||
consumer.accept(strings);
|
||||
}
|
||||
}
|
||||
|
||||
private void overrideMapIfPresent(Supplier<Map<String, String>> predicate,
|
||||
Consumer<Map<String, String>> consumer) {
|
||||
Map<String, String> strings = predicate.get();
|
||||
if (!strings.isEmpty()) {
|
||||
consumer.accept(strings);
|
||||
}
|
||||
}
|
||||
|
||||
private void overrideListIfPresent(Supplier<List<String>> predicate,
|
||||
Consumer<List<String>> consumer) {
|
||||
List<String> strings = predicate.get();
|
||||
if (!strings.isEmpty()) {
|
||||
consumer.accept(strings);
|
||||
}
|
||||
}
|
||||
|
||||
File releaserConfig(File clonedProjectFromOrg) {
|
||||
return new File(clonedProjectFromOrg, "config/releaser.yml");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.jakewharton.fliptables.FlipTableConverters;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import releaser.internal.tasks.TrainPostReleaseReleaserTask;
|
||||
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.explore.JobExplorer;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.NestedExceptionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
class SpringBatchExecutionResultHandler implements ExecutionResultHandler {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(SpringBatchExecutionResultHandler.class);
|
||||
|
||||
private final JobExplorer jobExplorer;
|
||||
|
||||
private final ConfigurableApplicationContext context;
|
||||
|
||||
SpringBatchExecutionResultHandler(JobExplorer jobExplorer,
|
||||
ConfigurableApplicationContext context) {
|
||||
this.jobExplorer = jobExplorer;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ExecutionResult executionResult) {
|
||||
buildSummaryTable();
|
||||
if (executionResult.isFailure()) {
|
||||
log.error("At least one failure occurred while running the release process",
|
||||
executionResult.foundExceptions());
|
||||
handleFailedBuild();
|
||||
exitWithException();
|
||||
return;
|
||||
}
|
||||
else if (executionResult.isUnstable()) {
|
||||
log.warn(
|
||||
"The release went fine, however at least one unstable post release task was found",
|
||||
executionResult.foundExceptions());
|
||||
handleUnstableException();
|
||||
}
|
||||
handleStableBuild();
|
||||
exitSuccessfully();
|
||||
}
|
||||
|
||||
void exitSuccessfully() {
|
||||
SpringApplication.exit(this.context, () -> 0);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
void exitWithException() {
|
||||
SpringApplication.exit(this.context, () -> 1);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
private void buildSummaryTable() {
|
||||
List<String> jobNames = this.jobExplorer.getJobNames();
|
||||
List<JobExecution> sortedJobExecutions = jobNames.stream()
|
||||
.flatMap(name -> this.jobExplorer.findJobInstancesByJobName(name, 0, 100)
|
||||
.stream())
|
||||
.flatMap(instance -> this.jobExplorer.getJobExecutions(instance).stream())
|
||||
.sorted(Comparator.comparing(JobExecution::getCreateTime))
|
||||
.collect(Collectors.toList());
|
||||
List<StepExecution> stepContexts = sortedJobExecutions.stream()
|
||||
.flatMap(j -> j.getStepExecutions().stream())
|
||||
.collect(Collectors.toCollection(LinkedList::new));
|
||||
printTable(buildTable(stepContexts));
|
||||
}
|
||||
|
||||
private List<Table> buildTable(List<StepExecution> stepContexts) {
|
||||
return stepContexts.stream().map(step -> {
|
||||
String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
|
||||
.format(step.getStartTime());
|
||||
long millis = ChronoUnit.MILLIS.between(step.getStartTime().toInstant(),
|
||||
step.getEndTime().toInstant());
|
||||
ExecutionContext context = step.getExecutionContext();
|
||||
ExecutionResultReport entity = (ExecutionResultReport) context.get("entity");
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
String projectName = TrainPostReleaseReleaserTask.class
|
||||
.isAssignableFrom(entity.getReleaserTaskType()) ? "postRelease"
|
||||
: entity.getProjectName();
|
||||
return new Table(date, time(millis), projectName, entity.getShortName(),
|
||||
entity.getDescription(), entity.getState(), entity.getExceptions());
|
||||
}).filter(Objects::nonNull).collect(Collectors.toCollection(LinkedList::new));
|
||||
}
|
||||
|
||||
private String time(long millis) {
|
||||
long minutes = (millis / 1000) / 60;
|
||||
long seconds = (millis / 1000) % 60;
|
||||
if (minutes == 0 && seconds == 0) {
|
||||
return millis + " ms";
|
||||
}
|
||||
else if (minutes == 0) {
|
||||
return seconds + " s";
|
||||
}
|
||||
return minutes + " min " + seconds + " s";
|
||||
}
|
||||
|
||||
private void printTable(List<Table> table) {
|
||||
String string = "\n\n***** BUILD REPORT *****\n\n"
|
||||
+ FlipTableConverters.fromIterable(table, Table.class)
|
||||
+ "\n\n***** BUILD REPORT *****\n\n";
|
||||
List<Table> brokenTasks = table.stream()
|
||||
.filter(table1 -> StringUtils.hasText(table1.thrownException))
|
||||
.collect(Collectors.toList());
|
||||
if (!brokenTasks.isEmpty()) {
|
||||
String brokenBuilds = "\n\n[BUILD UNSTABLE] The following release tasks are failing!\n\n"
|
||||
+ brokenTasks.stream().map(table1 -> String.format(
|
||||
"***** Project / Task : <%s/%s> ***** \nTask Description <%s>\nException Stacktrace \n\n%s",
|
||||
table1.projectName, table1.taskCaption,
|
||||
table1.taskDescription,
|
||||
table1.exceptions + "\n"
|
||||
+ table1.exceptions.stream()
|
||||
.map(Throwable::getStackTrace)
|
||||
.flatMap(e -> Arrays.stream(e))
|
||||
.map(StackTraceElement::toString)
|
||||
.collect(Collectors.joining("\n"))))
|
||||
.collect(Collectors.joining("\n\n"));
|
||||
log.warn(string + brokenBuilds);
|
||||
}
|
||||
else {
|
||||
log.info(string);
|
||||
}
|
||||
}
|
||||
|
||||
// File creation required by Jenkins
|
||||
private void handleUnstableException() {
|
||||
File buildStatus = new File("build_status");
|
||||
try {
|
||||
buildStatus.createNewFile();
|
||||
String text = "[BUILD UNSTABLE] The release happened successfully, but there were post release issues";
|
||||
Files.write(buildStatus.toPath(), text.getBytes());
|
||||
log.info(
|
||||
"\n\n\n ___ _ _ ___ _ ___ _ _ _ _ ___ _____ _ ___ _ ___ \n"
|
||||
+ " | _ ) | | |_ _| | | \\ | | | | \\| / __|_ _/_\\ | _ ) | | __|\n"
|
||||
+ " | _ \\ |_| || || |__| |) | | |_| | .` \\__ \\ | |/ _ \\| _ \\ |__| _| \n"
|
||||
+ " |___/\\___/|___|____|___/ \\___/|_|\\_|___/ |_/_/ \\_\\___/____|___|\n"
|
||||
+ " ");
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new IllegalStateException(
|
||||
"[BUILD UNSTABLE] Couldn't create a file to show that the build is unstable");
|
||||
}
|
||||
}
|
||||
|
||||
// File creation required by Jenkins
|
||||
private void handleStableBuild() {
|
||||
File buildStatus = new File("build_status");
|
||||
if (buildStatus.exists()) {
|
||||
log.info("Build status file has already been created!");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
buildStatus.createNewFile();
|
||||
String text = "[BUILD STABLE] All the release steps have been successfully executed!";
|
||||
Files.write(buildStatus.toPath(), text.getBytes());
|
||||
log.info(
|
||||
"\n\n\n ___ _ _ ___ _ ___ ___ _ _ ___ ___ ___ ___ ___ ___ _ _ _ \n"
|
||||
+ " | _ ) | | |_ _| | | \\ / __| | | |/ __/ __| __/ __/ __| __| | | | | \n"
|
||||
+ " | _ \\ |_| || || |__| |) | \\__ \\ |_| | (_| (__| _|\\__ \\__ \\ _|| |_| | |__ \n"
|
||||
+ " |___/\\___/|___|____|___/ |___/\\___/ \\___\\___|___|___/___/_| \\___/|____|\n"
|
||||
+ " ");
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.info("Failed to store the file but the build was stable");
|
||||
}
|
||||
}
|
||||
|
||||
// File creation required by Jenkins
|
||||
private void handleFailedBuild() {
|
||||
File buildStatus = new File("build_status");
|
||||
if (buildStatus.exists()) {
|
||||
log.info("Build status file has already been created!");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
buildStatus.createNewFile();
|
||||
String text = "[BUILD FAILED] There were exceptions while doing the release!";
|
||||
Files.write(buildStatus.toPath(), text.getBytes());
|
||||
log.info("\n\n\n ___ _ _ ___ _ ___ ___ _ ___ _ ___ ___ \n"
|
||||
+ " | _ ) | | |_ _| | | \\ | __/_\\ |_ _| | | __| \\ \n"
|
||||
+ " | _ \\ |_| || || |__| |) | | _/ _ \\ | || |__| _|| |) |\n"
|
||||
+ " |___/\\___/|___|____|___/ |_/_/ \\_\\___|____|___|___/ \n"
|
||||
+ " ");
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new IllegalStateException(
|
||||
"[BUILD FAILED] Couldn't create a file to show that the build is unstable");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Table {
|
||||
|
||||
final String creationTime;
|
||||
|
||||
final String executionTime;
|
||||
|
||||
final String projectName;
|
||||
|
||||
final String taskCaption;
|
||||
|
||||
final String taskDescription;
|
||||
|
||||
final String taskState;
|
||||
|
||||
final String thrownException;
|
||||
|
||||
List<Throwable> exceptions;
|
||||
|
||||
Table(String creationTime, String executionTime, String projectName,
|
||||
String taskCaption, String taskDescription, String taskState,
|
||||
List<Throwable> exceptions) {
|
||||
this.creationTime = creationTime;
|
||||
this.executionTime = executionTime;
|
||||
this.projectName = projectName;
|
||||
this.taskCaption = taskCaption;
|
||||
this.taskDescription = taskDescription;
|
||||
this.taskState = taskState;
|
||||
this.thrownException = exceptions == null ? "" : exceptions.stream()
|
||||
// TODO: Last but most specific
|
||||
.map(t -> NestedExceptionUtils.getMostSpecificCause(t).toString())
|
||||
.collect(Collectors.joining("\n"));
|
||||
this.exceptions = exceptions;
|
||||
}
|
||||
|
||||
public String getExecutionTime() {
|
||||
return this.executionTime;
|
||||
}
|
||||
|
||||
public String getCreationTime() {
|
||||
return this.creationTime;
|
||||
}
|
||||
|
||||
public String getProjectName() {
|
||||
return this.projectName;
|
||||
}
|
||||
|
||||
public String getTaskCaption() {
|
||||
return this.taskCaption;
|
||||
}
|
||||
|
||||
public String getTaskDescription() {
|
||||
return this.taskDescription;
|
||||
}
|
||||
|
||||
public String getTaskState() {
|
||||
return this.taskState;
|
||||
}
|
||||
|
||||
public String getThrownException() {
|
||||
return this.thrownException;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,666 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.Collections;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.options.Options;
|
||||
import releaser.internal.tasks.CompositeReleaserTask;
|
||||
import releaser.internal.tasks.PostReleaseReleaserTask;
|
||||
import releaser.internal.tasks.ReleaseReleaserTask;
|
||||
import releaser.internal.tasks.ReleaserTask;
|
||||
import releaser.internal.tech.BuildUnstableException;
|
||||
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobExecutionException;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.StepExecutionListener;
|
||||
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
|
||||
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
|
||||
import org.springframework.batch.core.job.builder.FlowBuilder;
|
||||
import org.springframework.batch.core.job.builder.FlowJobBuilder;
|
||||
import org.springframework.batch.core.job.builder.JobBuilder;
|
||||
import org.springframework.batch.core.job.builder.JobFlowBuilder;
|
||||
import org.springframework.batch.core.job.flow.Flow;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.batch.core.listener.StepExecutionListenerSupport;
|
||||
import org.springframework.batch.repeat.RepeatStatus;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
|
||||
class SpringBatchFlowRunner implements FlowRunner, Closeable {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(SpringBatchFlowRunner.class);
|
||||
|
||||
private static final String MSG = "\nPress 'q' to quit, 's' to skip, any key to continue\n\n";
|
||||
|
||||
private final ConsoleInputStepSkipper stepSkipper;
|
||||
|
||||
private final StepBuilderFactory stepBuilderFactory;
|
||||
|
||||
private final JobBuilderFactory jobBuilderFactory;
|
||||
|
||||
private final ProjectsToRunFactory projectsToRunFactory;
|
||||
|
||||
private final JobLauncher jobLauncher;
|
||||
|
||||
private final FlowRunnerTaskExecutorSupplier flowRunnerTaskExecutorSupplier;
|
||||
|
||||
private static final List<TaskExecutor> EXECUTORS = new ArrayList<>();
|
||||
|
||||
private final ExecutorService executorService;
|
||||
|
||||
private final ReleaserProperties releaserProperties;
|
||||
|
||||
SpringBatchFlowRunner(StepBuilderFactory stepBuilderFactory,
|
||||
JobBuilderFactory jobBuilderFactory,
|
||||
ProjectsToRunFactory projectsToRunFactory, JobLauncher jobLauncher,
|
||||
FlowRunnerTaskExecutorSupplier flowRunnerTaskExecutorSupplier,
|
||||
ConfigurableApplicationContext context,
|
||||
ReleaserProperties releaserProperties) {
|
||||
this.stepBuilderFactory = stepBuilderFactory;
|
||||
this.jobBuilderFactory = jobBuilderFactory;
|
||||
this.projectsToRunFactory = projectsToRunFactory;
|
||||
this.jobLauncher = jobLauncher;
|
||||
this.flowRunnerTaskExecutorSupplier = flowRunnerTaskExecutorSupplier;
|
||||
this.stepSkipper = new ConsoleInputStepSkipper(context);
|
||||
this.releaserProperties = releaserProperties;
|
||||
this.executorService = Executors.newFixedThreadPool(
|
||||
this.releaserProperties.getMetaRelease().getReleaseGroupThreadCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Decision beforeTask(Options options, ReleaserProperties properties,
|
||||
ReleaserTask releaserTask) {
|
||||
return decide(options, releaserTask);
|
||||
}
|
||||
|
||||
private Step createStep(ReleaserTask releaserTask,
|
||||
NamedArgumentsSupplier argsSupplier) {
|
||||
return this.stepBuilderFactory
|
||||
.get(argsSupplier.projectName + "_" + releaserTask.name())
|
||||
.tasklet((contribution, chunkContext) -> {
|
||||
Arguments args = argsSupplier.get();
|
||||
FlowRunner.Decision decision = beforeTask(args.options,
|
||||
args.properties, releaserTask);
|
||||
if (decision == FlowRunner.Decision.CONTINUE) {
|
||||
ExecutionResult result = runTask(releaserTask, args);
|
||||
contribution.getStepExecution().getExecutionContext()
|
||||
.put("result", result);
|
||||
List<Throwable> errors = (List<Throwable>) contribution
|
||||
.getStepExecution().getExecutionContext().get("errors");
|
||||
RuntimeException exception = result.foundExceptions();
|
||||
errors = addExceptionToErrors(errors, exception);
|
||||
String status = result.isUnstable() ? "UNSTABLE"
|
||||
: result.isFailure() ? "FAILURE" : "SUCCESS";
|
||||
ExecutionResultReport entity = buildEntity(releaserTask, args,
|
||||
status, errors);
|
||||
contribution.getStepExecution().getExecutionContext()
|
||||
.put("entity", entity);
|
||||
if (result.isFailureOrUnstable()) {
|
||||
contribution.getStepExecution().getExecutionContext()
|
||||
.put("errors", errors);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ExecutionResultReport entity = buildEntity(releaserTask, args,
|
||||
"SKIPPED", Collections.emptyList());
|
||||
contribution.getStepExecution().getExecutionContext()
|
||||
.put("entity", entity);
|
||||
log.info("Skipping step [{}]", releaserTask.name());
|
||||
}
|
||||
return RepeatStatus.FINISHED;
|
||||
}).listener(releaserListener(argsSupplier, releaserTask)).build();
|
||||
}
|
||||
|
||||
private List<Throwable> addExceptionToErrors(List<Throwable> errors,
|
||||
RuntimeException exception) {
|
||||
if (errors == null) {
|
||||
errors = new LinkedList<>();
|
||||
}
|
||||
if (exception != null) {
|
||||
errors.add(exception);
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
private ExecutionResultReport buildEntity(ReleaserTask releaserTask, Arguments args,
|
||||
String state, List<Throwable> errors) {
|
||||
String projectName = args.project.getName();
|
||||
String shortName = releaserTask.getClass().getSimpleName();
|
||||
String description = releaserTask.description();
|
||||
Class<? extends ReleaserTask> releaseType = releaserTask.getClass();
|
||||
return new ExecutionResultReport(projectName, shortName, description, releaseType,
|
||||
state, errors);
|
||||
}
|
||||
|
||||
private ExecutionResult runTask(ReleaserTask releaserTask, Arguments args) {
|
||||
ExecutionResult executionResult = releaserTask.apply(args);
|
||||
if (executionResult.isFailure() && releaserTask instanceof ReleaseReleaserTask) {
|
||||
throw executionResult.foundExceptions();
|
||||
}
|
||||
return executionResult;
|
||||
}
|
||||
|
||||
private StepExecutionListener releaserListener(NamedArgumentsSupplier argsSupplier,
|
||||
ReleaserTask releaserTask) {
|
||||
return new StepExecutionListenerSupport() {
|
||||
@Override
|
||||
public ExitStatus afterStep(StepExecution stepExecution) {
|
||||
Arguments args = argsSupplier.get();
|
||||
FlowRunner.Decision decision = afterTask(args.options, args.properties,
|
||||
releaserTask);
|
||||
if (decision == FlowRunner.Decision.ABORT) {
|
||||
return ExitStatus.FAILED;
|
||||
}
|
||||
ExecutionResult result = (ExecutionResult) stepExecution
|
||||
.getExecutionContext().get("result");
|
||||
if (result == null || result.isSuccess()) {
|
||||
return stepExecution.getExitStatus();
|
||||
}
|
||||
else if (result.isUnstable()) {
|
||||
return new ExitStatus(BuildUnstableException.EXIT_CODE,
|
||||
BuildUnstableException.DESCRIPTION);
|
||||
}
|
||||
else if (result.isFailure()) {
|
||||
return ExitStatus.FAILED;
|
||||
}
|
||||
return ExitStatus.COMPLETED;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runReleaseTasks(Options options, ReleaserProperties properties,
|
||||
ProjectsToRun projectsToRun, TasksToRun tasksToRun) {
|
||||
ProjectsToReleaseGroups groups = new ProjectsToReleaseGroups(properties);
|
||||
List<ReleaseGroup> releaseGroups = groups.toReleaseGroup(projectsToRun);
|
||||
if (groups.hasGroups()) {
|
||||
log.info("Found the following release groups {}", releaseGroups);
|
||||
}
|
||||
List<StuffToRun> flows = releaseGroups.stream()
|
||||
.map(group -> buildFlowForGroup(tasksToRun, group))
|
||||
.collect(Collectors.toCollection(LinkedList::new));
|
||||
Iterator<StuffToRun> flowsIterator = flows.iterator();
|
||||
if (!flowsIterator.hasNext()) {
|
||||
// nothing to run
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
if (flows.stream().allMatch(StuffToRun::hasCompositeTask)) {
|
||||
log.info("You've picked composite jobs to run");
|
||||
return runComposites(flows, groups);
|
||||
}
|
||||
return runJob(buildJobForFlows(flowsIterator));
|
||||
}
|
||||
|
||||
private ExecutionResult runComposites(List<StuffToRun> flows,
|
||||
ProjectsToReleaseGroups groups) {
|
||||
if (groups.hasGroups()) {
|
||||
// will run in parallel
|
||||
List<ExecutionResult> results = new LinkedList<>();
|
||||
for (StuffToRun flow : flows) {
|
||||
log.info("Releasing group [{}]", flow.releaseGroup);
|
||||
ExecutionResult executionResult = runInParallel(flow, flow.task).stream()
|
||||
.map(this::result)
|
||||
.reduce(new ExecutionResult(), ExecutionResult::merge);
|
||||
log.info("Group [{}] execution result is [{}]", flow.releaseGroup,
|
||||
executionResult);
|
||||
if (executionResult.isFailure()) {
|
||||
// stop running any additional flows when an release task exception
|
||||
// was found
|
||||
throw executionResult.foundExceptions();
|
||||
}
|
||||
results.add(executionResult);
|
||||
}
|
||||
return results.stream().reduce(new ExecutionResult(), ExecutionResult::merge);
|
||||
}
|
||||
// will run in sequence
|
||||
return flows.stream().map(s -> runInSequence(s, s.task)).flatMap(s -> s)
|
||||
.reduce(new ExecutionResult(), ExecutionResult::merge);
|
||||
}
|
||||
|
||||
private ExecutionResult result(Future<ExecutionResult> future) {
|
||||
try {
|
||||
return future.get();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Future<ExecutionResult>> runInParallel(StuffToRun stuffToRun,
|
||||
CompositeReleaserTask releaserTask) {
|
||||
log.info("Running composite tasks in parallel for {}", stuffToRun.releaseGroup);
|
||||
return stuffToRun.releaseGroup.projectsToRun.stream().map(s -> {
|
||||
log.info("Scheduling a build for project [{}]", s.projectName());
|
||||
return this.executorService.submit(() -> {
|
||||
log.info("Running a composite task [{}] in parallel",
|
||||
releaserTask.name());
|
||||
return releaserTask.apply(Arguments.forProject(s.get()));
|
||||
});
|
||||
}).collect(Collectors.toCollection(LinkedList::new));
|
||||
}
|
||||
|
||||
private Stream<ExecutionResult> runInSequence(StuffToRun stuffToRun,
|
||||
CompositeReleaserTask releaserTask) {
|
||||
return stuffToRun.releaseGroup.projectsToRun.stream()
|
||||
.map(s -> releaserTask.apply(Arguments.forProject(s.get())));
|
||||
}
|
||||
|
||||
private Job buildJobForFlows(Iterator<StuffToRun> flowsIterator) {
|
||||
JobBuilder release = this.jobBuilderFactory
|
||||
.get("release_" + System.currentTimeMillis());
|
||||
StuffToRun stuffToRun = flowsIterator.next();
|
||||
Flow first = stuffToRun.flow;
|
||||
JobFlowBuilder start = release.start(first);
|
||||
FlowBuilder<FlowJobBuilder> next = null;
|
||||
while (flowsIterator.hasNext()) {
|
||||
StuffToRun toRun = flowsIterator.next();
|
||||
next = start.next(toRun.flow);
|
||||
}
|
||||
FlowJobBuilder builder = next != null ? next.build() : start.build();
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private StuffToRun buildFlowForGroup(TasksToRun tasksToRun, ReleaseGroup group) {
|
||||
FlowBuilder<Flow> flowBuilder = new FlowBuilder<>(
|
||||
group.flowName() + (group.shouldRunInParallel() ? "_Parallel" : "") + "_"
|
||||
+ System.currentTimeMillis());
|
||||
Iterator<ProjectToRun.ProjectToRunSupplier> iterator = group.iterator();
|
||||
if (!iterator.hasNext() || tasksToRun.isEmpty()) {
|
||||
return new StuffToRun(group, flowBuilder.build());
|
||||
}
|
||||
// only one project to run - run in sequence
|
||||
final ProjectToRun.ProjectToRunSupplier project = iterator.next();
|
||||
if (tasksToRun.size() == 1
|
||||
&& tasksToRun.get(0) instanceof CompositeReleaserTask) {
|
||||
return new StuffToRun(group, (CompositeReleaserTask) tasksToRun.get(0));
|
||||
}
|
||||
flowBuilder.start(toFlowOfTasks(tasksToRun,
|
||||
new NamedArgumentsSupplier(project.projectName(),
|
||||
() -> Arguments.forProject(project.get())),
|
||||
flowBuilder(project.projectName())));
|
||||
if (!iterator.hasNext()) {
|
||||
return new StuffToRun(group, flowBuilder.build());
|
||||
}
|
||||
// more projects, run them in parallel
|
||||
FlowBuilder.SplitBuilder<Flow> split = flowBuilder.split(taskExecutor());
|
||||
List<Flow> flows = new LinkedList<>();
|
||||
while (iterator.hasNext()) {
|
||||
final ProjectToRun.ProjectToRunSupplier nextProject = iterator.next();
|
||||
String projectName = project.projectName();
|
||||
flows.add(toFlowOfTasks(tasksToRun,
|
||||
new NamedArgumentsSupplier(project.projectName(),
|
||||
() -> Arguments.forProject(nextProject.get())),
|
||||
flowBuilder(projectName)));
|
||||
}
|
||||
return new StuffToRun(group, split.add(flows.toArray(new Flow[0])).end());
|
||||
}
|
||||
|
||||
private FlowBuilder<Flow> flowBuilder(String projectName) {
|
||||
return new FlowBuilder<>(projectName + "_Flow_" + System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runPostReleaseTrainTasks(Options options,
|
||||
ReleaserProperties properties, String taskName, TasksToRun tasksToRun) {
|
||||
ProjectsToRun projectsToRun = postReleaseTrainProjects(
|
||||
new OptionsAndProperties(properties, options));
|
||||
Flow flow = postReleaseFlow(tasksToRun, properties, projectsToRun);
|
||||
String name = taskName + "_" + System.currentTimeMillis();
|
||||
if (flow == null) {
|
||||
log.info("No release train post release tasks to run, will do nothing");
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
Job job = this.jobBuilderFactory.get(name).start(flow).build().build();
|
||||
return runJob(job);
|
||||
}
|
||||
|
||||
private ProjectsToRun postReleaseTrainProjects(OptionsAndProperties options) {
|
||||
return this.projectsToRunFactory.postReleaseTrain(options);
|
||||
}
|
||||
|
||||
private Flow toFlowOfTasks(TasksToRun tasksToRun, NamedArgumentsSupplier args,
|
||||
FlowBuilder<Flow> flowBuilder) {
|
||||
Iterator<? extends ReleaserTask> iterator = tasksToRun.iterator();
|
||||
ReleaserTask task = iterator.next();
|
||||
flowBuilder.start(createStep(task, args));
|
||||
while (iterator.hasNext()) {
|
||||
flowBuilder.next(createStep(iterator.next(), args));
|
||||
}
|
||||
return flowBuilder.build();
|
||||
}
|
||||
|
||||
private ExecutionResult runJob(Job job) {
|
||||
try {
|
||||
JobExecution execution = this.jobLauncher.run(job, new JobParameters());
|
||||
if (!ExitStatus.COMPLETED.equals(execution.getExitStatus())) {
|
||||
return ExecutionResult.failure(new IllegalStateException(
|
||||
"Job failed to get executed successfully. Failed with exit code ["
|
||||
+ execution.getExitStatus().getExitCode()
|
||||
+ "] and description ["
|
||||
+ execution.getExitStatus().getExitDescription() + "]"));
|
||||
}
|
||||
List<Exception> thrownExceptions = exceptionsThrownBySteps(execution);
|
||||
if (thrownExceptions.isEmpty()) {
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
return new ExecutionResult(thrownExceptions);
|
||||
}
|
||||
catch (JobExecutionException ex) {
|
||||
return ExecutionResult.failure(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Exception> exceptionsThrownBySteps(JobExecution execution) {
|
||||
return execution.getStepExecutions().stream()
|
||||
.map(e -> e.getExecutionContext().get("errors") != null
|
||||
? (List) e.getExecutionContext().get("errors") : new LinkedList())
|
||||
.reduce(new LinkedList<Exception>(), (o, o2) -> {
|
||||
o.addAll(o2);
|
||||
return o;
|
||||
});
|
||||
}
|
||||
|
||||
private Flow postReleaseFlow(TasksToRun tasksToRun, ReleaserProperties properties,
|
||||
ProjectsToRun projectsToRun) {
|
||||
Iterator<? extends ReleaserTask> iterator = tasksToRun.iterator();
|
||||
if (!iterator.hasNext()) {
|
||||
return null;
|
||||
}
|
||||
ReleaserTask task = iterator.next();
|
||||
Flow flow = flow(properties, projectsToRun, task);
|
||||
FlowBuilder<Flow> flowBuilder = new FlowBuilder<Flow>(
|
||||
"parallelPostRelease_" + System.currentTimeMillis()).start(flow);
|
||||
if (!iterator.hasNext()) {
|
||||
return flowBuilder.build();
|
||||
}
|
||||
FlowBuilder.SplitBuilder<Flow> builder = flowBuilder.split(taskExecutor());
|
||||
List<Flow> flows = new LinkedList<>();
|
||||
while (iterator.hasNext()) {
|
||||
flows.add(flow(properties, projectsToRun, iterator.next()));
|
||||
}
|
||||
Flow[] objects = flows.toArray(new Flow[0]);
|
||||
return builder.add(objects).build();
|
||||
}
|
||||
|
||||
private TaskExecutor taskExecutor() {
|
||||
TaskExecutor taskExecutor = this.flowRunnerTaskExecutorSupplier.get();
|
||||
EXECUTORS.add(taskExecutor);
|
||||
return taskExecutor;
|
||||
}
|
||||
|
||||
private Flow flow(ReleaserProperties properties, ProjectsToRun projectsToRun,
|
||||
ReleaserTask task) {
|
||||
return new FlowBuilder<Flow>(task.name() + "Flow")
|
||||
.start(createStep(task, new NamedArgumentsSupplier("postRelease",
|
||||
() -> Arguments.forPostRelease(properties, projectsToRun))))
|
||||
.build();
|
||||
}
|
||||
|
||||
Decision decide(Options options, ReleaserTask task) {
|
||||
boolean interactive = options.interactive;
|
||||
printLog(interactive, task);
|
||||
if (interactive) {
|
||||
boolean skipStep = this.stepSkipper.skipStep();
|
||||
return skipStep ? Decision.SKIP : Decision.CONTINUE;
|
||||
}
|
||||
return Decision.CONTINUE;
|
||||
}
|
||||
|
||||
private void printLog(boolean interactive, ReleaserTask task) {
|
||||
String taskType = task instanceof PostReleaseReleaserTask ? "Post Release Task"
|
||||
: "Release Task";
|
||||
log.info("\n\n\n=== {} [{}] ===\n\n{} {}\n\n", task.header(), taskType,
|
||||
task.description(), interactive ? MSG : "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
EXECUTORS.stream().filter(t -> t instanceof DisposableBean).forEach(e -> {
|
||||
try {
|
||||
((DisposableBean) e).destroy();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
log.debug("Exception occurred while trying to destroy the bean", ex);
|
||||
}
|
||||
});
|
||||
this.executorService.shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class NamedArgumentsSupplier implements Supplier<Arguments> {
|
||||
|
||||
final String projectName;
|
||||
|
||||
final Supplier<Arguments> argumentsSupplier;
|
||||
|
||||
final AtomicReference<Arguments> arguments = new AtomicReference<>();
|
||||
|
||||
NamedArgumentsSupplier(String projectName, Supplier<Arguments> argumentsSupplier) {
|
||||
this.projectName = projectName;
|
||||
this.argumentsSupplier = argumentsSupplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Arguments get() {
|
||||
if (this.arguments.get() != null) {
|
||||
return arguments.get();
|
||||
}
|
||||
Arguments arguments = this.argumentsSupplier.get();
|
||||
this.arguments.set(arguments);
|
||||
return arguments;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ConsoleInputStepSkipper {
|
||||
|
||||
private final ConfigurableApplicationContext context;
|
||||
|
||||
ConsoleInputStepSkipper(ConfigurableApplicationContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public boolean skipStep() {
|
||||
String input = chosenOption();
|
||||
switch (input.toLowerCase()) {
|
||||
case "s":
|
||||
return true;
|
||||
case "q":
|
||||
SpringApplication.exit(this.context, () -> 0);
|
||||
System.exit(0);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
String chosenOption() {
|
||||
return System.console().readLine();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class StuffToRun {
|
||||
|
||||
final ReleaseGroup releaseGroup;
|
||||
|
||||
final Flow flow;
|
||||
|
||||
final CompositeReleaserTask task;
|
||||
|
||||
StuffToRun(ReleaseGroup releaseGroup, Flow flow) {
|
||||
this.releaseGroup = releaseGroup;
|
||||
this.flow = flow;
|
||||
this.task = null;
|
||||
}
|
||||
|
||||
StuffToRun(ReleaseGroup releaseGroup, CompositeReleaserTask task) {
|
||||
this.releaseGroup = releaseGroup;
|
||||
this.task = task;
|
||||
this.flow = null;
|
||||
}
|
||||
|
||||
boolean hasCompositeTask() {
|
||||
return this.task != null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ProjectsToReleaseGroups {
|
||||
|
||||
private final ReleaserProperties releaserProperties;
|
||||
|
||||
ProjectsToReleaseGroups(ReleaserProperties releaserProperties) {
|
||||
this.releaserProperties = releaserProperties;
|
||||
}
|
||||
|
||||
List<ReleaseGroup> toReleaseGroup(ProjectsToRun projectsToRun) {
|
||||
ReleaseGroups releaseGroups = new ReleaseGroups(
|
||||
this.releaserProperties.getMetaRelease().getReleaseGroups());
|
||||
return releaseGroup(releaseGroups, null, new LinkedList<>(),
|
||||
projectsToRun.iterator());
|
||||
}
|
||||
|
||||
boolean hasGroups() {
|
||||
return !this.releaserProperties.getMetaRelease().getReleaseGroups().isEmpty();
|
||||
}
|
||||
|
||||
private List<ReleaseGroup> releaseGroup(ReleaseGroups releaseGroups,
|
||||
ReleaseGroup currentGroup, List<ReleaseGroup> merged,
|
||||
Iterator<ProjectToRun.ProjectToRunSupplier> iterator) {
|
||||
if (iterator.hasNext()) {
|
||||
// sleuth
|
||||
ProjectToRun.ProjectToRunSupplier supplier = iterator.next();
|
||||
// sleuth,contract,gateway
|
||||
String[] group = releaseGroups.group(supplier.projectName());
|
||||
if (currentGroup != null && !currentGroup.sameGroup(group)) {
|
||||
// we've been adding things to the current group, but we need to stop now
|
||||
merged.add(currentGroup);
|
||||
currentGroup = null;
|
||||
}
|
||||
if (group.length == 0) {
|
||||
// if no group matching, return a single entry
|
||||
ReleaseGroup current = new ReleaseGroup(supplier, group);
|
||||
merged.add(current);
|
||||
return releaseGroup(releaseGroups, null, merged, iterator);
|
||||
}
|
||||
// if still in group add to the current one
|
||||
if (currentGroup != null) {
|
||||
currentGroup.add(supplier);
|
||||
}
|
||||
else {
|
||||
currentGroup = new ReleaseGroup(supplier, group);
|
||||
}
|
||||
return releaseGroup(releaseGroups, currentGroup, merged, iterator);
|
||||
}
|
||||
if (currentGroup != null) {
|
||||
merged.add(currentGroup);
|
||||
}
|
||||
return merged;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ReleaseGroup {
|
||||
|
||||
final List<ProjectToRun.ProjectToRunSupplier> projectsToRun = new LinkedList<>();
|
||||
|
||||
final String[] group;
|
||||
|
||||
ReleaseGroup(ProjectToRun.ProjectToRunSupplier supplier, String[] group) {
|
||||
this.projectsToRun.add(supplier);
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
Iterator<ProjectToRun.ProjectToRunSupplier> iterator() {
|
||||
return projectsToRun.iterator();
|
||||
}
|
||||
|
||||
void add(ProjectToRun.ProjectToRunSupplier projectToRun) {
|
||||
this.projectsToRun.add(projectToRun);
|
||||
}
|
||||
|
||||
boolean sameGroup(String[] group) {
|
||||
return Arrays.equals(group, this.group);
|
||||
}
|
||||
|
||||
boolean shouldRunInParallel() {
|
||||
return this.projectsToRun.size() > 1;
|
||||
}
|
||||
|
||||
String flowName() {
|
||||
return this.projectsToRun.get(0).projectName() + "_Flow";
|
||||
}
|
||||
|
||||
private String projectName() {
|
||||
return this.projectsToRun.isEmpty() ? "EMPTY"
|
||||
: this.projectsToRun.get(0).projectName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ReleaseGroup{" + "group="
|
||||
+ (group.length > 0 ? Arrays.toString(group) : projectName()) + '}';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ReleaseGroups {
|
||||
|
||||
private final List<String> releaseGroups;
|
||||
|
||||
ReleaseGroups(List<String> releaseGroups) {
|
||||
this.releaseGroups = releaseGroups;
|
||||
}
|
||||
|
||||
String[] group(String name) {
|
||||
String foundGroup = this.releaseGroups.stream().filter(s -> s.contains(name))
|
||||
.findFirst().orElse(null);
|
||||
if (foundGroup == null) {
|
||||
return new String[0];
|
||||
}
|
||||
return foundGroup.split(",");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import releaser.internal.options.Options;
|
||||
|
||||
/**
|
||||
* Contract for releasing a project or train .
|
||||
*/
|
||||
public interface SpringReleaser {
|
||||
|
||||
/**
|
||||
* Perform a release with default options.
|
||||
* @return result of the release
|
||||
*/
|
||||
ExecutionResult release();
|
||||
|
||||
/**
|
||||
* Perform a release with provided options.
|
||||
* @param options options for the release
|
||||
* @return result of the release
|
||||
*/
|
||||
ExecutionResult release(Options options);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import releaser.internal.tasks.ReleaserTask;
|
||||
|
||||
public class TasksToRun extends LinkedList<ReleaserTask> {
|
||||
|
||||
public TasksToRun() {
|
||||
}
|
||||
|
||||
public TasksToRun(Collection<? extends ReleaserTask> c) {
|
||||
super(c);
|
||||
}
|
||||
|
||||
public TasksToRun(ReleaserTask c) {
|
||||
add(c);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.options.Options;
|
||||
import releaser.internal.tasks.ReleaserTask;
|
||||
import releaser.internal.tasks.TrainPostReleaseReleaserTask;
|
||||
import releaser.internal.tasks.composite.DryRunCompositeTask;
|
||||
import releaser.internal.tasks.composite.MetaReleaseCompositeTask;
|
||||
import releaser.internal.tasks.composite.MetaReleaseDryRunCompositeTask;
|
||||
import releaser.internal.tasks.composite.ReleaseCompositeTask;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
class TasksToRunFactory {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(TasksToRunFactory.class);
|
||||
|
||||
private final ApplicationContext context;
|
||||
|
||||
TasksToRunFactory(ApplicationContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
TasksToRun release(OptionsAndProperties optionsAndProperties) {
|
||||
TasksToRun tasks = releaseTasks(optionsAndProperties);
|
||||
tasks.forEach(t -> t.setup(optionsAndProperties.options,
|
||||
optionsAndProperties.properties));
|
||||
log.info("Will run the following tasks {}",
|
||||
tasks.stream().map(t -> t.getClass().getSimpleName()).collect(Collectors
|
||||
.toCollection((Supplier<LinkedList<String>>) LinkedList::new)));
|
||||
return tasks;
|
||||
}
|
||||
|
||||
private TasksToRun releaseTasks(OptionsAndProperties optionsAndProperties) {
|
||||
Options options = optionsAndProperties.options;
|
||||
ReleaserProperties properties = optionsAndProperties.properties;
|
||||
if (properties.isPostReleaseTasksOnly()) {
|
||||
return new TasksToRun();
|
||||
}
|
||||
if (options.metaRelease) {
|
||||
if (options.dryRun) {
|
||||
return new TasksToRun(
|
||||
this.context.getBean(MetaReleaseDryRunCompositeTask.class));
|
||||
}
|
||||
return new TasksToRun(this.context.getBean(MetaReleaseCompositeTask.class));
|
||||
}
|
||||
if (options.dryRun) {
|
||||
return new TasksToRun(this.context.getBean(DryRunCompositeTask.class));
|
||||
}
|
||||
else if (options.fullRelease) {
|
||||
return new TasksToRun(this.context.getBean(ReleaseCompositeTask.class));
|
||||
}
|
||||
// A single project release
|
||||
List<ReleaserTask> tasks = new LinkedList<>(
|
||||
this.context.getBeansOfType(ReleaserTask.class).values());
|
||||
tasks.sort(AnnotationAwareOrderComparator.INSTANCE);
|
||||
return tasksToRunForSingleProject(options, tasks);
|
||||
}
|
||||
|
||||
TasksToRun postRelease(Options options) {
|
||||
if (!options.metaRelease || options.dryRun) {
|
||||
return new TasksToRun();
|
||||
}
|
||||
List<ReleaserTask> tasks = new LinkedList<>(
|
||||
this.context.getBeansOfType(TrainPostReleaseReleaserTask.class).values());
|
||||
tasks.sort(AnnotationAwareOrderComparator.INSTANCE);
|
||||
return new TasksToRun(tasks);
|
||||
}
|
||||
|
||||
private TasksToRun tasksToRunForSingleProject(Options options,
|
||||
List<ReleaserTask> tasks) {
|
||||
if (StringUtils.hasText(options.startFrom)) {
|
||||
return startFrom(tasks, options);
|
||||
}
|
||||
else if (StringUtils.hasText(options.range)) {
|
||||
return range(tasks, options.range);
|
||||
}
|
||||
else if (!options.taskNames.isEmpty()) {
|
||||
return tasks(tasks, options.taskNames);
|
||||
}
|
||||
else if (options.interactive) {
|
||||
return interactiveOnly(tasks);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("You haven't picked any recognizable option");
|
||||
}
|
||||
}
|
||||
|
||||
private TasksToRun interactiveOnly(List<ReleaserTask> tasks) {
|
||||
log.info(buildOptionsText(tasks).toString());
|
||||
return taskFromOption(tasks);
|
||||
}
|
||||
|
||||
private TasksToRun tasks(List<ReleaserTask> tasks, List<String> taskNames) {
|
||||
return tasks.stream().filter(t -> taskNames.contains(t.name()))
|
||||
.collect(Collectors.toCollection(TasksToRun::new));
|
||||
}
|
||||
|
||||
private TasksToRun range(List<ReleaserTask> tasks, String range) {
|
||||
String[] splitRange = range.split("-");
|
||||
String start = splitRange[0];
|
||||
String stop = "";
|
||||
if (splitRange.length == 2) {
|
||||
stop = splitRange[1];
|
||||
}
|
||||
boolean sameRange = start.equals(stop);
|
||||
TasksToRun tasksToRun = new TasksToRun();
|
||||
for (ReleaserTask task : tasks) {
|
||||
if (start.equals(task.name()) || start.equals(task.shortName())) {
|
||||
tasksToRun.add(task);
|
||||
if (sameRange) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (stop.equals(task.name()) || stop.equals(task.shortName())) {
|
||||
tasksToRun.add(task);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return tasksToRun;
|
||||
}
|
||||
|
||||
private TasksToRun startFrom(List<ReleaserTask> tasks, Options options) {
|
||||
TasksToRun tasksToRun = new TasksToRun();
|
||||
for (ReleaserTask task : tasks) {
|
||||
if (options.startFrom.trim().equals(task.name())
|
||||
|| options.startFrom.trim().equals(task.shortName())) {
|
||||
tasksToRun.add(task);
|
||||
}
|
||||
}
|
||||
return tasksToRun;
|
||||
}
|
||||
|
||||
private StringBuilder buildOptionsText(List<ReleaserTask> allTasks) {
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append("\n\n\n=== WHAT DO YOU WANT TO DO? ===\n\n");
|
||||
for (int i = 0; i < allTasks.size(); i++) {
|
||||
msg.append(i).append(") ").append(allTasks.get(i).description()).append("\n");
|
||||
}
|
||||
msg.append("\n").append(
|
||||
"You can pick a range of options by using the hyphen - e.g. '2-4' will execute jobs [2,3,4]\n");
|
||||
msg.append("You can execute all tasks starting from a job "
|
||||
+ "by using a hyphen and providing only one "
|
||||
+ "number - e.g. '8-' will execute jobs [8,9,10]\n");
|
||||
msg.append("You can execute given tasks by providing a "
|
||||
+ "comma separated list of tasks - e.g. "
|
||||
+ "'3,7,8' will execute jobs [3,7,8]\n");
|
||||
msg.append("\n").append("You can press 'q' to quit\n\n");
|
||||
return msg;
|
||||
}
|
||||
|
||||
TasksToRun taskFromOption(List<ReleaserTask> tasks) {
|
||||
String input = chosenOption();
|
||||
if ("q".equals(input.toLowerCase())) {
|
||||
SpringApplication.exit(this.context, () -> 0);
|
||||
System.exit(0);
|
||||
return null;
|
||||
}
|
||||
if (input.contains("-")) {
|
||||
return rangeInteractive(tasks, input);
|
||||
}
|
||||
else if (input.contains(",")) {
|
||||
return tasksInteractive(tasks, input);
|
||||
}
|
||||
else {
|
||||
return singleTask(tasks, input);
|
||||
}
|
||||
}
|
||||
|
||||
private TasksToRun singleTask(List<ReleaserTask> tasks, String input) {
|
||||
int chosenOption = Integer.parseInt(input);
|
||||
ReleaserTask task = tasks.get(chosenOption);
|
||||
log.info("\n\n\nYou chose [{}]: [{}]\n\n\n", chosenOption, task.description());
|
||||
return new TasksToRun(task);
|
||||
}
|
||||
|
||||
private TasksToRun tasksInteractive(List<ReleaserTask> tasks, String input) {
|
||||
List<String> tasksFromInput = Arrays.asList(input.split(","));
|
||||
List<String> taskNames = new ArrayList<>();
|
||||
for (String task : tasksFromInput) {
|
||||
int taskIndex = Integer.parseInt(task);
|
||||
taskNames.add(tasks.get(taskIndex).name());
|
||||
}
|
||||
return tasks(tasks, taskNames);
|
||||
}
|
||||
|
||||
private TasksToRun rangeInteractive(List<ReleaserTask> tasks, String input) {
|
||||
String[] range = input.split("-");
|
||||
Integer start = Integer.valueOf(range[0]);
|
||||
Integer stop = null;
|
||||
if (range.length == 2) {
|
||||
stop = Integer.valueOf(range[1]);
|
||||
}
|
||||
String firstName = tasks.get(start).name();
|
||||
String second = stop != null ? tasks.get(stop).name() : "";
|
||||
return range(tasks, firstName + "-" + second);
|
||||
}
|
||||
|
||||
String chosenOption() {
|
||||
return System.console() == null ? "-1" : System.console().readLine();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.project.ProjectVersion;
|
||||
import releaser.internal.project.Projects;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
class VersionsToBumpFactory implements Closeable {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(VersionsToBumpFactory.class);
|
||||
|
||||
private static final Map<File, ProjectsFromBom> CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
private final ReleaserProperties properties;
|
||||
|
||||
VersionsToBumpFactory(Releaser releaser, ReleaserProperties properties) {
|
||||
this.releaser = releaser;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
ProjectsFromBom withProject(File project) {
|
||||
return CACHE.computeIfAbsent(project, file -> {
|
||||
log.info("Fetch from git [{}], meta release [{}], project [{}]",
|
||||
this.properties.getGit().isFetchVersionsFromGit(),
|
||||
this.properties.getMetaRelease().isEnabled(), project);
|
||||
if (this.properties.getGit().isFetchVersionsFromGit()
|
||||
&& !this.properties.getMetaRelease().isEnabled()) {
|
||||
return fetchVersionsFromGitForSingleProject(project);
|
||||
}
|
||||
return fetchVersionsFromFixedProjects(project);
|
||||
});
|
||||
}
|
||||
|
||||
private ProjectsFromBom fetchVersionsFromFixedProjects(File project) {
|
||||
ProjectVersion originalVersion = new ProjectVersion(project);
|
||||
Projects fixedVersions = this.releaser.fixedVersions();
|
||||
String fixedVersionForProject = fixedVersions.forName(project.getName()).version;
|
||||
ProjectVersion versionFromBom = StringUtils.hasText(fixedVersionForProject)
|
||||
? new ProjectVersion(originalVersion.projectName, fixedVersionForProject)
|
||||
: new ProjectVersion(project);
|
||||
fixedVersions.add(versionFromBom);
|
||||
printSettingVersionFromFixedVersions(fixedVersions);
|
||||
return cachedProjectsFromBom(project, versionFromBom, fixedVersions);
|
||||
}
|
||||
|
||||
private ProjectsFromBom fetchVersionsFromGitForSingleProject(File project) {
|
||||
printVersionRetrieval();
|
||||
Projects projectsToUpdate = this.releaser.retrieveVersionsFromBom();
|
||||
ProjectVersion versionFromBom = assertNoSnapshotsForANonSnapshotProject(project,
|
||||
projectsToUpdate);
|
||||
return cachedProjectsFromBom(project, versionFromBom, projectsToUpdate);
|
||||
}
|
||||
|
||||
private ProjectsFromBom cachedProjectsFromBom(File project,
|
||||
ProjectVersion versionFromBom, Projects projectsToUpdate) {
|
||||
return new ProjectsFromBom(projectsToUpdate, versionFromBom);
|
||||
}
|
||||
|
||||
ProjectVersion assertNoSnapshotsForANonSnapshotProject(File project,
|
||||
Projects projectsToUpdate) {
|
||||
ProjectVersion versionFromBom;
|
||||
versionFromBom = projectsToUpdate.forFile(project);
|
||||
assertNoSnapshotsForANonSnapshotProject(projectsToUpdate, versionFromBom);
|
||||
return versionFromBom;
|
||||
}
|
||||
|
||||
private void assertNoSnapshotsForANonSnapshotProject(Projects projects,
|
||||
ProjectVersion versionFromBom) {
|
||||
if (!versionFromBom.isSnapshot() && projects.containsSnapshots()) {
|
||||
throw new IllegalStateException("You are trying to release a non snapshot "
|
||||
+ "version [" + versionFromBom + "] of the project ["
|
||||
+ versionFromBom.projectName + "] but "
|
||||
+ "there is at least one SNAPSHOT library version in the Spring Cloud Release project");
|
||||
}
|
||||
}
|
||||
|
||||
private void printVersionRetrieval() {
|
||||
log.info("\n\n\n=== RETRIEVING VERSIONS ===\n\nWill clone the BOM project"
|
||||
+ " to retrieve all versions");
|
||||
}
|
||||
|
||||
private void printSettingVersionFromFixedVersions(Projects projectsToUpdate) {
|
||||
log.info(
|
||||
"\n\n\n=== RETRIEVED VERSIONS ===\n\nWill use the fixed versions"
|
||||
+ " of projects\n\n{}",
|
||||
projectsToUpdate.stream().map(p -> p.projectName + " => " + p.version)
|
||||
.collect(Collectors.joining("\n")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
CACHE.clear();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks;
|
||||
|
||||
/**
|
||||
* Marker interface for a composite task. Composite tasks are capable of executing other
|
||||
* tasks - e.g. "fullRelease" composite task executes all single project releaser tasks.
|
||||
*/
|
||||
public interface CompositeReleaserTask extends ReleaserTask {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
|
||||
/**
|
||||
* Allows to disable the default flow and gives an option to manually setup the whole
|
||||
* releaser flow.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Documented
|
||||
@ConditionalOnProperty(value = "releaser.flow.default-enabled", matchIfMissing = true)
|
||||
public @interface ConditionalOnDefaultFlowEnabled {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks;
|
||||
|
||||
/**
|
||||
* Marker interface for running release tasks in a dry run mode. You should make a task
|
||||
* implement this interface when you want it to be a part of the dry-run option. For
|
||||
* example a typical scenario of a dry-run is to just update the poms / build.gradle
|
||||
* files, build and install the artifacts locally.
|
||||
*/
|
||||
public interface DryRunReleaseReleaserTask extends ReleaseReleaserTask {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks;
|
||||
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
|
||||
/**
|
||||
* Marker interface for running post release tasks.
|
||||
*/
|
||||
public interface PostReleaseReleaserTask extends ReleaserTask {
|
||||
|
||||
/**
|
||||
* Executes the task but catches exceptions and converts them into result. When an
|
||||
* exception is throw will treat it as an instability.
|
||||
* @param args - arguments to run the task
|
||||
* @return execution result
|
||||
*/
|
||||
default ExecutionResult apply(Arguments args) {
|
||||
try {
|
||||
return runTask(args);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return ExecutionResult.unstable(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks;
|
||||
|
||||
/**
|
||||
* Marker interface for a post release task for a single project. Example: update the
|
||||
* GitHub milestone for the project.
|
||||
*/
|
||||
public interface ProjectPostReleaseReleaserTask
|
||||
extends SingleProjectReleaserTask, PostReleaseReleaserTask {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks;
|
||||
|
||||
/**
|
||||
* Marker interface for a single project release task. Unlike the post release task, if
|
||||
* this one fails, it should fail the release process. Example: build the project.
|
||||
*/
|
||||
public interface ReleaseReleaserTask extends SingleProjectReleaserTask {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.options.Options;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tech.BuildUnstableException;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
* Describes a single release task.
|
||||
*/
|
||||
public interface ReleaserTask extends Ordered, Function<Arguments, ExecutionResult> {
|
||||
|
||||
/**
|
||||
* @return name of the release task (e.g. 'Build')
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* @return short name of the release task (e.g. 'b')
|
||||
*/
|
||||
String shortName();
|
||||
|
||||
/**
|
||||
* @return header presented in the logs when running the task
|
||||
*/
|
||||
String header();
|
||||
|
||||
/**
|
||||
* @return meaningful description of the release task.
|
||||
*/
|
||||
String description();
|
||||
|
||||
/**
|
||||
* If necessary mutates options and properties for the release task. This can be
|
||||
* useful for composite tasks that impose certain configuration.
|
||||
* @param options - options to mutate
|
||||
* @param properties - properties to mutate
|
||||
*/
|
||||
default void setup(Options options, ReleaserProperties properties) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the task but catches exceptions and converts them into result. Knows how
|
||||
* to differentiate between a failure and instability.
|
||||
* @param args - arguments to run the task
|
||||
* @return execution result
|
||||
*/
|
||||
default ExecutionResult apply(Arguments args) {
|
||||
try {
|
||||
return runTask(args);
|
||||
}
|
||||
catch (BuildUnstableException ex) {
|
||||
return ExecutionResult.unstable(ex);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return ExecutionResult.failure(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Main task execution logic.
|
||||
* @param args - arguments for the job
|
||||
* @return execution result of the job
|
||||
* @throws BuildUnstableException - when the task failed but the release flow
|
||||
* shouldn't be stopped (which means that the build is unstable)
|
||||
* @throws RuntimeException - when the task failed for any other reason
|
||||
*/
|
||||
ExecutionResult runTask(Arguments args)
|
||||
throws BuildUnstableException, RuntimeException;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks;
|
||||
|
||||
/**
|
||||
* Marker interface for a task for a single project.
|
||||
*/
|
||||
public interface SingleProjectReleaserTask extends ReleaserTask {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks;
|
||||
|
||||
/**
|
||||
* Marker interface for a post release task for the whole release train. Example: update
|
||||
* the documentation of the release train.
|
||||
*/
|
||||
public interface TrainPostReleaseReleaserTask extends PostReleaseReleaserTask {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.composite;
|
||||
|
||||
import releaser.internal.tasks.ConditionalOnDefaultFlowEnabled;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnDefaultFlowEnabled
|
||||
class CompositeTasksConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
DryRunCompositeTask dryRunCompositeTask(ApplicationContext context) {
|
||||
return new DryRunCompositeTask(context);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
MetaReleaseCompositeTask metaReleaseCompositeTask(ApplicationContext context) {
|
||||
return new MetaReleaseCompositeTask(context);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
MetaReleaseDryRunCompositeTask metaReleaseDryRunCompositeTask(
|
||||
ApplicationContext context) {
|
||||
return new MetaReleaseDryRunCompositeTask(context);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
ReleaseCompositeTask releaseCompositeTask(ApplicationContext context) {
|
||||
return new ReleaseCompositeTask(context);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
ReleaseVerboseCompositeTask releaseVerboseCompositeTask(ApplicationContext context) {
|
||||
return new ReleaseVerboseCompositeTask(context);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
TrainPostReleaseCompositeTask trainPostReleaseCompositeTask(
|
||||
ApplicationContext context) {
|
||||
return new TrainPostReleaseCompositeTask(context);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.composite;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.options.Options;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.spring.FlowRunner;
|
||||
import releaser.internal.spring.ProjectToRun;
|
||||
import releaser.internal.spring.ProjectsToRun;
|
||||
import releaser.internal.spring.TasksToRun;
|
||||
import releaser.internal.tasks.CompositeReleaserTask;
|
||||
import releaser.internal.tasks.DryRunReleaseReleaserTask;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
|
||||
/**
|
||||
* Marked by {@link Options#dryRun}.
|
||||
*/
|
||||
public class DryRunCompositeTask implements CompositeReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = -60;
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(DryRunCompositeTask.class);
|
||||
|
||||
private final ApplicationContext context;
|
||||
|
||||
private FlowRunner flowRunner;
|
||||
|
||||
public DryRunCompositeTask(ApplicationContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "dryRun";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "dr";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "DRY RUN";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Perform a dry run release of a single project - bumps versions and installs them locally";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
Map<String, DryRunReleaseReleaserTask> dryRunTasks = this.context
|
||||
.getBeansOfType(DryRunReleaseReleaserTask.class);
|
||||
List<DryRunReleaseReleaserTask> values = new LinkedList<>(dryRunTasks.values());
|
||||
values.sort(AnnotationAwareOrderComparator.INSTANCE);
|
||||
log.info("For project [{}], found the following dry run tasks {}",
|
||||
args.project.getName(),
|
||||
values.stream().map(r -> r.getClass().getSimpleName())
|
||||
.collect(Collectors.toCollection(LinkedList::new)));
|
||||
return flowRunner().runReleaseTasks(args.options, args.properties,
|
||||
new ProjectsToRun(new ProjectToRun.ProjectToRunSupplier(
|
||||
args.originalVersion.projectName, () -> args.projectToRun)),
|
||||
new TasksToRun(values));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup(Options options, ReleaserProperties properties) {
|
||||
options.dryRun = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return DryRunCompositeTask.ORDER;
|
||||
}
|
||||
|
||||
private FlowRunner flowRunner() {
|
||||
if (this.flowRunner == null) {
|
||||
this.flowRunner = this.context.getBean(FlowRunner.class);
|
||||
}
|
||||
return this.flowRunner;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.composite;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.options.Options;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.CompositeReleaserTask;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* Marked by {@link Options#metaRelease}.
|
||||
*/
|
||||
public class MetaReleaseCompositeTask implements CompositeReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = -80;
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(MetaReleaseCompositeTask.class);
|
||||
|
||||
private final ApplicationContext context;
|
||||
|
||||
private ReleaseCompositeTask releaserCompositeTask;
|
||||
|
||||
public MetaReleaseCompositeTask(ApplicationContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "metaRelease";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "x";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "META RELEASE";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Perform a meta release of projects";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
return releaserCompositeTask().apply(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup(Options options, ReleaserProperties properties) {
|
||||
properties.getGit().setFetchVersionsFromGit(false);
|
||||
properties.getMetaRelease().setEnabled(true);
|
||||
options.fullRelease = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return MetaReleaseCompositeTask.ORDER;
|
||||
}
|
||||
|
||||
private ReleaseCompositeTask releaserCompositeTask() {
|
||||
if (this.releaserCompositeTask == null) {
|
||||
this.releaserCompositeTask = this.context.getBean(ReleaseCompositeTask.class);
|
||||
}
|
||||
return this.releaserCompositeTask;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.composite;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.options.Options;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.CompositeReleaserTask;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* Marked by {@link Options#metaRelease} and {@link Options#dryRun}.
|
||||
*/
|
||||
public class MetaReleaseDryRunCompositeTask implements CompositeReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = -70;
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(MetaReleaseDryRunCompositeTask.class);
|
||||
|
||||
private final ApplicationContext context;
|
||||
|
||||
private DryRunCompositeTask dryRunCompositeTask;
|
||||
|
||||
public MetaReleaseDryRunCompositeTask(ApplicationContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "metaReleaseDryRun";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "xdr";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "META RELEASE DRY RUN";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Perform a meta release dry run of projects";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
return dryRunCompositeTask().apply(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup(Options options, ReleaserProperties properties) {
|
||||
properties.getGit().setFetchVersionsFromGit(false);
|
||||
properties.getMetaRelease().setEnabled(true);
|
||||
options.fullRelease = true;
|
||||
options.dryRun = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return MetaReleaseDryRunCompositeTask.ORDER;
|
||||
}
|
||||
|
||||
private DryRunCompositeTask dryRunCompositeTask() {
|
||||
if (this.dryRunCompositeTask == null) {
|
||||
this.dryRunCompositeTask = this.context.getBean(DryRunCompositeTask.class);
|
||||
}
|
||||
return this.dryRunCompositeTask;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.composite;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.options.Options;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.spring.FlowRunner;
|
||||
import releaser.internal.spring.ProjectToRun;
|
||||
import releaser.internal.spring.ProjectsToRun;
|
||||
import releaser.internal.spring.TasksToRun;
|
||||
import releaser.internal.tasks.CompositeReleaserTask;
|
||||
import releaser.internal.tasks.ProjectPostReleaseReleaserTask;
|
||||
import releaser.internal.tasks.ReleaseReleaserTask;
|
||||
import releaser.internal.tasks.ReleaserTask;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
|
||||
/**
|
||||
* Marked by {@link Options#fullRelease}.
|
||||
*/
|
||||
public class ReleaseCompositeTask implements CompositeReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = -100;
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ReleaseCompositeTask.class);
|
||||
|
||||
private final ApplicationContext context;
|
||||
|
||||
private FlowRunner flowRunner;
|
||||
|
||||
public ReleaseCompositeTask(ApplicationContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "release";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "fr";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "FULL RELEASE";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Perform a full release of this project without interruptions";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
Map<String, ReleaseReleaserTask> releaseTasks = this.context
|
||||
.getBeansOfType(ReleaseReleaserTask.class);
|
||||
Map<String, ProjectPostReleaseReleaserTask> projectPostReleaseTasks = this.context
|
||||
.getBeansOfType(ProjectPostReleaseReleaserTask.class);
|
||||
Collection<ReleaserTask> allReleaseTasks = new LinkedList<>(
|
||||
releaseTasks.values());
|
||||
allReleaseTasks.addAll(projectPostReleaseTasks.values());
|
||||
List<ReleaserTask> values = new LinkedList<>(allReleaseTasks);
|
||||
values.sort(AnnotationAwareOrderComparator.INSTANCE);
|
||||
log.info(
|
||||
"For project [{}], found the following release and project post release tasks {}",
|
||||
args.project.getName(),
|
||||
values.stream().map(r -> r.getClass().getSimpleName())
|
||||
.collect(Collectors.toCollection(LinkedList::new)));
|
||||
return flowRunner().runReleaseTasks(args.options, args.properties,
|
||||
new ProjectsToRun(new ProjectToRun.ProjectToRunSupplier(
|
||||
args.originalVersion.projectName, () -> args.projectToRun)),
|
||||
new TasksToRun(values));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup(Options options, ReleaserProperties properties) {
|
||||
options.fullRelease = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return ReleaseCompositeTask.ORDER;
|
||||
}
|
||||
|
||||
private FlowRunner flowRunner() {
|
||||
if (this.flowRunner == null) {
|
||||
this.flowRunner = this.context.getBean(FlowRunner.class);
|
||||
}
|
||||
return this.flowRunner;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.composite;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.options.Options;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.CompositeReleaserTask;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
public class ReleaseVerboseCompositeTask implements CompositeReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = -90;
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(ReleaseVerboseCompositeTask.class);
|
||||
|
||||
private final ApplicationContext context;
|
||||
|
||||
private ReleaseCompositeTask releaserCompositeTask;
|
||||
|
||||
public ReleaseVerboseCompositeTask(ApplicationContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "releaseVerbose";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "r";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "FULL VERBOSE RELEASE";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Perform a full release of this project in interactive mode (you'll be asked about skipping steps)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
return releaserCompositeTask().apply(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup(Options options, ReleaserProperties properties) {
|
||||
options.fullRelease = true;
|
||||
options.interactive = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return ReleaseVerboseCompositeTask.ORDER;
|
||||
}
|
||||
|
||||
private ReleaseCompositeTask releaserCompositeTask() {
|
||||
if (this.releaserCompositeTask == null) {
|
||||
this.releaserCompositeTask = this.context.getBean(ReleaseCompositeTask.class);
|
||||
}
|
||||
return this.releaserCompositeTask;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.composite;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.options.Options;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.spring.FlowRunner;
|
||||
import releaser.internal.spring.TasksToRun;
|
||||
import releaser.internal.tasks.CompositeReleaserTask;
|
||||
import releaser.internal.tasks.ReleaserTask;
|
||||
import releaser.internal.tasks.TrainPostReleaseReleaserTask;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
|
||||
/**
|
||||
* Marked by {@link Options#metaRelease} and
|
||||
* {@link ReleaserProperties#isPostReleaseTasksOnly()}.
|
||||
*/
|
||||
public class TrainPostReleaseCompositeTask implements CompositeReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = -50;
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(TrainPostReleaseCompositeTask.class);
|
||||
|
||||
private final ApplicationContext context;
|
||||
|
||||
private FlowRunner flowRunner;
|
||||
|
||||
public TrainPostReleaseCompositeTask(ApplicationContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "postRelease";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "pr";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "POST RELEASE TASKS";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Perform post release tasks for this release without interruptions";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
Map<String, TrainPostReleaseReleaserTask> trainPostReleaseReleaserTasks = this.context
|
||||
.getBeansOfType(TrainPostReleaseReleaserTask.class);
|
||||
List<ReleaserTask> values = new LinkedList<>(
|
||||
trainPostReleaseReleaserTasks.values());
|
||||
values.sort(AnnotationAwareOrderComparator.INSTANCE);
|
||||
log.info("Found the following post release tasks {}", values);
|
||||
return flowRunner().runPostReleaseTrainTasks(args.options, args.properties,
|
||||
this.name(), new TasksToRun(values));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup(Options options, ReleaserProperties properties) {
|
||||
options.metaRelease = true;
|
||||
properties.setPostReleaseTasksOnly(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return TrainPostReleaseCompositeTask.ORDER;
|
||||
}
|
||||
|
||||
private FlowRunner flowRunner() {
|
||||
if (this.flowRunner == null) {
|
||||
this.flowRunner = this.context.getBean(FlowRunner.class);
|
||||
}
|
||||
return this.flowRunner;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.postrelease;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.ProjectPostReleaseReleaserTask;
|
||||
|
||||
public class CloseMilestonesProjectPostReleaseTask
|
||||
implements ProjectPostReleaseReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = 70;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
public CloseMilestonesProjectPostReleaseTask(Releaser releaser) {
|
||||
this.releaser = releaser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "closeMilestone";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "m";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "CLOSING MILESTONE";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Close the milestone at Github";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
this.releaser.closeMilestone(args.versionFromBom);
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return CloseMilestonesProjectPostReleaseTask.ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.postrelease;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.TrainPostReleaseReleaserTask;
|
||||
|
||||
public class CreateTemplatesTrainPostReleaseTask implements TrainPostReleaseReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = 70;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
public CreateTemplatesTrainPostReleaseTask(Releaser releaser) {
|
||||
this.releaser = releaser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "createTemplates";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "t";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "CREATING TEMPLATES";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Create email / blog / tweet etc. templates";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
this.releaser.createEmail(args.versionFromBom, args.projects);
|
||||
this.releaser.createBlog(args.versionFromBom, args.projects);
|
||||
this.releaser.createTweet(args.versionFromBom, args.projects);
|
||||
this.releaser.createReleaseNotes(args.versionFromBom, args.projects);
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return CreateTemplatesTrainPostReleaseTask.ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.postrelease;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.tasks.ConditionalOnDefaultFlowEnabled;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnDefaultFlowEnabled
|
||||
@ConditionalOnProperty(value = "releaser.skip-post-release-tasks", havingValue = "false",
|
||||
matchIfMissing = true)
|
||||
class PostReleaseTasksConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty("releaser.git.update-github-milestones")
|
||||
CloseMilestonesProjectPostReleaseTask closeMilestonesReleaseTask(Releaser releaser) {
|
||||
return new CloseMilestonesProjectPostReleaseTask(releaser);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty("releaser.template.enabled")
|
||||
CreateTemplatesTrainPostReleaseTask createTemplatesTrainPostReleaseTask(
|
||||
Releaser releaser) {
|
||||
return new CreateTemplatesTrainPostReleaseTask(releaser);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty("releaser.git.run-updated-samples")
|
||||
RunUpdatedSamplesTrainPostReleaseTask runUpdatedSamplesTrainPostReleaseTask(
|
||||
Releaser releaser) {
|
||||
return new RunUpdatedSamplesTrainPostReleaseTask(releaser);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty("releaser.git.update-all-test-samples")
|
||||
UpdateAllTestSamplesTrainPostReleaseTask updateAllTestSamplesTrainPostReleaseTask(
|
||||
Releaser releaser) {
|
||||
return new UpdateAllTestSamplesTrainPostReleaseTask(releaser);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty("releaser.git.update-documentation-repo")
|
||||
UpdateDocsRepositoryProjectPostReleaseTask updateDocsRepositoryProjectPostReleaseTask(
|
||||
Releaser releaser) {
|
||||
return new UpdateDocsRepositoryProjectPostReleaseTask(releaser);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty("releaser.git.update-documentation-repo")
|
||||
UpdateDocsRepositoryTrainPostReleaseTask updateDocsRepositoryTrainPostReleaseTask(
|
||||
Releaser releaser) {
|
||||
return new UpdateDocsRepositoryTrainPostReleaseTask(releaser);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty("releaser.git.update-guides-repo")
|
||||
UpdateGuidesTrainPostReleaseTask updateGuidesTrainPostReleaseTask(Releaser releaser) {
|
||||
return new UpdateGuidesTrainPostReleaseTask(releaser);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty("releaser.git.update-release-train-docs")
|
||||
UpdateReleaseTrainDocsTrainPostReleaseTask updateReleaseTrainDocsTrainPostReleaseTask(
|
||||
Releaser releaser) {
|
||||
return new UpdateReleaseTrainDocsTrainPostReleaseTask(releaser);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty("releaser.git.update-release-train-wiki")
|
||||
UpdateReleaseTrainWikiTrainPostReleaseTask updateReleaseTrainWikiTrainPostReleaseTask(
|
||||
Releaser releaser) {
|
||||
return new UpdateReleaseTrainWikiTrainPostReleaseTask(releaser);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty("releaser.sagan.update-sagan")
|
||||
UpdateSaganProjectPostReleaseTask updateSaganProjectPostReleaseTask(
|
||||
Releaser releaser) {
|
||||
return new UpdateSaganProjectPostReleaseTask(releaser);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty("releaser.sagan.update-start-spring-io")
|
||||
UpdateStartSpringIoTrainPostReleaseTask updateStartSpringIoTrainPostReleaseTask(
|
||||
Releaser releaser) {
|
||||
return new UpdateStartSpringIoTrainPostReleaseTask(releaser);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.postrelease;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.TrainPostReleaseReleaserTask;
|
||||
|
||||
public class RunUpdatedSamplesTrainPostReleaseTask
|
||||
implements TrainPostReleaseReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = 120;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
public RunUpdatedSamplesTrainPostReleaseTask(Releaser releaser) {
|
||||
this.releaser = releaser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "runUpdatedSample";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "ud";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "UPDATE AND RUN SAMPLES";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Updates the sample project with versions and runs samples";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
this.releaser.runUpdatedSamples(args.projects);
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return RunUpdatedSamplesTrainPostReleaseTask.ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.postrelease;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.TrainPostReleaseReleaserTask;
|
||||
|
||||
public class UpdateAllTestSamplesTrainPostReleaseTask
|
||||
implements TrainPostReleaseReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = 130;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
public UpdateAllTestSamplesTrainPostReleaseTask(Releaser releaser) {
|
||||
this.releaser = releaser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "updateAllSamples";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "ua";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "UPDATE ALL SAMPLES WITH RELEASE TRAIN BUMPED VERSIONS";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Update all samples with release train bumped versions";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
this.releaser.updateAllSamples(args.projects);
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return UpdateAllTestSamplesTrainPostReleaseTask.ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.postrelease;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.ProjectPostReleaseReleaserTask;
|
||||
|
||||
public class UpdateDocsRepositoryProjectPostReleaseTask
|
||||
implements ProjectPostReleaseReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = 105;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
public UpdateDocsRepositoryProjectPostReleaseTask(Releaser releaser) {
|
||||
this.releaser = releaser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "updateDocumentationForProject";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "udp";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "UPDATE DOCUMENTATION FOR PROJECT";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Updating documentation repository for a single project";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
this.releaser.updateDocumentationRepositoryForSingleProject(args.projects,
|
||||
args.versionFromBom);
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return UpdateDocsRepositoryProjectPostReleaseTask.ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.postrelease;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.TrainPostReleaseReleaserTask;
|
||||
|
||||
public class UpdateDocsRepositoryTrainPostReleaseTask
|
||||
implements TrainPostReleaseReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = 110;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
public UpdateDocsRepositoryTrainPostReleaseTask(Releaser releaser) {
|
||||
this.releaser = releaser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "updateDocumentation";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "ud";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "UPDATE DOCUMENTATION FOR RELEASE TRAIN";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Updating documentation repository for a release train";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
this.releaser.updateDocumentationRepositoryForTrain(args.properties,
|
||||
args.projects, args.versionFromBom);
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return UpdateDocsRepositoryTrainPostReleaseTask.ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.postrelease;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.TrainPostReleaseReleaserTask;
|
||||
|
||||
public class UpdateGuidesTrainPostReleaseTask implements TrainPostReleaseReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = 80;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
public UpdateGuidesTrainPostReleaseTask(Releaser releaser) {
|
||||
this.releaser = releaser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "updateGuides";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "ug";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "UPDATE GUIDES";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Updating Spring Guides";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
this.releaser.updateSpringGuides(args.versionFromBom, args.projects,
|
||||
args.processedProjects);
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return UpdateGuidesTrainPostReleaseTask.ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.postrelease;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.TrainPostReleaseReleaserTask;
|
||||
|
||||
public class UpdateReleaseTrainDocsTrainPostReleaseTask
|
||||
implements TrainPostReleaseReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = 120;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
public UpdateReleaseTrainDocsTrainPostReleaseTask(Releaser releaser) {
|
||||
this.releaser = releaser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "updateReleaseTrainDocs";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "ur";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "UPDATE RELEASE TRAIN DOCS";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Updating release train documentation";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
this.releaser.generateReleaseTrainDocumentation(args.projects);
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return UpdateReleaseTrainDocsTrainPostReleaseTask.ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.postrelease;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.TrainPostReleaseReleaserTask;
|
||||
|
||||
public class UpdateReleaseTrainWikiTrainPostReleaseTask
|
||||
implements TrainPostReleaseReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = 140;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
public UpdateReleaseTrainWikiTrainPostReleaseTask(Releaser releaser) {
|
||||
this.releaser = releaser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "updateReleaseTrainWiki";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "uw";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "UPDATE RELEASE TRAIN WIKI";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Update release train wiki page";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
this.releaser.updateReleaseTrainWiki(args.projects);
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return UpdateReleaseTrainWikiTrainPostReleaseTask.ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.postrelease;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.ProjectPostReleaseReleaserTask;
|
||||
|
||||
public class UpdateSaganProjectPostReleaseTask implements ProjectPostReleaseReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = 100;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
public UpdateSaganProjectPostReleaseTask(Releaser releaser) {
|
||||
this.releaser = releaser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "updateSagan";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "g";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "UPDATE SAGAN";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Updating Sagan with release info";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
this.releaser.updateSagan(args.project, args.versionFromBom, args.projects);
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return UpdateSaganProjectPostReleaseTask.ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.postrelease;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.TrainPostReleaseReleaserTask;
|
||||
|
||||
public class UpdateStartSpringIoTrainPostReleaseTask
|
||||
implements TrainPostReleaseReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = 90;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
public UpdateStartSpringIoTrainPostReleaseTask(Releaser releaser) {
|
||||
this.releaser = releaser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "updateStartSpringIo";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "us";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "UPDATE START.SPRING.IO";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Updating start.spring.io";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
this.releaser.updateStartSpringIo(args.versionFromBom, args.projects);
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return UpdateStartSpringIoTrainPostReleaseTask.ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.release;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.DryRunReleaseReleaserTask;
|
||||
|
||||
public class BuildProjectReleaseTask implements DryRunReleaseReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = 10;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
public BuildProjectReleaseTask(Releaser releaser) {
|
||||
this.releaser = releaser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "build";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "b";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "BUILD PROJECT";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Build the project";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
this.releaser.buildProject(args.originalVersion, args.versionFromBom);
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return BuildProjectReleaseTask.ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.release;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.ReleaseReleaserTask;
|
||||
|
||||
public class BumpBackToSnapshotReleaseTask implements ReleaseReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = 50;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
public BumpBackToSnapshotReleaseTask(Releaser releaser) {
|
||||
this.releaser = releaser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "snapshots";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "s";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "REVERTING CHANGES & BUMPING VERSION (RELEASE ONLY)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Go back to snapshots and bump originalVersion by patch";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
this.releaser.rollbackReleaseVersion(args.project, args.projects,
|
||||
args.versionFromBom);
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return BumpBackToSnapshotReleaseTask.ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.release;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.ReleaseReleaserTask;
|
||||
|
||||
public class CommitReleaseTask implements ReleaseReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = 20;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
public CommitReleaseTask(Releaser releaser) {
|
||||
this.releaser = releaser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "commit";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "c";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "COMMITTING (ALL) AND PUSHING TAGS (NON-SNAPSHOTS)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Commit, tag and push the tag";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
this.releaser.commitAndPushTags(args.project, args.versionFromBom);
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return CommitReleaseTask.ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.release;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.ReleaseReleaserTask;
|
||||
|
||||
public class DeployArtifactsReleaseTask implements ReleaseReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = 30;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
public DeployArtifactsReleaseTask(Releaser releaser) {
|
||||
this.releaser = releaser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "deploy";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "d";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "ARTIFACT DEPLOYMENT";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Deploy the artifacts";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
this.releaser.deploy(args.originalVersion, args.versionFromBom);
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return DeployArtifactsReleaseTask.ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.release;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.ReleaseReleaserTask;
|
||||
|
||||
public class PublishDocsReleaseTask implements ReleaseReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = 40;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
public PublishDocsReleaseTask(Releaser releaser) {
|
||||
this.releaser = releaser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "docs";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "o";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "PUBLISHING DOCS";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Publish the docs";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
this.releaser.publishDocs(args.originalVersion, args.versionFromBom);
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return PublishDocsReleaseTask.ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.release;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.ReleaseReleaserTask;
|
||||
|
||||
public class PushChangesReleaseTask implements ReleaseReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = 60;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
public PushChangesReleaseTask(Releaser releaser) {
|
||||
this.releaser = releaser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "push";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "p";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "PUSHING CHANGES";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Push the commits";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
this.releaser.pushCurrentBranch(args.project);
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return PushChangesReleaseTask.ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.release;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.tasks.ConditionalOnDefaultFlowEnabled;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnDefaultFlowEnabled
|
||||
class ReleaseTasksConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
BuildProjectReleaseTask buildProjectReleaseTask(Releaser releaser) {
|
||||
return new BuildProjectReleaseTask(releaser);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
BumpBackToSnapshotReleaseTask bumpBackToSnapshotReleaseTask(Releaser releaser) {
|
||||
return new BumpBackToSnapshotReleaseTask(releaser);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
CommitReleaseTask commitReleaseTask(Releaser releaser) {
|
||||
return new CommitReleaseTask(releaser);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
DeployArtifactsReleaseTask deployArtifactsReleaseTask(Releaser releaser) {
|
||||
return new DeployArtifactsReleaseTask(releaser);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
PublishDocsReleaseTask publishDocsReleaseTask(Releaser releaser) {
|
||||
return new PublishDocsReleaseTask(releaser);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
PushChangesReleaseTask pushChangesReleaseTask(Releaser releaser) {
|
||||
return new PushChangesReleaseTask(releaser);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
UpdatingPomsReleaseTask updatingPomsReleaseTask(Releaser releaser) {
|
||||
return new UpdatingPomsReleaseTask(releaser);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.tasks.release;
|
||||
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.spring.Arguments;
|
||||
import releaser.internal.spring.ExecutionResult;
|
||||
import releaser.internal.tasks.DryRunReleaseReleaserTask;
|
||||
|
||||
public class UpdatingPomsReleaseTask implements DryRunReleaseReleaserTask {
|
||||
|
||||
/**
|
||||
* Order of this task. The higher value, the lower order.
|
||||
*/
|
||||
public static final int ORDER = 0;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
public UpdatingPomsReleaseTask(Releaser releaser) {
|
||||
this.releaser = releaser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "updatePoms";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shortName() {
|
||||
return "u";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header() {
|
||||
return "UPDATING VERSIONS";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Update versions from the BOM";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult runTask(Arguments args) {
|
||||
this.releaser.updateProjectFromBom(args.project, args.projects,
|
||||
args.versionFromBom);
|
||||
return ExecutionResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return UpdatingPomsReleaseTask.ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.buildsystem;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.maven.model.Model;
|
||||
import releaser.internal.tech.PomReader;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class TestPomReader {
|
||||
|
||||
public Model readPom(File pom) {
|
||||
return PomReader.readPom(pom);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.buildsystem;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.jgit.util.FileUtils;
|
||||
|
||||
public final class TestUtils {
|
||||
|
||||
private TestUtils() {
|
||||
throw new IllegalStateException("Can't instantiate a utility class");
|
||||
}
|
||||
|
||||
public static void prepareLocalRepo() throws IOException {
|
||||
prepareLocalRepo("target/test-classes/projects/", "spring-cloud");
|
||||
prepareLocalRepo("target/test-classes/projects/", "spring-cloud-wiki");
|
||||
prepareLocalRepo("target/test-classes/projects/", "spring-cloud-release");
|
||||
prepareLocalRepo("target/test-classes/projects/",
|
||||
"spring-cloud-release-with-snapshot");
|
||||
prepareLocalRepo("target/test-classes/projects/", "spring-cloud-consul");
|
||||
prepareLocalRepo("target/test-classes/projects/", "spring-cloud-build");
|
||||
prepareLocalRepo("target/test-classes/projects/", "spring-cloud-static-angel");
|
||||
}
|
||||
|
||||
private static void prepareLocalRepo(String buildDir, String repoPath)
|
||||
throws IOException {
|
||||
File dotGit = new File(buildDir + repoPath + "/.git");
|
||||
File git = new File(buildDir + repoPath + "/git");
|
||||
if (git.exists()) {
|
||||
if (dotGit.exists()) {
|
||||
FileUtils.delete(dotGit, FileUtils.RECURSIVE);
|
||||
}
|
||||
}
|
||||
git.renameTo(dotGit);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.docs;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.Collections;
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.git.ProjectGitHandler;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class TestDocumentationUpdater extends DocumentationUpdater {
|
||||
|
||||
public TestDocumentationUpdater(ReleaserProperties properties,
|
||||
CustomProjectDocumentationUpdater updater, ProjectGitHandler handler,
|
||||
TestReleaseContentsUpdater testRelease) {
|
||||
super(properties, new ProjectDocumentationUpdater(properties, handler,
|
||||
Collections.singletonList(updater)), testRelease);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.docs;
|
||||
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.git.ProjectGitHandler;
|
||||
import releaser.internal.template.TemplateGenerator;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class TestReleaseContentsUpdater extends ReleaseTrainContentsUpdater {
|
||||
|
||||
public TestReleaseContentsUpdater(ReleaserProperties properties,
|
||||
ProjectGitHandler handler, TemplateGenerator templateGenerator) {
|
||||
super(properties, handler, templateGenerator);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.git;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.RemoteRemoveCommand;
|
||||
import org.eclipse.jgit.api.RemoteSetUrlCommand;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.transport.URIish;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public final class GitTestUtils {
|
||||
|
||||
private GitTestUtils() {
|
||||
throw new IllegalStateException("Can't instantiate a utility class");
|
||||
}
|
||||
|
||||
public static void setOriginOnProjectToTmp(File origin, File project)
|
||||
throws GitAPIException, MalformedURLException {
|
||||
try (Git git = openGitProject(project)) {
|
||||
RemoteRemoveCommand remove = git.remoteRemove();
|
||||
remove.setName("origin");
|
||||
remove.call();
|
||||
RemoteSetUrlCommand command = git.remoteSetUrl();
|
||||
command.setUri(new URIish(origin.toURI().toURL()));
|
||||
command.setName("origin");
|
||||
command.setPush(true);
|
||||
command.call();
|
||||
}
|
||||
}
|
||||
|
||||
public static Git openGitProject(File project) {
|
||||
return new GitRepo.JGitFactory().open(project);
|
||||
}
|
||||
|
||||
public static File clonedProject(File baseDir, File projectToClone)
|
||||
throws IOException {
|
||||
GitRepo projectRepo = new GitRepo(baseDir);
|
||||
return projectRepo.cloneProject(new URIish(projectToClone.toURI().toURL()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
// @RunWith(MockitoJUnitRunner.class)
|
||||
@SuppressWarnings("unchecked")
|
||||
public class OptionsProcessorTests {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* @Mock Releaser releaser;
|
||||
*
|
||||
* FirstConsumer first = new FirstConsumer();
|
||||
*
|
||||
* SecondConsumer second = new SecondConsumer();
|
||||
*
|
||||
* ThirdConsumer third = new ThirdConsumer();
|
||||
*
|
||||
* Task firstTask = task("first", "1", "", "", this.first);
|
||||
*
|
||||
* List<Task> tasks = Arrays .asList(new Task[] { this.firstTask, task("second", "2", "",
|
||||
* "", this.second), task("third", "3", "", "", this.third) });
|
||||
*
|
||||
* OptionsProcessor optionsProcessor;
|
||||
*
|
||||
* static Task task(String name, String shortName, String header, String description,
|
||||
* Consumer<Args> function) { return new Task(name, shortName, header, description,
|
||||
* function); }
|
||||
*
|
||||
* @Before public void setup() { this.optionsProcessor = new
|
||||
* OptionsProcessor(this.releaser, new ReleaserProperties(), this.tasks); Task.stepSkipper
|
||||
* = () -> false; }
|
||||
*
|
||||
* @After public void clean() { Task.stepSkipper = new ConsoleInputStepSkipper(); }
|
||||
*
|
||||
* @Test public void should_throw_exception_when_an_invalid_option_was_picked() { Options
|
||||
* options = nonInteractiveOpts().options();
|
||||
*
|
||||
* thenThrownBy(() -> this.optionsProcessor.processOptions(options, args()))
|
||||
* .hasMessageContaining("You haven't picked any recognizable option"); }
|
||||
*
|
||||
* @Test public void should_execute_only_tasks_after_the_provided_one_using_full_name() {
|
||||
* Options options = nonInteractiveOpts().startFrom("second").options();
|
||||
*
|
||||
* this.optionsProcessor.processOptions(options, args());
|
||||
*
|
||||
* then(this.first.executed).isFalse(); then(this.second.executed).isTrue();
|
||||
* then(this.third.executed).isTrue(); }
|
||||
*
|
||||
* @Test public void should_execute_only_tasks_after_the_provided_one_using_short_name() {
|
||||
* Options options = nonInteractiveOpts().startFrom("2").options();
|
||||
*
|
||||
* this.optionsProcessor.processOptions(options, args());
|
||||
*
|
||||
* then(this.first.executed).isFalse(); then(this.second.executed).isTrue();
|
||||
* then(this.third.executed).isTrue(); }
|
||||
*
|
||||
* @Test public void should_execute_only_tasks_from_range_using_full_name() { Options
|
||||
* options = nonInteractiveOpts().range("second-third").options();
|
||||
*
|
||||
* this.optionsProcessor.processOptions(options, args());
|
||||
*
|
||||
* then(this.first.executed).isFalse(); then(this.second.executed).isTrue();
|
||||
* then(this.third.executed).isTrue(); }
|
||||
*
|
||||
* @Test public void should_execute_only_tasks_from_range_using_short_name() { Options
|
||||
* options = nonInteractiveOpts().range("2-3").options();
|
||||
*
|
||||
* this.optionsProcessor.processOptions(options, args());
|
||||
*
|
||||
* then(this.first.executed).isFalse(); then(this.second.executed).isTrue();
|
||||
* then(this.third.executed).isTrue(); }
|
||||
*
|
||||
* @Test public void
|
||||
* should_execute_only_tasks_from_range_using_full_name_with_same_range() { Options
|
||||
* options = nonInteractiveOpts().range("second-second").options();
|
||||
*
|
||||
* this.optionsProcessor.processOptions(options, args());
|
||||
*
|
||||
* then(this.first.executed).isFalse(); then(this.second.executed).isTrue();
|
||||
* then(this.third.executed).isFalse(); }
|
||||
*
|
||||
* @Test public void
|
||||
* should_execute_only_tasks_from_range_using_short_name_with_same_range() { Options
|
||||
* options = nonInteractiveOpts().range("2-2").options();
|
||||
*
|
||||
* this.optionsProcessor.processOptions(options, args());
|
||||
*
|
||||
* then(this.first.executed).isFalse(); then(this.second.executed).isTrue();
|
||||
* then(this.third.executed).isFalse(); }
|
||||
*
|
||||
* @Test public void should_execute_only_tasks_from_multi_using_full_name() { Options
|
||||
* options = nonInteractiveOpts().taskNames(list("first", "third")) .options();
|
||||
*
|
||||
* this.optionsProcessor.processOptions(options, args());
|
||||
*
|
||||
* then(this.first.executed).isTrue(); then(this.second.executed).isFalse();
|
||||
* then(this.third.executed).isTrue(); }
|
||||
*
|
||||
* @Test public void should_execute_only_tasks_from_multi_using_short_name() { Options
|
||||
* options = nonInteractiveOpts().taskNames(list("1", "3")).options();
|
||||
*
|
||||
* this.optionsProcessor.processOptions(options, args());
|
||||
*
|
||||
* then(this.first.executed).isTrue(); then(this.second.executed).isFalse();
|
||||
* then(this.third.executed).isTrue(); }
|
||||
*
|
||||
* @Test public void should_execute_interactively_only_single_task() {
|
||||
* this.optionsProcessor = new OptionsProcessor(this.releaser, new ReleaserProperties(),
|
||||
* this.tasks) {
|
||||
*
|
||||
* @Override String chosenOption() { return "0"; } }; Options options =
|
||||
* interactiveOpts().options();
|
||||
*
|
||||
* this.optionsProcessor.processOptions(options, args());
|
||||
*
|
||||
* then(this.first.executed).isTrue(); then(this.second.executed).isFalse();
|
||||
* then(this.third.executed).isFalse(); }
|
||||
*
|
||||
* @Test public void should_execute_interactively_range_of_tasks() { this.optionsProcessor
|
||||
* = new OptionsProcessor(this.releaser, new ReleaserProperties(), this.tasks) {
|
||||
*
|
||||
* @Override String chosenOption() { return "0-1"; } }; Options options =
|
||||
* interactiveOpts().options();
|
||||
*
|
||||
* this.optionsProcessor.processOptions(options, args());
|
||||
*
|
||||
* then(this.first.executed).isTrue(); then(this.second.executed).isTrue();
|
||||
* then(this.third.executed).isFalse(); }
|
||||
*
|
||||
* @Test public void should_execute_interactively_start_from() { this.optionsProcessor =
|
||||
* new OptionsProcessor(this.releaser, new ReleaserProperties(), this.tasks) {
|
||||
*
|
||||
* @Override String chosenOption() { return "1-"; } }; Options options =
|
||||
* interactiveOpts().options();
|
||||
*
|
||||
* this.optionsProcessor.processOptions(options, args());
|
||||
*
|
||||
* then(this.first.executed).isFalse(); then(this.second.executed).isTrue();
|
||||
* then(this.third.executed).isTrue(); }
|
||||
*
|
||||
* @Test public void should_execute_interactively_multi() { this.optionsProcessor = new
|
||||
* OptionsProcessor(this.releaser, new ReleaserProperties(), this.tasks) {
|
||||
*
|
||||
* @Override String chosenOption() { return "0,2"; } }; Options options =
|
||||
* interactiveOpts().options();
|
||||
*
|
||||
* this.optionsProcessor.processOptions(options, args());
|
||||
*
|
||||
* then(this.first.executed).isTrue(); then(this.second.executed).isFalse();
|
||||
* then(this.third.executed).isTrue(); }
|
||||
*
|
||||
* @Test public void should_execute_full_release() { this.optionsProcessor = new
|
||||
* OptionsProcessor(this.releaser, new ReleaserProperties(), this.tasks) {
|
||||
*
|
||||
* @Override Task releaseTask() { return OptionsProcessorTests.this.firstTask; }
|
||||
*
|
||||
* @Override String chosenOption() { return "0"; } }; Options options =
|
||||
* nonInteractiveOpts().fullRelease(true).options();
|
||||
*
|
||||
* this.optionsProcessor.processOptions(options, args());
|
||||
*
|
||||
* then(this.first.executed).isTrue(); then(this.second.executed).isFalse();
|
||||
* then(this.third.executed).isFalse(); }
|
||||
*
|
||||
* @Test public void should_execute_full_verbose_release() { this.optionsProcessor = new
|
||||
* OptionsProcessor(this.releaser, new ReleaserProperties(), this.tasks) {
|
||||
*
|
||||
* @Override Task releaseVerboseTask() { return OptionsProcessorTests.this.firstTask; }
|
||||
*
|
||||
* @Override String chosenOption() { return "0"; } }; Options options =
|
||||
* interactiveOpts().fullRelease(true).options();
|
||||
*
|
||||
* this.optionsProcessor.processOptions(options, args());
|
||||
*
|
||||
* then(this.first.executed).isTrue(); then(this.second.executed).isFalse();
|
||||
* then(this.third.executed).isFalse(); }
|
||||
*
|
||||
* @Test public void should_remove_single_quotes() { Options options =
|
||||
* interactiveOpts().fullRelease(true).range("'1-2'")
|
||||
* .startFrom("'c'").taskNames(Arrays.asList("'a'", "'b'")).options();
|
||||
*
|
||||
* then(options.range).isEqualTo("1-2"); then(options.startFrom).isEqualTo("c");
|
||||
* then(options.taskNames).containsOnly("a", "b"); }
|
||||
*
|
||||
* private OptionsBuilder interactiveOpts() { return new OptionsBuilder(); }
|
||||
*
|
||||
* private OptionsBuilder nonInteractiveOpts() { return new
|
||||
* OptionsBuilder().interactive(false); }
|
||||
*
|
||||
* private Args args() { return new Args(null, null, null, null, null, null, false,
|
||||
* TaskType.RELEASE, null); }
|
||||
*
|
||||
* private List<String> list(String... list) { return Arrays.asList(list); }
|
||||
*
|
||||
* }
|
||||
*
|
||||
* class FirstConsumer implements Consumer<Args> {
|
||||
*
|
||||
* boolean executed;
|
||||
*
|
||||
* @Override public void accept(Args o) { this.executed = true; }
|
||||
*
|
||||
* }
|
||||
*
|
||||
* class SecondConsumer implements Consumer<Args> {
|
||||
*
|
||||
* boolean executed;
|
||||
*
|
||||
* @Override public void accept(Args o) { this.executed = true; }
|
||||
*
|
||||
* }
|
||||
*
|
||||
* class ThirdConsumer implements Consumer<Args> {
|
||||
*
|
||||
* boolean executed;
|
||||
*
|
||||
* @Override public void accept(Args o) { this.executed = true; }
|
||||
*
|
||||
* }
|
||||
*/
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import org.assertj.core.api.BDDAssertions;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.ReleaserPropertiesAware;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@Import(ReleaserPropertiesIntegrationTests.Config.class)
|
||||
public class ReleaserPropertiesIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
List<ReleaserPropertiesAware> propertiesAware;
|
||||
|
||||
@Autowired
|
||||
ApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void should_update_properties() {
|
||||
ReleaserProperties properties = new ReleaserProperties();
|
||||
properties.getPom().setBranch("fooooo");
|
||||
|
||||
new ReleaserPropertiesUpdater(this.context).updateProperties(properties,
|
||||
new File("."));
|
||||
|
||||
BDDAssertions.then(this.propertiesAware).hasSize(2);
|
||||
this.propertiesAware.forEach(aware -> BDDAssertions
|
||||
.then(((ReleaserPropertiesHaving) aware).properties.getPom().getBranch())
|
||||
.isEqualTo("fooooo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_update_properties_including_existing_releaser_config() {
|
||||
ReleaserProperties properties = new ReleaserProperties();
|
||||
properties.getPom().setBranch("barrrr");
|
||||
URL resource = ReleaserPropertiesIntegrationTests.class
|
||||
.getResource("/projects/project-with-config");
|
||||
|
||||
new ReleaserPropertiesUpdater(this.context).updateProperties(properties,
|
||||
new File(resource.getFile()));
|
||||
|
||||
BDDAssertions.then(this.propertiesAware).hasSize(2);
|
||||
this.propertiesAware.forEach(aware -> {
|
||||
ReleaserPropertiesHaving having = ((ReleaserPropertiesHaving) aware);
|
||||
BDDAssertions.then(having.properties.getPom().getBranch())
|
||||
.isEqualTo("barrrr");
|
||||
BDDAssertions.then(having.properties.getMaven().getBuildCommand())
|
||||
.isEqualTo("./scripts/noIntegration.sh");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_update_properties_including_existing_releaser_config_for_netflix() {
|
||||
ReleaserProperties properties = new ReleaserProperties();
|
||||
properties.getPom().setBranch("bazzzz");
|
||||
URL resource = ReleaserPropertiesIntegrationTests.class
|
||||
.getResource("/projects/project-with-netflix-config");
|
||||
|
||||
new ReleaserPropertiesUpdater(this.context).updateProperties(properties,
|
||||
new File(resource.getFile()));
|
||||
|
||||
BDDAssertions.then(this.propertiesAware).hasSize(2);
|
||||
this.propertiesAware.forEach(aware -> {
|
||||
ReleaserPropertiesHaving having = ((ReleaserPropertiesHaving) aware);
|
||||
BDDAssertions.then(having.properties.getPom().getBranch())
|
||||
.isEqualTo("bazzzz");
|
||||
BDDAssertions.then(having.properties.getMaven().getBuildCommand())
|
||||
.isEqualTo("./scripts/build.sh {{systemProps}}");
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
ReleaserPropertiesAware aware1() {
|
||||
return new ReleaserPropertiesHaving();
|
||||
}
|
||||
|
||||
@Bean
|
||||
ReleaserPropertiesAware aware2() {
|
||||
return new ReleaserPropertiesHaving();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class ReleaserPropertiesHaving implements ReleaserPropertiesAware {
|
||||
|
||||
ReleaserProperties properties;
|
||||
|
||||
@Override
|
||||
public void setReleaserProperties(ReleaserProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
ReleaserProperties getProps() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.assertj.core.api.BDDAssertions;
|
||||
import org.junit.Test;
|
||||
import org.mockito.BDDMockito;
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.ReleaserPropertiesAware;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class ReleaserPropertiesUpdaterTests {
|
||||
|
||||
ApplicationContext context = BDDMockito.mock(ApplicationContext.class);
|
||||
|
||||
File relaserUpdater;
|
||||
|
||||
public ReleaserPropertiesUpdaterTests() throws URISyntaxException {
|
||||
this.relaserUpdater = new File(ReleaserPropertiesUpdaterTests.class
|
||||
.getResource("/projects/releaser-updater/").toURI());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_update_properties() {
|
||||
ReleaserProperties original = originalReleaserProperties();
|
||||
Aware aware = new Aware();
|
||||
BDDMockito.given(this.context.getBeansOfType(BDDMockito.any(Class.class)))
|
||||
.willReturn(beansOfType(aware));
|
||||
ReleaserPropertiesUpdater updater = new ReleaserPropertiesUpdater(this.context);
|
||||
|
||||
ReleaserProperties props = updater.updateProperties(original,
|
||||
this.relaserUpdater);
|
||||
|
||||
BDDAssertions.then(aware.properties).isNotNull();
|
||||
BDDAssertions.then(props.getMaven().getBuildCommand()).isEqualTo("maven_build");
|
||||
BDDAssertions.then(props.getGradle().getBuildCommand()).isEqualTo("gradle_build");
|
||||
BDDAssertions.then(props.getBash().getBuildCommand()).isEqualTo("bash_build");
|
||||
BDDAssertions.then(props.getMaven().getSystemProperties()).isEqualTo("-Dfoo=bar");
|
||||
}
|
||||
|
||||
ReleaserProperties originalReleaserProperties() {
|
||||
ReleaserProperties props = new ReleaserProperties();
|
||||
props.getMaven().setSystemProperties("-Dfoo=bar");
|
||||
return props;
|
||||
}
|
||||
|
||||
private Map<String, Object> beansOfType(Aware aware) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("foo", aware);
|
||||
return map;
|
||||
}
|
||||
|
||||
class Aware implements ReleaserPropertiesAware {
|
||||
|
||||
ReleaserProperties properties;
|
||||
|
||||
@Override
|
||||
public void setReleaserProperties(ReleaserProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.assertj.core.api.BDDAssertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import releaser.internal.ReleaserProperties;
|
||||
|
||||
class SpringBatchFlowRunnerTests {
|
||||
|
||||
@Test
|
||||
void releaseGroup() {
|
||||
ReleaserProperties properties = new ReleaserProperties();
|
||||
properties.getMetaRelease().setReleaseGroups(Arrays.asList("c,d", "e,f,g"));
|
||||
ProjectsToRun projectsToRun = projectsToRun();
|
||||
|
||||
List<ReleaseGroup> groups = new ProjectsToReleaseGroups(properties)
|
||||
.toReleaseGroup(projectsToRun);
|
||||
|
||||
BDDAssertions.then(groups).hasSize(5);
|
||||
BDDAssertions.then(projectNames(0, groups)).containsExactly("a");
|
||||
BDDAssertions.then(projectNames(1, groups)).containsExactly("b");
|
||||
BDDAssertions.then(projectNames(2, groups)).containsExactly("d", "c");
|
||||
BDDAssertions.then(projectNames(3, groups)).containsExactly("e", "f", "g");
|
||||
BDDAssertions.then(projectNames(4, groups)).containsExactly("h");
|
||||
}
|
||||
|
||||
private List<String> projectNames(int index, List<ReleaseGroup> groups) {
|
||||
return groups.get(index).projectsToRun.stream()
|
||||
.map(ProjectToRun.ProjectToRunSupplier::projectName)
|
||||
.collect(Collectors.toCollection(LinkedList::new));
|
||||
}
|
||||
|
||||
private ProjectsToRun projectsToRun() {
|
||||
ProjectsToRun projectsToRun = new ProjectsToRun();
|
||||
projectsToRun.add(new ProjectToRun.ProjectToRunSupplier("a", () -> null));
|
||||
projectsToRun.add(new ProjectToRun.ProjectToRunSupplier("b", () -> null));
|
||||
projectsToRun.add(new ProjectToRun.ProjectToRunSupplier("d", () -> null));
|
||||
projectsToRun.add(new ProjectToRun.ProjectToRunSupplier("c", () -> null));
|
||||
projectsToRun.add(new ProjectToRun.ProjectToRunSupplier("e", () -> null));
|
||||
projectsToRun.add(new ProjectToRun.ProjectToRunSupplier("f", () -> null));
|
||||
projectsToRun.add(new ProjectToRun.ProjectToRunSupplier("g", () -> null));
|
||||
projectsToRun.add(new ProjectToRun.ProjectToRunSupplier("h", () -> null));
|
||||
return projectsToRun;
|
||||
}
|
||||
|
||||
}
|
||||
79
releaser-spring/src/test/resources/application.yml
Normal file
79
releaser-spring/src/test/resources/application.yml
Normal file
@@ -0,0 +1,79 @@
|
||||
spring:
|
||||
main:
|
||||
web-application-type: none
|
||||
datasource:
|
||||
url: jdbc:h2:mem:${random.uuid}
|
||||
jackson:
|
||||
deserialization:
|
||||
FAIL_ON_UNKNOWN_PROPERTIES: true
|
||||
releaser:
|
||||
git:
|
||||
release-train-bom-url: https://github.com/spring-cloud/spring-cloud-release
|
||||
documentation-url: https://github.com/spring-cloud/spring-cloud-static
|
||||
spring-project-url: https://github.com/spring-projects/spring-cloud
|
||||
test-samples-project-url: https://github.com/spring-cloud/spring-cloud-core-tests
|
||||
release-train-docs-url: https://github.com/spring-cloud-samples/scripts
|
||||
release-train-wiki-url: https://github.com/spring-projects/spring-cloud.wiki
|
||||
documentation-branch: gh-pages
|
||||
spring-project-branch: gh-pages
|
||||
test-samples-branch: master
|
||||
release-train-docs-branch: master
|
||||
release-train-wiki-page-prefix: Spring-Cloud
|
||||
fetch-versions-from-git: true
|
||||
oauth-token:
|
||||
# username:
|
||||
# password:
|
||||
update-documentation-repo: true
|
||||
update-github-milestones: true
|
||||
update-spring-guides: true
|
||||
update-start-spring-io: true
|
||||
update-spring-project: true
|
||||
run-updated-samples: true
|
||||
update-release-train-docs: true
|
||||
update-release-train-wiki: true
|
||||
update-all-test-samples: true
|
||||
all-test-sample-urls:
|
||||
spring-cloud-sleuth:
|
||||
- https://github.com/spring-cloud-samples/sleuth-issues
|
||||
- https://github.com/spring-cloud-samples/sleuth-documentation-apps
|
||||
spring-cloud-contract:
|
||||
- https://github.com/spring-cloud-samples/spring-cloud-contract-samples
|
||||
- https://github.com/spring-cloud-samples/the-legacy-app
|
||||
- https://github.com/spring-cloud-samples/sc-contract-car-rental
|
||||
pom:
|
||||
branch: master
|
||||
pom-with-boot-starter-parent: spring-cloud-starter-parent/pom.xml
|
||||
this-train-bom: spring-cloud-dependencies/pom.xml
|
||||
bom-version-pattern: "^(spring-cloud-.*)\\.version$"
|
||||
ignored-pom-regex:
|
||||
- "^.*\\.git/.*$"
|
||||
- "^.*spring-cloud-contract-maven-plugin/src/test/projects/.*$"
|
||||
- "^.*spring-cloud-contract-maven-plugin/target/.*$"
|
||||
- "^.*src/test/bats/.*$"
|
||||
- "^.*samples/standalone/[a-z]+/.*$"
|
||||
sagan:
|
||||
update-sagan: true
|
||||
base-url: https://spring.io
|
||||
docs-adocs-file: docs/src/main/asciidoc
|
||||
index-section-file-name: sagan-index.adoc
|
||||
boot-section-file-name: sagan-boot.adoc
|
||||
template:
|
||||
enabled: true
|
||||
template-folder: cloud
|
||||
versions:
|
||||
all-versions-file-url: https://raw.githubusercontent.com/spring-io/start.spring.io/master/start-site/src/main/resources/application.yml
|
||||
bom-name: spring-cloud
|
||||
# fixed-versions:
|
||||
meta-release:
|
||||
enabled: false
|
||||
release-train-project-name: spring-cloud-release
|
||||
release-train-dependency-names:
|
||||
- spring-cloud
|
||||
- spring-cloud-dependencies
|
||||
- spring-cloud-starter
|
||||
- spring-cloud-starter-build
|
||||
git-org-url: https://github.com/spring-cloud
|
||||
projects-to-skip:
|
||||
- spring-boot
|
||||
- spring-cloud-stream
|
||||
- spring-cloud-task
|
||||
@@ -0,0 +1,4 @@
|
||||
releaser.maven.buildCommand: ./scripts/noIntegration.sh
|
||||
releaser.gradle.gradlePropsSubstitution:
|
||||
verifierVersion: spring-cloud-contract
|
||||
bootVersion: spring-boot
|
||||
@@ -0,0 +1,3 @@
|
||||
releaser:
|
||||
maven:
|
||||
buildCommand: ./scripts/build.sh {{systemProps}}
|
||||
@@ -0,0 +1,6 @@
|
||||
releaser.maven.buildCommand: maven_build
|
||||
releaser.bash.buildCommand: bash_build
|
||||
releaser.gradle.buildCommand: gradle_build
|
||||
releaser.gradle.gradlePropsSubstitution:
|
||||
verifierVersion: spring-cloud-contract
|
||||
bootVersion: spring-boot
|
||||
Reference in New Issue
Block a user