From eeea7032669039a4dcdc2b6c17d4910728a6d97f Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 7 Sep 2023 10:29:20 +0200 Subject: [PATCH] Add process to build antora-based documentation sites. Closes #57 --- readme.adoc | 1 + .../data/release/issues/github/GitHub.java | 72 +++++++++++++++---- .../release/issues/github/GitHubCommands.java | 26 +++++++ .../issues/github/GitHubWorkflows.java | 37 ++++++++++ 4 files changed, 124 insertions(+), 12 deletions(-) create mode 100644 src/main/java/org/springframework/data/release/issues/github/GitHubWorkflows.java diff --git a/readme.adoc b/readme.adoc index b3656bb..0f6448d 100644 --- a/readme.adoc +++ b/readme.adoc @@ -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` |=== diff --git a/src/main/java/org/springframework/data/release/issues/github/GitHub.java b/src/main/java/org/springframework/data/release/issues/github/GitHub.java index 792df71..2e97266 100644 --- a/src/main/java/org/springframework/data/release/issues/github/GitHub.java +++ b/src/main/java/org/springframework/data/release/issues/github/GitHub.java @@ -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> MILESTONES_TYPE = new ParameterizedTypeReference>() {}; private static final ParameterizedTypeReference> ISSUES_TYPE = new ParameterizedTypeReference>() {}; private static final ParameterizedTypeReference ISSUE_TYPE = new ParameterizedTypeReference() {}; - + private static final ParameterizedTypeReference WORKFLOWS_TYPE = new ParameterizedTypeReference() {}; private static final Map 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 ticketIds) { @@ -559,7 +556,7 @@ public class GitHub extends GitHubSupport implements IssueTracker { List 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 body = new LinkedHashMap<>(); + body.put("ref", "main"); + body.put("inputs", Collections.singletonMap("module", project.getName().toLowerCase(Locale.ROOT))); + + Map parameters = newUrlTemplateVariables(); + parameters.put("workflow_id", workflow.getId()); + + ResponseEntity 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 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) { diff --git a/src/main/java/org/springframework/data/release/issues/github/GitHubCommands.java b/src/main/java/org/springframework/data/release/issues/github/GitHubCommands.java index 8ffea28..9656cd1 100644 --- a/src/main/java/org/springframework/data/release/issues/github/GitHubCommands.java +++ b/src/main/java/org/springframework/data/release/issues/github/GitHubCommands.java @@ -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 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); + } + }); + + } + } diff --git a/src/main/java/org/springframework/data/release/issues/github/GitHubWorkflows.java b/src/main/java/org/springframework/data/release/issues/github/GitHubWorkflows.java new file mode 100644 index 0000000..d8e7a32 --- /dev/null +++ b/src/main/java/org/springframework/data/release/issues/github/GitHubWorkflows.java @@ -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 workflows; + + @Value + static class GitHubWorkflow { + String name; + long id; + String path; + String state; + } +}