Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
marcingrzejszczak committed Feb 25, 2025
1 parent 531df6d commit f95f591
Show file tree
Hide file tree
Showing 14 changed files with 206 additions and 117 deletions.
13 changes: 7 additions & 6 deletions src/main/java/io/micrometer/release/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> excludedDependencyScopes = List.of("testCompile", "testImplementation", "checkstyle",
"runtime", "nohttp", "testRuntime", "optional");

private final AtomicReference<Set<Dependency>> dependenciesCache = new AtomicReference<>();
private final List<String> 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<Dependency> fetchAllDependencies() {
Set<Dependency> cachedDependencies = dependenciesCache.get();
if (cachedDependencies != null) {
log.info("Returned cached dependencies");
return cachedDependencies;
}
public Set<Dependency> fetchAllDependencies() {
log.info("Fetching test and optional dependencies...");
List<String> projectLines = projectLines();
List<String> subprojects = projectLines.stream()
Expand All @@ -72,36 +60,32 @@ Set<Dependency> 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;
Expand All @@ -123,11 +107,11 @@ static String extractVersion(String line) {
return null;
}

List<String> dependenciesLines(List<String> gradleCommand) {
public List<String> dependenciesLines(List<String> gradleCommand) {
return processRunner.runSilently(gradleCommand);
}

List<String> projectLines() {
public List<String> projectLines() {
return processRunner.runSilently("./gradlew", "projects");
}

Expand Down
56 changes: 56 additions & 0 deletions src/main/java/io/micrometer/release/common/Input.java
Original file line number Diff line number Diff line change
@@ -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");
}
}
43 changes: 27 additions & 16 deletions src/main/java/io/micrometer/release/common/ProcessRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.*;
Expand All @@ -33,14 +32,21 @@ public class ProcessRunner {

private final String repo;

private final File directory;

private final Map<String, String> 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<String, String> envVars) {
Expand Down Expand Up @@ -78,29 +84,29 @@ private List<String> run(boolean shouldLog, String... command) {
List<String> 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) {
log(line);
}
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);
}
});
Expand All @@ -114,12 +120,12 @@ private List<String> 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");
Expand All @@ -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);
}

Expand All @@ -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<String> commands = new LinkedList<>(Arrays.stream(command).toList());
commands.add("--repo");
commands.add(repo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading

0 comments on commit f95f591

Please sign in to comment.