Improvements to common build and new Reactor task (merge with rebase) (#183)

* Reactor: For reference, mention additional inputs in app properties

* Polish: fix javadoc copypasta and mark potential problem in GitRepo

* Common: Expose method for git log (list revisions between 2 refs)

* Common: Only post-process RtGithub beans into CachingGithub

* Common: Make Sagan noOp if property is not explicitly set

* Common: Fix Process command executor outputting to app's stdout

This prevents the command executor from capturing the command's output.

* Common: Fix findTagOrBranchHeadRevision and log

In findTag... we need to compare name using refs/tags/
and refs/heads/ prefixes.

In log we need to peel symbolic tags to get the right
ObjectId. Optional.map did seem to cause issues.

* Common: Add isMergeCommit to SimpleCommit

* Common: Add method to find tag SHA by name

* Common: Polish how exit codes are generated and used

* Common: Add BuildReportHandler to show report earlier than last step

This commit also filters out tasks that haven't run yet, avoiding
NPE due to endTime being null.

* Reactor: restart task should not be part of dry-runs

* Reactor: Alter Gradle build command to include bumpVersionsInReadme task

* Reactor: Add GenerateReleaseNotesTask

Also added partial tests for the task.

Avoids generating notes if snapshot, mark as pre-release if milestone
or rc.

* Reactor: Split out configurations and use profiles for test

* Reactor: Fix org in application.yml

* Reactor: Fix some formatting

* Reactor: Force github OAuth token at Github client creation

* Reactor: Split parseChangelog into several more testable methods

* Reactor: Let interactive GenerateReleaseNotesTask force a log range

* Reactor: Allow multiple dispatch of note entries

Switching from a single TYPE to an EnumSet

* Reactor: Extract issue numbers in title too just in case

* Reactor: Fix alternative titles markdown and description

Also better protect agains Github client failures when
fetching more info like title and labels.

* Reactor: Polish format (newlines) in tag input, notes output

* Reactor: Check tag exists but not release. Check on SHA1

* Reactor: Make checks we can save notes draft BEFORE querying commits

* Reactor: Attempt to find existing release draft (max 2 month old), avoid unnecessary calls

If an existing draft is found, append notes to it.

* Reactor: Ask only for "from" change for interactive log/release notes
This commit is contained in:
Simon Baslé
2020-01-22 10:44:59 +01:00
committed by Marcin Grzejszczak
parent 7632b99031
commit 188c079bd6
22 changed files with 1448 additions and 140 deletions

View File

@@ -17,6 +17,7 @@
package releaser.internal.github;
import com.jcabi.github.Github;
import com.jcabi.github.RtGithub;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
@@ -32,7 +33,7 @@ class GithubConfiguration {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if (bean instanceof Github) {
if (bean instanceof RtGithub) {
return new CachingGithub((Github) bean);
}
return bean;

View File

@@ -36,7 +36,7 @@ class SaganConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(value = "releaser.sagan.update-sagan", matchIfMissing = true)
@ConditionalOnProperty(value = "releaser.sagan.update-sagan", havingValue = "true")
SaganClient saganClient(ReleaserProperties properties) {
RestTemplate restTemplate = restTemplate(properties);
return new RestTemplateSaganClient(restTemplate, properties);
@@ -44,7 +44,8 @@ class SaganConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(value = "releaser.sagan.update-sagan", havingValue = "false")
@ConditionalOnProperty(value = "releaser.sagan.update-sagan", havingValue = "false",
matchIfMissing = true)
SaganClient noOpSaganClient() {
return new SaganClient() {
@Override

View File

@@ -56,8 +56,8 @@ class BatchConfiguration {
@Bean
@ConditionalOnMissingBean
ExecutionResultHandler springBatchExecutionResultHandler(JobExplorer jobExplorer,
ConfigurableApplicationContext context) {
SpringBatchExecutionResultHandler springBatchExecutionResultHandler(
JobExplorer jobExplorer, ConfigurableApplicationContext context) {
return new SpringBatchExecutionResultHandler(jobExplorer, context);
}
@@ -74,11 +74,11 @@ class BatchConfiguration {
JobBuilderFactory jobBuilderFactory,
ProjectsToRunFactory projectsToRunFactory, JobLauncher jobLauncher,
FlowRunnerTaskExecutorSupplier flowRunnerTaskExecutorSupplier,
ConfigurableApplicationContext context,
ReleaserProperties releaserProperties) {
ConfigurableApplicationContext context, ReleaserProperties releaserProperties,
BuildReportHandler reportHandler) {
return new SpringBatchFlowRunner(stepBuilderFactory, jobBuilderFactory,
projectsToRunFactory, jobLauncher, flowRunnerTaskExecutorSupplier,
context, releaserProperties);
context, releaserProperties, reportHandler);
}
@Bean

View File

@@ -0,0 +1,32 @@
/*
* 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;
/**
* Handles reporting the results of the build. Similar to {@link ExecutionResultHandler}
* with the difference that it could be invoked before the final result is determined, and
* shouldn't handle exiting the application.
*/
public interface BuildReportHandler {
/**
* Display a report summarizing the state of the build so far. Can be invoked during
* normal execution, so it should filter out eg. tasks that are running.
*/
void reportBuildSummary();
}

View File

@@ -43,7 +43,8 @@ import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.NestedExceptionUtils;
import org.springframework.util.StringUtils;
class SpringBatchExecutionResultHandler implements ExecutionResultHandler {
class SpringBatchExecutionResultHandler
implements ExecutionResultHandler, BuildReportHandler {
private static final Logger log = LoggerFactory
.getLogger(SpringBatchExecutionResultHandler.class);
@@ -60,7 +61,7 @@ class SpringBatchExecutionResultHandler implements ExecutionResultHandler {
@Override
public void accept(ExecutionResult executionResult) {
buildSummaryTable();
reportBuildSummary();
if (executionResult.isFailure()) {
log.error("At least one failure occurred while running the release process",
executionResult.foundExceptions());
@@ -79,21 +80,21 @@ class SpringBatchExecutionResultHandler implements ExecutionResultHandler {
}
void exitSuccessfully() {
SpringApplication.exit(this.context, () -> 0);
System.exit(0);
System.exit(SpringApplication.exit(this.context, () -> 0));
}
void exitWithException() {
SpringApplication.exit(this.context, () -> 1);
System.exit(1);
System.exit(SpringApplication.exit(this.context, () -> 1));
}
private void buildSummaryTable() {
@Override
public void reportBuildSummary() {
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())
.filter(j -> !j.isRunning())
.sorted(Comparator.comparing(JobExecution::getCreateTime))
.collect(Collectors.toList());
List<StepExecution> stepContexts = sortedJobExecutions.stream()

View File

@@ -93,14 +93,14 @@ class SpringBatchFlowRunner implements FlowRunner, Closeable {
JobBuilderFactory jobBuilderFactory,
ProjectsToRunFactory projectsToRunFactory, JobLauncher jobLauncher,
FlowRunnerTaskExecutorSupplier flowRunnerTaskExecutorSupplier,
ConfigurableApplicationContext context,
ReleaserProperties releaserProperties) {
ConfigurableApplicationContext context, ReleaserProperties releaserProperties,
BuildReportHandler reportHandler) {
this.stepBuilderFactory = stepBuilderFactory;
this.jobBuilderFactory = jobBuilderFactory;
this.projectsToRunFactory = projectsToRunFactory;
this.jobLauncher = jobLauncher;
this.flowRunnerTaskExecutorSupplier = flowRunnerTaskExecutorSupplier;
this.stepSkipper = new ConsoleInputStepSkipper(context);
this.stepSkipper = new ConsoleInputStepSkipper(context, reportHandler);
this.releaserProperties = releaserProperties;
this.executorService = Executors.newFixedThreadPool(
this.releaserProperties.getMetaRelease().getReleaseGroupThreadCount());
@@ -534,8 +534,12 @@ class ConsoleInputStepSkipper {
private final ConfigurableApplicationContext context;
ConsoleInputStepSkipper(ConfigurableApplicationContext context) {
private final BuildReportHandler reportHandler;
ConsoleInputStepSkipper(ConfigurableApplicationContext context,
BuildReportHandler reportHandler) {
this.context = context;
this.reportHandler = reportHandler;
}
public boolean skipStep() {
@@ -544,8 +548,8 @@ class ConsoleInputStepSkipper {
case "s":
return true;
case "q":
SpringApplication.exit(this.context, () -> 0);
System.exit(0);
reportHandler.reportBuildSummary();
System.exit(SpringApplication.exit(this.context, () -> 0));
return true;
default:
return false;