diff --git a/java-cloud-bom/release-note-generation/src/main/java/com/google/cloud/ReleaseNoteGeneration.java b/java-cloud-bom/release-note-generation/src/main/java/com/google/cloud/ReleaseNoteGeneration.java index 483df61ba1ed..773501f0ce8f 100644 --- a/java-cloud-bom/release-note-generation/src/main/java/com/google/cloud/ReleaseNoteGeneration.java +++ b/java-cloud-bom/release-note-generation/src/main/java/com/google/cloud/ReleaseNoteGeneration.java @@ -113,16 +113,44 @@ public static void main(String[] arguments) } @VisibleForTesting final StringBuilder report = new StringBuilder(); + private boolean monorepoReleaseExists = true; @VisibleForTesting ReleaseNoteGeneration() {} + private static boolean releaseExists(String repository, String tag) { + Process process = null; + try { + ProcessBuilder builder = + new ProcessBuilder( + "gh", "release", "--repo", GOOGLEAPIS_ORG + "/" + repository, "view", tag); + builder.redirectOutput(ProcessBuilder.Redirect.DISCARD); + builder.redirectError(ProcessBuilder.Redirect.DISCARD); + process = builder.start(); + boolean finished = process.waitFor(1, TimeUnit.MINUTES); + if (!finished) { + return false; + } + return process.exitValue() == 0; + } catch (IOException e) { + return false; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return false; + } finally { + if (process != null && process.isAlive()) { + process.destroyForcibly(); + } + } + } + @VisibleForTesting String generateReport(Bom bom, String googleCloudJavaVersion) throws MavenRepositoryException, ArtifactDescriptorException, IOException, InterruptedException { + monorepoReleaseExists = releaseExists("google-cloud-java", "v" + googleCloudJavaVersion); Bom previousBom = previousBom(bom); DefaultArtifact bomArtifact = new DefaultArtifact(bom.getCoordinates()); @@ -422,10 +450,15 @@ private static String releaseUrlForSplitRepo(String libraryName, String version) "https://github.com/googleapis/java-%s/releases/tag/v%s", libraryName, version); } - private static String releaseUrlForMonorepo(String libraryName, String version) { - // libraryName is unused for the monorepo release note as of Dec 2022 - return String.format( - "https://github.com/googleapis/google-cloud-java/releases/tag/v%s", version); + private String releaseUrlForMonorepo(String libraryName, String version) { + if (monorepoReleaseExists) { + return String.format( + "https://github.com/googleapis/google-cloud-java/releases/tag/v%s", version); + } else { + return String.format( + "https://github.com/googleapis/google-cloud-java/releases/tag/v%s-%s", + version, libraryName); + } } /** @@ -612,16 +645,43 @@ static String fetchReleaseNote(String owner, String repository, String tag) throws IOException, InterruptedException { // gh release --repo googleapis/java-storage view v2.16.0 - ProcessBuilder builder = - new ProcessBuilder("gh", "release", "--repo", owner + "/" + repository, "view", tag); - builder.redirectErrorStream(true); - Process process = builder.start(); - String output = - new String( - process.getInputStream().readAllBytes(), java.nio.charset.StandardCharsets.UTF_8); - boolean finished = process.waitFor(1, TimeUnit.MINUTES); - Verify.verify(finished, "The process timed out"); - Verify.verify(0 == process.exitValue(), "The command failed: %s", output); - return output; + File tempFile = java.nio.file.Files.createTempFile("gh-release-notes", ".txt").toFile(); + tempFile.deleteOnExit(); + + Process process = null; + try { + ProcessBuilder builder = + new ProcessBuilder("gh", "release", "--repo", owner + "/" + repository, "view", tag); + builder.redirectErrorStream(true); + builder.redirectOutput(ProcessBuilder.Redirect.to(tempFile)); + + process = builder.start(); + boolean finished = process.waitFor(1, TimeUnit.MINUTES); + if (!finished) { + throw new IOException("The process timed out"); + } + + String output = + new String( + java.nio.file.Files.readAllBytes(tempFile.toPath()), + java.nio.charset.StandardCharsets.UTF_8); + + if (process.exitValue() != 0) { + String trimmedOutput = output.trim(); + String lowerOutput = trimmedOutput.toLowerCase(); + if (lowerOutput.contains("not found") || lowerOutput.contains("404")) { + System.err.println( + "Warning: The command failed (release likely not found): " + trimmedOutput); + return ""; + } + throw new IOException("The command failed: " + trimmedOutput); + } + return output; + } finally { + if (process != null && process.isAlive()) { + process.destroyForcibly(); + } + tempFile.delete(); + } } }