diff --git a/projects/spring-cloud/src/main/resources/application.yml b/projects/spring-cloud/src/main/resources/application.yml index 95d93d38..c840cfdd 100644 --- a/projects/spring-cloud/src/main/resources/application.yml +++ b/projects/spring-cloud/src/main/resources/application.yml @@ -33,6 +33,7 @@ releaser: number-of-checked-milestones: 50 update-documentation-repo: true update-github-milestones: true + create-release-notes-for-milestone: true update-spring-guides: true update-start-spring-io: true update-spring-project: true diff --git a/projects/spring-cloud/src/test/java/releaser/cloud/spring/meta/SpringMetaReleaseAcceptanceTests.java b/projects/spring-cloud/src/test/java/releaser/cloud/spring/meta/SpringMetaReleaseAcceptanceTests.java index df0086d9..24039f6d 100644 --- a/projects/spring-cloud/src/test/java/releaser/cloud/spring/meta/SpringMetaReleaseAcceptanceTests.java +++ b/projects/spring-cloud/src/test/java/releaser/cloud/spring/meta/SpringMetaReleaseAcceptanceTests.java @@ -89,7 +89,8 @@ public class SpringMetaReleaseAcceptanceTests extends AbstractSpringCloudMetaAcc GitTestUtils.setOriginOnProjectToTmp(origin, project); run(defaultRunner(), - properties("debugx=true").properties("test.metarelease=true") + properties("debugx=true") + .properties("test.metarelease=true", "releaser.git.create-release-notes-for-milestone=false") .properties(metaReleaseArgs(project, tempDirTestSamplesProject, tempDirReleaseTrainDocs, tempDirSpringCloud, tempDirReleaseTrainWiki, tempDirAllTestSample) .bomBranch("v2022.0.2").addFixedVersions(v2022_0_4()).build()), @@ -131,7 +132,8 @@ public class SpringMetaReleaseAcceptanceTests extends AbstractSpringCloudMetaAcc File project = cloneToTemporaryDirectory(tempDirSpringCloudConsulProject, tmpFile("spring-cloud-consul")); GitTestUtils.setOriginOnProjectToTmp(origin, project); - run(defaultRunner(), properties("debugx=true").properties("test.metarelease=true") + run(defaultRunner(), properties("debugx=true") + .properties("test.metarelease=true", "releaser.git.create-release-notes-for-milestone=false") .properties(metaReleaseArgsForParallel(project, tempDirTestSamplesProject, tempDirReleaseTrainDocs, tempDirSpringCloud, tempDirReleaseTrainWiki, tempDirAllTestSample).bomBranch("v2022.0.2") .addFixedVersions(v2022_0_4()) diff --git a/releaser-core/src/main/java/releaser/internal/Releaser.java b/releaser-core/src/main/java/releaser/internal/Releaser.java index cacb48d2..fe8ba8a7 100644 --- a/releaser-core/src/main/java/releaser/internal/Releaser.java +++ b/releaser-core/src/main/java/releaser/internal/Releaser.java @@ -193,6 +193,9 @@ public class Releaser { try { this.projectGitHubHandler.closeMilestone(releaseVersion); log.info("\nSuccessfully closed milestone"); + log.info("\nWill try to create release notes for milestone"); + this.projectGitHubHandler.createReleaseNotesForMilestone(releaseVersion); + log.info("\nSuccessfully created release notes for milestone"); return ExecutionResult.success(); } catch (Exception ex) { diff --git a/releaser-core/src/main/java/releaser/internal/ReleaserProperties.java b/releaser-core/src/main/java/releaser/internal/ReleaserProperties.java index 831dc29b..b61310be 100644 --- a/releaser-core/src/main/java/releaser/internal/ReleaserProperties.java +++ b/releaser-core/src/main/java/releaser/internal/ReleaserProperties.java @@ -530,6 +530,11 @@ public class ReleaserProperties implements Serializable { */ private String password; + /** + * URL to the fat jar with Github Changelog Generator. + */ + private String githubChangelogGeneratorUrl = "https://github.com/spring-io/github-changelog-generator/releases/download/v0.0.8/github-changelog-generator.jar"; + /** * In order not to iterate endlessly over milestones we introduce a threshold of * milestones that we will go through to find the matching milestone. @@ -546,6 +551,11 @@ public class ReleaserProperties implements Serializable { */ private boolean updateGithubMilestones = false; + /** + * If set to {@code false}, will not create release notes for milestone. + */ + private boolean createReleaseNotesForMilestone = false; + /** * If set to {@code false}, will not update Spring Guides for a release train. */ @@ -814,6 +824,22 @@ public class ReleaserProperties implements Serializable { this.updateGithubMilestones = updateGithubMilestones; } + public boolean isCreateReleaseNotesForMilestone() { + return createReleaseNotesForMilestone; + } + + public void setCreateReleaseNotesForMilestone(boolean createReleaseNotesForMilestone) { + this.createReleaseNotesForMilestone = createReleaseNotesForMilestone; + } + + public String getGithubChangelogGeneratorUrl() { + return githubChangelogGeneratorUrl; + } + + public void setGithubChangelogGeneratorUrl(String githubChangelogGeneratorUrl) { + this.githubChangelogGeneratorUrl = githubChangelogGeneratorUrl; + } + public String getOrgName() { return this.orgName; } diff --git a/releaser-core/src/main/java/releaser/internal/github/GithubMilestones.java b/releaser-core/src/main/java/releaser/internal/github/GithubMilestones.java index 4134ecce..9ebd3760 100644 --- a/releaser-core/src/main/java/releaser/internal/github/GithubMilestones.java +++ b/releaser-core/src/main/java/releaser/internal/github/GithubMilestones.java @@ -16,18 +16,27 @@ package releaser.internal.github; +import java.io.FileOutputStream; import java.io.IOException; import java.net.URL; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; import org.kohsuke.github.GHIssueState; import org.kohsuke.github.GHMilestone; +import org.kohsuke.github.GHRepository; import org.kohsuke.github.GitHub; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import releaser.internal.ReleaserProperties; import releaser.internal.project.ProjectVersion; +import releaser.internal.tech.ReleaserProcessExecutor; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -40,6 +49,8 @@ class GithubMilestones { static final Map MILESTONE_URL_CACHE = new ConcurrentHashMap<>(); static final Map MILESTONE_CACHE = new ConcurrentHashMap<>(); + static final AtomicReference DOWNLOADED_GITHUB_CHANGELOG = new AtomicReference<>(); + private static final Logger log = LoggerFactory.getLogger(GithubMilestones.class); private final GitHub github; @@ -85,6 +96,72 @@ class GithubMilestones { } } + void createReleaseNotesForMilestone(ProjectVersion version) { + String contents = null; + if (version.isReleaseTrain()) { + String listOfReleases = this.properties.getFixedVersions().entrySet().stream() + .sorted(Map.Entry.comparingByKey()) + .filter(entry -> !entry.getKey().equals("spring-boot") && this.properties.getMetaRelease() + .getReleaseTrainDependencyNames().stream().noneMatch(s -> entry.getKey().equals(s))) + .map(entry -> "- " + entry.getKey() + " [" + entry.getValue() + "](https://github.com/" + org() + + "/" + entry.getKey() + "/releases/tag/v" + entry.getValue() + ")") + .collect(Collectors.joining("\n")); + contents = "## :star: Releases\n\n" + listOfReleases; + } + else { + try { + boolean notPreviouslyDownloaded = DOWNLOADED_GITHUB_CHANGELOG.compareAndSet(null, + Files.createTempFile("releaser-changelog-generator", ".jar")); + if (notPreviouslyDownloaded) { + try (ReadableByteChannel readableByteChannel = Channels.newChannel( + new URL(this.properties.getGit().getGithubChangelogGeneratorUrl()).openStream())) { + downloadFatJarIfNotPresent(readableByteChannel); + } + } + contents = readChangelogFromGeneratorOutput(version); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + createGithubMilestoneReleaseNotes(version, contents); + } + + String readChangelogFromGeneratorOutput(ProjectVersion version) throws IOException { + Path path = DOWNLOADED_GITHUB_CHANGELOG.get(); + Path workDir = path.getParent(); + ReleaserProcessExecutor processExecutor = new ReleaserProcessExecutor(workDir.toAbsolutePath().toString()); + // java -jar -Dchangelog.repository=spring-cloud/spring-cloud-sleuth + // github-changelog-generator.jar 3.1.8 ./sleuth.md + processExecutor.runCommand(new String[] { "java", "-jar", + "-Dchangelog.repository=" + this.properties.getGit().getOrgName() + "/" + version.projectName, + "-Dgithub.username=" + this.properties.getGit().getUsername(), + "-Dgithub.password=" + this.properties.getGit().getOauthToken(), path.getFileName().toString(), + version.version, version.projectName + ".md" }, 2L); + return Files.readString(workDir.resolve(version.projectName + ".md")); + } + + void createGithubMilestoneReleaseNotes(ProjectVersion version, String contents) { + try { + String tag = "v" + version.version; + log.info("Creating a new release {} for project {}", tag, version.projectName); + getRepository(version).createRelease(tag).name(version.version).body(contents).create(); + log.info("Created a new release"); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + + private void downloadFatJarIfNotPresent(ReadableByteChannel readableByteChannel) throws IOException { + Path path = DOWNLOADED_GITHUB_CHANGELOG.get(); + log.info("Will download the github changelog generator from {} to {}", + this.properties.getGit().getGithubChangelogGeneratorUrl(), path); + FileOutputStream fileOutputStream = new FileOutputStream(path.toFile()); + fileOutputStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE); + log.info("File downloaded"); + } + GHMilestone matchingMilestone(String tagVersion, Iterable milestones) { log.debug("Successfully received list of milestones [{}]", milestones); log.info("Will try to match against tag version [{}]", tagVersion); @@ -144,24 +221,23 @@ class GithubMilestones { return version.contains("RELEASE") ? version.substring(0, version.lastIndexOf(".")) : ""; } - String milestoneTitle(GHMilestone milestone) throws IOException { - return milestone.getTitle(); - } - URL foundMilestoneUrl(GHMilestone milestone) throws IOException { return milestone.getUrl(); } private Iterable openMilestones(ProjectVersion version) { try { - return this.github.getRepository(org() + "/" + version.projectName).listMilestones(GHIssueState.OPEN) - .toList(); + return getRepository(version).listMilestones(GHIssueState.OPEN).toList(); } catch (IOException e) { throw new RuntimeException(e); } } + private GHRepository getRepository(ProjectVersion version) throws IOException { + return this.github.getRepository(org() + "/" + version.projectName); + } + private Iterable closedMilestones(ProjectVersion version) { try { return this.github.getRepository(org() + "/" + version.projectName).listMilestones(GHIssueState.CLOSED) diff --git a/releaser-core/src/main/java/releaser/internal/github/ProjectGitHubHandler.java b/releaser-core/src/main/java/releaser/internal/github/ProjectGitHubHandler.java index 1fbd7a51..10a48b5e 100644 --- a/releaser-core/src/main/java/releaser/internal/github/ProjectGitHubHandler.java +++ b/releaser-core/src/main/java/releaser/internal/github/ProjectGitHubHandler.java @@ -60,6 +60,15 @@ public class ProjectGitHubHandler { this.githubMilestones.closeMilestone(releaseVersion); } + public void createReleaseNotesForMilestone(ProjectVersion releaseVersion) { + if (!this.properties.getGit().isCreateReleaseNotesForMilestone()) { + log.info("Will not create release notes for milestone, since the switch to do so " + + "is off. Set [releaser.git.create-release-notes-for-milestone] to [true] to change that"); + return; + } + this.githubMilestones.createReleaseNotesForMilestone(releaseVersion); + } + public void createIssueInSpringGuides(Projects projects, ProjectVersion version) { if (!this.properties.getGit().isUpdateSpringGuides()) { log.info("Will not update the release train documentation, since the switch to do so " @@ -71,7 +80,7 @@ public class ProjectGitHubHandler { public void createIssueInStartSpringIo(Projects projects, ProjectVersion version) { if (!this.properties.getGit().isUpdateStartSpringIo()) { - log.info("Will not update the release train documentation, since the switch to do so " + log.info("Will not update start.spring.io, since the switch to do so " + "is off. Set [releaser.git.update-start-spring-io] to [true] to change that"); return; } diff --git a/releaser-core/src/main/java/releaser/internal/project/ProjectCommandExecutor.java b/releaser-core/src/main/java/releaser/internal/project/ProjectCommandExecutor.java index e24553b1..050600d5 100644 --- a/releaser-core/src/main/java/releaser/internal/project/ProjectCommandExecutor.java +++ b/releaser-core/src/main/java/releaser/internal/project/ProjectCommandExecutor.java @@ -27,8 +27,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; @@ -36,10 +34,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.zeroturnaround.exec.ProcessExecutor; -import org.zeroturnaround.exec.ProcessResult; -import org.zeroturnaround.exec.stream.slf4j.Slf4jStream; import releaser.internal.ReleaserProperties; +import releaser.internal.tech.ReleaserProcessExecutor; import org.springframework.util.StringUtils; @@ -242,76 +238,6 @@ public class ProjectCommandExecutor { } -class ReleaserProcessExecutor { - - private static final Logger log = LoggerFactory.getLogger(ReleaserProcessExecutor.class); - - private static String[] OS_OPERATORS = { "|", "<", ">", "||", "&&" }; - - private String workingDir; - - ReleaserProcessExecutor(String workingDir) { - this.workingDir = workingDir; - } - - void runCommand(String[] commands, long waitTimeInMinutes) { - doRunCommand(commands, waitTimeInMinutes); - } - - String runCommandWithOutput(String[] commands, long waitTimeInMinutes) { - return doRunCommand(commands, waitTimeInMinutes).outputUTF8(); - } - - private ProcessResult doRunCommand(String[] commands, long waitTimeInMinutes) { - String workingDir = this.workingDir; - log.info("Will run the command from [{}] and wait for result for [{}] minutes", workingDir, waitTimeInMinutes); - - try { - ProcessExecutor processExecutor = processExecutor(commands, workingDir).timeout(waitTimeInMinutes, - TimeUnit.MINUTES); - final ProcessResult processResult = doExecute(processExecutor); - int processExitValue = processResult.getExitValue(); - if (processExitValue != 0) { - throw new IllegalStateException("The process has exited with exit code [" + processExitValue + "]"); - } - return processResult; - } - catch (InterruptedException | IOException e) { - throw new IllegalStateException("Process execution failed", e); - } - catch (TimeoutException e) { - log.error("The command hasn't managed to finish in [{}] minutes", waitTimeInMinutes); - throw new IllegalStateException("Process waiting time of [" + waitTimeInMinutes + "] minutes exceeded", e); - } - } - - ProcessResult doExecute(ProcessExecutor processExecutor) - throws IOException, InterruptedException, TimeoutException { - return processExecutor.execute(); - } - - ProcessExecutor processExecutor(String[] commands, String workingDir) { - String[] commandsToRun = commands; - String lastArg = String.join(" ", commands); - if (Arrays.stream(OS_OPERATORS).anyMatch(lastArg::contains)) { - commandsToRun = commandToExecute(lastArg); - } - log.info("Will run the command [{}]", Arrays.toString(commandsToRun)); - return new ProcessExecutor().command(commandsToRun).destroyOnExit().readOutput(true) - // releaser.commands logger should be configured to redirect - // only to a file (with additivity=false). ideally the root logger should - // append to same file on top of whatever root appender, so that file - // contains the most output - .redirectOutputAlsoTo(Slf4jStream.of("releaser.commands").asInfo()) - .redirectErrorAlsoTo(Slf4jStream.of("releaser.commands").asWarn()).directory(new File(workingDir)); - } - - String[] commandToExecute(String lastArg) { - return new String[] { "/bin/bash", "-c", lastArg }; - } - -} - class CommandPicker { private static final Log log = LogFactory.getLog(CommandPicker.class); diff --git a/releaser-core/src/main/java/releaser/internal/tech/ReleaserProcessExecutor.java b/releaser-core/src/main/java/releaser/internal/tech/ReleaserProcessExecutor.java new file mode 100644 index 00000000..544dfebb --- /dev/null +++ b/releaser-core/src/main/java/releaser/internal/tech/ReleaserProcessExecutor.java @@ -0,0 +1,99 @@ +/* + * Copyright 2013-2019 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 + * + * 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 releaser.internal.tech; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.zeroturnaround.exec.ProcessExecutor; +import org.zeroturnaround.exec.ProcessResult; +import org.zeroturnaround.exec.stream.slf4j.Slf4jStream; + +public class ReleaserProcessExecutor { + + private static final Logger log = LoggerFactory.getLogger(ReleaserProcessExecutor.class); + + private static String[] OS_OPERATORS = { "|", "<", ">", "||", "&&" }; + + private String workingDir; + + public ReleaserProcessExecutor(String workingDir) { + this.workingDir = workingDir; + } + + public void runCommand(String[] commands, long waitTimeInMinutes) { + doRunCommand(commands, waitTimeInMinutes); + } + + public String runCommandWithOutput(String[] commands, long waitTimeInMinutes) { + return doRunCommand(commands, waitTimeInMinutes).outputUTF8(); + } + + private ProcessResult doRunCommand(String[] commands, long waitTimeInMinutes) { + String workingDir = this.workingDir; + log.info("Will run the command from [{}] and wait for result for [{}] minutes", workingDir, waitTimeInMinutes); + + try { + ProcessExecutor processExecutor = processExecutor(commands, workingDir).timeout(waitTimeInMinutes, + TimeUnit.MINUTES); + final ProcessResult processResult = doExecute(processExecutor); + int processExitValue = processResult.getExitValue(); + if (processExitValue != 0) { + throw new IllegalStateException("The process has exited with exit code [" + processExitValue + "]"); + } + return processResult; + } + catch (InterruptedException | IOException e) { + throw new IllegalStateException("Process execution failed", e); + } + catch (TimeoutException e) { + log.error("The command hasn't managed to finish in [{}] minutes", waitTimeInMinutes); + throw new IllegalStateException("Process waiting time of [" + waitTimeInMinutes + "] minutes exceeded", e); + } + } + + ProcessResult doExecute(ProcessExecutor processExecutor) + throws IOException, InterruptedException, TimeoutException { + return processExecutor.execute(); + } + + ProcessExecutor processExecutor(String[] commands, String workingDir) { + String[] commandsToRun = commands; + String lastArg = String.join(" ", commands); + if (Arrays.stream(OS_OPERATORS).anyMatch(lastArg::contains)) { + commandsToRun = commandToExecute(lastArg); + } + log.info("Will run the command [{}]", Arrays.toString(commandsToRun)); + return new ProcessExecutor().command(commandsToRun).destroyOnExit().readOutput(true) + // releaser.commands logger should be configured to redirect + // only to a file (with additivity=false). ideally the root logger should + // append to same file on top of whatever root appender, so that file + // contains the most output + .redirectOutputAlsoTo(Slf4jStream.of("releaser.commands").asInfo()) + .redirectErrorAlsoTo(Slf4jStream.of("releaser.commands").asWarn()).directory(new File(workingDir)); + } + + String[] commandToExecute(String lastArg) { + return new String[] { "/bin/bash", "-c", lastArg }; + } + +} diff --git a/releaser-core/src/main/java/releaser/internal/template/NotesGenerator.java b/releaser-core/src/main/java/releaser/internal/template/NotesGenerator.java index 15b2a9b7..8a04b396 100644 --- a/releaser-core/src/main/java/releaser/internal/template/NotesGenerator.java +++ b/releaser-core/src/main/java/releaser/internal/template/NotesGenerator.java @@ -24,7 +24,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import releaser.internal.ReleaserProperties; import releaser.internal.github.ProjectGitHubHandler; -import releaser.internal.project.ProjectVersion; import releaser.internal.project.Projects; import org.springframework.util.StringUtils; @@ -50,24 +49,14 @@ class NotesGenerator { .map(projectVersion -> { String name = projectVersion.projectName; String version = projectVersion.version; - String closedMilestoneUrl = closedMilestoneUrl(projectVersion); + String release = "https://github.com/" + this.properties.getGit().getOrgName() + "/" + + projectVersion.projectName + "/releases/tag/v" + projectVersion.version; String convertedName = Arrays.stream(name.split("-")).map(StringUtils::capitalize) .collect(Collectors.joining(" ")); - return new Notes(convertedName, version, closedMilestoneUrl); + return new Notes(convertedName, version, release); }).collect(Collectors.toSet()); } - private String closedMilestoneUrl(ProjectVersion projectVersion) { - try { - return this.handler.milestoneUrl(projectVersion); - } - catch (Exception ex) { - log.warn("Exception occurred while trying to fetch a milestone url. Will fallback to tag url", ex); - return "https://github.com/" + this.properties.getGit().getOrgName() + "/" + projectVersion.projectName - + "/releases/tag/v" + projectVersion.version; - } - } - } class Notes { diff --git a/releaser-core/src/test/java/releaser/internal/docs/ReleaseTrainContentsUpdaterTests.java b/releaser-core/src/test/java/releaser/internal/docs/ReleaseTrainContentsUpdaterTests.java index 5bafeba5..3d9ff93f 100644 --- a/releaser-core/src/test/java/releaser/internal/docs/ReleaseTrainContentsUpdaterTests.java +++ b/releaser-core/src/test/java/releaser/internal/docs/ReleaseTrainContentsUpdaterTests.java @@ -123,8 +123,8 @@ public class ReleaseTrainContentsUpdaterTests { File file = this.updater.updateReleaseTrainWiki(newReleaseTrain()); BDDAssertions.then(file).isNotNull(); - BDDAssertions.then(edgwareWikiEntryContent(file)).contains("# Edgware.SR7") - .contains("Spring Cloud Consul `2.0.1.RELEASE` ([issues](http://www.foo.com/))"); + BDDAssertions.then(edgwareWikiEntryContent(file)).contains("# Edgware.SR7").contains( + "Spring Cloud Consul `2.0.1.RELEASE` ([issues](https://github.com/spring-cloud/spring-cloud-consul/releases/tag/v2.0.1.RELEASE))"); BDDAssertions.then(GitTestUtils.openGitProject(file).log().call().iterator().next().getShortMessage()) .contains("Updating project page to release train [Edgware.SR7]"); } @@ -138,8 +138,8 @@ public class ReleaseTrainContentsUpdaterTests { File file = this.updater.updateReleaseTrainWiki(freshNewReleaseTrain()); BDDAssertions.then(file).isNotNull(); - BDDAssertions.then(greenwichWikiEntryContent(file)).contains("# Greenwich.RELEASE") - .contains("Spring Cloud Consul `2.0.1.RELEASE` ([issues](http://www.foo.com/))"); + BDDAssertions.then(greenwichWikiEntryContent(file)).contains("# Greenwich.RELEASE").contains( + "Spring Cloud Consul `2.0.1.RELEASE` ([issues](https://github.com/spring-cloud/spring-cloud-consul/releases/tag/v2.0.1.RELEASE))"); BDDAssertions.then(GitTestUtils.openGitProject(file).log().call().iterator().next().getShortMessage()) .contains("Updating project page to release train [Greenwich.RELEASE]"); } @@ -154,8 +154,8 @@ public class ReleaseTrainContentsUpdaterTests { File file = this.updater.updateReleaseTrainWiki(freshNewReleaseTrainCalver()); BDDAssertions.then(file).isNotNull(); - BDDAssertions.then(calverWikiEntryContent(file)).contains("# 2020.0.5") - .contains("Spring Cloud Consul `2.0.1.RELEASE` ([issues](http://www.foo.com/))"); + BDDAssertions.then(calverWikiEntryContent(file)).contains("# 2020.0.5").contains( + "Spring Cloud Consul `2.0.1.RELEASE` ([issues](https://github.com/spring-cloud/spring-cloud-consul/releases/tag/v2.0.1.RELEASE))"); BDDAssertions.then(GitTestUtils.openGitProject(file).log().call().iterator().next().getShortMessage()) .contains("Updating project page to release train [2020.0.5]"); } diff --git a/releaser-core/src/test/java/releaser/internal/github/GithubMilestonesTests.java b/releaser-core/src/test/java/releaser/internal/github/GithubMilestonesTests.java index c9ef88be..8ce4fc47 100644 --- a/releaser-core/src/test/java/releaser/internal/github/GithubMilestonesTests.java +++ b/releaser-core/src/test/java/releaser/internal/github/GithubMilestonesTests.java @@ -18,6 +18,9 @@ package releaser.internal.github; import java.io.IOException; import java.net.URL; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; import com.github.tomakehurst.wiremock.junit5.WireMockTest; import org.junit.jupiter.api.BeforeEach; @@ -43,13 +46,15 @@ class GithubMilestonesTests { private static final String ORG = "marcingrzejszczak"; - private static final String TOKEN = "foo"; + private static final String USER = "marcingrzejszczak"; + + private static final String TOKEN = "TOKEN"; GitHub github; @BeforeEach public void setup() throws IOException { - this.github = GitHub.connectToEnterprise("http://localhost:12345", TOKEN); + this.github = GitHub.connectToEnterpriseWithOAuth("http://localhost:12345", USER, TOKEN); } @Test @@ -117,10 +122,6 @@ class GithubMilestonesTests { @Test void should_return_null_if_no_matching_milestone_was_found() { GithubMilestones milestones = new GithubMilestones(this.github, withToken()) { - @Override - String milestoneTitle(GHMilestone milestone) { - return "0.9.0"; - } @Override URL foundMilestoneUrl(GHMilestone milestone) throws IOException { @@ -143,14 +144,6 @@ class GithubMilestonesTests { then(capturedOutput.toString()).contains("No matching milestones were found within the provided threshold [0]"); } - private ProjectVersion nonGaSleuthProject() { - return new ProjectVersion("test-repo", "0.0.1-SNAPSHOT"); - } - - private ProjectVersion notMatchingProjectVersion() { - return new ProjectVersion("test-repo", "0.0.100-SNAPSHOT"); - } - @Test void should_throw_exception_when_there_is_no_matching_milestone(CapturedOutput capturedOutput) throws IOException { GithubMilestones milestones = new GithubMilestones(this.github, withToken()) { @@ -188,13 +181,91 @@ class GithubMilestonesTests { .hasMessageContaining("You must set the value of the OAuth token"); } + @Test + void should_create_a_release_for_release_train_with_links_to_other_releases(CapturedOutput capturedOutput) + throws IOException { + GithubMilestones milestones = new GithubMilestones(this.github, metaReleaser()); + + milestones.createReleaseNotesForMilestone(releaseTrain()); + + then(capturedOutput.toString()).contains("Created a new release"); + } + + @Test + void should_create_a_release_for_a_single_project(CapturedOutput capturedOutput) throws IOException { + GithubMilestones milestones = new GithubMilestones(this.github, withToken()) { + @Override + String readChangelogFromGeneratorOutput(ProjectVersion version) throws IOException { + return "FOOOO"; + } + }; + + milestones.createReleaseNotesForMilestone(gaContractVersion()); + + then(capturedOutput.toString()).contains("Created a new release"); + } + + ProjectVersion nonGaSleuthProject() { + return new ProjectVersion("test-repo", "0.0.1-SNAPSHOT"); + } + + ProjectVersion releaseTrain() { + return new ProjectVersion("spring-cloud-release", "2021.0.8"); + } + + ProjectVersion gaContractVersion() { + return new ProjectVersion("spring-cloud-contract", "3.1.8"); + } + + ProjectVersion notMatchingProjectVersion() { + return new ProjectVersion("test-repo", "0.0.100-SNAPSHOT"); + } + ReleaserProperties withToken() { ReleaserProperties properties = new ReleaserProperties(); properties.getGit().setOauthToken(TOKEN); properties.getGit().setOrgName(ORG); + properties.getGit().setUsername(USER); return properties; } + ReleaserProperties metaReleaser() { + ReleaserProperties properties = new ReleaserProperties(); + properties.setFixedVersions(v2021_0_8()); + properties.getGit().setOauthToken(TOKEN); + properties.getGit().setOrgName(ORG); + properties.getGit().setUsername(USER); + properties.getMetaRelease() + .setReleaseTrainDependencyNames(Arrays.asList("spring-cloud", "spring-cloud-release")); + return properties; + } + + public Map v2021_0_8() { + Map versions = new LinkedHashMap<>(); + versions.put("spring-boot", "2.6.15"); + versions.put("spring-cloud-build", "3.1.8"); + versions.put("spring-cloud-commons", "3.1.7"); + versions.put("spring-cloud-function", "3.2.11"); + versions.put("spring-cloud-stream", "3.2.9"); + versions.put("spring-cloud-bus", "3.1.2"); + versions.put("spring-cloud-task", "2.4.6"); + versions.put("spring-cloud-config", "3.1.8"); + versions.put("spring-cloud-netflix", "3.1.7"); + versions.put("spring-cloud-cloudfoundry", "3.1.3"); + versions.put("spring-cloud-openfeign", "3.1.8"); + versions.put("spring-cloud-consul", "3.1.4"); + versions.put("spring-cloud-circuitbreaker", "2.1.7"); + versions.put("spring-cloud-gateway", "3.1.8"); + versions.put("spring-cloud-sleuth", "3.1.9"); + versions.put("spring-cloud-zookeeper", "3.1.4"); + versions.put("spring-cloud-contract", "3.1.8"); + versions.put("spring-cloud-kubernetes", "2.1.8"); + versions.put("spring-cloud-vault", "3.1.3"); + versions.put("spring-cloud-release", "2021.0.8"); + versions.put("spring-cloud-cli", "3.1.1"); + return versions; + } + ReleaserProperties withThreshold() { ReleaserProperties properties = withToken(); properties.getGit().setNumberOfCheckedMilestones(0); diff --git a/releaser-core/src/test/java/releaser/internal/project/ProjectCommandExecutorTests.java b/releaser-core/src/test/java/releaser/internal/project/ProjectCommandExecutorTests.java index 0822ad57..1745420b 100644 --- a/releaser-core/src/test/java/releaser/internal/project/ProjectCommandExecutorTests.java +++ b/releaser-core/src/test/java/releaser/internal/project/ProjectCommandExecutorTests.java @@ -16,14 +16,10 @@ package releaser.internal.project; -import java.io.BufferedOutputStream; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.OutputStream; import java.net.URISyntaxException; import java.nio.file.Files; -import java.util.concurrent.TimeoutException; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.BeforeEach; @@ -35,6 +31,8 @@ import org.zeroturnaround.exec.ProcessResult; import releaser.internal.PomUpdateAcceptanceTests; import releaser.internal.ReleaserProperties; import releaser.internal.buildsystem.TestUtils; +import releaser.internal.tech.ReleaserProcessExecutor; +import releaser.internal.tech.TestReleaserProcessExecutor; import org.springframework.boot.test.system.OutputCaptureExtension; import org.springframework.util.FileSystemUtils; @@ -471,10 +469,10 @@ public class ProjectCommandExecutorTests { ProjectCommandExecutor builder = new ProjectCommandExecutor() { @Override ReleaserProcessExecutor executor(String workingDir) { - return new ReleaserProcessExecutor(properties.getWorkingDir()) { + return new TestReleaserProcessExecutor(properties.getWorkingDir(), temporaryFolder) { + @Override - ProcessResult doExecute(ProcessExecutor processExecutor) - throws IOException, InterruptedException, TimeoutException { + public ProcessResult doExecute(ProcessExecutor processExecutor) { return new ProcessResult(1, null); } }; @@ -486,7 +484,7 @@ public class ProjectCommandExecutorTests { } private TestReleaserProcessExecutor testExecutor(String workingDir) { - return new TestReleaserProcessExecutor(workingDir); + return new TestReleaserProcessExecutor(workingDir, temporaryFolder); } private File tmpFile(String relativePath) { @@ -505,35 +503,4 @@ public class ProjectCommandExecutorTests { return new ProjectVersion("foo", "0.100.0.BUILD-SNAPSHOT"); } - class TestReleaserProcessExecutor extends ReleaserProcessExecutor { - - int counter = 0; - - TestReleaserProcessExecutor(String workingDir) { - super(workingDir); - } - - @Override - ProcessExecutor processExecutor(String[] commands, String workingDir) { - this.counter++; - final ProcessExecutor processExecutor = super.processExecutor(commands, workingDir); - - File tempFile = tmpFile("/builder/resolved/resolved.log"); - try { - tempFile.createNewFile(); - OutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile)); - - return processExecutor - // use redirectOutputAlsoTo to avoid overriding all output - // destinations - .redirectOutput(fos); - } - catch (IOException e) { - e.printStackTrace(); - return processExecutor; - } - } - - } - } diff --git a/releaser-core/src/test/java/releaser/internal/tech/TestReleaserProcessExecutor.java b/releaser-core/src/test/java/releaser/internal/tech/TestReleaserProcessExecutor.java new file mode 100644 index 00000000..f8d24563 --- /dev/null +++ b/releaser-core/src/test/java/releaser/internal/tech/TestReleaserProcessExecutor.java @@ -0,0 +1,71 @@ +/* + * Copyright 2013-2019 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 + * + * 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 releaser.internal.tech; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.concurrent.TimeoutException; + +import org.zeroturnaround.exec.ProcessExecutor; +import org.zeroturnaround.exec.ProcessResult; + +public class TestReleaserProcessExecutor extends ReleaserProcessExecutor { + + public int counter = 0; + + final File temporaryFolder; + + public TestReleaserProcessExecutor(String workingDir, File temporaryFolder) { + super(workingDir); + this.temporaryFolder = temporaryFolder; + } + + @Override + ProcessExecutor processExecutor(String[] commands, String workingDir) { + this.counter++; + final ProcessExecutor processExecutor = super.processExecutor(commands, workingDir); + + File tempFile = tmpFile("/builder/resolved/resolved.log"); + try { + tempFile.createNewFile(); + OutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile)); + + return processExecutor + // use redirectOutputAlsoTo to avoid overriding all output + // destinations + .redirectOutput(fos); + } + catch (IOException e) { + e.printStackTrace(); + return processExecutor; + } + } + + @Override + public ProcessResult doExecute(ProcessExecutor processExecutor) + throws IOException, InterruptedException, TimeoutException { + return super.doExecute(processExecutor); + } + + private File tmpFile(String relativePath) { + return new File(this.temporaryFolder, relativePath); + } + +} diff --git a/releaser-core/src/test/java/releaser/internal/template/TemplateGeneratorTests.java b/releaser-core/src/test/java/releaser/internal/template/TemplateGeneratorTests.java index 13a50c24..bbb180f5 100644 --- a/releaser-core/src/test/java/releaser/internal/template/TemplateGeneratorTests.java +++ b/releaser-core/src/test/java/releaser/internal/template/TemplateGeneratorTests.java @@ -109,8 +109,10 @@ public class TemplateGeneratorTests { then(content(generatedBlog)).contains("General Availability (RELEASE) of the [Spring Cloud Dalston]") .contains("The release can be found in [Maven Central]").contains("### Spring Cloud Sleuth") - .contains("| Spring Cloud Sleuth | 1.0.0.RELEASE | ([issues](https://foo.bar.com))") - .contains("| Spring Cloud Foo | 1.0.2.RELEASE |  ") + .contains( + "| Spring Cloud Sleuth | 1.0.0.RELEASE | ([issues](https://github.com/spring-cloud/spring-cloud-sleuth/releases/tag/v1.0.0.RELEASE))") + .contains( + "| Spring Cloud Foo | 1.0.2.RELEASE | ([issues](https://github.com/spring-cloud/spring-cloud-foo/releases/tag/v1.0.2.RELEASE))") .contains("Dalston.RELEASE") .contains("mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Dalston.RELEASE'"); } @@ -129,7 +131,8 @@ public class TemplateGeneratorTests { then(content(generatedBlog)).contains("General Availability (RELEASE) of the [Spring Cloud Dalston]") .contains("The release can be found in [Maven Central]").contains("### Spring Cloud Sleuth") - .contains("| Spring Cloud Sleuth | 1.0.0.RELEASE | ([issues](https://foo.bar.com))") + .contains( + "| Spring Cloud Sleuth | 1.0.0.RELEASE | ([issues](https://github.com/spring-cloud/spring-cloud-sleuth/releases/tag/v1.0.0.RELEASE))") .contains("Dalston.RELEASE") .contains("mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Dalston.RELEASE'"); } @@ -148,7 +151,8 @@ public class TemplateGeneratorTests { then(content(generatedBlog)).contains("General Availability (RELEASE) of the [Spring Cloud 2020.0.5]") .contains("The release can be found in [Maven Central]").contains("### Spring Cloud Sleuth") - .contains("| Spring Cloud Sleuth | 1.0.0 | ([issues](https://foo.bar.com))") + .contains( + "| Spring Cloud Sleuth | 1.0.0 | ([issues](https://github.com/spring-cloud/spring-cloud-sleuth/releases/tag/v1.0.0))") .contains("2020.0.5") .contains("mavenBom 'org.springframework.cloud:spring-cloud-dependencies:2020.0.5'"); } @@ -167,7 +171,8 @@ public class TemplateGeneratorTests { then(content(generatedBlog)).contains("Service Release 1 (SR1) of the [Spring Cloud Dalston]") .contains("The release can be found in [Maven Central]").contains("### Spring Cloud Sleuth") - .contains("| Spring Cloud Sleuth | 1.0.0.RELEASE | ([issues](https://foo.bar.com))") + .contains( + "| Spring Cloud Sleuth | 1.0.0.RELEASE | ([issues](https://github.com/spring-cloud/spring-cloud-sleuth/releases/tag/v1.0.0.RELEASE))") .contains("Dalston.SR1") .contains("mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Dalston.SR1'"); } @@ -186,7 +191,8 @@ public class TemplateGeneratorTests { then(content(generatedBlog)).contains("Service Release 1 (SR1) of the [Spring Cloud Dalston]") .contains("The release can be found in [Maven Central]").contains("### Spring Cloud Sleuth") - .contains("| Spring Cloud Sleuth | 1.0.0.RELEASE | ([issues](https://foo.bar.com))") + .contains( + "| Spring Cloud Sleuth | 1.0.0.RELEASE | ([issues](https://github.com/spring-cloud/spring-cloud-sleuth/releases/tag/v1.0.0.RELEASE))") .contains("Dalston.SR1") .contains("mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Dalston.SR1'"); } @@ -205,7 +211,8 @@ public class TemplateGeneratorTests { then(content(generatedBlog)).contains("Milestone 1 (M1) of the [Spring Cloud Dalston]") .contains("The release can be found in [Spring Milestone]").contains("### Spring Cloud Sleuth") - .contains("| Spring Cloud Sleuth | 1.0.0.M1 | ([issues](https://foo.bar.com))") + .contains( + "| Spring Cloud Sleuth | 1.0.0.M1 | ([issues](https://github.com/spring-cloud/spring-cloud-sleuth/releases/tag/v1.0.0.M1))") .contains("spring-milestones").contains("url 'https://repo.spring.io/milestone'") .contains("Dalston.M1") .contains("mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Dalston.M1'"); @@ -225,7 +232,8 @@ public class TemplateGeneratorTests { then(content(generatedBlog)).contains("Milestone 1 (M1) of the [Spring Cloud Dalston]") .contains("The release can be found in [Spring Milestone]").contains("### Spring Cloud Sleuth") - .contains("| Spring Cloud Sleuth | 1.0.0.M1 | ([issues](https://foo.bar.com))") + .contains( + "| Spring Cloud Sleuth | 1.0.0.M1 | ([issues](https://github.com/spring-cloud/spring-cloud-sleuth/releases/tag/v1.0.0.M1))") .contains("spring-milestones").contains("url 'https://repo.spring.io/milestone'") .contains("Dalston.M1") .contains("mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Dalston.M1'"); @@ -246,7 +254,8 @@ public class TemplateGeneratorTests { then(content(generatedBlog)).contains("Milestone 1 (M1) of the [Spring Cloud 2020.0.0]") .contains("The release can be found in [Spring Milestone]").contains("### Spring Cloud Sleuth") - .contains("| Spring Cloud Sleuth | 1.0.0-M1 | ([issues](https://foo.bar.com))") + .contains( + "| Spring Cloud Sleuth | 1.0.0-M1 | ([issues](https://github.com/spring-cloud/spring-cloud-sleuth/releases/tag/v1.0.0-M1))") .contains("spring-milestones").contains("url 'https://repo.spring.io/milestone'") .contains("2020.0.0-M1") .contains("mavenBom 'org.springframework.cloud:spring-cloud-dependencies:2020.0.0-M1'"); @@ -266,7 +275,8 @@ public class TemplateGeneratorTests { then(content(generatedBlog)).contains("Release Candidate 1 (RC1) of the [Spring Cloud Dalston]") .contains("The release can be found in [Spring Milestone]").contains("### Spring Cloud Sleuth") - .contains("| Spring Cloud Sleuth | 1.0.0.RC1 | ([issues](https://foo.bar.com))") + .contains( + "| Spring Cloud Sleuth | 1.0.0.RC1 | ([issues](https://github.com/spring-cloud/spring-cloud-sleuth/releases/tag/v1.0.0.RC1))") .contains("spring-milestones").contains("url 'https://repo.spring.io/milestone'") .contains("Dalston.RC1") .contains("mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Dalston.RC1'"); @@ -286,7 +296,8 @@ public class TemplateGeneratorTests { then(content(generatedBlog)).contains("Release Candidate 1 (RC1) of the [Spring Cloud Dalston]") .contains("The release can be found in [Spring Milestone]").contains("### Spring Cloud Sleuth") - .contains("| Spring Cloud Sleuth | 1.0.0.RC1 | ([issues](https://foo.bar.com))") + .contains( + "| Spring Cloud Sleuth | 1.0.0.RC1 | ([issues](https://github.com/spring-cloud/spring-cloud-sleuth/releases/tag/v1.0.0.RC1))") .contains("spring-milestones").contains("url 'https://repo.spring.io/milestone'") .contains("Dalston.RC1") .contains("mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Dalston.RC1'"); @@ -306,7 +317,8 @@ public class TemplateGeneratorTests { then(content(generatedBlog)).contains("Release Candidate 1 (RC1) of the [Spring Cloud 2020.0.0]") .contains("The release can be found in [Spring Milestone]").contains("### Spring Cloud Sleuth") - .contains("| Spring Cloud Sleuth | 1.0.0-RC1 | ([issues](https://foo.bar.com))") + .contains( + "| Spring Cloud Sleuth | 1.0.0-RC1 | ([issues](https://github.com/spring-cloud/spring-cloud-sleuth/releases/tag/v1.0.0-RC1))") .contains("spring-milestones").contains("url 'https://repo.spring.io/milestone'") .contains("2020.0.0-RC1") .contains("mavenBom 'org.springframework.cloud:spring-cloud-dependencies:2020.0.0-RC1'"); @@ -331,9 +343,10 @@ public class TemplateGeneratorTests { File generatedOutput = new TemplateGenerator(this.props, handler).releaseNotes(projects); - then(content(generatedOutput)).contains("# Dalston.RC1") - .contains("Spring Cloud Sleuth `1.0.0.RC1` ([issues](https://foo.bar.com?closed=1))") - .contains("Spring Cloud Consul `1.0.1.RC1` ([issues](https://foo.bar.com?closed=1))") + then(content(generatedOutput)).contains("# Dalston.RC1").contains( + "Spring Cloud Sleuth `1.0.0.RC1` ([issues](https://github.com/spring-cloud/spring-cloud-sleuth/releases/tag/v1.0.0.RC1))") + .contains( + "Spring Cloud Consul `1.0.1.RC1` ([issues](https://github.com/spring-cloud/spring-cloud-consul/releases/tag/v1.0.1.RC1))") .doesNotContain("Boot"); } diff --git a/releaser-core/src/test/resources/application.yml b/releaser-core/src/test/resources/application.yml index fc14c4db..4ac489dc 100644 --- a/releaser-core/src/test/resources/application.yml +++ b/releaser-core/src/test/resources/application.yml @@ -13,6 +13,7 @@ releaser: flow: default-enabled: true git: + org-name: "spring-cloud" release-train-bom-url: https://github.com/spring-cloud/spring-cloud-release documentation-url: https://github.com/spring-cloud/spring-cloud-static spring-project-url: https://github.com/spring-projects/spring-cloud @@ -30,6 +31,7 @@ releaser: # username: # password: number-of-checked-milestones: 50 + create-release-notes-for-milestone: true update-documentation-repo: true update-github-milestones: true update-spring-guides: true @@ -114,4 +116,4 @@ releaser: projects-to-skip: - spring-boot - spring-cloud-stream - - spring-cloud-task \ No newline at end of file + - spring-cloud-task diff --git a/releaser-core/src/test/resources/mappings/github/repos_spring-cloud_spring-cloud-contract-c46099cb-2d70-4432-8883-dc240cc51269.json b/releaser-core/src/test/resources/mappings/github/repos_spring-cloud_spring-cloud-contract-c46099cb-2d70-4432-8883-dc240cc51269.json new file mode 100644 index 00000000..3277bfda --- /dev/null +++ b/releaser-core/src/test/resources/mappings/github/repos_spring-cloud_spring-cloud-contract-c46099cb-2d70-4432-8883-dc240cc51269.json @@ -0,0 +1,16 @@ +{ + "id" : "c46099cb-2d70-4432-8883-dc240cc51269", + "name" : "repos_spring-cloud_spring-cloud-contract", + "request" : { + "url" : "/repos/marcingrzejszczak/spring-cloud-contract", + "method" : "GET" + }, + "response" : { + "status" : 200, + "body" : "{\"id\":60979397,\"node_id\":\"MDEwOlJlcG9zaXRvcnk2MDk3OTM5Nw==\",\"name\":\"spring-cloud-contract\",\"full_name\":\"marcingrzejszczak/spring-cloud-contract\",\"private\":false,\"owner\":{\"login\":\"spring-cloud\",\"id\":7815877,\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjc4MTU4Nzc=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/7815877?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/spring-cloud\",\"html_url\":\"https://github.com/spring-cloud\",\"followers_url\":\"https://api.github.com/users/marcingrzejszczak/followers\",\"following_url\":\"https://api.github.com/users/marcingrzejszczak/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/marcingrzejszczak/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/marcingrzejszczak/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/marcingrzejszczak/subscriptions\",\"organizations_url\":\"https://api.github.com/users/marcingrzejszczak/orgs\",\"repos_url\":\"https://api.github.com/users/marcingrzejszczak/repos\",\"events_url\":\"https://api.github.com/users/marcingrzejszczak/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/marcingrzejszczak/received_events\",\"type\":\"Organization\",\"site_admin\":false},\"html_url\":\"https://github.com/marcingrzejszczak/spring-cloud-contract\",\"description\":\"Support for Consumer Driven Contracts in Spring\",\"fork\":false,\"url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract\",\"forks_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/forks\",\"keys_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/teams\",\"hooks_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/hooks\",\"issue_events_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/events\",\"assignees_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/tags\",\"blobs_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/languages\",\"stargazers_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/stargazers\",\"contributors_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/contributors\",\"subscribers_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/subscribers\",\"subscription_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/subscription\",\"commits_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/merges\",\"archive_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/downloads\",\"issues_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/deployments\",\"created_at\":\"2016-06-12T17:11:44Z\",\"updated_at\":\"2023-06-20T14:45:01Z\",\"pushed_at\":\"2023-07-03T05:05:52Z\",\"git_url\":\"git://github.com/marcingrzejszczak/spring-cloud-contract.git\",\"ssh_url\":\"git@github.com:marcingrzejszczak/spring-cloud-contract.git\",\"clone_url\":\"https://github.com/marcingrzejszczak/spring-cloud-contract.git\",\"svn_url\":\"https://github.com/marcingrzejszczak/spring-cloud-contract\",\"homepage\":\"https://cloud.spring.io/spring-cloud-contract\",\"size\":134011,\"stargazers_count\":681,\"watchers_count\":681,\"language\":\"Java\",\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":true,\"has_discussions\":false,\"forks_count\":417,\"mirror_url\":null,\"archived\":false,\"disabled\":false,\"open_issues_count\":72,\"license\":{\"key\":\"apache-2.0\",\"name\":\"Apache License 2.0\",\"spdx_id\":\"Apache-2.0\",\"url\":\"https://api.github.com/licenses/apache-2.0\",\"node_id\":\"MDc6TGljZW5zZTI=\"},\"allow_forking\":true,\"is_template\":false,\"web_commit_signoff_required\":false,\"topics\":[\"cloud-native\",\"consumer-driven-contracts\",\"java\",\"microservices\",\"spring\",\"spring-boot\",\"spring-cloud\",\"spring-cloud-core\",\"testing\"],\"visibility\":\"public\",\"forks\":417,\"open_issues\":72,\"watchers\":681,\"default_branch\":\"main\",\"permissions\":{\"admin\":true,\"maintain\":true,\"push\":true,\"triage\":true,\"pull\":true},\"temp_clone_token\":\"\",\"allow_squash_merge\":true,\"allow_merge_commit\":true,\"allow_rebase_merge\":true,\"allow_auto_merge\":false,\"delete_branch_on_merge\":false,\"allow_update_branch\":false,\"use_squash_pr_title_as_default\":false,\"squash_merge_commit_message\":\"COMMIT_MESSAGES\",\"squash_merge_commit_title\":\"COMMIT_OR_PR_TITLE\",\"merge_commit_message\":\"PR_TITLE\",\"merge_commit_title\":\"MERGE_MESSAGE\",\"organization\":{\"login\":\"spring-cloud\",\"id\":7815877,\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjc4MTU4Nzc=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/7815877?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/spring-cloud\",\"html_url\":\"https://github.com/spring-cloud\",\"followers_url\":\"https://api.github.com/users/marcingrzejszczak/followers\",\"following_url\":\"https://api.github.com/users/marcingrzejszczak/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/marcingrzejszczak/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/marcingrzejszczak/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/marcingrzejszczak/subscriptions\",\"organizations_url\":\"https://api.github.com/users/marcingrzejszczak/orgs\",\"repos_url\":\"https://api.github.com/users/marcingrzejszczak/repos\",\"events_url\":\"https://api.github.com/users/marcingrzejszczak/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/marcingrzejszczak/received_events\",\"type\":\"Organization\",\"site_admin\":false},\"security_and_analysis\":{\"secret_scanning\":{\"status\":\"enabled\"},\"secret_scanning_push_protection\":{\"status\":\"disabled\"},\"dependabot_security_updates\":{\"status\":\"enabled\"}},\"network_count\":417,\"subscribers_count\":42}" + }, + "uuid" : "c46099cb-2d70-4432-8883-dc240cc51269", + "persistent" : true, + "insertionIndex" : 13 +} + diff --git a/releaser-core/src/test/resources/mappings/github/repos_spring-cloud_spring-cloud-contract_releases-51824e73-a0f3-48f0-85d4-0cc0f48c70f5.json b/releaser-core/src/test/resources/mappings/github/repos_spring-cloud_spring-cloud-contract_releases-51824e73-a0f3-48f0-85d4-0cc0f48c70f5.json new file mode 100644 index 00000000..78d90e95 --- /dev/null +++ b/releaser-core/src/test/resources/mappings/github/repos_spring-cloud_spring-cloud-contract_releases-51824e73-a0f3-48f0-85d4-0cc0f48c70f5.json @@ -0,0 +1,21 @@ +{ + "id" : "51824e73-a0f3-48f0-85d4-0cc0f48c70f5", + "name" : "repos_spring-cloud_spring-cloud-contract_releases", + "request" : { + "url" : "/repos/marcingrzejszczak/spring-cloud-contract/releases", + "method" : "POST", + "bodyPatterns" : [ { + "equalToJson" : "{\"tag_name\":\"v3.1.8\",\"name\":\"3.1.8\",\"body\":\"FOOOO\"}", + "ignoreArrayOrder" : true, + "ignoreExtraElements" : true + } ] + }, + "response" : { + "status" : 201, + "body" : "{\"url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/releases/110836354\",\"assets_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/releases/110836354/assets\",\"upload_url\":\"https://uploads.github.com/repos/marcingrzejszczak/spring-cloud-contract/releases/110836354/assets{?name,label}\",\"html_url\":\"https://github.com/marcingrzejszczak/spring-cloud-contract/releases/tag/v3.1.8\",\"id\":110836354,\"author\":{\"login\":\"marcingrzejszczak\",\"id\":3297437,\"node_id\":\"MDQ6VXNlcjMyOTc0Mzc=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/3297437?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/marcingrzejszczak\",\"html_url\":\"https://github.com/marcingrzejszczak\",\"followers_url\":\"https://api.github.com/users/marcingrzejszczak/followers\",\"following_url\":\"https://api.github.com/users/marcingrzejszczak/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/marcingrzejszczak/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/marcingrzejszczak/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/marcingrzejszczak/subscriptions\",\"organizations_url\":\"https://api.github.com/users/marcingrzejszczak/orgs\",\"repos_url\":\"https://api.github.com/users/marcingrzejszczak/repos\",\"events_url\":\"https://api.github.com/users/marcingrzejszczak/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/marcingrzejszczak/received_events\",\"type\":\"User\",\"site_admin\":false},\"node_id\":\"RE_kwDOA6J4xc4GmzqC\",\"tag_name\":\"v3.1.8\",\"target_commitish\":\"main\",\"name\":\"3.1.8\",\"draft\":false,\"prerelease\":false,\"created_at\":\"2023-06-29T13:38:36Z\",\"published_at\":\"2023-07-03T09:24:59Z\",\"assets\":[],\"tarball_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/tarball/v3.1.8\",\"zipball_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-contract/zipball/v3.1.8\",\"body\":\"FOOOO\",\"mentions_count\":1}" + }, + "uuid" : "51824e73-a0f3-48f0-85d4-0cc0f48c70f5", + "persistent" : true, + "insertionIndex" : 14 +} + diff --git a/releaser-core/src/test/resources/mappings/github/repos_spring-cloud_spring-cloud-release-7b47dc75-72e1-40fb-94dd-b800a6ece12a.json b/releaser-core/src/test/resources/mappings/github/repos_spring-cloud_spring-cloud-release-7b47dc75-72e1-40fb-94dd-b800a6ece12a.json new file mode 100644 index 00000000..bc53fc87 --- /dev/null +++ b/releaser-core/src/test/resources/mappings/github/repos_spring-cloud_spring-cloud-release-7b47dc75-72e1-40fb-94dd-b800a6ece12a.json @@ -0,0 +1,16 @@ +{ + "id" : "7b47dc75-72e1-40fb-94dd-b800a6ece12a", + "name" : "repos_spring-cloud_spring-cloud-release", + "request" : { + "url" : "/repos/marcingrzejszczak/spring-cloud-release", + "method" : "GET" + }, + "response" : { + "status" : 200, + "body" : "{\"id\":22482664,\"node_id\":\"MDEwOlJlcG9zaXRvcnkyMjQ4MjY2NA==\",\"name\":\"spring-cloud-release\",\"full_name\":\"marcingrzejszczak/spring-cloud-release\",\"private\":false,\"owner\":{\"login\":\"spring-cloud\",\"id\":7815877,\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjc4MTU4Nzc=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/7815877?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/spring-cloud\",\"html_url\":\"https://github.com/spring-cloud\",\"followers_url\":\"https://api.github.com/users/marcingrzejszczak/followers\",\"following_url\":\"https://api.github.com/users/marcingrzejszczak/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/marcingrzejszczak/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/marcingrzejszczak/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/marcingrzejszczak/subscriptions\",\"organizations_url\":\"https://api.github.com/users/marcingrzejszczak/orgs\",\"repos_url\":\"https://api.github.com/users/marcingrzejszczak/repos\",\"events_url\":\"https://api.github.com/users/marcingrzejszczak/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/marcingrzejszczak/received_events\",\"type\":\"Organization\",\"site_admin\":false},\"html_url\":\"https://github.com/marcingrzejszczak/spring-cloud-release\",\"description\":\"Spring Cloud Release Train - dependency management across a wide range of Spring Cloud projects.\",\"fork\":false,\"url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release\",\"forks_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/forks\",\"keys_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/teams\",\"hooks_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/hooks\",\"issue_events_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/events\",\"assignees_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/tags\",\"blobs_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/languages\",\"stargazers_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/stargazers\",\"contributors_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/contributors\",\"subscribers_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/subscribers\",\"subscription_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/subscription\",\"commits_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/merges\",\"archive_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/downloads\",\"issues_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/deployments\",\"created_at\":\"2014-07-31T19:52:26Z\",\"updated_at\":\"2023-06-28T16:49:45Z\",\"pushed_at\":\"2023-06-30T16:26:11Z\",\"git_url\":\"git://github.com/marcingrzejszczak/spring-cloud-release.git\",\"ssh_url\":\"git@github.com:marcingrzejszczak/spring-cloud-release.git\",\"clone_url\":\"https://github.com/marcingrzejszczak/spring-cloud-release.git\",\"svn_url\":\"https://github.com/marcingrzejszczak/spring-cloud-release\",\"homepage\":\"http://projects.spring.io/spring-cloud\",\"size\":3253,\"stargazers_count\":801,\"watchers_count\":801,\"language\":\"Java\",\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":true,\"has_discussions\":false,\"forks_count\":171,\"mirror_url\":null,\"archived\":false,\"disabled\":false,\"open_issues_count\":6,\"license\":{\"key\":\"apache-2.0\",\"name\":\"Apache License 2.0\",\"spdx_id\":\"Apache-2.0\",\"url\":\"https://api.github.com/licenses/apache-2.0\",\"node_id\":\"MDc6TGljZW5zZTI=\"},\"allow_forking\":true,\"is_template\":false,\"web_commit_signoff_required\":false,\"topics\":[\"cloud-native\",\"java\",\"microservices\",\"spring\",\"spring-boot\",\"spring-cloud\",\"spring-cloud-core\"],\"visibility\":\"public\",\"forks\":171,\"open_issues\":6,\"watchers\":801,\"default_branch\":\"main\",\"permissions\":{\"admin\":true,\"maintain\":true,\"push\":true,\"triage\":true,\"pull\":true},\"temp_clone_token\":\"\",\"allow_squash_merge\":true,\"allow_merge_commit\":true,\"allow_rebase_merge\":true,\"allow_auto_merge\":false,\"delete_branch_on_merge\":false,\"allow_update_branch\":false,\"use_squash_pr_title_as_default\":false,\"squash_merge_commit_message\":\"COMMIT_MESSAGES\",\"squash_merge_commit_title\":\"COMMIT_OR_PR_TITLE\",\"merge_commit_message\":\"PR_TITLE\",\"merge_commit_title\":\"MERGE_MESSAGE\",\"organization\":{\"login\":\"spring-cloud\",\"id\":7815877,\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjc4MTU4Nzc=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/7815877?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/spring-cloud\",\"html_url\":\"https://github.com/spring-cloud\",\"followers_url\":\"https://api.github.com/users/marcingrzejszczak/followers\",\"following_url\":\"https://api.github.com/users/marcingrzejszczak/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/marcingrzejszczak/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/marcingrzejszczak/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/marcingrzejszczak/subscriptions\",\"organizations_url\":\"https://api.github.com/users/marcingrzejszczak/orgs\",\"repos_url\":\"https://api.github.com/users/marcingrzejszczak/repos\",\"events_url\":\"https://api.github.com/users/marcingrzejszczak/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/marcingrzejszczak/received_events\",\"type\":\"Organization\",\"site_admin\":false},\"security_and_analysis\":{\"secret_scanning\":{\"status\":\"enabled\"},\"secret_scanning_push_protection\":{\"status\":\"disabled\"},\"dependabot_security_updates\":{\"status\":\"enabled\"}},\"network_count\":171,\"subscribers_count\":128}" + }, + "uuid" : "7b47dc75-72e1-40fb-94dd-b800a6ece12a", + "persistent" : true, + "insertionIndex" : 19 +} + diff --git a/releaser-core/src/test/resources/mappings/github/repos_spring-cloud_spring-cloud-release_releases-d5590618-183a-41f8-affb-df6ce0a52903.json b/releaser-core/src/test/resources/mappings/github/repos_spring-cloud_spring-cloud-release_releases-d5590618-183a-41f8-affb-df6ce0a52903.json new file mode 100644 index 00000000..56a00ce7 --- /dev/null +++ b/releaser-core/src/test/resources/mappings/github/repos_spring-cloud_spring-cloud-release_releases-d5590618-183a-41f8-affb-df6ce0a52903.json @@ -0,0 +1,20 @@ +{ + "id" : "d5590618-183a-41f8-affb-df6ce0a52903", + "name" : "repos_spring-cloud_spring-cloud-release_releases", + "request" : { + "url" : "/repos/marcingrzejszczak/spring-cloud-release/releases", + "method" : "POST", + "bodyPatterns" : [ { + "equalToJson" : "{\"tag_name\":\"v2021.0.8\",\"name\":\"2021.0.8\",\"body\":\"## :star: Releases\\n\\n- spring-cloud-build [3.1.8](https://github.com/marcingrzejszczak/spring-cloud-build/releases/tag/v3.1.8)\\n- spring-cloud-bus [3.1.2](https://github.com/marcingrzejszczak/spring-cloud-bus/releases/tag/v3.1.2)\\n- spring-cloud-circuitbreaker [2.1.7](https://github.com/marcingrzejszczak/spring-cloud-circuitbreaker/releases/tag/v2.1.7)\\n- spring-cloud-cli [3.1.1](https://github.com/marcingrzejszczak/spring-cloud-cli/releases/tag/v3.1.1)\\n- spring-cloud-cloudfoundry [3.1.3](https://github.com/marcingrzejszczak/spring-cloud-cloudfoundry/releases/tag/v3.1.3)\\n- spring-cloud-commons [3.1.7](https://github.com/marcingrzejszczak/spring-cloud-commons/releases/tag/v3.1.7)\\n- spring-cloud-config [3.1.8](https://github.com/marcingrzejszczak/spring-cloud-config/releases/tag/v3.1.8)\\n- spring-cloud-consul [3.1.4](https://github.com/marcingrzejszczak/spring-cloud-consul/releases/tag/v3.1.4)\\n- spring-cloud-contract [3.1.8](https://github.com/marcingrzejszczak/spring-cloud-contract/releases/tag/v3.1.8)\\n- spring-cloud-function [3.2.11](https://github.com/marcingrzejszczak/spring-cloud-function/releases/tag/v3.2.11)\\n- spring-cloud-gateway [3.1.8](https://github.com/marcingrzejszczak/spring-cloud-gateway/releases/tag/v3.1.8)\\n- spring-cloud-kubernetes [2.1.8](https://github.com/marcingrzejszczak/spring-cloud-kubernetes/releases/tag/v2.1.8)\\n- spring-cloud-netflix [3.1.7](https://github.com/marcingrzejszczak/spring-cloud-netflix/releases/tag/v3.1.7)\\n- spring-cloud-openfeign [3.1.8](https://github.com/marcingrzejszczak/spring-cloud-openfeign/releases/tag/v3.1.8)\\n- spring-cloud-sleuth [3.1.9](https://github.com/marcingrzejszczak/spring-cloud-sleuth/releases/tag/v3.1.9)\\n- spring-cloud-stream [3.2.9](https://github.com/marcingrzejszczak/spring-cloud-stream/releases/tag/v3.2.9)\\n- spring-cloud-task [2.4.6](https://github.com/marcingrzejszczak/spring-cloud-task/releases/tag/v2.4.6)\\n- spring-cloud-vault [3.1.3](https://github.com/marcingrzejszczak/spring-cloud-vault/releases/tag/v3.1.3)\\n- spring-cloud-zookeeper [3.1.4](https://github.com/marcingrzejszczak/spring-cloud-zookeeper/releases/tag/v3.1.4)\"}", + "ignoreArrayOrder" : true, + "ignoreExtraElements" : true + } ] + }, + "response" : { + "status" : 201, + "body" : "{\"url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/releases/110837728\",\"assets_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/releases/110837728/assets\",\"upload_url\":\"https://uploads.github.com/repos/marcingrzejszczak/spring-cloud-release/releases/110837728/assets{?name,label}\",\"html_url\":\"https://github.com/marcingrzejszczak/spring-cloud-release/releases/tag/v2021.0.8\",\"id\":110837728,\"author\":{\"login\":\"marcingrzejszczak\",\"id\":3297437,\"node_id\":\"MDQ6VXNlcjMyOTc0Mzc=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/3297437?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/marcingrzejszczak\",\"html_url\":\"https://github.com/marcingrzejszczak\",\"followers_url\":\"https://api.github.com/users/marcingrzejszczak/followers\",\"following_url\":\"https://api.github.com/users/marcingrzejszczak/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/marcingrzejszczak/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/marcingrzejszczak/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/marcingrzejszczak/subscriptions\",\"organizations_url\":\"https://api.github.com/users/marcingrzejszczak/orgs\",\"repos_url\":\"https://api.github.com/users/marcingrzejszczak/repos\",\"events_url\":\"https://api.github.com/users/marcingrzejszczak/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/marcingrzejszczak/received_events\",\"type\":\"User\",\"site_admin\":false},\"node_id\":\"RE_kwDOAVcO6M4Gmz_g\",\"tag_name\":\"v2021.0.8\",\"target_commitish\":\"main\",\"name\":\"2021.0.8\",\"draft\":false,\"prerelease\":false,\"created_at\":\"2023-06-29T14:46:01Z\",\"published_at\":\"2023-07-03T09:36:59Z\",\"assets\":[],\"tarball_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/tarball/v2021.0.8\",\"zipball_url\":\"https://api.github.com/repos/marcingrzejszczak/spring-cloud-release/zipball/v2021.0.8\",\"body\":\"## :star: Releases\\n\\n- spring-cloud-build [3.1.8](https://github.com/marcingrzejszczak/spring-cloud-build/releases/tag/v3.1.8)\\n- spring-cloud-bus [3.1.2](https://github.com/marcingrzejszczak/spring-cloud-bus/releases/tag/v3.1.2)\\n- spring-cloud-circuitbreaker [2.1.7](https://github.com/marcingrzejszczak/spring-cloud-circuitbreaker/releases/tag/v2.1.7)\\n- spring-cloud-cli [3.1.1](https://github.com/marcingrzejszczak/spring-cloud-cli/releases/tag/v3.1.1)\\n- spring-cloud-cloudfoundry [3.1.3](https://github.com/marcingrzejszczak/spring-cloud-cloudfoundry/releases/tag/v3.1.3)\\n- spring-cloud-commons [3.1.7](https://github.com/marcingrzejszczak/spring-cloud-commons/releases/tag/v3.1.7)\\n- spring-cloud-config [3.1.8](https://github.com/marcingrzejszczak/spring-cloud-config/releases/tag/v3.1.8)\\n- spring-cloud-consul [3.1.4](https://github.com/marcingrzejszczak/spring-cloud-consul/releases/tag/v3.1.4)\\n- spring-cloud-contract [3.1.8](https://github.com/marcingrzejszczak/spring-cloud-contract/releases/tag/v3.1.8)\\n- spring-cloud-function [3.2.11](https://github.com/marcingrzejszczak/spring-cloud-function/releases/tag/v3.2.11)\\n- spring-cloud-gateway [3.1.8](https://github.com/marcingrzejszczak/spring-cloud-gateway/releases/tag/v3.1.8)\\n- spring-cloud-kubernetes [2.1.8](https://github.com/marcingrzejszczak/spring-cloud-kubernetes/releases/tag/v2.1.8)\\n- spring-cloud-netflix [3.1.7](https://github.com/marcingrzejszczak/spring-cloud-netflix/releases/tag/v3.1.7)\\n- spring-cloud-openfeign [3.1.8](https://github.com/marcingrzejszczak/spring-cloud-openfeign/releases/tag/v3.1.8)\\n- spring-cloud-sleuth [3.1.9](https://github.com/marcingrzejszczak/spring-cloud-sleuth/releases/tag/v3.1.9)\\n- spring-cloud-stream [3.2.9](https://github.com/marcingrzejszczak/spring-cloud-stream/releases/tag/v3.2.9)\\n- spring-cloud-task [2.4.6](https://github.com/marcingrzejszczak/spring-cloud-task/releases/tag/v2.4.6)\\n- spring-cloud-vault [3.1.3](https://github.com/marcingrzejszczak/spring-cloud-vault/releases/tag/v3.1.3)\\n- spring-cloud-zookeeper [3.1.4](https://github.com/marcingrzejszczak/spring-cloud-zookeeper/releases/tag/v3.1.4)\"}" + }, + "uuid" : "d5590618-183a-41f8-affb-df6ce0a52903", + "persistent" : true, + "insertionIndex" : 20 +}