Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

- branch protection enhancements #435

Merged
merged 1 commit into from
Aug 30, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main/java/org/kohsuke/github/GHBranch.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public URL getProtectionUrl() {

@Preview @Deprecated
public GHBranchProtection getProtection() throws IOException {
return root.retrieve().withPreview(LOKI).to(protection_url, GHBranchProtection.class);
return root.retrieve().withPreview(LOKI).to(protection_url, GHBranchProtection.class).wrap(this);
}

/**
Expand All @@ -82,7 +82,7 @@ public String getSHA1() {
*/
@Preview @Deprecated
public void disableProtection() throws IOException {
new Requester(root).method("DELETE").withPreview(LOKI).to(protection_url);
new Requester(root).method("DELETE").to(protection_url);
}

/**
Expand Down
58 changes: 58 additions & 0 deletions src/main/java/org/kohsuke/github/GHBranchProtection.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,21 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

import static org.kohsuke.github.Previews.ZZZAX;

import java.io.IOException;
import java.util.Collection;

@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD",
"URF_UNREAD_FIELD" }, justification = "JSON API")
public class GHBranchProtection {
private static final String REQUIRE_SIGNATURES_URI = "/required_signatures";

@JsonProperty("enforce_admins")
private EnforceAdmins enforceAdmins;

private GitHub root;

@JsonProperty("required_pull_request_reviews")
private RequiredReviews requiredReviews;

Expand All @@ -23,6 +30,18 @@ public class GHBranchProtection {
@JsonProperty
private String url;

@Preview @Deprecated
public RequiredSignatures enabledSignedCommits() throws IOException {
return requester().method("POST")
.to(url + REQUIRE_SIGNATURES_URI, RequiredSignatures.class);
}

@Preview @Deprecated
public void disableSignedCommits() throws IOException {
requester().method("DELETE")
.to(url + REQUIRE_SIGNATURES_URI);
}

public EnforceAdmins getEnforceAdmins() {
return enforceAdmins;
}
Expand All @@ -31,6 +50,12 @@ public RequiredReviews getRequiredReviews() {
return requiredReviews;
}

@Preview @Deprecated
public RequiredSignatures getRequiredSignatures() throws IOException {
return requester().method("GET")
.to(url + REQUIRE_SIGNATURES_URI, RequiredSignatures.class);
}

public RequiredStatusChecks getRequiredStatusChecks() {
return requiredStatusChecks;
}
Expand All @@ -43,6 +68,15 @@ public String getUrl() {
return url;
}

GHBranchProtection wrap(GHBranch branch) {
this.root = branch.getRoot();
return this;
}

private Requester requester() {
return new Requester(root).withPreview(ZZZAX);
}

public static class EnforceAdmins {
@JsonProperty
private boolean enabled;
Expand All @@ -69,6 +103,9 @@ public static class RequiredReviews {
@JsonProperty("require_code_owner_reviews")
private boolean requireCodeOwnerReviews;

@JsonProperty("required_approving_review_count")
private int requiredReviewers;

@JsonProperty
private String url;

Expand All @@ -87,6 +124,27 @@ public boolean isDismissStaleReviews() {
public boolean isRequireCodeOwnerReviews() {
return requireCodeOwnerReviews;
}

public int getRequiredReviewers()
{
return requiredReviewers;
}
}

public static class RequiredSignatures {
@JsonProperty
private boolean enabled;

@JsonProperty
private String url;

public String getUrl() {
return url;
}

public boolean isEnabled() {
return enabled;
}
}

public static class RequiredStatusChecks {
Expand Down
34 changes: 25 additions & 9 deletions src/main/java/org/kohsuke/github/GHBranchProtectionBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ public GHBranchProtectionBuilder addRequiredChecks(String... checks) {
}

public GHBranchProtectionBuilder dismissStaleReviews() {
getPrReviews().put("dismiss_stale_reviews", true);
dismissStaleReviews(true);
return this;
}

public GHBranchProtectionBuilder dismissStaleReviews(boolean v) {
getPrReviews().put("dismiss_stale_reviews", v);
return this;
}

Expand All @@ -54,7 +59,8 @@ public GHBranchProtection enable() throws IOException {
.withNullable("required_pull_request_reviews", prReviews)
.withNullable("restrictions", restrictions)
.withNullable("enforce_admins", enforceAdmins)
.to(branch.getProtectionUrl().toString(), GHBranchProtection.class);
.to(branch.getProtectionUrl().toString(), GHBranchProtection.class)
.wrap(branch);
}

public GHBranchProtectionBuilder includeAdmins() {
Expand All @@ -66,6 +72,11 @@ public GHBranchProtectionBuilder includeAdmins(boolean v) {
return this;
}

public GHBranchProtectionBuilder requiredReviewers(int v) {
getPrReviews().put("required_approving_review_count", v);
return this;
}

public GHBranchProtectionBuilder requireBranchIsUpToDate() {
return requireBranchIsUpToDate(true);
}
Expand All @@ -89,6 +100,16 @@ public GHBranchProtectionBuilder requireReviews() {
return this;
}

public GHBranchProtectionBuilder restrictReviewDismissals() {
getPrReviews();

if (!prReviews.containsKey("dismissal_restrictions")) {
prReviews.put("dismissal_restrictions", new Restrictions());
}

return this;
}

public GHBranchProtectionBuilder restrictPushAccess() {
getRestrictions();
return this;
Expand Down Expand Up @@ -151,12 +172,7 @@ public GHBranchProtectionBuilder userReviewDismissals(GHUser... users) {
}

private void addReviewRestriction(String restriction, boolean isTeam) {
getPrReviews();

if (!prReviews.containsKey("dismissal_restrictions")) {
prReviews.put("dismissal_restrictions", new Restrictions());
}

restrictReviewDismissals();
Restrictions restrictions = (Restrictions) prReviews.get("dismissal_restrictions");

if (isTeam) {
Expand Down Expand Up @@ -188,7 +204,7 @@ private StatusChecks getStatusChecks() {
}

private Requester requester() {
return new Requester(branch.getRoot()).withPreview(LOKI);
return new Requester(branch.getRoot()).withPreview(LUKE_CAGE);
}

private static class Restrictions {
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/org/kohsuke/github/Previews.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
*/
/*package*/ class Previews {
static final String LOKI = "application/vnd.github.loki-preview+json";
static final String LUKE_CAGE = "application/vnd.github.luke-cage-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 CLOAK = "application/vnd.github.cloak-preview";
static final String ZZZAX = "application/vnd.github.zzzax-preview+json";
}
27 changes: 27 additions & 0 deletions src/test/java/org/kohsuke/github/GHBranchProtectionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.junit.Test;
import org.kohsuke.github.GHBranchProtection.EnforceAdmins;
import org.kohsuke.github.GHBranchProtection.RequiredReviews;
import org.kohsuke.github.GHBranchProtection.RequiredSignatures;
import org.kohsuke.github.GHBranchProtection.RequiredStatusChecks;

import java.io.FileNotFoundException;
Expand Down Expand Up @@ -32,6 +33,12 @@ public void setUp() throws Exception {
branch = repo.getBranch(BRANCH);

if (branch.isProtected()) {
GHBranchProtection protection = branch.getProtection();
if (protection.getRequiredSignatures().isEnabled()) {
protection.disableSignedCommits();
}

assertFalse(protection.getRequiredSignatures().isEnabled());
branch.disableProtection();
}

Expand All @@ -47,6 +54,7 @@ public void testEnableBranchProtections() throws Exception {
.requireBranchIsUpToDate()
.requireCodeOwnReviews()
.dismissStaleReviews()
.requiredReviewers(2)
.includeAdmins()
.enable();

Expand All @@ -59,6 +67,7 @@ public void testEnableBranchProtections() throws Exception {
assertNotNull(requiredReviews);
assertTrue(requiredReviews.isDismissStaleReviews());
assertTrue(requiredReviews.isRequireCodeOwnerReviews());
assertEquals(2, requiredReviews.getRequiredReviewers());

EnforceAdmins enforceAdmins = protection.getEnforceAdmins();
assertNotNull(enforceAdmins);
Expand All @@ -79,4 +88,22 @@ public void testEnableRequireReviewsOnly() throws Exception {

assertNotNull(protection.getRequiredReviews());
}

@Test
public void testSignedCommits() throws Exception {
GHBranchProtection protection = branch.enableProtection().enable();

RequiredSignatures signatures = protection.getRequiredSignatures();
assertNotNull(signatures);
assertFalse(signatures.isEnabled());

signatures = protection.enabledSignedCommits();
assertNotNull(signatures);
assertTrue(signatures.isEnabled());

protection.disableSignedCommits();
signatures = protection.getRequiredSignatures();
assertNotNull(signatures);
assertFalse(signatures.isEnabled());
}
}