1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.changes.github;
20
21 import java.io.IOException;
22 import java.net.MalformedURLException;
23 import java.net.URL;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.List;
27
28 import org.apache.maven.plugin.logging.Log;
29 import org.apache.maven.plugins.changes.issues.Issue;
30 import org.apache.maven.project.MavenProject;
31 import org.apache.maven.settings.Server;
32 import org.apache.maven.settings.Settings;
33 import org.apache.maven.settings.building.SettingsProblem;
34 import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
35 import org.apache.maven.settings.crypto.SettingsDecrypter;
36 import org.apache.maven.settings.crypto.SettingsDecryptionResult;
37 import org.kohsuke.github.GHIssue;
38 import org.kohsuke.github.GHIssueState;
39 import org.kohsuke.github.GHLabel;
40 import org.kohsuke.github.GitHubBuilder;
41
42
43
44
45 public class GitHubDownloader {
46
47
48
49
50 private GitHubBuilder client;
51
52
53
54
55 private boolean includeOpenIssues;
56
57
58
59
60 private boolean onlyMilestoneIssues;
61
62
63
64
65 private String githubOwner;
66
67
68
69
70 private String githubRepo;
71
72
73
74
75 private String githubIssueURL;
76
77 public GitHubDownloader(MavenProject project, boolean includeOpenIssues, boolean onlyMilestoneIssues)
78 throws IOException {
79 this.includeOpenIssues = includeOpenIssues;
80 this.onlyMilestoneIssues = onlyMilestoneIssues;
81
82 URL githubURL = new URL(project.getIssueManagement().getUrl());
83
84
85
86 if (githubURL.getHost().equalsIgnoreCase("github.com")) {
87 this.client = new GitHubBuilder();
88 } else {
89 this.client = new GitHubBuilder()
90 .withEndpoint(githubURL.getProtocol() + "://" + githubURL.getHost()
91 + (githubURL.getPort() == -1 ? "" : ":" + githubURL.getPort()));
92 }
93
94 this.githubIssueURL = project.getIssueManagement().getUrl();
95 if (!this.githubIssueURL.endsWith("/")) {
96 this.githubIssueURL = this.githubIssueURL + "/";
97 }
98
99 String urlPath = githubURL.getPath();
100 if (urlPath.startsWith("/")) {
101 urlPath = urlPath.substring(1);
102 }
103
104 if (urlPath.endsWith("/")) {
105 urlPath = urlPath.substring(0, urlPath.length() - 2);
106 }
107
108 String[] urlPathParts = urlPath.split("/");
109
110 if (urlPathParts.length != 3) {
111 throw new MalformedURLException(
112 "GitHub issue management URL must look like, " + "[GITHUB_DOMAIN]/[OWNER]/[REPO]/issues");
113 }
114
115 this.githubOwner = urlPathParts[0];
116 this.githubRepo = urlPathParts[1];
117 }
118
119 protected Issue createIssue(GHIssue githubIssue) throws IOException {
120 Issue issue = new Issue();
121
122 issue.setKey(String.valueOf(githubIssue.getNumber()));
123 issue.setId(String.valueOf(githubIssue.getNumber()));
124
125 issue.setLink(this.githubIssueURL + githubIssue.getNumber());
126
127 issue.setCreated(githubIssue.getCreatedAt());
128
129 issue.setUpdated(githubIssue.getUpdatedAt());
130
131 if (githubIssue.getAssignee() != null) {
132 if (githubIssue.getAssignee().getName() != null) {
133 issue.setAssignee(githubIssue.getAssignee().getName());
134 } else {
135 issue.setAssignee(githubIssue.getAssignee().getLogin());
136 }
137 }
138
139 issue.setSummary(githubIssue.getTitle());
140
141 if (githubIssue.getMilestone() != null) {
142 issue.addFixVersion(githubIssue.getMilestone().getTitle());
143 }
144
145 issue.setReporter(githubIssue.getUser().getLogin());
146
147 issue.setStatus(githubIssue.getState().name());
148
149 final Collection<GHLabel> labels = githubIssue.getLabels();
150 if (labels != null && !labels.isEmpty()) {
151 issue.setType(labels.stream().findAny().get().getName());
152 }
153
154 return issue;
155 }
156
157 public List<Issue> getIssueList() throws IOException {
158 List<Issue> issueList = new ArrayList<>();
159
160 if (includeOpenIssues) {
161 final List<GHIssue> openIssues =
162 client.build().getRepository(githubOwner + "/" + githubRepo).getIssues(GHIssueState.OPEN);
163 for (final GHIssue issue : openIssues) {
164 if (!onlyMilestoneIssues || issue.getMilestone() != null) {
165 issueList.add(createIssue(issue));
166 }
167 }
168 }
169
170 final List<GHIssue> closedIssues =
171 client.build().getRepository(githubOwner + "/" + githubRepo).getIssues(GHIssueState.CLOSED);
172
173 for (final GHIssue issue : closedIssues) {
174 if (!onlyMilestoneIssues || issue.getMilestone() != null) {
175 issueList.add(createIssue(issue));
176 }
177 }
178
179 return issueList;
180 }
181
182 public void configureAuthentication(
183 SettingsDecrypter decrypter, String githubAPIServerId, Settings settings, Log log) {
184 boolean configured = false;
185
186 List<Server> servers = settings.getServers();
187
188 for (Server server : servers) {
189 if (server.getId().equals(githubAPIServerId)) {
190 SettingsDecryptionResult result = decrypter.decrypt(new DefaultSettingsDecryptionRequest(server));
191 for (SettingsProblem problem : result.getProblems()) {
192 log.error(problem.getMessage(), problem.getException());
193 }
194 server = result.getServer();
195 String password = server.getPassword();
196 client.withJwtToken(password);
197
198 configured = true;
199 break;
200 }
201 }
202
203 if (!configured) {
204 log.warn("Can't find server id [" + githubAPIServerId + "] configured in settings.xml");
205 }
206 }
207 }