Add process to build antora-based documentation sites.

Closes #57
This commit is contained in:
Mark Paluch
2023-09-07 10:29:20 +02:00
parent b48184881d
commit eeea703266
4 changed files with 124 additions and 12 deletions

View File

@@ -146,6 +146,7 @@ Both are available in the Spring/Pivotal Last Pass repository.
2+| *Post-release tasks*
|Close JIRA tickets and GitHub release tickets. |`$ tracker close $trainIteration`
|Create new release versions and tickets for upcoming version |`$ tracker setup-next $trainIteration.next`
|Trigger Antora documentation build (once all artifacts have arrived at the final Maven repository) |`$ github trigger documentation $trainIteration`
|Update versions in Projects Service. `$releaseTrains` is given as comma separated lists of code names, without spaces. E.g. `Moore,Neumann` |`$ projects update $releaseTrains`
|Create list of docs for release announcements |`$ announcement $trainIteration`
|===

View File

@@ -15,15 +15,7 @@
*/
package org.springframework.data.release.issues.github;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -43,6 +35,7 @@ import org.springframework.data.release.issues.Changelog;
import org.springframework.data.release.issues.IssueTracker;
import org.springframework.data.release.issues.Ticket;
import org.springframework.data.release.issues.Tickets;
import org.springframework.data.release.issues.github.GitHubWorkflows.GitHubWorkflow;
import org.springframework.data.release.model.ArtifactVersion;
import org.springframework.data.release.model.DocumentationMetadata;
import org.springframework.data.release.model.Iteration;
@@ -79,10 +72,14 @@ public class GitHub extends GitHubSupport implements IssueTracker {
private static final String RELEASE_URI_TEMPLATE = "/repos/spring-projects/{repoName}/releases";
private static final String RELEASE_BY_ID_URI_TEMPLATE = "/repos/spring-projects/{repoName}/releases/{id}";
private static final String WORKFLOWS = "/repos/spring-projects/spring-data-dev-tools/actions/workflows";
private static final String WORKFLOW_DISPATCH = "/repos/spring-projects/spring-data-dev-tools/actions/workflows/{workflow_id}/dispatches";
private static final ParameterizedTypeReference<List<Milestone>> MILESTONES_TYPE = new ParameterizedTypeReference<List<Milestone>>() {};
private static final ParameterizedTypeReference<List<GitHubReadIssue>> ISSUES_TYPE = new ParameterizedTypeReference<List<GitHubReadIssue>>() {};
private static final ParameterizedTypeReference<GitHubReadIssue> ISSUE_TYPE = new ParameterizedTypeReference<GitHubReadIssue>() {};
private static final ParameterizedTypeReference<GitHubWorkflows> WORKFLOWS_TYPE = new ParameterizedTypeReference<GitHubWorkflows>() {};
private static final Map<TicketType, Label> TICKET_LABELS = new HashMap<>();
static {
@@ -548,9 +545,9 @@ public class GitHub extends GitHubSupport implements IssueTracker {
}
/**
* @param ticketReferences
* @param iteration
* @param module
* @param ticketIds
*/
public void createOrUpdateRelease(TrainIteration iteration, ModuleIteration module, List<String> ticketIds) {
@@ -559,7 +556,7 @@ public class GitHub extends GitHubSupport implements IssueTracker {
List<GitHubReadIssue> gitHubIssues = findGitHubIssues(module, ticketIds);
ArtifactVersion version = ArtifactVersion.of(module);
DocumentationMetadata documentation = DocumentationMetadata.of(module.getProject(), version, false);
DocumentationMetadata documentation = DocumentationMetadata.of(module, version, false);
ChangelogGenerator generator = new ChangelogGenerator();
generator.getExcludeContributors().addAll(properties.getTeam());
@@ -619,6 +616,57 @@ public class GitHub extends GitHubSupport implements IssueTracker {
logger.log("GitHub", "Authentication verified.");
}
/**
* Trigger the Antora workflow for the given module.
*/
public void triggerAntoraWorkflow(Project project) {
logger.log("GitHub", "Triggering Antora workflow for %s…", project.getName());
GitHubWorkflow workflow = getWorkflow();
Map<String, Object> body = new LinkedHashMap<>();
body.put("ref", "main");
body.put("inputs", Collections.singletonMap("module", project.getName().toLowerCase(Locale.ROOT)));
Map<String, Object> parameters = newUrlTemplateVariables();
parameters.put("workflow_id", workflow.getId());
ResponseEntity<Map> entity = operations.exchange(WORKFLOW_DISPATCH, HttpMethod.POST, new HttpEntity<>(body),
Map.class, parameters);
if (!entity.getStatusCode().is2xxSuccessful()) {
throw new IllegalStateException("Cannot trigger Antora workflow. Status: " + entity.getStatusCode());
}
logger.log("GitHub", "Antora workflow for %s started…", project.getName());
}
@Cacheable("get-workflow")
public GitHubWorkflow getWorkflow() {
ResponseEntity<GitHubWorkflows> entity = operations.exchange(WORKFLOWS, HttpMethod.GET, null, WORKFLOWS_TYPE);
if (!entity.getStatusCode().is2xxSuccessful()) {
throw new IllegalStateException(String.format("Cannot obtain Workflows. Status: %s", entity.getStatusCode()));
}
GitHubWorkflows workflows = entity.getBody();
for (GitHubWorkflow workflow : workflows.getWorkflows()) {
if (workflow.getPath().endsWith("antora-site.yml")) {
if (!workflow.getState().equals("active")) {
throw new IllegalStateException("Antora workflow is not active");
}
return workflow;
}
}
throw new NoSuchElementException("Cannot resolve Antora workflow");
}
private String getDocumentationLinks(ModuleIteration module, DocumentationMetadata documentation) {
if (module.getProject() == Projects.BUILD || module.getProject() == Projects.BOM) {

View File

@@ -20,7 +20,10 @@ import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;
@@ -31,6 +34,7 @@ import org.springframework.data.release.issues.IssueTracker;
import org.springframework.data.release.issues.TicketReference;
import org.springframework.data.release.model.Iteration;
import org.springframework.data.release.model.Project;
import org.springframework.data.release.model.Projects;
import org.springframework.data.release.model.Tracker;
import org.springframework.data.release.model.TrainIteration;
import org.springframework.data.release.utils.ExecutionUtils;
@@ -90,4 +94,26 @@ public class GitHubCommands extends TimedCommand {
});
}
@CliCommand(value = "github trigger documentation")
public void triggerDocumentation(@CliOption(key = "", mandatory = true) TrainIteration iteration,
@CliOption(key = "module", mandatory = false) String module) {
Set<Project> skip = new HashSet<>(Arrays.asList(Projects.BOM, Projects.BUILD, Projects.R2DBC, Projects.JDBC,
Projects.SOLR, Projects.GEODE, Projects.SMOKE_TESTS));
iteration.forEach(it -> {
Project project = it.getProject();
if (skip.contains(project)) {
return;
}
if (module == null || module.equalsIgnoreCase(project.getName())) {
gitHub.triggerAntoraWorkflow(project);
}
});
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2023 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.release.issues.github;
import lombok.Value;
import java.util.List;
/**
* @author Mark Paluch
*/
@Value
class GitHubWorkflows {
private List<GitHubWorkflow> workflows;
@Value
static class GitHubWorkflow {
String name;
long id;
String path;
String state;
}
}