Notify SCMSourceOwners about changes for GitLab Push Hooks (Fixes #298)
This commit is contained in:
parent
1ea956f34c
commit
d404a9dc4d
|
@ -20,6 +20,7 @@ import hudson.security.AccessDeniedException2;
|
|||
import hudson.security.Permission;
|
||||
import hudson.util.HttpResponses;
|
||||
import jenkins.model.Jenkins;
|
||||
import jenkins.scm.api.SCMSourceOwner;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.kohsuke.stapler.StaplerRequest;
|
||||
import org.kohsuke.stapler.StaplerResponse;
|
||||
|
@ -46,20 +47,25 @@ public class ActionResolver {
|
|||
|
||||
public WebHookAction resolve(final String projectName, StaplerRequest request) {
|
||||
Iterator<String> restOfPathParts = Splitter.on('/').omitEmptyStrings().split(request.getRestOfPath()).iterator();
|
||||
Job<?, ?> project = resolveProject(projectName, restOfPathParts);
|
||||
Item project = resolveProject(projectName, restOfPathParts);
|
||||
if (project == null) {
|
||||
throw HttpResponses.notFound();
|
||||
}
|
||||
return resolveAction(project, Joiner.on('/').join(restOfPathParts), request);
|
||||
}
|
||||
|
||||
private WebHookAction resolveAction(Job<?, ?> project, String restOfPath, StaplerRequest request) {
|
||||
private WebHookAction resolveAction(Item project, String restOfPath, StaplerRequest request) {
|
||||
String method = request.getMethod();
|
||||
if (method.equals("POST")) {
|
||||
checkPermission(Item.BUILD);
|
||||
return onPost(project, request);
|
||||
} else if (method.equals("GET")) {
|
||||
return onGet(project, restOfPath, request);
|
||||
if (project instanceof Job<?, ?>) {
|
||||
return onGet((Job<?, ?>) project, restOfPath, request);
|
||||
} else {
|
||||
LOGGER.log(Level.FINE, "GET is not supported for this project {0}", project.getName());
|
||||
return new NoopAction();
|
||||
}
|
||||
}
|
||||
LOGGER.log(Level.FINE, "Unsupported HTTP method: {0}", method);
|
||||
return new NoopAction();
|
||||
|
@ -94,7 +100,7 @@ public class ActionResolver {
|
|||
}
|
||||
}
|
||||
|
||||
private WebHookAction onPost(Job<?, ?> project, StaplerRequest request) {
|
||||
private WebHookAction onPost(Item project, StaplerRequest request) {
|
||||
String eventHeader = request.getHeader("X-Gitlab-Event");
|
||||
if (eventHeader == null) {
|
||||
LOGGER.log(Level.FINE, "Missing X-Gitlab-Event header");
|
||||
|
@ -107,7 +113,7 @@ public class ActionResolver {
|
|||
case "Tag Push Hook":
|
||||
return new PushBuildAction(project, getRequestBody(request));
|
||||
case "Note Hook":
|
||||
return new NoteBuildAction(project, getRequestBody(request));
|
||||
return new NoteBuildAction(project, getRequestBody(request));
|
||||
default:
|
||||
LOGGER.log(Level.FINE, "Unsupported X-Gitlab-Event header: {0}", eventHeader);
|
||||
return new NoopAction();
|
||||
|
@ -125,17 +131,17 @@ public class ActionResolver {
|
|||
return requestBody;
|
||||
}
|
||||
|
||||
private Job<?, ?> resolveProject(final String projectName, final Iterator<String> restOfPathParts) {
|
||||
return ACLUtil.impersonate(ACL.SYSTEM, new ACLUtil.Function<Job<?, ?>>() {
|
||||
public Job<?, ?> invoke() {
|
||||
private Item resolveProject(final String projectName, final Iterator<String> restOfPathParts) {
|
||||
return ACLUtil.impersonate(ACL.SYSTEM, new ACLUtil.Function<Item>() {
|
||||
public Item invoke() {
|
||||
final Jenkins jenkins = Jenkins.getInstance();
|
||||
if (jenkins != null) {
|
||||
Item item = jenkins.getItemByFullName(projectName);
|
||||
while (item instanceof ItemGroup<?> && !(item instanceof Job<?, ?>) && restOfPathParts.hasNext()) {
|
||||
while (item instanceof ItemGroup<?> && !(item instanceof Job<?, ?> || item instanceof SCMSourceOwner) && restOfPathParts.hasNext()) {
|
||||
item = jenkins.getItem(restOfPathParts.next(), (ItemGroup<?>) item);
|
||||
}
|
||||
if (item instanceof Job<?, ?>) {
|
||||
return (Job<?, ?>) item;
|
||||
if (item instanceof Job<?, ?> || item instanceof SCMSourceOwner) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
LOGGER.log(Level.FINE, "No project found: {0}, {1}", toArray(projectName, Joiner.on('/').join(restOfPathParts)));
|
||||
|
@ -149,7 +155,7 @@ public class ActionResolver {
|
|||
try {
|
||||
Jenkins.getInstance().checkPermission(permission);
|
||||
} catch (AccessDeniedException2 e) {
|
||||
throw HttpResponses.error(403, e.getMessage());
|
||||
throw HttpResponses.errorWithoutStack(403, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.dabsquared.gitlabjenkins.gitlab.hook.model.MergeRequestHook;
|
|||
import com.dabsquared.gitlabjenkins.gitlab.hook.model.MergeRequestObjectAttributes;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.hook.model.Project;
|
||||
import com.dabsquared.gitlabjenkins.util.JsonUtil;
|
||||
import hudson.model.Item;
|
||||
import hudson.model.Job;
|
||||
import hudson.security.ACL;
|
||||
import hudson.util.HttpResponses;
|
||||
|
@ -20,10 +21,10 @@ import static com.dabsquared.gitlabjenkins.util.JsonUtil.toPrettyPrint;
|
|||
public class MergeRequestBuildAction extends BuildWebHookAction {
|
||||
|
||||
private final static Logger LOGGER = Logger.getLogger(MergeRequestBuildAction.class.getName());
|
||||
private Job<?, ?> project;
|
||||
private Item project;
|
||||
private MergeRequestHook mergeRequestHook;
|
||||
|
||||
public MergeRequestBuildAction(Job<?, ?> project, String json) {
|
||||
public MergeRequestBuildAction(Item project, String json) {
|
||||
LOGGER.log(Level.FINE, "MergeRequest: {0}", toPrettyPrint(json));
|
||||
this.project = project;
|
||||
this.mergeRequestHook = JsonUtil.read(json, MergeRequestHook.class);
|
||||
|
@ -46,9 +47,12 @@ public class MergeRequestBuildAction extends BuildWebHookAction {
|
|||
}
|
||||
|
||||
public void execute() {
|
||||
if (!(project instanceof Job<?, ?>)) {
|
||||
throw HttpResponses.errorWithoutStack(409, "Merge Request Hook is not supported for this project");
|
||||
}
|
||||
ACL.impersonate(ACL.SYSTEM, new Runnable() {
|
||||
public void run() {
|
||||
GitLabPushTrigger trigger = GitLabPushTrigger.getFromJob(project);
|
||||
GitLabPushTrigger trigger = GitLabPushTrigger.getFromJob((Job<?, ?>) project);
|
||||
if (trigger != null) {
|
||||
trigger.onPost(mergeRequestHook);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.dabsquared.gitlabjenkins.GitLabPushTrigger;
|
|||
import com.dabsquared.gitlabjenkins.gitlab.hook.model.NoteHook;
|
||||
import com.dabsquared.gitlabjenkins.util.JsonUtil;
|
||||
import com.dabsquared.gitlabjenkins.webhook.WebHookAction;
|
||||
import hudson.model.Item;
|
||||
import hudson.model.Job;
|
||||
import hudson.security.ACL;
|
||||
import hudson.util.HttpResponses;
|
||||
|
@ -20,19 +21,22 @@ import static com.dabsquared.gitlabjenkins.util.JsonUtil.toPrettyPrint;
|
|||
public class NoteBuildAction implements WebHookAction {
|
||||
|
||||
private final static Logger LOGGER = Logger.getLogger(NoteBuildAction.class.getName());
|
||||
private Job<?, ?> project;
|
||||
private Item project;
|
||||
private NoteHook noteHook;
|
||||
|
||||
public NoteBuildAction(Job<?, ?> project, String json) {
|
||||
public NoteBuildAction(Item project, String json) {
|
||||
LOGGER.log(Level.FINE, "Note: {0}", toPrettyPrint(json));
|
||||
this.project = project;
|
||||
this.noteHook = JsonUtil.read(json, NoteHook.class);
|
||||
}
|
||||
|
||||
public void execute(StaplerResponse response) {
|
||||
if (!(project instanceof Job<?, ?>)) {
|
||||
throw HttpResponses.errorWithoutStack(409, "Note Hook is not supported for this project");
|
||||
}
|
||||
ACL.impersonate(ACL.SYSTEM, new Runnable() {
|
||||
public void run() {
|
||||
GitLabPushTrigger trigger = GitLabPushTrigger.getFromJob(project);
|
||||
GitLabPushTrigger trigger = GitLabPushTrigger.getFromJob((Job<?, ?>) project);
|
||||
if (trigger != null) {
|
||||
trigger.onPost(noteHook);
|
||||
}
|
||||
|
|
|
@ -4,19 +4,24 @@ import com.dabsquared.gitlabjenkins.GitLabPushTrigger;
|
|||
import com.dabsquared.gitlabjenkins.gitlab.hook.model.Project;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.hook.model.PushHook;
|
||||
import com.dabsquared.gitlabjenkins.util.JsonUtil;
|
||||
import com.dabsquared.gitlabjenkins.webhook.WebHookAction;
|
||||
import hudson.model.Item;
|
||||
import hudson.model.Job;
|
||||
import hudson.security.ACL;
|
||||
import hudson.util.HttpResponses;
|
||||
import jenkins.plugins.git.GitSCMSource;
|
||||
import jenkins.scm.api.SCMSource;
|
||||
import jenkins.scm.api.SCMSourceOwner;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.kohsuke.stapler.StaplerResponse;
|
||||
import org.eclipse.jgit.transport.URIish;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.dabsquared.gitlabjenkins.util.JsonUtil.toPrettyPrint;
|
||||
import static com.dabsquared.gitlabjenkins.util.LoggerUtil.toArray;
|
||||
|
||||
/**
|
||||
* @author Robin Müller
|
||||
|
@ -24,11 +29,11 @@ import static com.dabsquared.gitlabjenkins.util.JsonUtil.toPrettyPrint;
|
|||
public class PushBuildAction extends BuildWebHookAction {
|
||||
|
||||
private final static Logger LOGGER = Logger.getLogger(PushBuildAction.class.getName());
|
||||
private final Job<?, ?> project;
|
||||
private final Item project;
|
||||
|
||||
private PushHook pushHook;
|
||||
|
||||
public PushBuildAction(Job<?, ?> project, String json) {
|
||||
public PushBuildAction(Item project, String json) {
|
||||
LOGGER.log(Level.FINE, "Push: {0}", toPrettyPrint(json));
|
||||
this.project = project;
|
||||
this.pushHook = JsonUtil.read(json, PushHook.class);
|
||||
|
@ -58,14 +63,45 @@ public class PushBuildAction extends BuildWebHookAction {
|
|||
return;
|
||||
}
|
||||
|
||||
ACL.impersonate(ACL.SYSTEM, new Runnable() {
|
||||
public void run() {
|
||||
GitLabPushTrigger trigger = GitLabPushTrigger.getFromJob(project);
|
||||
if (trigger != null) {
|
||||
trigger.onPost(pushHook);
|
||||
if (project instanceof Job<?, ?>) {
|
||||
ACL.impersonate(ACL.SYSTEM, new Runnable() {
|
||||
public void run() {
|
||||
GitLabPushTrigger trigger = GitLabPushTrigger.getFromJob((Job<?, ?>) project);
|
||||
if (trigger != null) {
|
||||
trigger.onPost(pushHook);
|
||||
}
|
||||
}
|
||||
});
|
||||
throw HttpResponses.ok();
|
||||
}
|
||||
if (project instanceof SCMSourceOwner) {
|
||||
ACL.impersonate(ACL.SYSTEM, new SCMSourceOwnerNotifier());
|
||||
throw HttpResponses.ok();
|
||||
}
|
||||
throw HttpResponses.errorWithoutStack(409, "Push Hook is not supported for this project");
|
||||
}
|
||||
|
||||
private class SCMSourceOwnerNotifier implements Runnable {
|
||||
public void run() {
|
||||
for (SCMSource scmSource : ((SCMSourceOwner) project).getSCMSources()) {
|
||||
if (scmSource instanceof GitSCMSource) {
|
||||
GitSCMSource gitSCMSource = (GitSCMSource) scmSource;
|
||||
try {
|
||||
if (new URIish(gitSCMSource.getRemote()).equals(new URIish(gitSCMSource.getRemote()))) {
|
||||
if (!gitSCMSource.isIgnoreOnPushNotifications()) {
|
||||
LOGGER.log(Level.FINE, "Notify scmSourceOwner {0} about changes for {1}",
|
||||
toArray(project.getName(), gitSCMSource.getRemote()));
|
||||
((SCMSourceOwner) project).onSCMSourceUpdated(scmSource);
|
||||
} else {
|
||||
LOGGER.log(Level.FINE, "Ignore on push notification for scmSourceOwner {0} about changes for {1}",
|
||||
toArray(project.getName(), gitSCMSource.getRemote()));
|
||||
}
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
throw HttpResponses.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue