Skip to content

Commit 4865c23

Browse files
committed
Merge branch '2.3.x' into 2.4.x
Closes gh-25695
2 parents 2560f26 + bf33e7e commit 4865c23

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
@@ -23,6 +23,7 @@
2323
import java.nio.file.Path;
2424
import java.util.ArrayList;
2525
import java.util.Arrays;
26+
import java.util.LinkedHashSet;
2627
import java.util.List;
2728
import java.util.Optional;
2829
import java.util.Properties;
@@ -41,6 +42,7 @@
4142
import org.springframework.boot.build.bom.BomExtension;
4243
import org.springframework.boot.build.bom.bomr.github.GitHub;
4344
import org.springframework.boot.build.bom.bomr.github.GitHubRepository;
45+
import org.springframework.boot.build.bom.bomr.github.Issue;
4446
import org.springframework.boot.build.bom.bomr.github.Milestone;
4547
import org.springframework.util.StringUtils;
4648

@@ -83,6 +85,7 @@ void upgradeDependencies() {
8385
"Unknown label(s): " + StringUtils.collectionToCommaDelimitedString(unknownLabels));
8486
}
8587
Milestone milestone = determineMilestone(repository);
88+
List<Issue> existingUpgradeIssues = repository.findIssues(issueLabels, milestone);
8689
List<Upgrade> upgrades = new InteractiveUpgradeResolver(
8790
new MavenMetadataVersionResolver(Arrays.asList("https://repo1.maven.org/maven2/")),
8891
this.bom.getUpgrade().getPolicy(), getServices().get(UserInputHandler.class))
@@ -92,10 +95,22 @@ void upgradeDependencies() {
9295
UpgradeApplicator upgradeApplicator = new UpgradeApplicator(buildFile, gradleProperties);
9396
for (Upgrade upgrade : upgrades) {
9497
String title = "Upgrade to " + upgrade.getLibrary().getName() + " " + upgrade.getVersion();
95-
System.out.println(title);
98+
Issue existingUpgradeIssue = findExistingUpgradeIssue(existingUpgradeIssues, upgrade);
99+
if (existingUpgradeIssue != null) {
100+
System.out.println(title + " (supersedes #" + existingUpgradeIssue.getNumber() + " "
101+
+ existingUpgradeIssue.getTitle() + ")");
102+
}
103+
else {
104+
System.out.println(title);
105+
}
96106
try {
97107
Path modified = upgradeApplicator.apply(upgrade);
98-
int issueNumber = repository.openIssue(title, issueLabels, milestone);
108+
int issueNumber = repository.openIssue(title,
109+
(existingUpgradeIssue != null) ? "Supersedes #" + existingUpgradeIssue.getNumber() : "",
110+
issueLabels, milestone);
111+
if (existingUpgradeIssue != null) {
112+
existingUpgradeIssue.label(Arrays.asList("type: task", "status: superseded"));
113+
}
99114
if (new ProcessBuilder().command("git", "add", modified.toFile().getAbsolutePath()).start()
100115
.waitFor() != 0) {
101116
throw new IllegalStateException("git add failed");
@@ -114,6 +129,17 @@ void upgradeDependencies() {
114129
}
115130
}
116131

132+
private Issue findExistingUpgradeIssue(List<Issue> existingUpgradeIssues, Upgrade upgrade) {
133+
String toMatch = "Upgrade to " + upgrade.getLibrary().getName();
134+
for (Issue existingUpgradeIssue : existingUpgradeIssues) {
135+
if (existingUpgradeIssue.getTitle().substring(0, existingUpgradeIssue.getTitle().lastIndexOf(' '))
136+
.equals(toMatch)) {
137+
return existingUpgradeIssue;
138+
}
139+
}
140+
return null;
141+
}
142+
117143
private GitHub createGitHub() {
118144
Properties bomrProperties = new Properties();
119145
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)