Skip to content

Commit cc68edd

Browse files
authored
Search for working gh client. (#199)
* Search for working gh client. Signed-off-by: Kanstantsin Shautsou <kanstantsin.sha@gmail.com> * fixup Signed-off-by: Kanstantsin Shautsou <kanstantsin.sha@gmail.com> * Friendly exception. Signed-off-by: Kanstantsin Shautsou <kanstantsin.sha@gmail.com> * Fix test? Signed-off-by: Kanstantsin Shautsou <kanstantsin.sha@gmail.com> * Root file should exist for LocalData Signed-off-by: Kanstantsin Shautsou <kanstantsin.sha@gmail.com> * Route repo with getGithub() Signed-off-by: Kanstantsin Shautsou <kanstantsin.sha@gmail.com> * Fix test Signed-off-by: Kanstantsin Shautsou <kanstantsin.sha@gmail.com> * WIP * Introduce error reporting to UI Signed-off-by: Kanstantsin Shautsou <kanstantsin.sha@gmail.com> * Rename, refactor Signed-off-by: Kanstantsin Shautsou <kanstantsin.sha@gmail.com> * Checkstyle Signed-off-by: Kanstantsin Shautsou <kanstantsin.sha@gmail.com> * Checkstyle Signed-off-by: Kanstantsin Shautsou <kanstantsin.sha@gmail.com> * Small changes Signed-off-by: Kanstantsin Shautsou <kanstantsin.sha@gmail.com> * More logs Signed-off-by: Kanstantsin Shautsou <kanstantsin.sha@gmail.com>
1 parent 712703a commit cc68edd

18 files changed

Lines changed: 426 additions & 193 deletions

File tree

github-pullrequest-plugin/pom.xml

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
<powermock.version>1.6.0</powermock.version>
4747
<logback.version>1.1.3</logback.version>
4848
<workflow.version>1.14</workflow.version>
49+
<matrix.version>1.6</matrix.version>
4950
<excluded.tests>**/its/*.java</excluded.tests>
5051
<java.level>8</java.level>
5152
</properties>
@@ -102,7 +103,7 @@
102103
<dependency>
103104
<groupId>org.jenkins-ci.plugins</groupId>
104105
<artifactId>matrix-project</artifactId>
105-
<version>1.6</version>
106+
<version>${matrix.version}</version>
106107
</dependency>
107108

108109
<!--for publishers-->
@@ -219,19 +220,19 @@
219220
</dependency>
220221

221222
<!-- tests logging -->
222-
<dependency>
223-
<groupId>ch.qos.logback</groupId>
224-
<artifactId>logback-core</artifactId>
225-
<version>${logback.version}</version>
226-
<scope>test</scope>
227-
</dependency>
223+
<!--<dependency>-->
224+
<!--<groupId>ch.qos.logback</groupId>-->
225+
<!--<artifactId>logback-core</artifactId>-->
226+
<!--<version>${logback.version}</version>-->
227+
<!--<scope>test</scope>-->
228+
<!--</dependency>-->
228229

229-
<dependency>
230-
<groupId>ch.qos.logback</groupId>
231-
<artifactId>logback-classic</artifactId>
232-
<version>${logback.version}</version>
233-
<scope>test</scope>
234-
</dependency>
230+
<!--<dependency>-->
231+
<!--<groupId>ch.qos.logback</groupId>-->
232+
<!--<artifactId>logback-classic</artifactId>-->
233+
<!--<version>${logback.version}</version>-->
234+
<!--<scope>test</scope>-->
235+
<!--</dependency>-->
235236

236237
<dependency>
237238
<groupId>org.codehaus.groovy</groupId>

github-pullrequest-plugin/src/main/java/com/github/kostyasha/github/integration/branch/GitHubBranchTrigger.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.github.kostyasha.github.integration.branch.trigger.JobRunnerForBranchCause;
77
import com.github.kostyasha.github.integration.generic.GitHubTrigger;
88
import com.github.kostyasha.github.integration.generic.GitHubTriggerDescriptor;
9+
import com.github.kostyasha.github.integration.generic.errors.impl.GitHubHookRegistrationError;
910
import hudson.Extension;
1011
import hudson.model.Job;
1112
import hudson.triggers.Trigger;
@@ -113,9 +114,17 @@ public void start(Job<?, ?> job, boolean newInstance) {
113114
LOG.info("Starting GitHub Branch trigger for project {}", job.getFullName());
114115
super.start(job, newInstance);
115116

116-
if (newInstance && getRepoProvider().isManageHooks(this) &&
117-
withHookTriggerMode().apply(job)) {
118-
getRepoProvider().registerHookFor(this);
117+
if (newInstance && getRepoProvider().isManageHooks(this) && withHookTriggerMode().apply(job)) {
118+
try {
119+
getRepoProvider().registerHookFor(this);
120+
getErrorsAction().removeErrors(GitHubHookRegistrationError.class);
121+
} catch (Throwable error) {
122+
getErrorsAction().addOrReplaceError(new GitHubHookRegistrationError(
123+
String.format("Failed register hook for %s. <br/> Because %s",
124+
job.getFullName(), error.toString())
125+
));
126+
throw error;
127+
}
119128
}
120129
}
121130

@@ -290,7 +299,7 @@ public DescriptorImpl() {
290299

291300
@Override
292301
public String getDisplayName() {
293-
return "Experimental: GitHub Branches";
302+
return "GitHub Branches";
294303
}
295304

296305
// list all available descriptors for choosing in job configuration

github-pullrequest-plugin/src/main/java/com/github/kostyasha/github/integration/generic/GitHubTrigger.java

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import antlr.ANTLRException;
44
import com.cloudbees.jenkins.GitHubRepositoryName;
55
import com.coravy.hudson.plugins.github.GithubProjectProperty;
6+
import com.github.kostyasha.github.integration.generic.errors.GitHubErrorsAction;
7+
import com.github.kostyasha.github.integration.generic.errors.impl.GitHubRepoProviderError;
68
import com.github.kostyasha.github.integration.generic.repoprovider.GitHubPluginRepoProvider;
79
import com.google.common.annotations.Beta;
810
import hudson.model.Action;
@@ -17,8 +19,8 @@
1719
import javax.annotation.CheckForNull;
1820
import javax.annotation.Nonnull;
1921
import java.io.IOException;
22+
import java.util.ArrayList;
2023
import java.util.Collection;
21-
import java.util.Collections;
2224
import java.util.List;
2325

2426
import static com.google.common.base.Preconditions.checkNotNull;
@@ -48,8 +50,12 @@ public abstract class GitHubTrigger<T extends GitHubTrigger<T>> extends Trigger<
4850
private List<GitHubRepoProvider> repoProviders = asList(new GitHubPluginRepoProvider()); // default
4951
private transient GitHubRepoProvider repoProvider = null;
5052

53+
@CheckForNull
54+
private GitHubErrorsAction errorsAction;
55+
5156
// for performance
5257
private transient GitHubRepositoryName repoName;
58+
5359
protected GitHubTrigger(String cronTabSpec) throws ANTLRException {
5460
super(cronTabSpec);
5561
}
@@ -101,6 +107,7 @@ public GitHubRepositoryName getRepoName() {
101107
public void setRepoName(GitHubRepositoryName repoName) {
102108
this.repoName = repoName;
103109
}
110+
104111
@Beta
105112
@Nonnull
106113
public List<GitHubRepoProvider> getRepoProviders() {
@@ -123,21 +130,35 @@ public void setRepoProvider(@Nonnull GitHubRepoProvider prov) {
123130

124131
@Beta
125132
public GitHubRepoProvider getRepoProvider() {
133+
final ArrayList<Throwable> throwables = new ArrayList<>();
126134
if (isNull(repoProvider)) {
127135
boolean failed = false;
128136
for (GitHubRepoProvider prov : getRepoProviders()) {
129137
try {
130138
prov.getGHRepository(this);
131139
repoProvider = prov;
132-
} catch (Exception ignore) {
140+
} catch (Exception ex) {
141+
LOG.debug("Provider failed:", ex);
142+
throwables.add(ex);
133143
failed = true;
134144
}
135145
}
136146
if (failed) {
137-
LOG.error("Can't find repo provider for GitHubBranchTrigger job: {}", getJob().getFullName());
147+
LOG.error("Can't find repo provider for GitHubBranchTrigger job: {}. All repo providers failed: {}",
148+
getJob().getFullName(), throwables
149+
);
138150
}
139151
}
140-
checkState(nonNull(repoProvider), "Can't get repo provider for GH repo %s for %s", job.getName());
152+
153+
if (isNull(repoProvider)) {
154+
getErrorsAction().addOrReplaceError(new GitHubRepoProviderError(
155+
String.format("Can't find repo provider for %s.<br/> All providers failed: %s", job.getName(), throwables)
156+
));
157+
}
158+
159+
checkState(nonNull(repoProvider), "Can't find repo provider for %s", job.getName());
160+
getErrorsAction().removeErrors(GitHubRepoProviderError.class);
161+
141162
return repoProvider;
142163
}
143164

@@ -148,6 +169,14 @@ public GHRepository getRemoteRepository() throws IOException {
148169
return remoteRepository;
149170
}
150171

172+
@Nonnull
173+
public GitHubErrorsAction getErrorsAction() {
174+
if (isNull(errorsAction)) {
175+
errorsAction = new GitHubErrorsAction(getDescriptor().getDisplayName() + " Trigger Errors");
176+
}
177+
return errorsAction;
178+
}
179+
151180
@Override
152181
public void stop() {
153182
//TODO clean hooks?
@@ -164,10 +193,13 @@ public void stop() {
164193
@Nonnull
165194
@Override
166195
public Collection<? extends Action> getProjectActions() {
167-
if (isNull(getPollingLogAction())) {
168-
return Collections.emptyList();
196+
final ArrayList<Action> actions = new ArrayList<>();
197+
198+
if (nonNull(getPollingLogAction())) {
199+
actions.add(getPollingLogAction());
169200
}
170-
return Collections.singleton(getPollingLogAction());
201+
actions.add(getErrorsAction());
202+
return actions;
171203
}
172204

173205
@CheckForNull
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.github.kostyasha.github.integration.generic.errors;
2+
3+
import hudson.ExtensionPoint;
4+
5+
import javax.annotation.Nonnull;
6+
7+
/**
8+
* Custom errors that participate in list of {@link GitHubErrorsAction}.
9+
* index.groovy
10+
*
11+
* @author Kanstantsin Shautsou
12+
*/
13+
public abstract class GitHubError implements ExtensionPoint {
14+
private String description;
15+
16+
public GitHubError(@Nonnull String description) {
17+
this.description = description;
18+
}
19+
20+
@Nonnull
21+
public abstract String getTitle();
22+
23+
/**
24+
* Raw displayed html content as description.
25+
*/
26+
@Nonnull
27+
public String getHtmlDescription() {
28+
return description;
29+
}
30+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package com.github.kostyasha.github.integration.generic.errors;
2+
3+
import hudson.model.ProminentProjectAction;
4+
5+
import javax.annotation.Nonnull;
6+
import java.util.HashSet;
7+
import java.util.Set;
8+
9+
import static java.util.Collections.synchronizedSet;
10+
import static java.util.Objects.isNull;
11+
12+
/**
13+
* Action that reports errors on job view page. Consists of sinle Actions.
14+
*
15+
* @author Kanstantsin Shautsou
16+
*/
17+
public class GitHubErrorsAction implements ProminentProjectAction {
18+
19+
private String description;
20+
private final Set<GitHubError> errors = synchronizedSet(new HashSet<>());
21+
22+
public GitHubErrorsAction(@Nonnull String description) {
23+
this.description = description;
24+
}
25+
26+
@Nonnull
27+
public String getDescription() {
28+
return description;
29+
}
30+
31+
@Nonnull
32+
public Set<GitHubError> getErrors() {
33+
return errors;
34+
}
35+
36+
public boolean addOrReplaceError(@Nonnull GitHubError a) {
37+
if (isNull(a)) {
38+
throw new IllegalArgumentException("Action must be non-null");
39+
}
40+
Set<GitHubError> old = new HashSet<>(1);
41+
Set<GitHubError> current = getErrors();
42+
boolean found = false;
43+
for (GitHubError curErr : current) {
44+
if (!found && a.equals(curErr)) {
45+
found = true;
46+
} else if (curErr.getClass() == a.getClass()) {
47+
old.add(curErr);
48+
}
49+
}
50+
current.removeAll(old);
51+
if (!found) {
52+
getErrors().add(a);
53+
}
54+
return !found || !old.isEmpty();
55+
}
56+
57+
public boolean removeErrors(@Nonnull Class<? extends GitHubError> clazz) {
58+
if (isNull(clazz)) {
59+
throw new IllegalArgumentException("Action type must be non-null");
60+
}
61+
Set<GitHubError> old = new HashSet<>();
62+
Set<GitHubError> current = getErrors();
63+
for (GitHubError err : current) {
64+
if (clazz.isInstance(err)) {
65+
old.add(err);
66+
}
67+
}
68+
return current.removeAll(old);
69+
}
70+
71+
@Nonnull
72+
public Set<GitHubError> getErrorsSnapshot() {
73+
synchronized (errors) {
74+
return new HashSet<>(getErrors());
75+
}
76+
}
77+
78+
@Override
79+
public String getIconFileName() {
80+
return null;
81+
}
82+
83+
@Override
84+
public String getDisplayName() {
85+
return "";
86+
}
87+
88+
@Override
89+
public String getUrlName() {
90+
return "";
91+
}
92+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.github.kostyasha.github.integration.generic.errors.impl;
2+
3+
import com.github.kostyasha.github.integration.generic.errors.GitHubError;
4+
5+
import javax.annotation.Nonnull;
6+
7+
/**
8+
* When hook registration in trigger fails.
9+
*
10+
* @author Kanstantsin Shautsou
11+
*/
12+
public class GitHubHookRegistrationError extends GitHubError {
13+
public GitHubHookRegistrationError(@Nonnull String description) {
14+
super(description);
15+
}
16+
17+
@Nonnull
18+
@Override
19+
public String getTitle() {
20+
return "GitHub Hook Registration error";
21+
}
22+
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.github.kostyasha.github.integration.generic.errors.impl;
2+
3+
import com.github.kostyasha.github.integration.generic.errors.GitHubError;
4+
5+
import javax.annotation.Nonnull;
6+
7+
/**
8+
* Used during {@link com.github.kostyasha.github.integration.generic.GitHubRepoProvider} resolve.
9+
*
10+
* @author Kanstantsin Shautsou
11+
*/
12+
public class GitHubRepoProviderError extends GitHubError {
13+
14+
public GitHubRepoProviderError(@Nonnull String description) {
15+
super(description);
16+
}
17+
18+
@Nonnull
19+
@Override
20+
public String getTitle() {
21+
return "GitHub Repo Provider Error";
22+
}
23+
}

0 commit comments

Comments
 (0)