Skip to content

Commit 4ed1cbf

Browse files
committed
Merge branch '2.4.x'
Closes gh-25696
2 parents 21c7df9 + 4865c23 commit 4ed1cbf

File tree

4 files changed

+117
-11
lines changed

4 files changed

+117
-11
lines changed

buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/UpgradeBom.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.io.Reader;
2323
import java.nio.file.Path;
2424
import java.util.ArrayList;
25+
import java.util.Arrays;
2526
import java.util.LinkedHashSet;
2627
import java.util.List;
2728
import java.util.Optional;
@@ -43,6 +44,7 @@
4344
import org.springframework.boot.build.bom.BomExtension;
4445
import org.springframework.boot.build.bom.bomr.github.GitHub;
4546
import org.springframework.boot.build.bom.bomr.github.GitHubRepository;
47+
import org.springframework.boot.build.bom.bomr.github.Issue;
4648
import org.springframework.boot.build.bom.bomr.github.Milestone;
4749
import org.springframework.util.StringUtils;
4850

@@ -94,6 +96,7 @@ void upgradeDependencies() {
9496
"Unknown label(s): " + StringUtils.collectionToCommaDelimitedString(unknownLabels));
9597
}
9698
Milestone milestone = determineMilestone(repository);
99+
List<Issue> existingUpgradeIssues = repository.findIssues(issueLabels, milestone);
97100
List<Upgrade> upgrades = new InteractiveUpgradeResolver(new MavenMetadataVersionResolver(this.repositoryUrls),
98101
this.bom.getUpgrade().getPolicy(), getServices().get(UserInputHandler.class))
99102
.resolveUpgrades(this.bom.getLibraries());
@@ -102,10 +105,22 @@ void upgradeDependencies() {
102105
UpgradeApplicator upgradeApplicator = new UpgradeApplicator(buildFile, gradleProperties);
103106
for (Upgrade upgrade : upgrades) {
104107
String title = "Upgrade to " + upgrade.getLibrary().getName() + " " + upgrade.getVersion();
105-
System.out.println(title);
108+
Issue existingUpgradeIssue = findExistingUpgradeIssue(existingUpgradeIssues, upgrade);
109+
if (existingUpgradeIssue != null) {
110+
System.out.println(title + " (supersedes #" + existingUpgradeIssue.getNumber() + " "
111+
+ existingUpgradeIssue.getTitle() + ")");
112+
}
113+
else {
114+
System.out.println(title);
115+
}
106116
try {
107117
Path modified = upgradeApplicator.apply(upgrade);
108-
int issueNumber = repository.openIssue(title, issueLabels, milestone);
118+
int issueNumber = repository.openIssue(title,
119+
(existingUpgradeIssue != null) ? "Supersedes #" + existingUpgradeIssue.getNumber() : "",
120+
issueLabels, milestone);
121+
if (existingUpgradeIssue != null) {
122+
existingUpgradeIssue.label(Arrays.asList("type: task", "status: superseded"));
123+
}
109124
if (new ProcessBuilder().command("git", "add", modified.toFile().getAbsolutePath()).start()
110125
.waitFor() != 0) {
111126
throw new IllegalStateException("git add failed");
@@ -124,6 +139,17 @@ void upgradeDependencies() {
124139
}
125140
}
126141

142+
private Issue findExistingUpgradeIssue(List<Issue> existingUpgradeIssues, Upgrade upgrade) {
143+
String toMatch = "Upgrade to " + upgrade.getLibrary().getName();
144+
for (Issue existingUpgradeIssue : existingUpgradeIssues) {
145+
if (existingUpgradeIssue.getTitle().substring(0, existingUpgradeIssue.getTitle().lastIndexOf(' '))
146+
.equals(toMatch)) {
147+
return existingUpgradeIssue;
148+
}
149+
}
150+
return null;
151+
}
152+
127153
private GitHub createGitHub() {
128154
Properties bomrProperties = new Properties();
129155
try (Reader reader = new FileReader(new File(System.getProperty("user.home"), ".bomr.properties"))) {

buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/github/GitHubRepository.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -29,11 +29,12 @@ public interface GitHubRepository {
2929
* Opens a new issue with the given title. The given {@code labels} will be applied to
3030
* the issue and it will be assigned to the given {@code milestone}.
3131
* @param title the title of the issue
32+
* @param body the body of the issue
3233
* @param labels the labels to apply to the issue
3334
* @param milestone the milestone to assign the issue to
3435
* @return the number of the new issue
3536
*/
36-
int openIssue(String title, List<String> labels, Milestone milestone);
37+
int openIssue(String title, String body, List<String> labels, Milestone milestone);
3738

3839
/**
3940
* Returns the labels in the repository.
@@ -47,4 +48,13 @@ public interface GitHubRepository {
4748
*/
4849
List<Milestone> getMilestones();
4950

51+
/**
52+
* Finds issues that have the given {@code labels} and are assigned to the given
53+
* {@code milestone}.
54+
* @param labels issue labels
55+
* @param milestone assigned milestone
56+
* @return the matching issues
57+
*/
58+
List<Issue> findIssues(List<String> labels, Milestone milestone);
59+
5060
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2012-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.build.bom.bomr.github;
18+
19+
import java.util.Collections;
20+
import java.util.List;
21+
import java.util.Map;
22+
23+
import org.springframework.web.client.RestTemplate;
24+
25+
/**
26+
* Minimal representation of a GitHub issue.
27+
*
28+
* @author Andy Wilkinson
29+
*/
30+
public class Issue {
31+
32+
private final RestTemplate rest;
33+
34+
private final int number;
35+
36+
private final String title;
37+
38+
Issue(RestTemplate rest, int number, String title) {
39+
this.rest = rest;
40+
this.number = number;
41+
this.title = title;
42+
}
43+
44+
public int getNumber() {
45+
return this.number;
46+
}
47+
48+
public String getTitle() {
49+
return this.title;
50+
}
51+
52+
/**
53+
* Labels the issue with the given {@code labels}. Any existing labels are removed.
54+
* @param labels the labels to apply to the issue
55+
*/
56+
public void label(List<String> labels) {
57+
Map<String, List<String>> body = Collections.singletonMap("labels", labels);
58+
this.rest.put("issues/" + this.number + "/labels", body);
59+
}
60+
61+
}

buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/github/StandardGitHubRepository.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -40,16 +40,17 @@ final class StandardGitHubRepository implements GitHubRepository {
4040

4141
@Override
4242
@SuppressWarnings("rawtypes")
43-
public int openIssue(String title, List<String> labels, Milestone milestone) {
44-
Map<String, Object> body = new HashMap<>();
45-
body.put("title", title);
43+
public int openIssue(String title, String body, List<String> labels, Milestone milestone) {
44+
Map<String, Object> requestBody = new HashMap<>();
45+
requestBody.put("title", title);
4646
if (milestone != null) {
47-
body.put("milestone", milestone.getNumber());
47+
requestBody.put("milestone", milestone.getNumber());
4848
}
4949
if (!labels.isEmpty()) {
50-
body.put("labels", labels);
50+
requestBody.put("labels", labels);
5151
}
52-
ResponseEntity<Map> response = this.rest.postForEntity("issues", body, Map.class);
52+
requestBody.put("body", body);
53+
ResponseEntity<Map> response = this.rest.postForEntity("issues", requestBody, Map.class);
5354
return (Integer) response.getBody().get("number");
5455
}
5556

@@ -64,6 +65,14 @@ public List<Milestone> getMilestones() {
6465
(milestone) -> new Milestone((String) milestone.get("title"), (Integer) milestone.get("number")));
6566
}
6667

68+
@Override
69+
public List<Issue> findIssues(List<String> labels, Milestone milestone) {
70+
return get(
71+
"issues?per_page=100&state=all&labels=" + String.join(",", labels) + "&milestone="
72+
+ milestone.getNumber(),
73+
(issue) -> new Issue(this.rest, (Integer) issue.get("number"), (String) issue.get("title")));
74+
}
75+
6776
@SuppressWarnings({ "rawtypes", "unchecked" })
6877
private <T> List<T> get(String name, Function<Map<String, Object>, T> mapper) {
6978
ResponseEntity<List> response = this.rest.getForEntity(name, List.class);

0 commit comments

Comments
 (0)