mirror of
https://github.com/jlengrand/github-api.git
synced 2026-03-11 08:21:23 +00:00
Compare commits
44 Commits
github-api
...
github-api
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
336924ef23 | ||
|
|
ad28ca4a90 | ||
|
|
aebbe86cfc | ||
|
|
df9faf4943 | ||
|
|
3e295b6be4 | ||
|
|
8dd6dbf995 | ||
|
|
612139f2ff | ||
|
|
240bcabb76 | ||
|
|
cda27d5963 | ||
|
|
2f8c3997f7 | ||
|
|
46b89a48db | ||
|
|
5c9cbee2f9 | ||
|
|
ee8973c239 | ||
|
|
2e2813f363 | ||
|
|
7ceca0769f | ||
|
|
4d277cc61f | ||
|
|
e67fbb4621 | ||
|
|
29b5357ceb | ||
|
|
9dabec107b | ||
|
|
23cd51a6da | ||
|
|
7396395f90 | ||
|
|
4abe87036c | ||
|
|
8d1b44db97 | ||
|
|
f2fe8eaf86 | ||
|
|
46715cac08 | ||
|
|
0f21eba57f | ||
|
|
cb7620395a | ||
|
|
3a40af8871 | ||
|
|
c9b5074bc4 | ||
|
|
44d4d0d767 | ||
|
|
64af13f40d | ||
|
|
e9b59c6bef | ||
|
|
3d03659508 | ||
|
|
0374d2de48 | ||
|
|
2627dc5ee4 | ||
|
|
5554332b5b | ||
|
|
1cffea892b | ||
|
|
fd859815b0 | ||
|
|
166e26d101 | ||
|
|
429b26cee8 | ||
|
|
75f0c08ca4 | ||
|
|
1f4325e7db | ||
|
|
f2e7b40425 | ||
|
|
4ee3086b6d |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -3,3 +3,7 @@ target
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.classpath
|
||||
.project
|
||||
.settings/
|
||||
.DS_Store
|
||||
|
||||
10
pom.xml
10
pom.xml
@@ -7,7 +7,7 @@
|
||||
</parent>
|
||||
|
||||
<artifactId>github-api</artifactId>
|
||||
<version>1.84</version>
|
||||
<version>1.87</version>
|
||||
<name>GitHub API for Java</name>
|
||||
<url>http://github-api.kohsuke.org/</url>
|
||||
<description>GitHub API for Java</description>
|
||||
@@ -16,7 +16,7 @@
|
||||
<connection>scm:git:git@github.com/kohsuke/${project.artifactId}.git</connection>
|
||||
<developerConnection>scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git</developerConnection>
|
||||
<url>http://${project.artifactId}.kohsuke.org/</url>
|
||||
<tag>github-api-1.84</tag>
|
||||
<tag>github-api-1.87</tag>
|
||||
</scm>
|
||||
|
||||
<distributionManagement>
|
||||
@@ -34,6 +34,12 @@
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<rerunFailingTestsCount>2</rerunFailingTestsCount>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>animal-sniffer-maven-plugin</artifactId>
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @see GHBranch#disableProtection()
|
||||
*/
|
||||
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD", "URF_UNREAD_FIELD"}, justification = "JSON API")
|
||||
class BranchProtection {
|
||||
boolean enabled;
|
||||
RequiredStatusChecks requiredStatusChecks;
|
||||
|
||||
static class RequiredStatusChecks {
|
||||
EnforcementLevel enforcement_level;
|
||||
List<String> contexts = new ArrayList<String>();
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,11 @@ package org.kohsuke.github;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* This was added during preview API period but it has changed since then.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@Deprecated
|
||||
public enum EnforcementLevel {
|
||||
OFF, NON_ADMINS, EVERYONE;
|
||||
|
||||
|
||||
@@ -4,21 +4,18 @@ import static org.kohsuke.github.Previews.LOKI;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.kohsuke.github.BranchProtection.RequiredStatusChecks;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
/**
|
||||
* A branch in a repository.
|
||||
*
|
||||
*
|
||||
* @author Yusuke Kokubo
|
||||
*/
|
||||
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||
"NP_UNWRITTEN_FIELD", "URF_UNREAD_FIELD"}, justification = "JSON API")
|
||||
public class GHBranch {
|
||||
private GitHub root;
|
||||
@@ -33,7 +30,7 @@ public class GHBranch {
|
||||
|
||||
public static class Commit {
|
||||
String sha;
|
||||
|
||||
|
||||
@SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
|
||||
String url;
|
||||
}
|
||||
@@ -69,6 +66,10 @@ public class GHBranch {
|
||||
return GitHub.parseURL(protection_url);
|
||||
}
|
||||
|
||||
@Preview @Deprecated
|
||||
public GHBranchProtection getProtection() throws IOException {
|
||||
return root.retrieve().withPreview(LOKI).to(protection_url, GHBranchProtection.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* The commit that this branch currently points to.
|
||||
@@ -82,9 +83,7 @@ public class GHBranch {
|
||||
*/
|
||||
@Preview @Deprecated
|
||||
public void disableProtection() throws IOException {
|
||||
BranchProtection bp = new BranchProtection();
|
||||
bp.enabled = false;
|
||||
setProtection(bp);
|
||||
new Requester(root).method("DELETE").withPreview(LOKI).to(protection_url);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,28 +92,31 @@ public class GHBranch {
|
||||
* @see GHCommitStatus#getContext()
|
||||
*/
|
||||
@Preview @Deprecated
|
||||
public GHBranchProtectionBuilder enableProtection() {
|
||||
return new GHBranchProtectionBuilder(this);
|
||||
}
|
||||
|
||||
// backward compatibility with previous signature
|
||||
@Deprecated
|
||||
public void enableProtection(EnforcementLevel level, Collection<String> contexts) throws IOException {
|
||||
BranchProtection bp = new BranchProtection();
|
||||
bp.enabled = true;
|
||||
bp.requiredStatusChecks = new RequiredStatusChecks();
|
||||
bp.requiredStatusChecks.enforcement_level = level;
|
||||
bp.requiredStatusChecks.contexts.addAll(contexts);
|
||||
setProtection(bp);
|
||||
}
|
||||
|
||||
@Preview @Deprecated
|
||||
public void enableProtection(EnforcementLevel level, String... contexts) throws IOException {
|
||||
enableProtection(level, Arrays.asList(contexts));
|
||||
}
|
||||
|
||||
private void setProtection(BranchProtection bp) throws IOException {
|
||||
new Requester(root).method("PATCH").withPreview(LOKI)._with("protection",bp).to(getApiRoute());
|
||||
switch (level) {
|
||||
case OFF:
|
||||
disableProtection();
|
||||
break;
|
||||
case NON_ADMINS:
|
||||
case EVERYONE:
|
||||
enableProtection()
|
||||
.addRequiredChecks(contexts)
|
||||
.includeAdmins(level==EnforcementLevel.EVERYONE)
|
||||
.enable();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
String getApiRoute() {
|
||||
return owner.getApiTailUrl("/branches/"+name);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final String url = owner != null ? owner.getUrl().toString() : "unknown";
|
||||
|
||||
152
src/main/java/org/kohsuke/github/GHBranchProtection.java
Normal file
152
src/main/java/org/kohsuke/github/GHBranchProtection.java
Normal file
@@ -0,0 +1,152 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD",
|
||||
"URF_UNREAD_FIELD" }, justification = "JSON API")
|
||||
public class GHBranchProtection {
|
||||
@JsonProperty("enforce_admins")
|
||||
private EnforceAdmins enforceAdmins;
|
||||
|
||||
@JsonProperty("required_pull_request_reviews")
|
||||
private RequiredReviews requiredReviews;
|
||||
|
||||
@JsonProperty("required_status_checks")
|
||||
private RequiredStatusChecks requiredStatusChecks;
|
||||
|
||||
@JsonProperty
|
||||
private Restrictions restrictions;
|
||||
|
||||
@JsonProperty
|
||||
private String url;
|
||||
|
||||
public EnforceAdmins getEnforceAdmins() {
|
||||
return enforceAdmins;
|
||||
}
|
||||
|
||||
public RequiredReviews getRequiredReviews() {
|
||||
return requiredReviews;
|
||||
}
|
||||
|
||||
public RequiredStatusChecks getRequiredStatusChecks() {
|
||||
return requiredStatusChecks;
|
||||
}
|
||||
|
||||
public Restrictions getRestrictions() {
|
||||
return restrictions;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public static class EnforceAdmins {
|
||||
@JsonProperty
|
||||
private boolean enabled;
|
||||
|
||||
@JsonProperty
|
||||
private String url;
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
}
|
||||
|
||||
public static class RequiredReviews {
|
||||
@JsonProperty("dismissal_restrictions")
|
||||
private Restrictions dismissalRestriction;
|
||||
|
||||
@JsonProperty("dismiss_stale_reviews")
|
||||
private boolean dismissStaleReviews;
|
||||
|
||||
@JsonProperty("require_code_owner_reviews")
|
||||
private boolean requireCodeOwnerReviews;
|
||||
|
||||
@JsonProperty
|
||||
private String url;
|
||||
|
||||
public Restrictions getDismissalRestrictions() {
|
||||
return dismissalRestriction;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public boolean isDismissStaleReviews() {
|
||||
return dismissStaleReviews;
|
||||
}
|
||||
|
||||
public boolean isRequireCodeOwnerReviews() {
|
||||
return requireCodeOwnerReviews;
|
||||
}
|
||||
}
|
||||
|
||||
public static class RequiredStatusChecks {
|
||||
@JsonProperty
|
||||
private Collection<String> contexts;
|
||||
|
||||
@JsonProperty
|
||||
private boolean strict;
|
||||
|
||||
@JsonProperty
|
||||
private String url;
|
||||
|
||||
public Collection<String> getContexts() {
|
||||
return contexts;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public boolean isRequiresBranchUpToDate() {
|
||||
return strict;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Restrictions {
|
||||
@JsonProperty
|
||||
private Collection<GHTeam> teams;
|
||||
|
||||
@JsonProperty("teams_url")
|
||||
private String teamsUrl;
|
||||
|
||||
@JsonProperty
|
||||
private String url;
|
||||
|
||||
@JsonProperty
|
||||
private Collection<GHUser> users;
|
||||
|
||||
@JsonProperty("users_url")
|
||||
private String usersUrl;
|
||||
|
||||
public Collection<GHTeam> getTeams() {
|
||||
return teams;
|
||||
}
|
||||
|
||||
public String getTeamsUrl() {
|
||||
return teamsUrl;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public Collection<GHUser> getUsers() {
|
||||
return users;
|
||||
}
|
||||
|
||||
public String getUsersUrl() {
|
||||
return usersUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
203
src/main/java/org/kohsuke/github/GHBranchProtectionBuilder.java
Normal file
203
src/main/java/org/kohsuke/github/GHBranchProtectionBuilder.java
Normal file
@@ -0,0 +1,203 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import static org.kohsuke.github.Previews.LOKI;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
/**
|
||||
* Builder to configure the branch protection settings.
|
||||
*
|
||||
* @see GHBranch#enableProtection()
|
||||
*/
|
||||
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD",
|
||||
"URF_UNREAD_FIELD" }, justification = "JSON API")
|
||||
public class GHBranchProtectionBuilder {
|
||||
private final GHBranch branch;
|
||||
|
||||
private boolean enforceAdmins;
|
||||
private Map<String, Object> prReviews;
|
||||
private Restrictions restrictions;
|
||||
private StatusChecks statusChecks;
|
||||
|
||||
GHBranchProtectionBuilder(GHBranch branch) {
|
||||
this.branch = branch;
|
||||
}
|
||||
|
||||
public GHBranchProtectionBuilder addRequiredChecks(Collection<String> checks) {
|
||||
getStatusChecks().contexts.addAll(checks);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GHBranchProtectionBuilder addRequiredChecks(String... checks) {
|
||||
addRequiredChecks(Arrays.asList(checks));
|
||||
return this;
|
||||
}
|
||||
|
||||
public GHBranchProtectionBuilder dismissStaleReviews() {
|
||||
getPrReviews().put("dismiss_stale_reviews", true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GHBranchProtection enable() throws IOException {
|
||||
return requester().method("PUT")
|
||||
.withNullable("required_status_checks", statusChecks)
|
||||
.withNullable("required_pull_request_reviews", prReviews)
|
||||
.withNullable("restrictions", restrictions)
|
||||
.withNullable("enforce_admins", enforceAdmins)
|
||||
.to(branch.getProtectionUrl().toString(), GHBranchProtection.class);
|
||||
}
|
||||
|
||||
public GHBranchProtectionBuilder includeAdmins() {
|
||||
return includeAdmins(true);
|
||||
}
|
||||
|
||||
public GHBranchProtectionBuilder includeAdmins(boolean v) {
|
||||
enforceAdmins = v;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GHBranchProtectionBuilder requireBranchIsUpToDate() {
|
||||
return requireBranchIsUpToDate(true);
|
||||
}
|
||||
|
||||
public GHBranchProtectionBuilder requireBranchIsUpToDate(boolean v) {
|
||||
getStatusChecks().strict = v;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GHBranchProtectionBuilder requireCodeOwnReviews() {
|
||||
return requireCodeOwnReviews(true);
|
||||
}
|
||||
|
||||
public GHBranchProtectionBuilder requireCodeOwnReviews(boolean v) {
|
||||
getPrReviews().put("require_code_owner_reviews", v);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GHBranchProtectionBuilder requireReviews() {
|
||||
getPrReviews();
|
||||
return this;
|
||||
}
|
||||
|
||||
public GHBranchProtectionBuilder restrictPushAccess() {
|
||||
getRestrictions();
|
||||
return this;
|
||||
}
|
||||
|
||||
public GHBranchProtectionBuilder teamPushAccess(Collection<GHTeam> teams) {
|
||||
for (GHTeam team : teams) {
|
||||
teamPushAccess(team);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public GHBranchProtectionBuilder teamPushAccess(GHTeam... teams) {
|
||||
for (GHTeam team : teams) {
|
||||
getRestrictions().teams.add(team.getSlug());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public GHBranchProtectionBuilder teamReviewDismissals(Collection<GHTeam> teams) {
|
||||
for (GHTeam team : teams) {
|
||||
teamReviewDismissals(team);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public GHBranchProtectionBuilder teamReviewDismissals(GHTeam... teams) {
|
||||
for (GHTeam team : teams) {
|
||||
addReviewRestriction(team.getSlug(), true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public GHBranchProtectionBuilder userPushAccess(Collection<GHUser> users) {
|
||||
for (GHUser user : users) {
|
||||
userPushAccess(user);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public GHBranchProtectionBuilder userPushAccess(GHUser... users) {
|
||||
for (GHUser user : users) {
|
||||
getRestrictions().users.add(user.getLogin());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public GHBranchProtectionBuilder userReviewDismissals(Collection<GHUser> users) {
|
||||
for (GHUser team : users) {
|
||||
userReviewDismissals(team);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public GHBranchProtectionBuilder userReviewDismissals(GHUser... users) {
|
||||
for (GHUser user : users) {
|
||||
addReviewRestriction(user.getLogin(), false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private void addReviewRestriction(String restriction, boolean isTeam) {
|
||||
getPrReviews();
|
||||
|
||||
if (!prReviews.containsKey("dismissal_restrictions")) {
|
||||
prReviews.put("dismissal_restrictions", new Restrictions());
|
||||
}
|
||||
|
||||
Restrictions restrictions = (Restrictions) prReviews.get("dismissal_restrictions");
|
||||
|
||||
if (isTeam) {
|
||||
restrictions.teams.add(restriction);
|
||||
} else {
|
||||
restrictions.users.add(restriction);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> getPrReviews() {
|
||||
if (prReviews == null) {
|
||||
prReviews = new HashMap<String, Object>();
|
||||
}
|
||||
return prReviews;
|
||||
}
|
||||
|
||||
private Restrictions getRestrictions() {
|
||||
if (restrictions == null) {
|
||||
restrictions = new Restrictions();
|
||||
}
|
||||
return restrictions;
|
||||
}
|
||||
|
||||
private StatusChecks getStatusChecks() {
|
||||
if (statusChecks == null) {
|
||||
statusChecks = new StatusChecks();
|
||||
}
|
||||
return statusChecks;
|
||||
}
|
||||
|
||||
private Requester requester() {
|
||||
return new Requester(branch.getRoot()).withPreview(LOKI);
|
||||
}
|
||||
|
||||
private static class Restrictions {
|
||||
private Set<String> teams = new HashSet<String>();
|
||||
private Set<String> users = new HashSet<String>();
|
||||
}
|
||||
|
||||
private static class StatusChecks {
|
||||
final List<String> contexts = new ArrayList<String>();
|
||||
boolean strict;
|
||||
}
|
||||
}
|
||||
137
src/main/java/org/kohsuke/github/GHCommitSearchBuilder.java
Normal file
137
src/main/java/org/kohsuke/github/GHCommitSearchBuilder.java
Normal file
@@ -0,0 +1,137 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
/**
|
||||
* Search commits.
|
||||
*
|
||||
* @author Marc de Verdelhan
|
||||
* @see GitHub#searchCommits()
|
||||
*/
|
||||
@Preview @Deprecated
|
||||
public class GHCommitSearchBuilder extends GHSearchBuilder<GHCommit> {
|
||||
/*package*/ GHCommitSearchBuilder(GitHub root) {
|
||||
super(root,CommitSearchResult.class);
|
||||
req.withPreview(Previews.CLOAK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search terms.
|
||||
*/
|
||||
public GHCommitSearchBuilder q(String term) {
|
||||
super.q(term);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GHCommitSearchBuilder author(String v) {
|
||||
return q("author:"+v);
|
||||
}
|
||||
|
||||
public GHCommitSearchBuilder committer(String v) {
|
||||
return q("committer:"+v);
|
||||
}
|
||||
|
||||
public GHCommitSearchBuilder authorName(String v) {
|
||||
return q("author-name:"+v);
|
||||
}
|
||||
|
||||
public GHCommitSearchBuilder committerName(String v) {
|
||||
return q("committer-name:"+v);
|
||||
}
|
||||
|
||||
public GHCommitSearchBuilder authorEmail(String v) {
|
||||
return q("author-email:"+v);
|
||||
}
|
||||
|
||||
public GHCommitSearchBuilder committerEmail(String v) {
|
||||
return q("committer-email:"+v);
|
||||
}
|
||||
|
||||
public GHCommitSearchBuilder authorDate(String v) {
|
||||
return q("author-date:"+v);
|
||||
}
|
||||
|
||||
public GHCommitSearchBuilder committerDate(String v) {
|
||||
return q("committer-date:"+v);
|
||||
}
|
||||
|
||||
public GHCommitSearchBuilder merge(boolean merge) {
|
||||
return q("merge:"+Boolean.valueOf(merge).toString().toLowerCase());
|
||||
}
|
||||
|
||||
public GHCommitSearchBuilder hash(String v) {
|
||||
return q("hash:"+v);
|
||||
}
|
||||
|
||||
public GHCommitSearchBuilder parent(String v) {
|
||||
return q("parent:"+v);
|
||||
}
|
||||
|
||||
public GHCommitSearchBuilder tree(String v) {
|
||||
return q("tree:"+v);
|
||||
}
|
||||
|
||||
public GHCommitSearchBuilder is(String v) {
|
||||
return q("is:"+v);
|
||||
}
|
||||
|
||||
public GHCommitSearchBuilder user(String v) {
|
||||
return q("user:"+v);
|
||||
}
|
||||
|
||||
public GHCommitSearchBuilder org(String v) {
|
||||
return q("org:"+v);
|
||||
}
|
||||
|
||||
public GHCommitSearchBuilder repo(String v) {
|
||||
return q("repo:"+v);
|
||||
}
|
||||
|
||||
public GHCommitSearchBuilder order(GHDirection v) {
|
||||
req.with("order",v);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GHCommitSearchBuilder sort(Sort sort) {
|
||||
req.with("sort",sort);
|
||||
return this;
|
||||
}
|
||||
|
||||
public enum Sort { AUTHOR_DATE, COMMITTER_DATE }
|
||||
|
||||
private static class CommitSearchResult extends SearchResult<GHCommit> {
|
||||
private GHCommit[] items;
|
||||
|
||||
@Override
|
||||
/*package*/ GHCommit[] getItems(GitHub root) {
|
||||
for (GHCommit commit : items) {
|
||||
String repoName = getRepoName(commit.url);
|
||||
try {
|
||||
GHRepository repo = root.getRepository(repoName);
|
||||
commit.wrapUp(repo);
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param commitUrl a commit URL
|
||||
* @return the repo name ("username/reponame")
|
||||
*/
|
||||
private static String getRepoName(String commitUrl) {
|
||||
if (StringUtils.isBlank(commitUrl)) {
|
||||
return null;
|
||||
}
|
||||
int indexOfUsername = (GitHub.GITHUB_URL + "/repos/").length();
|
||||
String[] tokens = commitUrl.substring(indexOfUsername).split("/", 3);
|
||||
return tokens[0] + '/' + tokens[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getApiUrl() {
|
||||
return "/search/commits";
|
||||
}
|
||||
}
|
||||
@@ -21,17 +21,30 @@ public enum GHEvent {
|
||||
FORK_APPLY,
|
||||
GIST,
|
||||
GOLLUM,
|
||||
INSTALLATION,
|
||||
INSTALLATION_REPOSITORIES,
|
||||
ISSUE_COMMENT,
|
||||
ISSUES,
|
||||
LABEL,
|
||||
MARKETPLACE_PURCHASE,
|
||||
MEMBER,
|
||||
MEMBERSHIP,
|
||||
MILESTONE,
|
||||
ORGANIZATION,
|
||||
ORG_BLOCK,
|
||||
PAGE_BUILD,
|
||||
PROJECT_CARD,
|
||||
PROJECT_COLUMN,
|
||||
PROJECT,
|
||||
PUBLIC,
|
||||
PULL_REQUEST,
|
||||
PULL_REQUEST_REVIEW,
|
||||
PULL_REQUEST_REVIEW_COMMENT,
|
||||
PUSH,
|
||||
RELEASE,
|
||||
REPOSITORY, // only valid for org hooks
|
||||
STATUS,
|
||||
TEAM,
|
||||
TEAM_ADD,
|
||||
WATCH,
|
||||
PING,
|
||||
|
||||
@@ -41,6 +41,13 @@ public abstract class GHHook extends GHObject {
|
||||
return Collections.unmodifiableMap(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see <a href="https://developer.github.com/v3/repos/hooks/#ping-a-hook">Ping hook</a>
|
||||
*/
|
||||
public void ping() throws IOException {
|
||||
new Requester(getRoot()).method("POST").to(getApiRoute() + "/pings");
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes this hook.
|
||||
*/
|
||||
|
||||
@@ -25,8 +25,14 @@ package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import javax.annotation.CheckForNull;
|
||||
|
||||
import static org.kohsuke.github.Previews.BLACK_CAT;
|
||||
|
||||
/**
|
||||
* A pull request.
|
||||
@@ -208,7 +214,7 @@ public class GHPullRequest extends GHIssue {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all the commits associated to this pull request.
|
||||
* Retrieves all the files associated to this pull request.
|
||||
*/
|
||||
public PagedIterable<GHPullRequestFileDetail> listFiles() {
|
||||
return new PagedIterable<GHPullRequestFileDetail>() {
|
||||
@@ -223,6 +229,27 @@ public class GHPullRequest extends GHIssue {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all the reviews associated to this pull request.
|
||||
*/
|
||||
public PagedIterable<GHPullRequestReview> listReviews() {
|
||||
return new PagedIterable<GHPullRequestReview>() {
|
||||
public PagedIterator<GHPullRequestReview> _iterator(int pageSize) {
|
||||
return new PagedIterator<GHPullRequestReview>(root.retrieve()
|
||||
.withPreview(BLACK_CAT)
|
||||
.asIterator(String.format("%s/reviews", getApiRoute()),
|
||||
GHPullRequestReview[].class, pageSize)) {
|
||||
@Override
|
||||
protected void wrapUp(GHPullRequestReview[] page) {
|
||||
for (GHPullRequestReview r: page) {
|
||||
r.wrapUp(GHPullRequest.this);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains all the review comments associated with this pull request.
|
||||
*/
|
||||
@@ -259,6 +286,34 @@ public class GHPullRequest extends GHIssue {
|
||||
};
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Deprecated
|
||||
public GHPullRequestReview createReview(String body, @CheckForNull GHPullRequestReviewState event,
|
||||
GHPullRequestReviewComment... comments)
|
||||
throws IOException {
|
||||
return createReview(body, event, Arrays.asList(comments));
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Deprecated
|
||||
public GHPullRequestReview createReview(String body, @CheckForNull GHPullRequestReviewState event,
|
||||
List<GHPullRequestReviewComment> comments)
|
||||
throws IOException {
|
||||
// if (event == null) {
|
||||
// event = GHPullRequestReviewState.PENDING;
|
||||
// }
|
||||
List<DraftReviewComment> draftComments = new ArrayList<DraftReviewComment>(comments.size());
|
||||
for (GHPullRequestReviewComment c : comments) {
|
||||
draftComments.add(new DraftReviewComment(c.getBody(), c.getPath(), c.getPosition()));
|
||||
}
|
||||
return new Requester(root).method("POST")
|
||||
.with("body", body)
|
||||
//.with("event", event.name())
|
||||
._with("comments", draftComments)
|
||||
.withPreview(BLACK_CAT)
|
||||
.to(getApiRoute() + "/reviews", GHPullRequestReview.class).wrapUp(this);
|
||||
}
|
||||
|
||||
public GHPullRequestReviewComment createReviewComment(String body, String sha, String path, int position) throws IOException {
|
||||
return new Requester(root).method("POST")
|
||||
.with("body", body)
|
||||
@@ -300,4 +355,28 @@ public class GHPullRequest extends GHIssue {
|
||||
fetchedIssueDetails = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static class DraftReviewComment {
|
||||
private String body;
|
||||
private String path;
|
||||
private int position;
|
||||
|
||||
public DraftReviewComment(String body, String path, int position) {
|
||||
this.body = body;
|
||||
this.path = path;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public int getPosition() {
|
||||
return position;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
149
src/main/java/org/kohsuke/github/GHPullRequestReview.java
Normal file
149
src/main/java/org/kohsuke/github/GHPullRequestReview.java
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2017, CloudBees, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
import static org.kohsuke.github.Previews.BLACK_CAT;
|
||||
|
||||
/**
|
||||
* Review to the pull request
|
||||
*
|
||||
* @see GHPullRequest#listReviews()
|
||||
* @see GHPullRequest#createReview(String, GHPullRequestReviewState, GHPullRequestReviewComment...)
|
||||
*/
|
||||
public class GHPullRequestReview extends GHObject {
|
||||
GHPullRequest owner;
|
||||
|
||||
private String body;
|
||||
private GHUser user;
|
||||
private String commit_id;
|
||||
private GHPullRequestReviewState state;
|
||||
|
||||
/*package*/ GHPullRequestReview wrapUp(GHPullRequest owner) {
|
||||
this.owner = owner;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pull request to which this review is associated.
|
||||
*/
|
||||
public GHPullRequest getParent() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* The comment itself.
|
||||
*/
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user who posted this review.
|
||||
*/
|
||||
public GHUser getUser() throws IOException {
|
||||
return owner.root.getUser(user.getLogin());
|
||||
}
|
||||
|
||||
public String getCommitId() {
|
||||
return commit_id;
|
||||
}
|
||||
|
||||
public GHPullRequestReviewState getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getHtmlUrl() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String getApiRoute() {
|
||||
return owner.getApiRoute()+"/reviews/"+id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the comment.
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
public void submit(String body, GHPullRequestReviewState event) throws IOException {
|
||||
new Requester(owner.root).method("POST")
|
||||
.with("body", body)
|
||||
.with("event", event.action())
|
||||
.withPreview("application/vnd.github.black-cat-preview+json")
|
||||
.to(getApiRoute()+"/events",this);
|
||||
this.body = body;
|
||||
this.state = event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes this review.
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
public void delete() throws IOException {
|
||||
new Requester(owner.root).method("DELETE")
|
||||
.withPreview(BLACK_CAT)
|
||||
.to(getApiRoute());
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismisses this review.
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
public void dismiss(String message) throws IOException {
|
||||
new Requester(owner.root).method("PUT")
|
||||
.with("message", message)
|
||||
.withPreview(BLACK_CAT)
|
||||
.to(getApiRoute()+"/dismissals");
|
||||
state = GHPullRequestReviewState.DISMISSED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains all the review comments associated with this pull request review.
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
public PagedIterable<GHPullRequestReviewComment> listReviewComments() throws IOException {
|
||||
return new PagedIterable<GHPullRequestReviewComment>() {
|
||||
public PagedIterator<GHPullRequestReviewComment> _iterator(int pageSize) {
|
||||
return new PagedIterator<GHPullRequestReviewComment>(
|
||||
owner.root.retrieve()
|
||||
.withPreview(BLACK_CAT)
|
||||
.asIterator(getApiRoute() + "/comments",
|
||||
GHPullRequestReviewComment[].class, pageSize)) {
|
||||
protected void wrapUp(GHPullRequestReviewComment[] page) {
|
||||
for (GHPullRequestReviewComment c : page)
|
||||
c.wrapUp(owner);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -44,6 +44,14 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
|
||||
private int position;
|
||||
private int originalPosition;
|
||||
|
||||
public static GHPullRequestReviewComment draft(String body, String path, int position) {
|
||||
GHPullRequestReviewComment result = new GHPullRequestReviewComment();
|
||||
result.body = body;
|
||||
result.path = path;
|
||||
result.position = position;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*package*/ GHPullRequestReviewComment wrapUp(GHPullRequest owner) {
|
||||
this.owner = owner;
|
||||
return this;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
public enum GHPullRequestReviewState {
|
||||
PENDING(null),
|
||||
APPROVED("APPROVE"),
|
||||
REQUEST_CHANGES("REQUEST_CHANGES"),
|
||||
COMMENTED("COMMENT"),
|
||||
DISMISSED(null);
|
||||
|
||||
private final String _action;
|
||||
|
||||
GHPullRequestReviewState(String action) {
|
||||
_action = action;
|
||||
}
|
||||
|
||||
public String action() {
|
||||
return _action;
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ import static org.kohsuke.github.Previews.*;
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||
"NP_UNWRITTEN_FIELD"}, justification = "JSON API")
|
||||
public class GHRepository extends GHObject {
|
||||
/*package almost final*/ GitHub root;
|
||||
@@ -298,6 +298,14 @@ public class GHRepository extends GHObject {
|
||||
public List<GHRelease> getReleases() throws IOException {
|
||||
return listReleases().asList();
|
||||
}
|
||||
|
||||
public GHRelease getLatestRelease() throws IOException {
|
||||
try {
|
||||
return root.retrieve().to(getApiTailUrl("releases/latest"), GHRelease.class).wrap(this);
|
||||
} catch (FileNotFoundException e) {
|
||||
return null; // no latest release
|
||||
}
|
||||
}
|
||||
|
||||
public PagedIterable<GHRelease> listReleases() throws IOException {
|
||||
return new PagedIterable<GHRelease>() {
|
||||
@@ -434,8 +442,8 @@ public class GHRepository extends GHObject {
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Gets the collaborators on this repository.
|
||||
* This set always appear to include the owner.
|
||||
@@ -486,9 +494,8 @@ public class GHRepository extends GHObject {
|
||||
* @throws FileNotFoundException under some conditions (e.g., private repo you can see but are not an admin of); treat as unknown
|
||||
* @throws HttpException with a 403 under other conditions (e.g., public repo you have no special rights to); treat as unknown
|
||||
*/
|
||||
@Deprecated @Preview
|
||||
public GHPermissionType getPermission(String user) throws IOException {
|
||||
GHPermission perm = root.retrieve().withPreview(KORRA).to(getApiTailUrl("collaborators/" + user + "/permission"), GHPermission.class);
|
||||
GHPermission perm = root.retrieve().to(getApiTailUrl("collaborators/" + user + "/permission"), GHPermission.class);
|
||||
perm.wrapUp(root);
|
||||
return perm.getPermissionType();
|
||||
}
|
||||
@@ -498,7 +505,6 @@ public class GHRepository extends GHObject {
|
||||
* @throws FileNotFoundException under some conditions (e.g., private repo you can see but are not an admin of); treat as unknown
|
||||
* @throws HttpException with a 403 under other conditions (e.g., public repo you have no special rights to); treat as unknown
|
||||
*/
|
||||
@Deprecated @Preview
|
||||
public GHPermissionType getPermission(GHUser u) throws IOException {
|
||||
return getPermission(u.getLogin());
|
||||
}
|
||||
@@ -784,6 +790,26 @@ public class GHRepository extends GHObject {
|
||||
return GHRef.wrap(root.retrieve().to(String.format("/repos/%s/%s/git/refs", getOwnerName(), name), GHRef[].class), root);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves all refs for the github repository.
|
||||
*
|
||||
* @return paged iterable of all refs
|
||||
* @throws IOException on failure communicating with GitHub, potentially due to an invalid ref type being requested
|
||||
*/
|
||||
public PagedIterable<GHRef> listRefs() throws IOException {
|
||||
final String url = String.format("/repos/%s/%s/git/refs", getOwnerName(), name);
|
||||
return new PagedIterable<GHRef>() {
|
||||
public PagedIterator<GHRef> _iterator(int pageSize) {
|
||||
return new PagedIterator<GHRef>(root.retrieve().asIterator(url, GHRef[].class, pageSize)) {
|
||||
protected void wrapUp(GHRef[] page) {
|
||||
// no-op
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all refs of the given type for the current GitHub repository.
|
||||
* @param refType the type of reg to search for e.g. <tt>tags</tt> or <tt>commits</tt>
|
||||
@@ -793,6 +819,27 @@ public class GHRepository extends GHObject {
|
||||
public GHRef[] getRefs(String refType) throws IOException {
|
||||
return GHRef.wrap(root.retrieve().to(String.format("/repos/%s/%s/git/refs/%s", getOwnerName(), name, refType), GHRef[].class),root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all refs of the given type for the current GitHub repository.
|
||||
*
|
||||
* @param refType the type of reg to search for e.g. <tt>tags</tt> or <tt>commits</tt>
|
||||
* @return paged iterable of all refs of the specified type
|
||||
* @throws IOException on failure communicating with GitHub, potentially due to an invalid ref type being requested
|
||||
*/
|
||||
public PagedIterable<GHRef> listRefs(String refType) throws IOException {
|
||||
final String url = String.format("/repos/%s/%s/git/refs/%s", getOwnerName(), name, refType);
|
||||
return new PagedIterable<GHRef>() {
|
||||
public PagedIterator<GHRef> _iterator(int pageSize) {
|
||||
return new PagedIterator<GHRef>(root.retrieve().asIterator(url, GHRef[].class, pageSize)) {
|
||||
protected void wrapUp(GHRef[] page) {
|
||||
// no-op
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive a ref of the given type for the current GitHub repository.
|
||||
*
|
||||
@@ -810,6 +857,18 @@ public class GHRepository extends GHObject {
|
||||
refName = refName.replaceAll("#", "%23");
|
||||
return root.retrieve().to(String.format("/repos/%s/%s/git/refs/%s", getOwnerName(), name, refName), GHRef.class).wrap(root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <strong>annotated</strong> tag object. Only valid if the {@link GHRef#getObject()} has a
|
||||
* {@link GHRef.GHObject#getType()} of {@code tag}.
|
||||
*
|
||||
* @param sha the sha of the tag object
|
||||
* @return the annotated tag object
|
||||
*/
|
||||
public GHTagObject getTagObject(String sha) throws IOException {
|
||||
return root.retrieve().to(getApiTailUrl("git/tags/" + sha), GHTagObject.class).wrap(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive a tree of the given type for the current GitHub repository.
|
||||
*
|
||||
@@ -1146,7 +1205,7 @@ public class GHRepository extends GHObject {
|
||||
* @deprecated
|
||||
* Use {@link #getHooks()} and {@link #createHook(String, Map, Collection, boolean)}
|
||||
*/
|
||||
@SuppressFBWarnings(value = "DMI_COLLECTION_OF_URLS",
|
||||
@SuppressFBWarnings(value = "DMI_COLLECTION_OF_URLS",
|
||||
justification = "It causes a performance degradation, but we have already exposed it to the API")
|
||||
public Set<URL> getPostCommitHooks() {
|
||||
return postCommitHooks;
|
||||
@@ -1155,7 +1214,7 @@ public class GHRepository extends GHObject {
|
||||
/**
|
||||
* Live set view of the post-commit hook.
|
||||
*/
|
||||
@SuppressFBWarnings(value = "DMI_COLLECTION_OF_URLS",
|
||||
@SuppressFBWarnings(value = "DMI_COLLECTION_OF_URLS",
|
||||
justification = "It causes a performance degradation, but we have already exposed it to the API")
|
||||
@SkipFromToString
|
||||
private final Set<URL> postCommitHooks = new AbstractSet<URL>() {
|
||||
@@ -1223,7 +1282,7 @@ public class GHRepository extends GHObject {
|
||||
*/
|
||||
public Map<String,GHBranch> getBranches() throws IOException {
|
||||
Map<String,GHBranch> r = new TreeMap<String,GHBranch>();
|
||||
for (GHBranch p : root.retrieve().to(getApiTailUrl("branches"), GHBranch[].class)) {
|
||||
for (GHBranch p : root.retrieve().withPreview(LOKI).to(getApiTailUrl("branches"), GHBranch[].class)) {
|
||||
p.wrap(this);
|
||||
r.put(p.getName(),p);
|
||||
}
|
||||
@@ -1231,7 +1290,7 @@ public class GHRepository extends GHObject {
|
||||
}
|
||||
|
||||
public GHBranch getBranch(String name) throws IOException {
|
||||
return root.retrieve().to(getApiTailUrl("branches/"+name),GHBranch.class).wrap(this);
|
||||
return root.retrieve().withPreview(LOKI).to(getApiTailUrl("branches/"+name),GHBranch.class).wrap(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1453,7 +1512,7 @@ public class GHRepository extends GHObject {
|
||||
public boolean equals(Object obj) {
|
||||
// We ignore contributions in the calculation
|
||||
return super.equals(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
60
src/main/java/org/kohsuke/github/GHTagObject.java
Normal file
60
src/main/java/org/kohsuke/github/GHTagObject.java
Normal file
@@ -0,0 +1,60 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
/**
|
||||
* Represents an annotated tag in a {@link GHRepository}
|
||||
*
|
||||
* @see GHRepository#getAnnotatedTag()
|
||||
*/
|
||||
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||
"NP_UNWRITTEN_FIELD"}, justification = "JSON API")
|
||||
public class GHTagObject {
|
||||
private GHRepository owner;
|
||||
private GitHub root;
|
||||
|
||||
private String tag;
|
||||
private String sha;
|
||||
private String url;
|
||||
private String message;
|
||||
private GitUser tagger;
|
||||
private GHRef.GHObject object;
|
||||
|
||||
/*package*/ GHTagObject wrap(GHRepository owner) {
|
||||
this.owner = owner;
|
||||
this.root = owner.root;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GHRepository getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public GitHub getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public String getSha() {
|
||||
return sha;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public GitUser getTagger() {
|
||||
return tagger;
|
||||
}
|
||||
|
||||
public GHRef.GHObject getObject() {
|
||||
return object;
|
||||
}
|
||||
}
|
||||
@@ -47,13 +47,12 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.annotation.CheckForNull;
|
||||
import javax.annotation.Nonnull;
|
||||
import org.apache.commons.codec.Charsets;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY;
|
||||
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;
|
||||
@@ -303,7 +302,7 @@ public class GitHub {
|
||||
GHRateLimit r = new GHRateLimit();
|
||||
r.limit = r.remaining = 1000000;
|
||||
long hour = 60L * 60L; // this is madness, storing the date as seconds in a Date object
|
||||
r.reset = new Date((System.currentTimeMillis() + hour) / 1000L );
|
||||
r.reset = new Date(System.currentTimeMillis() / 1000L + hour);
|
||||
return rateLimit = r;
|
||||
}
|
||||
}
|
||||
@@ -703,13 +702,31 @@ public class GitHub {
|
||||
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
|
||||
X-Content-Type-Options: nosniff
|
||||
*/
|
||||
return uc.getResponseCode() == HTTP_UNAUTHORIZED
|
||||
&& uc.getHeaderField("X-GitHub-Media-Type") != null;
|
||||
try {
|
||||
return uc.getResponseCode() == HTTP_UNAUTHORIZED
|
||||
&& uc.getHeaderField("X-GitHub-Media-Type") != null;
|
||||
} finally {
|
||||
// ensure that the connection opened by getResponseCode gets closed
|
||||
try {
|
||||
IOUtils.closeQuietly(uc.getInputStream());
|
||||
} catch (IOException ignore) {
|
||||
// ignore
|
||||
}
|
||||
IOUtils.closeQuietly(uc.getErrorStream());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search commits.
|
||||
*/
|
||||
@Preview @Deprecated
|
||||
public GHCommitSearchBuilder searchCommits() {
|
||||
return new GHCommitSearchBuilder(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search issues.
|
||||
*/
|
||||
|
||||
@@ -7,5 +7,6 @@ package org.kohsuke.github;
|
||||
static final String LOKI = "application/vnd.github.loki-preview+json";
|
||||
static final String DRAX = "application/vnd.github.drax-preview+json";
|
||||
static final String SQUIRREL_GIRL = "application/vnd.github.squirrel-girl-preview";
|
||||
static final String KORRA = "application/vnd.github.korra-preview";
|
||||
static final String CLOAK = "application/vnd.github.cloak-preview";
|
||||
static final String BLACK_CAT = "application/vnd.github.black-cat-preview+json";
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import java.lang.reflect.Field;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
@@ -48,7 +49,6 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -58,6 +58,7 @@ import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import java.util.logging.Level;
|
||||
import static java.util.logging.Level.*;
|
||||
import static org.kohsuke.github.GitHub.MAPPER;
|
||||
|
||||
@@ -169,6 +170,11 @@ class Requester {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Requester withNullable(String key, Object value) {
|
||||
args.add(new Entry(key, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Requester _with(String key, Object value) {
|
||||
if (value!=null) {
|
||||
args.add(new Entry(key,value));
|
||||
@@ -313,7 +319,7 @@ class Requester {
|
||||
setupConnection(root.getApiURL(tailApiUrl));
|
||||
|
||||
buildRequest();
|
||||
|
||||
|
||||
try {
|
||||
return wrapStream(uc.getInputStream());
|
||||
} catch (IOException e) {
|
||||
@@ -580,6 +586,10 @@ class Requester {
|
||||
}
|
||||
|
||||
private <T> T parse(Class<T> type, T instance) throws IOException {
|
||||
return parse(type, instance, 2);
|
||||
}
|
||||
|
||||
private <T> T parse(Class<T> type, T instance, int timeouts) throws IOException {
|
||||
InputStreamReader r = null;
|
||||
int responseCode = -1;
|
||||
String responseMessage = null;
|
||||
@@ -610,6 +620,10 @@ class Requester {
|
||||
// to preserve backward compatibility
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
if (e instanceof SocketTimeoutException && timeouts > 0) {
|
||||
LOGGER.log(Level.INFO, "timed out accessing " + uc.getURL() + "; will try " + timeouts + " more time(s)", e);
|
||||
return parse(type, instance, timeouts - 1);
|
||||
}
|
||||
throw new HttpException(responseCode, responseMessage, uc.getURL(), e);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(r);
|
||||
@@ -642,6 +656,24 @@ class Requester {
|
||||
" handling exception " + e, e);
|
||||
throw e;
|
||||
}
|
||||
InputStream es = wrapStream(uc.getErrorStream());
|
||||
if (es != null) {
|
||||
try {
|
||||
String error = IOUtils.toString(es, "UTF-8");
|
||||
if (e instanceof FileNotFoundException) {
|
||||
// pass through 404 Not Found to allow the caller to handle it intelligently
|
||||
e = (IOException) new FileNotFoundException(error).initCause(e);
|
||||
} else if (e instanceof HttpException) {
|
||||
HttpException http = (HttpException) e;
|
||||
e = new HttpException(error, http.getResponseCode(), http.getResponseMessage(),
|
||||
http.getUrl(), e);
|
||||
} else {
|
||||
e = (IOException) new IOException(error).initCause(e);
|
||||
}
|
||||
} finally {
|
||||
IOUtils.closeQuietly(es);
|
||||
}
|
||||
}
|
||||
if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) // 401 / Unauthorized == bad creds
|
||||
throw e;
|
||||
|
||||
@@ -657,24 +689,7 @@ class Requester {
|
||||
return;
|
||||
}
|
||||
|
||||
InputStream es = wrapStream(uc.getErrorStream());
|
||||
try {
|
||||
if (es!=null) {
|
||||
String error = IOUtils.toString(es, "UTF-8");
|
||||
if (e instanceof FileNotFoundException) {
|
||||
// pass through 404 Not Found to allow the caller to handle it intelligently
|
||||
throw (IOException) new FileNotFoundException(error).initCause(e);
|
||||
} else if (e instanceof HttpException) {
|
||||
HttpException http = (HttpException) e;
|
||||
throw (IOException) new HttpException(error, http.getResponseCode(), http.getResponseMessage(), http.getUrl(), e);
|
||||
} else {
|
||||
throw (IOException) new IOException(error).initCause(e);
|
||||
}
|
||||
} else
|
||||
throw e;
|
||||
} finally {
|
||||
IOUtils.closeQuietly(es);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
private static final List<String> METHODS_WITHOUT_BODY = asList("GET", "DELETE");
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.util.Properties;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
@@ -19,9 +22,17 @@ public abstract class AbstractGitHubApiTestBase extends Assert {
|
||||
public void setUp() throws Exception {
|
||||
File f = new File(System.getProperty("user.home"), ".github.kohsuke2");
|
||||
if (f.exists()) {
|
||||
Properties props = new Properties();
|
||||
FileInputStream in = null;
|
||||
try {
|
||||
in = new FileInputStream(f);
|
||||
props.load(in);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(in);
|
||||
}
|
||||
// use the non-standard credential preferentially, so that developers of this library do not have
|
||||
// to clutter their event stream.
|
||||
gitHub = GitHubBuilder.fromPropertyFile(f.getPath()).withRateLimitHandler(RateLimitHandler.FAIL).build();
|
||||
gitHub = GitHubBuilder.fromProperties(props).withRateLimitHandler(RateLimitHandler.FAIL).build();
|
||||
} else {
|
||||
gitHub = GitHubBuilder.fromCredentials().withRateLimitHandler(RateLimitHandler.FAIL).build();
|
||||
}
|
||||
|
||||
@@ -685,6 +685,15 @@ public class AppTest extends AbstractGitHubApiTestBase {
|
||||
assertFalse(all.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommitSearch() throws IOException {
|
||||
PagedSearchIterable<GHCommit> r = gitHub.searchCommits().author("kohsuke").list();
|
||||
assertTrue(r.getTotalCount() > 0);
|
||||
|
||||
GHCommit firstCommit = r.iterator().next();
|
||||
assertTrue(firstCommit.getFiles().size() > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIssueSearch() throws IOException {
|
||||
PagedSearchIterable<GHIssue> r = gitHub.searchIssues().mentions("kohsuke").isOpen().list();
|
||||
|
||||
82
src/test/java/org/kohsuke/github/GHBranchProtectionTest.java
Normal file
82
src/test/java/org/kohsuke/github/GHBranchProtectionTest.java
Normal file
@@ -0,0 +1,82 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.kohsuke.github.GHBranchProtection.EnforceAdmins;
|
||||
import org.kohsuke.github.GHBranchProtection.RequiredReviews;
|
||||
import org.kohsuke.github.GHBranchProtection.RequiredStatusChecks;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
public class GHBranchProtectionTest extends AbstractGitHubApiTestBase {
|
||||
private static final String BRANCH = "bp-test";
|
||||
private static final String BRANCH_REF = "heads/" + BRANCH;
|
||||
|
||||
private GHBranch branch;
|
||||
|
||||
private GHRepository repo;
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
repo = gitHub.getRepository("github-api-test-org/GHContentIntegrationTest").fork();
|
||||
|
||||
try {
|
||||
repo.getRef(BRANCH_REF);
|
||||
} catch (FileNotFoundException e) {
|
||||
repo.createRef("refs/" + BRANCH_REF, repo.getBranch("master").getSHA1());
|
||||
}
|
||||
|
||||
branch = repo.getBranch(BRANCH);
|
||||
|
||||
if (branch.isProtected()) {
|
||||
branch.disableProtection();
|
||||
}
|
||||
|
||||
branch = repo.getBranch(BRANCH);
|
||||
assertFalse(branch.isProtected());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnableBranchProtections() throws Exception {
|
||||
// team/user restrictions require an organization repo to test against
|
||||
GHBranchProtection protection = branch.enableProtection()
|
||||
.addRequiredChecks("test-status-check")
|
||||
.requireBranchIsUpToDate()
|
||||
.requireCodeOwnReviews()
|
||||
.dismissStaleReviews()
|
||||
.includeAdmins()
|
||||
.enable();
|
||||
|
||||
RequiredStatusChecks statusChecks = protection.getRequiredStatusChecks();
|
||||
assertNotNull(statusChecks);
|
||||
assertTrue(statusChecks.isRequiresBranchUpToDate());
|
||||
assertTrue(statusChecks.getContexts().contains("test-status-check"));
|
||||
|
||||
RequiredReviews requiredReviews = protection.getRequiredReviews();
|
||||
assertNotNull(requiredReviews);
|
||||
assertTrue(requiredReviews.isDismissStaleReviews());
|
||||
assertTrue(requiredReviews.isRequireCodeOwnerReviews());
|
||||
|
||||
EnforceAdmins enforceAdmins = protection.getEnforceAdmins();
|
||||
assertNotNull(enforceAdmins);
|
||||
assertTrue(enforceAdmins.isEnabled());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnableProtectionOnly() throws Exception {
|
||||
branch.enableProtection().enable();
|
||||
assertTrue(repo.getBranch(BRANCH).isProtected());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnableRequireReviewsOnly() throws Exception {
|
||||
GHBranchProtection protection = branch.enableProtection()
|
||||
.requireReviews()
|
||||
.enable();
|
||||
|
||||
assertNotNull(protection.getRequiredReviews());
|
||||
}
|
||||
}
|
||||
@@ -20,13 +20,6 @@ public class GHContentIntegrationTest extends AbstractGitHubApiTestBase {
|
||||
repo = gitHub.getRepository("github-api-test-org/GHContentIntegrationTest").fork();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBranchProtection() throws Exception {
|
||||
GHBranch b = repo.getBranch("master");
|
||||
b.enableProtection(EnforcementLevel.NON_ADMINS, "foo/bar");
|
||||
b.disableProtection();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetFileContent() throws Exception {
|
||||
GHContent content = repo.getFileContent("ghcontent-ro/a-file-with-content");
|
||||
|
||||
@@ -7,6 +7,9 @@ import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@@ -26,6 +29,33 @@ public class PullRequestTest extends AbstractGitHubApiTestBase {
|
||||
p.comment("Some comment");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPullRequestReviews() throws Exception {
|
||||
String name = rnd.next();
|
||||
GHPullRequest p = getRepository().createPullRequest(name, "stable", "master", "## test");
|
||||
GHPullRequestReview draftReview = p.createReview("Some draft review", null,
|
||||
GHPullRequestReviewComment.draft("Some niggle", "changelog.html", 1)
|
||||
);
|
||||
assertThat(draftReview.getState(), is(GHPullRequestReviewState.PENDING));
|
||||
assertThat(draftReview.getBody(), is("Some draft review"));
|
||||
assertThat(draftReview.getCommitId(), notNullValue());
|
||||
List<GHPullRequestReview> reviews = p.listReviews().asList();
|
||||
assertThat(reviews.size(), is(1));
|
||||
GHPullRequestReview review = reviews.get(0);
|
||||
assertThat(review.getState(), is(GHPullRequestReviewState.PENDING));
|
||||
assertThat(review.getBody(), is("Some draft review"));
|
||||
assertThat(review.getCommitId(), notNullValue());
|
||||
review.submit("Some review comment", GHPullRequestReviewState.COMMENTED);
|
||||
List<GHPullRequestReviewComment> comments = review.listReviewComments().asList();
|
||||
assertEquals(1, comments.size());
|
||||
GHPullRequestReviewComment comment = comments.get(0);
|
||||
assertEquals("Some niggle", comment.getBody());
|
||||
review = p.createReview("Some new review", null,
|
||||
GHPullRequestReviewComment.draft("Some niggle", "changelog.html", 1)
|
||||
);
|
||||
review.delete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPullRequestReviewComments() throws Exception {
|
||||
String name = rnd.next();
|
||||
|
||||
@@ -67,6 +67,32 @@ public class RepositoryTest extends AbstractGitHubApiTestBase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void LatestRepositoryExist() {
|
||||
try {
|
||||
// add the repository that have latest release
|
||||
GHRelease release = gitHub.getRepository("kamontat/CheckIDNumber").getLatestRelease();
|
||||
assertEquals("v3.0", release.getTagName());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void LatestRepositoryNotExist() {
|
||||
try {
|
||||
// add the repository that `NOT` have latest release
|
||||
GHRelease release = gitHub.getRepository("kamontat/Java8Example").getLatestRelease();
|
||||
assertNull(release);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
private GHRepository getRepository() throws IOException {
|
||||
return gitHub.getOrganization("github-api-test-org").getRepository("jenkins");
|
||||
|
||||
Reference in New Issue
Block a user