From 870d8ff0c4138bb30f2649758228a0413f482c32 Mon Sep 17 00:00:00 2001 From: Michael Pigg Date: Thu, 22 Dec 2022 11:37:45 -0500 Subject: [PATCH] Add support for GHE pre-receive hook configuration --- .../kohsuke/github/GHOrgPreReceiveHook.java | 41 +++++ .../org/kohsuke/github/GHOrganization.java | 7 + .../org/kohsuke/github/GHPreReceiveHook.java | 31 ++++ .../github/GHPreReceiveHookEnforcement.java | 9 ++ .../org/kohsuke/github/GHPreReceiveHooks.java | 142 ++++++++++++++++++ .../kohsuke/github/GHRepoPreReceiveHook.java | 28 ++++ .../java/org/kohsuke/github/GHRepository.java | 7 + 7 files changed, 265 insertions(+) create mode 100644 src/main/java/org/kohsuke/github/GHOrgPreReceiveHook.java create mode 100644 src/main/java/org/kohsuke/github/GHPreReceiveHook.java create mode 100644 src/main/java/org/kohsuke/github/GHPreReceiveHookEnforcement.java create mode 100644 src/main/java/org/kohsuke/github/GHPreReceiveHooks.java create mode 100644 src/main/java/org/kohsuke/github/GHRepoPreReceiveHook.java diff --git a/src/main/java/org/kohsuke/github/GHOrgPreReceiveHook.java b/src/main/java/org/kohsuke/github/GHOrgPreReceiveHook.java new file mode 100644 index 0000000000..73687c008a --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHOrgPreReceiveHook.java @@ -0,0 +1,41 @@ +package org.kohsuke.github; + +import java.io.IOException; +import java.net.URL; + +public class GHOrgPreReceiveHook extends GHPreReceiveHook { + + transient GHOrganization organization; + + boolean allowDownstreamConfiguration; + + public GHOrgPreReceiveHook() { + } + + public GHOrgPreReceiveHook(long id, GHPreReceiveHookEnforcement enforcement, boolean allowDownstreamConfiguration) { + this.id = id; + this.enforcement = enforcement.toParameterValue(); + this.allowDownstreamConfiguration = allowDownstreamConfiguration; + } + + @Override + public URL getHtmlUrl() throws IOException { + return null; + } + + GHOrgPreReceiveHook wrap(GHOrganization organization) { + this.organization = organization; + return this; + } + + static GHOrgPreReceiveHook makeHook(long id, + GHPreReceiveHookEnforcement enforcement, + boolean allowDownstreamConfiguration) { + final GHOrgPreReceiveHook hook = new GHOrgPreReceiveHook(); + hook.id = id; + hook.enforcement = enforcement.toParameterValue(); + hook.allowDownstreamConfiguration = allowDownstreamConfiguration; + return hook; + } + +} diff --git a/src/main/java/org/kohsuke/github/GHOrganization.java b/src/main/java/org/kohsuke/github/GHOrganization.java index 5b45e63143..7a4fe341d6 100644 --- a/src/main/java/org/kohsuke/github/GHOrganization.java +++ b/src/main/java/org/kohsuke/github/GHOrganization.java @@ -782,4 +782,11 @@ public GHHook createWebHook(URL url, Collection events) throws IOExcept public GHHook createWebHook(URL url) throws IOException { return createWebHook(url, null); } + + public GHPreReceiveHook configurePreReceiveHook(long id, + GHPreReceiveHookEnforcement enforcement, + boolean downstreamConfigurable) throws IOException { + return GHPreReceiveHooks.orgContext(this) + .configurePreReceiveHook(new GHOrgPreReceiveHook(id, enforcement, downstreamConfigurable)); + } } diff --git a/src/main/java/org/kohsuke/github/GHPreReceiveHook.java b/src/main/java/org/kohsuke/github/GHPreReceiveHook.java new file mode 100644 index 0000000000..3c75ef4888 --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHPreReceiveHook.java @@ -0,0 +1,31 @@ +package org.kohsuke.github; + +import java.util.Locale; + +public abstract class GHPreReceiveHook extends GHObject { + long id; + + String name; + + String enforcement; + + @Override + public long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getEnforcement() { + return enforcement; + } + + public GHPreReceiveHookEnforcement getEnforcementType() { + return Enum.valueOf(GHPreReceiveHookEnforcement.class, this.enforcement.toUpperCase(Locale.ENGLISH)); + } + public GHPreReceiveHook() { + } + +} diff --git a/src/main/java/org/kohsuke/github/GHPreReceiveHookEnforcement.java b/src/main/java/org/kohsuke/github/GHPreReceiveHookEnforcement.java new file mode 100644 index 0000000000..1d53636094 --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHPreReceiveHookEnforcement.java @@ -0,0 +1,9 @@ +package org.kohsuke.github; + +public enum GHPreReceiveHookEnforcement { + DISABLED, ENABLED, TESTING; + + public String toParameterValue() { + return this.name().toLowerCase(); + } +} diff --git a/src/main/java/org/kohsuke/github/GHPreReceiveHooks.java b/src/main/java/org/kohsuke/github/GHPreReceiveHooks.java new file mode 100644 index 0000000000..02ed4373b0 --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHPreReceiveHooks.java @@ -0,0 +1,142 @@ +package org.kohsuke.github; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public class GHPreReceiveHooks { + + static abstract class Context extends GitHubInteractiveObject { + + private Context(GitHub root) { + super(root); + } + + /** + * Collection. + * + * @return the string + */ + abstract String collection(); + + /** + * Collection class. + * + * @return the class + */ + abstract Class collectionClass(); + + /** + * Clazz. + * + * @return the class + */ + abstract Class clazz(); + + /** + * Wrap. + * + * @param hook + * the hook + * @return the GH hook + */ + abstract GHPreReceiveHook wrap(GHPreReceiveHook hook); + + abstract Map hookExtraParameters(GHPreReceiveHook hook); + + public GHPreReceiveHook configurePreReceiveHook(GHPreReceiveHook hook) throws IOException { + GHPreReceiveHook updatedHook = root().createRequest() + .method("PATCH") + .with("enforcement", hook.getEnforcement()) + .with(hookExtraParameters(hook)) + .withUrlPath(collection(), Long.toString(hook.getId())) + .fetch(clazz()); + + return wrap(updatedHook); + } + + } + + private static class OrgContext extends Context { + private final GHOrganization organization; + + private OrgContext(GHOrganization organization) { + super(organization.root()); + this.organization = organization; + } + + @Override + String collection() { + return String.format("/orgs/%s/pre-receive-hooks", organization.login); + } + + @Override + Class collectionClass() { + return GHOrgPreReceiveHook[].class; + } + + @Override + Class clazz() { + return GHOrgPreReceiveHook.class; + } + + @Override + GHPreReceiveHook wrap(GHPreReceiveHook hook) { + return ((GHOrgPreReceiveHook) hook).wrap(organization); + } + + @Override + Map hookExtraParameters(GHPreReceiveHook hook) { + final Map params = new HashMap<>(); + if (hook instanceof GHOrgPreReceiveHook) { + params.put("allow_downstream_configuration", + Boolean.valueOf(((GHOrgPreReceiveHook) hook).allowDownstreamConfiguration)); + } + return params; + } + } + + private static class RepositoryContext extends Context { + private final GHRepository repository; + private final GHUser owner; + + private RepositoryContext(GHRepository repository, GHUser owner) { + super(repository.root()); + this.repository = repository; + this.owner = owner; + } + + String collection() { + return String.format("/repos/%s/%s/pre-receive-hooks", owner.getLogin(), repository.getName()); + } + + @Override + Class collectionClass() { + return GHRepoPreReceiveHook[].class; + } + + @Override + Class clazz() { + return GHRepoPreReceiveHook.class; + } + + @Override + GHPreReceiveHook wrap(GHPreReceiveHook hook) { + return ((GHRepoPreReceiveHook) hook).wrap(repository); + } + + @Override + Map hookExtraParameters(GHPreReceiveHook hook) { + return Collections.emptyMap(); + } + } + + static Context repoContext(GHRepository repository, GHUser owner) { + return new RepositoryContext(repository, owner); + } + + static Context orgContext(GHOrganization organization) { + return new OrgContext(organization); + } +} diff --git a/src/main/java/org/kohsuke/github/GHRepoPreReceiveHook.java b/src/main/java/org/kohsuke/github/GHRepoPreReceiveHook.java new file mode 100644 index 0000000000..23f138044c --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHRepoPreReceiveHook.java @@ -0,0 +1,28 @@ +package org.kohsuke.github; + +import java.io.IOException; +import java.net.URL; + +public class GHRepoPreReceiveHook extends GHPreReceiveHook { + + transient GHRepository repository; + + public GHRepoPreReceiveHook() { + } + + public GHRepoPreReceiveHook(long id, GHPreReceiveHookEnforcement enforcement) { + this.id = id; + this.enforcement = enforcement.toParameterValue(); + } + + @Override + public URL getHtmlUrl() throws IOException { + return null; + } + + GHRepoPreReceiveHook wrap(GHRepository owner) { + this.repository = owner; + return this; + } + +} diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index fa5db64beb..ee959542a0 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -2463,6 +2463,13 @@ public GHHook createWebHook(URL url) throws IOException { return createWebHook(url, null); } + public GHPreReceiveHook setPreReceiveHookEnforcement(long id, GHPreReceiveHookEnforcement enforcement) + throws IOException { + GHRepoPreReceiveHook hook = new GHRepoPreReceiveHook(); + return GHPreReceiveHooks.repoContext(this, owner) + .configurePreReceiveHook(new GHRepoPreReceiveHook(id, enforcement)); + } + /** * Returns a set that represents the post-commit hook URLs. The returned set is live, and changes made to them are * reflected to GitHub.