From f95f591067a08d219ce5741572d809ac68896106 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 25 Feb 2025 10:48:11 +0100 Subject: [PATCH] WIP --- src/main/java/io/micrometer/release/Main.java | 13 +-- .../{single => common}/Dependency.java | 4 +- .../{single => common}/GradleParser.java | 60 +++++------- .../io/micrometer/release/common/Input.java | 56 +++++++++++ .../release/common/ProcessRunner.java | 43 +++++---- .../release/single/ChangelogProcessor.java | 2 + .../release/single/PostReleaseWorkflow.java | 31 +----- .../{single => train}/DependencyVerifier.java | 96 ++++++++++++++----- .../train/ProjectTrainReleaseWorkflow.java | 3 +- .../release/train/ReleaseScheduler.java | 9 ++ .../java/io/micrometer/release/MainTests.java | 2 +- .../single/ChangelogProcessorTests.java | 1 + .../PostReleaseWorkflowAcceptanceTests.java | 1 + .../DependencyVerifierTests.java | 2 +- 14 files changed, 206 insertions(+), 117 deletions(-) rename src/main/java/io/micrometer/release/{single => common}/Dependency.java (82%) rename src/main/java/io/micrometer/release/{single => common}/GradleParser.java (68%) create mode 100644 src/main/java/io/micrometer/release/common/Input.java rename src/main/java/io/micrometer/release/{single => train}/DependencyVerifier.java (64%) rename src/test/java/io/micrometer/release/{single => train}/DependencyVerifierTests.java (99%) diff --git a/src/main/java/io/micrometer/release/Main.java b/src/main/java/io/micrometer/release/Main.java index 543196c..5ecbfa6 100644 --- a/src/main/java/io/micrometer/release/Main.java +++ b/src/main/java/io/micrometer/release/Main.java @@ -15,6 +15,7 @@ */ package io.micrometer.release; +import io.micrometer.release.common.Input; import io.micrometer.release.common.ProcessRunner; import io.micrometer.release.single.PostReleaseWorkflow; import io.micrometer.release.train.ProjectTrainReleaseWorkflow; @@ -47,7 +48,7 @@ public static void main(String[] args) throws Exception { void run() { ProcessRunner processRunner = new ProcessRunner(); PostReleaseWorkflow postReleaseWorkflow = newPostReleaseWorkflow(processRunner); - String githubOrgRepo = getGithubRepository(); + String githubOrgRepo = getGithubOrgRepository(); String githubRefName = getGithubRefName(); String previousRefName = getPreviousRefName(); String trainVersions = getTrainVersions(); @@ -79,20 +80,20 @@ void run() { } } - String getGithubRepository() { - return System.getenv("GITHUB_REPOSITORY"); + String getGithubOrgRepository() { + return Input.getGithubOrgRepository(); } String getPreviousRefName() { - return System.getenv("PREVIOUS_REF_NAME"); + return Input.getPreviousRefName(); } String getGithubRefName() { - return System.getenv("GITHUB_REF_NAME"); + return Input.getGithubRefName(); } String getTrainVersions() { - return System.getenv("TRAIN_VERSIONS"); + return Input.getTrainVersions(); } ProjectTrainReleaseWorkflow trainReleaseWorkflow(String githubOrgRepo, String artifactToCheck, diff --git a/src/main/java/io/micrometer/release/single/Dependency.java b/src/main/java/io/micrometer/release/common/Dependency.java similarity index 82% rename from src/main/java/io/micrometer/release/single/Dependency.java rename to src/main/java/io/micrometer/release/common/Dependency.java index 5fba1f6..fa7efee 100644 --- a/src/main/java/io/micrometer/release/single/Dependency.java +++ b/src/main/java/io/micrometer/release/common/Dependency.java @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.micrometer.release.single; +package io.micrometer.release.common; -record Dependency(String group, String artifact, String version, boolean toIgnore) { +public record Dependency(String group, String artifact, String version, boolean toIgnore) { } diff --git a/src/main/java/io/micrometer/release/single/GradleParser.java b/src/main/java/io/micrometer/release/common/GradleParser.java similarity index 68% rename from src/main/java/io/micrometer/release/single/GradleParser.java rename to src/main/java/io/micrometer/release/common/GradleParser.java index 014443e..6ce0430 100644 --- a/src/main/java/io/micrometer/release/single/GradleParser.java +++ b/src/main/java/io/micrometer/release/common/GradleParser.java @@ -13,41 +13,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.micrometer.release.single; - -import io.micrometer.release.common.ProcessRunner; - -import java.util.concurrent.atomic.AtomicReference; +package io.micrometer.release.common; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; -class GradleParser { +public class GradleParser { private static final Logger log = LoggerFactory.getLogger(GradleParser.class); - private final List excludedDependencyScopes = List.of("testCompile", "testImplementation", "checkstyle", - "runtime", "nohttp", "testRuntime", "optional"); - - private final AtomicReference> dependenciesCache = new AtomicReference<>(); + private final List excludedDependencyScopes = List.of("testCompile", + "testImplementation", "checkstyle", + "runtime", "nohttp", "testRuntime", "optional"); private final ProcessRunner processRunner; - GradleParser(ProcessRunner processRunner) { + public GradleParser(ProcessRunner processRunner) { this.processRunner = processRunner; } - Set fetchAllDependencies() { - Set cachedDependencies = dependenciesCache.get(); - if (cachedDependencies != null) { - log.info("Returned cached dependencies"); - return cachedDependencies; - } + public Set fetchAllDependencies() { log.info("Fetching test and optional dependencies..."); List projectLines = projectLines(); List subprojects = projectLines.stream() @@ -72,36 +60,32 @@ Set fetchAllDependencies() { boolean finalTestOrOptional = testOrOptional; dependencies.stream() .filter(dependency -> dependency.group().equalsIgnoreCase(parts[1]) - && dependency.artifact().equalsIgnoreCase(parts[2])) + && dependency.artifact().equalsIgnoreCase(parts[2])) .findFirst() .ifPresentOrElse(dependency -> { - log.debug("Dependency {} is already present in compile scope", parts[1] + ":" + parts[2]); + log.debug("Dependency {} is already present in compile scope", + parts[1] + ":" + parts[2]); if (dependency.toIgnore() && !finalTestOrOptional) { log.debug( - "Dependency {} was previously set in test or compile scope and will be in favour of one in compile scope", - dependency); + "Dependency {} was previously set in test or compile scope and will be in favour of one in compile scope", + dependency); dependencies.remove(dependency); - dependencies.add(new Dependency(parts[1], parts[2], version, finalTestOrOptional)); + dependencies.add(new Dependency(parts[1], parts[2], version, + finalTestOrOptional)); } - }, () -> dependencies.add(new Dependency(parts[1], parts[2], version, finalTestOrOptional))); - } - else if (excludedDependencyScopes.stream() + }, () -> dependencies.add( + new Dependency(parts[1], parts[2], version, finalTestOrOptional))); + } else if (excludedDependencyScopes.stream() .anyMatch(string -> line.toLowerCase().contains(string.toLowerCase()))) { testOrOptional = true; - } - else if (line.isEmpty() || line.isBlank()) { + } else if (line.isEmpty() || line.isBlank()) { testOrOptional = false; } } } - dependenciesCache.set(dependencies); return dependencies; } - void clearCache() { - dependenciesCache.set(null); - } - static String extractVersion(String line) { if (line == null || line.trim().isEmpty()) { return null; @@ -123,11 +107,11 @@ static String extractVersion(String line) { return null; } - List dependenciesLines(List gradleCommand) { + public List dependenciesLines(List gradleCommand) { return processRunner.runSilently(gradleCommand); } - List projectLines() { + public List projectLines() { return processRunner.runSilently("./gradlew", "projects"); } diff --git a/src/main/java/io/micrometer/release/common/Input.java b/src/main/java/io/micrometer/release/common/Input.java new file mode 100644 index 0000000..5b88a51 --- /dev/null +++ b/src/main/java/io/micrometer/release/common/Input.java @@ -0,0 +1,56 @@ +/* + * Copyright 2025 Broadcom. + * + * 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 io.micrometer.release.common; + +public class Input { + + public static void assertInputs(String githubOrgRepo, String githubRefName, + String previousRefName) { + if (githubOrgRepo == null) { + throw new IllegalStateException( + "No repo found, please provide the GITHUB_REPOSITORY env variable"); + } + if (githubRefName == null) { + throw new IllegalStateException( + "No github ref found, please provide the GITHUB_REF_NAME env variable"); + } + if (!githubRefName.startsWith("v")) { + throw new IllegalStateException( + "Github ref must be a tag (must start with 'v'): " + githubRefName); + } + if (previousRefName != null && !previousRefName.isBlank() && !previousRefName.startsWith( + "v")) { + throw new IllegalStateException( + "Previous github ref must be a tag (must start with 'v'): " + previousRefName); + } + } + + public static String getGithubOrgRepository() { + return System.getenv("GITHUB_REPOSITORY"); + } + + public static String getPreviousRefName() { + return System.getenv("PREVIOUS_REF_NAME"); + } + + public static String getGithubRefName() { + return System.getenv("GITHUB_REF_NAME"); + } + + public static String getTrainVersions() { + return System.getenv("TRAIN_VERSIONS"); + } +} diff --git a/src/main/java/io/micrometer/release/common/ProcessRunner.java b/src/main/java/io/micrometer/release/common/ProcessRunner.java index cacbf2a..97f4e7b 100644 --- a/src/main/java/io/micrometer/release/common/ProcessRunner.java +++ b/src/main/java/io/micrometer/release/common/ProcessRunner.java @@ -15,12 +15,11 @@ */ package io.micrometer.release.common; -import java.io.File; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.BufferedReader; +import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.*; @@ -33,14 +32,21 @@ public class ProcessRunner { private final String repo; + private final File directory; + private final Map envVars = new HashMap<>(); public ProcessRunner() { - this.repo = null; + this(null, null); } public ProcessRunner(String repo) { + this(repo, null); + } + + public ProcessRunner(String repo, File directory) { this.repo = repo; + this.directory = directory; } public ProcessRunner withEnvVars(Map envVars) { @@ -78,7 +84,8 @@ private List run(boolean shouldLog, String... command) { List errorLines = new ArrayList<>(); Thread outputThread = new Thread(() -> { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(process.getInputStream()))) { String line; while ((line = reader.readLine()) != null) { if (shouldLog) { @@ -86,21 +93,20 @@ private List run(boolean shouldLog, String... command) { } lines.add(line); } - } - catch (IOException e) { + } catch (IOException e) { log.error("Error reading process output", e); } }); Thread errorThread = new Thread(() -> { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) { + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(process.getErrorStream()))) { String line; while ((line = reader.readLine()) != null) { log.error(line); errorLines.add(line); } - } - catch (IOException e) { + } catch (IOException e) { log.error("Error reading process error stream", e); } }); @@ -114,12 +120,12 @@ private List run(boolean shouldLog, String... command) { int exitCode = process.waitFor(); if (exitCode != 0) { - String errorMessage = String.format("Failed to run the command %s. Exit code: %d.%nError output:%n%s", - Arrays.toString(processedCommand), exitCode, String.join("\n", errorLines)); + String errorMessage = String.format( + "Failed to run the command %s. Exit code: %d.%nError output:%n%s", + Arrays.toString(processedCommand), exitCode, String.join("\n", errorLines)); throw new IllegalStateException(errorMessage); } - } - catch (IOException | InterruptedException e) { + } catch (IOException | InterruptedException e) { throw new IllegalStateException("A failure around the process execution happened", e); } log.info("Command executed successfully"); @@ -132,7 +138,11 @@ void log(String logLine) { Process startProcess(String... processedCommand) throws IOException, InterruptedException { runGitConfig(); - ProcessBuilder processBuilder = new ProcessBuilder(processedCommand).redirectErrorStream(false); + ProcessBuilder processBuilder = new ProcessBuilder(processedCommand).redirectErrorStream( + false); + if (directory != null) { + processBuilder.directory(directory); + } return doStartProcess(processBuilder); } @@ -146,14 +156,15 @@ Process doStartProcess(ProcessBuilder processBuilder) throws IOException { } void runGitConfig() throws InterruptedException, IOException { - doStartProcess(new ProcessBuilder("git", "config", "--global", "--add", "safe.directory", "/github/workspace")) + doStartProcess(new ProcessBuilder("git", "config", "--global", "--add", "safe.directory", + "/github/workspace")) .waitFor(); } private String[] processCommand(String[] command) { String[] processedCommand = command; if (repo != null && command.length > 2 && command[0].equalsIgnoreCase("gh") - && !command[1].equalsIgnoreCase("api")) { + && !command[1].equalsIgnoreCase("api")) { List commands = new LinkedList<>(Arrays.stream(command).toList()); commands.add("--repo"); commands.add(repo); diff --git a/src/main/java/io/micrometer/release/single/ChangelogProcessor.java b/src/main/java/io/micrometer/release/single/ChangelogProcessor.java index 09bbfd9..9014fc4 100644 --- a/src/main/java/io/micrometer/release/single/ChangelogProcessor.java +++ b/src/main/java/io/micrometer/release/single/ChangelogProcessor.java @@ -15,6 +15,8 @@ */ package io.micrometer.release.single; +import io.micrometer.release.common.Dependency; +import io.micrometer.release.common.GradleParser; import io.micrometer.release.common.ProcessRunner; import io.micrometer.release.single.ChangelogSection.Section; import org.slf4j.Logger; diff --git a/src/main/java/io/micrometer/release/single/PostReleaseWorkflow.java b/src/main/java/io/micrometer/release/single/PostReleaseWorkflow.java index 845f498..cbd96e0 100644 --- a/src/main/java/io/micrometer/release/single/PostReleaseWorkflow.java +++ b/src/main/java/io/micrometer/release/single/PostReleaseWorkflow.java @@ -15,14 +15,13 @@ */ package io.micrometer.release.single; +import io.micrometer.release.common.Input; import io.micrometer.release.common.ProcessRunner; import java.io.File; public class PostReleaseWorkflow { - private final DependencyVerifier dependencyVerifier; - private final ChangelogGeneratorDownloader changelogGeneratorDownloader; private final ChangelogGenerator changelogGenerator; @@ -37,12 +36,10 @@ public class PostReleaseWorkflow { private final NotificationSender notificationSender; - PostReleaseWorkflow(DependencyVerifier dependencyVerifier, - ChangelogGeneratorDownloader changelogGeneratorDownloader, ChangelogGenerator changelogGenerator, + PostReleaseWorkflow(ChangelogGeneratorDownloader changelogGeneratorDownloader, ChangelogGenerator changelogGenerator, ChangelogFetcher changelogFetcher, ChangelogProcessor changelogProcessor, ReleaseNotesUpdater releaseNotesUpdater, MilestoneUpdater milestoneUpdater, NotificationSender notificationSender) { - this.dependencyVerifier = dependencyVerifier; this.changelogGeneratorDownloader = changelogGeneratorDownloader; this.changelogGenerator = changelogGenerator; this.changelogFetcher = changelogFetcher; @@ -53,7 +50,7 @@ public class PostReleaseWorkflow { } public PostReleaseWorkflow(ProcessRunner processRunner) { - this(new DependencyVerifier(processRunner), new ChangelogGeneratorDownloader(), + this(new ChangelogGeneratorDownloader(), new ChangelogGenerator(processRunner), new ChangelogFetcher(processRunner), new ChangelogProcessor(processRunner), new ReleaseNotesUpdater(processRunner), new MilestoneUpdater(processRunner), new NotificationSender()); @@ -63,7 +60,7 @@ public PostReleaseWorkflow(ProcessRunner processRunner) { // v1.3.1 // v1.2.5 (optional) public void run(String githubOrgRepo, String githubRefName, String previousRefName) { - assertInputs(githubOrgRepo, githubRefName, previousRefName); + Input.assertInputs(githubOrgRepo, githubRefName, previousRefName); String githubRepo = githubOrgRepo.contains("/") ? githubOrgRepo.split("/")[1] : githubOrgRepo; // Run dependabot and wait for it to complete @@ -94,26 +91,6 @@ public void run(String githubOrgRepo, String githubRefName, String previousRefNa sendNotifications(githubRepo, githubRefName, newMilestoneId); } - private void verifyDependencies(String githubOrgRepo) { - dependencyVerifier.verifyDependencies(githubOrgRepo); - } - - void assertInputs(String githubOrgRepo, String githubRefName, String previousRefName) { - if (githubOrgRepo == null) { - throw new IllegalStateException("No repo found, please provide the GITHUB_REPOSITORY env variable"); - } - if (githubRefName == null) { - throw new IllegalStateException("No github ref found, please provide the GITHUB_REF_NAME env variable"); - } - if (!githubRefName.startsWith("v")) { - throw new IllegalStateException("Github ref must be a tag (must start with 'v'): " + githubRefName); - } - if (previousRefName != null && !previousRefName.isBlank() && !previousRefName.startsWith("v")) { - throw new IllegalStateException( - "Previous github ref must be a tag (must start with 'v'): " + previousRefName); - } - } - private File downloadChangelogGenerator() { try { return changelogGeneratorDownloader.downloadChangelogGenerator(); diff --git a/src/main/java/io/micrometer/release/single/DependencyVerifier.java b/src/main/java/io/micrometer/release/train/DependencyVerifier.java similarity index 64% rename from src/main/java/io/micrometer/release/single/DependencyVerifier.java rename to src/main/java/io/micrometer/release/train/DependencyVerifier.java index 67c3131..15d31d7 100644 --- a/src/main/java/io/micrometer/release/single/DependencyVerifier.java +++ b/src/main/java/io/micrometer/release/train/DependencyVerifier.java @@ -13,20 +13,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.micrometer.release.single; - -import static java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME; +package io.micrometer.release.train; +import io.micrometer.release.common.Dependency; +import io.micrometer.release.common.GradleParser; import io.micrometer.release.common.ProcessRunner; - -import java.time.ZonedDateTime; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; +import java.time.ZonedDateTime; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.concurrent.TimeUnit; +import static java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME; + class DependencyVerifier { private final Logger log = LoggerFactory.getLogger(DependencyVerifier.class); @@ -50,8 +53,9 @@ class DependencyVerifier { } // for tests - DependencyVerifier(ProcessRunner processRunner, int initialWait, int timeout, int waitBetweenRuns, - TimeUnit timeUnit) { + DependencyVerifier(ProcessRunner processRunner, int initialWait, int timeout, + int waitBetweenRuns, + TimeUnit timeUnit) { this.processRunner = processRunner; this.initialWait = initialWait; this.timeout = timeout; @@ -59,7 +63,26 @@ class DependencyVerifier { this.timeUnit = timeUnit; } - boolean verifyDependencies(String orgRepository) { + boolean verifyDependencies(String branch, String orgRepository) { + cloneRepo(branch, orgRepository); + GradleParser gradleParser = getGradleParser(branch); + Set dependenciesBeforeDependabot = gradleParser.fetchAllDependencies(); + Status status = dependabotUpdateStatus(orgRepository); + pullTheLatestRepoChanges(); + Set dependenciesAfterDependabot = gradleParser.fetchAllDependencies(); + Set diff = new HashSet<>(dependenciesAfterDependabot); + diff.removeAll(dependenciesBeforeDependabot); + if (status == Status.NO_PRS) { + if (!diff.isEmpty()) { + throw new IllegalStateException("There were open PRs however the dependencies differ. Different dependencies: [" + diff + "]"); + } + } else { + // TODO: Take from env vars micrometer / tracing / context propagation library versions and assert that they were updated in the diff + } + return true; + } + + private Status dependabotUpdateStatus(String orgRepository) { String githubServerTime = getGitHubServerTime(); triggerDependabotCheck(orgRepository); log.info("Waiting {} {} for PRs to be created...", initialWait, timeUnit); @@ -67,15 +90,30 @@ boolean verifyDependencies(String orgRepository) { return waitForDependabotUpdates(githubServerTime); } + private GradleParser getGradleParser(String branch) { + ProcessRunner branchProcessRunner = new ProcessRunner(null, new File(branch)); + return new GradleParser(branchProcessRunner); + } + + private void cloneRepo(String branch, String orgRepository) { + log.info("Cloning out {} branch to folder {}", branch, branch); + processRunner.run("git", "clone", "-b", + branch, "--single-branch", "https://github.com/" + orgRepository + ".git", branch); + } + + private void pullTheLatestRepoChanges() { + processRunner.run("git", "pull"); + } + private void sleep(int timeoutToSleep) { if (timeoutToSleep <= 0) { - log.warn("Timeout set to {} {}, won't wait, will continue...", timeoutToSleep, timeUnit); + log.warn("Timeout set to {} {}, won't wait, will continue...", timeoutToSleep, + timeUnit); return; } try { Thread.sleep(timeUnit.toMillis(timeoutToSleep)); - } - catch (InterruptedException e) { + } catch (InterruptedException e) { throw new IllegalStateException(e); } } @@ -86,10 +124,12 @@ private String getGitHubServerTime() { String dateHeader = response.stream() .filter(line -> line.startsWith("Date:")) .findFirst() - .orElseThrow(() -> new IllegalStateException("Could not get GitHub server time from response headers")); + .orElseThrow(() -> new IllegalStateException( + "Could not get GitHub server time from response headers")); // Parse RFC 1123 date to ZonedDateTime and format as ISO-8601 (done by default by // dateTime.toInstant()) - ZonedDateTime dateTime = ZonedDateTime.parse(dateHeader.substring(5).trim(), RFC_1123_DATE_TIME); + ZonedDateTime dateTime = ZonedDateTime.parse(dateHeader.substring(5).trim(), + RFC_1123_DATE_TIME); String serverTime = dateTime.toInstant().toString(); log.info("GH server time: {}", serverTime); return serverTime; @@ -97,19 +137,20 @@ private String getGitHubServerTime() { private void triggerDependabotCheck(String orgRepository) { log.info("Will trigger a Dependabot check..."); - processRunner.run("gh", "api", "/repos/" + orgRepository + "/dispatches", "-X", "POST", "-F", - "event_type=check-dependencies"); + processRunner.run("gh", "api", "/repos/" + orgRepository + "/dispatches", "-X", "POST", + "-F", + "event_type=check-dependencies"); log.info("Triggered Dependabot check"); } - private boolean waitForDependabotUpdates(String githubServerTime) { + private Status waitForDependabotUpdates(String githubServerTime) { long startTime = System.currentTimeMillis(); long timeoutMillis = timeUnit.toMillis(timeout); while (System.currentTimeMillis() - startTime < timeoutMillis) { List openPRs = getOpenMicrometerDependabotPRs(githubServerTime); if (openPRs.isEmpty()) { log.info("No pending Micrometer updates"); - return true; + return Status.NO_PRS; } boolean allProcessed = true; for (String pr : openPRs) { @@ -119,7 +160,7 @@ private boolean waitForDependabotUpdates(String githubServerTime) { } if (allProcessed) { log.info("All Dependabot PRs processed"); - return true; + return Status.ALL_PRS_COMPLETED; } log.info("Not all PRs processed, will try again..."); sleep(waitBetweenRuns); @@ -135,9 +176,11 @@ private List getOpenMicrometerDependabotPRs(String githubServerTime) { // 5948 // 5772 String result = String.join("\n", - processRunner.run("gh", "pr", "list", "--search", - String.format("is:open author:app/dependabot created:>=%s", githubServerTime), "--json", - "number,title", "--jq", ".[] | select(.title | contains(\"io.micrometer\")) | .number")); + processRunner.run("gh", "pr", "list", "--search", + String.format("is:open author:app/dependabot created:>=%s", githubServerTime), + "--json", + "number,title", "--jq", + ".[] | select(.title | contains(\"io.micrometer\")) | .number")); List prNumbers = result.lines().filter(line -> !line.trim().isEmpty()).toList(); log.info("Got [{}] dependabot PRs related to micrometer", prNumbers.size()); return prNumbers; @@ -146,7 +189,8 @@ private List getOpenMicrometerDependabotPRs(String githubServerTime) { private boolean checkPRStatus(String prNumber) { log.info("Will check PR status for PR with number [{}]...", prNumber); String status = String.join("\n", processRunner.run("gh", "pr", "view", prNumber, "--json", - "mergeStateStatus,mergeable,state", "--jq", "[.mergeStateStatus, .state] | join(\",\")")); + "mergeStateStatus,mergeable,state", "--jq", + "[.mergeStateStatus, .state] | join(\",\")")); // BLOCKED,OPEN // CONFLICTING // CLOSED,MERGED @@ -157,11 +201,13 @@ private boolean checkPRStatus(String prNumber) { boolean isCompleted = status.contains("CLOSED") || status.contains("MERGED"); if (isCompleted) { log.info("PR #{} is completed", prNumber); - } - else { + } else { log.info("PR #{} status: {}", prNumber, status); } return isCompleted; } + enum Status { + NO_PRS, ALL_PRS_COMPLETED + } } diff --git a/src/main/java/io/micrometer/release/train/ProjectTrainReleaseWorkflow.java b/src/main/java/io/micrometer/release/train/ProjectTrainReleaseWorkflow.java index f4a1107..d13d2b2 100644 --- a/src/main/java/io/micrometer/release/train/ProjectTrainReleaseWorkflow.java +++ b/src/main/java/io/micrometer/release/train/ProjectTrainReleaseWorkflow.java @@ -72,7 +72,8 @@ public void run(String commaSeparatedListOfVersions) { // successfully (now we're waiting for sync to central) // For each branch now run a post release action // Finally check if sync is finished - List versions = Arrays.stream(commaSeparatedListOfVersions.split(",")).map(String::trim).toList(); + List versions = Arrays.stream(commaSeparatedListOfVersions.split(",")) + .map(String::trim).toList(); Map versionToBranch = versionToBranchConverter.convert(versions); releaseScheduler.runReleaseAndCheckCi(versionToBranch); postReleaseTaskScheduler.runPostReleaseTasks(versions); diff --git a/src/main/java/io/micrometer/release/train/ReleaseScheduler.java b/src/main/java/io/micrometer/release/train/ReleaseScheduler.java index ca9b898..2942c9f 100644 --- a/src/main/java/io/micrometer/release/train/ReleaseScheduler.java +++ b/src/main/java/io/micrometer/release/train/ReleaseScheduler.java @@ -15,6 +15,7 @@ */ package io.micrometer.release.train; +import io.micrometer.release.common.Input; import io.micrometer.release.common.ProcessRunner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,9 +33,12 @@ class ReleaseScheduler { private final ProcessRunner processRunner; + private final DependencyVerifier dependencyVerifier; + ReleaseScheduler(CircleCiChecker circleCiChecker, ProcessRunner processRunner) { this.circleCiChecker = circleCiChecker; this.processRunner = processRunner; + this.dependencyVerifier = new DependencyVerifier(processRunner); } void runReleaseAndCheckCi(Map versionToBranch) { @@ -48,6 +52,7 @@ void runReleaseAndCheckCi(Map versionToBranch) { private void handleReleaseAndCI(String version, String branch) { try { + dependencyVerifier.verifyDependencies(getOrgRepository()); createGithubRelease(version, branch); boolean buildSuccessful = circleCiChecker.checkBuildStatus(version); if (!buildSuccessful) { @@ -59,6 +64,10 @@ private void handleReleaseAndCI(String version, String branch) { } } + String getOrgRepository() { + return Input.getGithubOrgRepository(); + } + private void createGithubRelease(String version, String branch) throws IOException, InterruptedException { log.info("Creating GitHub release for version: [{}] from branch: [{}]", version, branch); processRunner.run("gh", "release", "create", "v" + version, "--target", branch, "-t", version); diff --git a/src/test/java/io/micrometer/release/MainTests.java b/src/test/java/io/micrometer/release/MainTests.java index 2f612d9..54ce5cf 100644 --- a/src/test/java/io/micrometer/release/MainTests.java +++ b/src/test/java/io/micrometer/release/MainTests.java @@ -77,7 +77,7 @@ String getTrainVersions() { } @Override - String getGithubRepository() { + String getGithubOrgRepository() { return "micrometer-metrics/micrometer"; } diff --git a/src/test/java/io/micrometer/release/single/ChangelogProcessorTests.java b/src/test/java/io/micrometer/release/single/ChangelogProcessorTests.java index 1ec212b..e52eea6 100644 --- a/src/test/java/io/micrometer/release/single/ChangelogProcessorTests.java +++ b/src/test/java/io/micrometer/release/single/ChangelogProcessorTests.java @@ -15,6 +15,7 @@ */ package io.micrometer.release.single; +import io.micrometer.release.common.GradleParser; import io.micrometer.release.common.ProcessRunner; import org.junit.jupiter.api.Test; diff --git a/src/test/java/io/micrometer/release/single/PostReleaseWorkflowAcceptanceTests.java b/src/test/java/io/micrometer/release/single/PostReleaseWorkflowAcceptanceTests.java index d6bac4b..ddb371e 100644 --- a/src/test/java/io/micrometer/release/single/PostReleaseWorkflowAcceptanceTests.java +++ b/src/test/java/io/micrometer/release/single/PostReleaseWorkflowAcceptanceTests.java @@ -17,6 +17,7 @@ import com.github.tomakehurst.wiremock.junit5.WireMockExtension; import io.micrometer.release.common.ProcessRunner; +import io.micrometer.release.train.DependencyVerifierTests; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.params.ParameterizedTest; diff --git a/src/test/java/io/micrometer/release/single/DependencyVerifierTests.java b/src/test/java/io/micrometer/release/train/DependencyVerifierTests.java similarity index 99% rename from src/test/java/io/micrometer/release/single/DependencyVerifierTests.java rename to src/test/java/io/micrometer/release/train/DependencyVerifierTests.java index 06a732a..a1f63eb 100644 --- a/src/test/java/io/micrometer/release/single/DependencyVerifierTests.java +++ b/src/test/java/io/micrometer/release/train/DependencyVerifierTests.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.micrometer.release.single; +package io.micrometer.release.train; import io.micrometer.release.common.ProcessRunner;