Add the ability to run a new project created hook
Notify users when a new project has been created. This could solve an issue in the Jenkins gerrit-trigger-plugin where we need to continuously fetch the whole project list (using the command gerrit ls-projects) to get project name auto completion working in the Project Configuration pages. By letting the plug-in pickup new projects on the fly, our auto completion would be up-to-date much quicker and also drain less resources from Gerrit. The hook takes the following form: project-created --project <project name> --head <head name> Change-Id: Ibf53946b12df4efd2f929fa7fc6d23499ed7ed88
This commit is contained in:
parent
507b58dae2
commit
53286f2503
@ -153,6 +153,19 @@ hashtags:: List of hashtags on the change after tags were added or removed
|
|||||||
eventCreatedOn:: Time in seconds since the UNIX epoch when this event was
|
eventCreatedOn:: Time in seconds since the UNIX epoch when this event was
|
||||||
created.
|
created.
|
||||||
|
|
||||||
|
=== Project Created
|
||||||
|
|
||||||
|
Sent when a new project has been created.
|
||||||
|
|
||||||
|
type:: "project-created"
|
||||||
|
|
||||||
|
projectName:: The created project name
|
||||||
|
|
||||||
|
projectHead:: The created project head name
|
||||||
|
|
||||||
|
eventCreatedOn:: Time in seconds since the UNIX epoch when this event was
|
||||||
|
created.
|
||||||
|
|
||||||
=== Merge Failed
|
=== Merge Failed
|
||||||
|
|
||||||
Sent when a change has failed to be merged into the git repository.
|
Sent when a change has failed to be merged into the git repository.
|
||||||
|
@ -1832,6 +1832,11 @@ Optional filename for the draft published hook, if not specified then
|
|||||||
Optional filename for the hashtags changed hook, if not specified then
|
Optional filename for the hashtags changed hook, if not specified then
|
||||||
`hashtags-changed` will be used.
|
`hashtags-changed` will be used.
|
||||||
|
|
||||||
|
[[hooks.projectCreatedHook]]hooks.projectCreatedHook::
|
||||||
|
+
|
||||||
|
Optional filename for the project created hook, if not specified then
|
||||||
|
`project-created` will be used.
|
||||||
|
|
||||||
[[hooks.mergeFailedHook]]hooks.mergeFailedHook::
|
[[hooks.mergeFailedHook]]hooks.mergeFailedHook::
|
||||||
+
|
+
|
||||||
Optional filename for the merge failed hook, if not specified then
|
Optional filename for the merge failed hook, if not specified then
|
||||||
|
@ -110,6 +110,14 @@ Called whenever a ref has been updated.
|
|||||||
ref-updated --oldrev <old rev> --newrev <new rev> --refname <ref name> --project <project name> --submitter <submitter>
|
ref-updated --oldrev <old rev> --newrev <new rev> --refname <ref name> --project <project name> --submitter <submitter>
|
||||||
====
|
====
|
||||||
|
|
||||||
|
=== project-created
|
||||||
|
|
||||||
|
Called whenever a project has been created.
|
||||||
|
|
||||||
|
====
|
||||||
|
project-created --project <project name> --head <head name>
|
||||||
|
====
|
||||||
|
|
||||||
=== reviewer-added
|
=== reviewer-added
|
||||||
|
|
||||||
Called whenever a reviewer is added to a change.
|
Called whenever a reviewer is added to a change.
|
||||||
|
@ -20,6 +20,7 @@ import com.google.gerrit.common.data.ContributorAgreement;
|
|||||||
import com.google.gerrit.common.data.LabelType;
|
import com.google.gerrit.common.data.LabelType;
|
||||||
import com.google.gerrit.common.data.LabelTypes;
|
import com.google.gerrit.common.data.LabelTypes;
|
||||||
import com.google.gerrit.extensions.events.LifecycleListener;
|
import com.google.gerrit.extensions.events.LifecycleListener;
|
||||||
|
import com.google.gerrit.extensions.events.NewProjectCreatedListener;
|
||||||
import com.google.gerrit.extensions.registration.DynamicSet;
|
import com.google.gerrit.extensions.registration.DynamicSet;
|
||||||
import com.google.gerrit.lifecycle.LifecycleModule;
|
import com.google.gerrit.lifecycle.LifecycleModule;
|
||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
@ -40,11 +41,11 @@ import com.google.gerrit.server.events.ChangeMergedEvent;
|
|||||||
import com.google.gerrit.server.events.ChangeRestoredEvent;
|
import com.google.gerrit.server.events.ChangeRestoredEvent;
|
||||||
import com.google.gerrit.server.events.CommentAddedEvent;
|
import com.google.gerrit.server.events.CommentAddedEvent;
|
||||||
import com.google.gerrit.server.events.DraftPublishedEvent;
|
import com.google.gerrit.server.events.DraftPublishedEvent;
|
||||||
import com.google.gerrit.server.events.Event;
|
|
||||||
import com.google.gerrit.server.events.EventFactory;
|
import com.google.gerrit.server.events.EventFactory;
|
||||||
import com.google.gerrit.server.events.HashtagsChangedEvent;
|
import com.google.gerrit.server.events.HashtagsChangedEvent;
|
||||||
import com.google.gerrit.server.events.MergeFailedEvent;
|
import com.google.gerrit.server.events.MergeFailedEvent;
|
||||||
import com.google.gerrit.server.events.PatchSetCreatedEvent;
|
import com.google.gerrit.server.events.PatchSetCreatedEvent;
|
||||||
|
import com.google.gerrit.server.events.ProjectCreatedEvent;
|
||||||
import com.google.gerrit.server.events.RefUpdatedEvent;
|
import com.google.gerrit.server.events.RefUpdatedEvent;
|
||||||
import com.google.gerrit.server.events.ReviewerAddedEvent;
|
import com.google.gerrit.server.events.ReviewerAddedEvent;
|
||||||
import com.google.gerrit.server.events.TopicChangedEvent;
|
import com.google.gerrit.server.events.TopicChangedEvent;
|
||||||
@ -89,7 +90,7 @@ import java.util.concurrent.TimeoutException;
|
|||||||
/** Spawns local executables when a hook action occurs. */
|
/** Spawns local executables when a hook action occurs. */
|
||||||
@Singleton
|
@Singleton
|
||||||
public class ChangeHookRunner implements ChangeHooks, EventDispatcher,
|
public class ChangeHookRunner implements ChangeHooks, EventDispatcher,
|
||||||
EventSource, LifecycleListener {
|
EventSource, LifecycleListener, NewProjectCreatedListener {
|
||||||
/** A logger for this class. */
|
/** A logger for this class. */
|
||||||
private static final Logger log = LoggerFactory.getLogger(ChangeHookRunner.class);
|
private static final Logger log = LoggerFactory.getLogger(ChangeHookRunner.class);
|
||||||
|
|
||||||
@ -100,6 +101,7 @@ public class ChangeHookRunner implements ChangeHooks, EventDispatcher,
|
|||||||
bind(ChangeHooks.class).to(ChangeHookRunner.class);
|
bind(ChangeHooks.class).to(ChangeHookRunner.class);
|
||||||
bind(EventDispatcher.class).to(ChangeHookRunner.class);
|
bind(EventDispatcher.class).to(ChangeHookRunner.class);
|
||||||
bind(EventSource.class).to(ChangeHookRunner.class);
|
bind(EventSource.class).to(ChangeHookRunner.class);
|
||||||
|
DynamicSet.bind(binder(), NewProjectCreatedListener.class).to(ChangeHookRunner.class);
|
||||||
listener().to(ChangeHookRunner.class);
|
listener().to(ChangeHookRunner.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,6 +211,9 @@ public class ChangeHookRunner implements ChangeHooks, EventDispatcher,
|
|||||||
/** Path of the hashtags changed hook */
|
/** Path of the hashtags changed hook */
|
||||||
private final Path hashtagsChangedHook;
|
private final Path hashtagsChangedHook;
|
||||||
|
|
||||||
|
/** Path of the project created hook. */
|
||||||
|
private final Path projectCreatedHook;
|
||||||
|
|
||||||
private final String anonymousCowardName;
|
private final String anonymousCowardName;
|
||||||
|
|
||||||
/** Repository Manager. */
|
/** Repository Manager. */
|
||||||
@ -282,6 +287,7 @@ public class ChangeHookRunner implements ChangeHooks, EventDispatcher,
|
|||||||
claSignedHook = hook(config, hooksPath, "cla-signed");
|
claSignedHook = hook(config, hooksPath, "cla-signed");
|
||||||
refUpdateHook = hook(config, hooksPath, "ref-update");
|
refUpdateHook = hook(config, hooksPath, "ref-update");
|
||||||
hashtagsChangedHook = hook(config, hooksPath, "hashtags-changed");
|
hashtagsChangedHook = hook(config, hooksPath, "hashtags-changed");
|
||||||
|
projectCreatedHook = hook(config, hooksPath, "project-created");
|
||||||
|
|
||||||
syncHookTimeout = config.getInt("hooks", "syncHookTimeout", 30);
|
syncHookTimeout = config.getInt("hooks", "syncHookTimeout", 30);
|
||||||
syncHookThreadPool = Executors.newCachedThreadPool(
|
syncHookThreadPool = Executors.newCachedThreadPool(
|
||||||
@ -346,6 +352,20 @@ public class ChangeHookRunner implements ChangeHooks, EventDispatcher,
|
|||||||
return runSyncHook(project.getNameKey(), refUpdateHook, args);
|
return runSyncHook(project.getNameKey(), refUpdateHook, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doProjectCreatedHook(Project.NameKey project, String headName) {
|
||||||
|
ProjectCreatedEvent event = new ProjectCreatedEvent();
|
||||||
|
event.projectName = project.get();
|
||||||
|
event.headName = headName;
|
||||||
|
fireEvent(project, event);
|
||||||
|
|
||||||
|
List<String> args = new ArrayList<>();
|
||||||
|
addArg(args, "--project", project.get());
|
||||||
|
addArg(args, "--head", headName);
|
||||||
|
|
||||||
|
runHook(project, projectCreatedHook, args);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fire the Patchset Created Hook.
|
* Fire the Patchset Created Hook.
|
||||||
*
|
*
|
||||||
@ -695,24 +715,24 @@ public class ChangeHookRunner implements ChangeHooks, EventDispatcher,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postEvent(Change change, Event event, ReviewDb db)
|
public void postEvent(Change change, com.google.gerrit.server.events.Event event,
|
||||||
throws OrmException {
|
ReviewDb db) throws OrmException {
|
||||||
fireEvent(change, event, db);
|
fireEvent(change, event, db);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postEvent(Branch.NameKey branchName, Event event) {
|
public void postEvent(Branch.NameKey branchName, com.google.gerrit.server.events.Event event) {
|
||||||
fireEvent(branchName, event);
|
fireEvent(branchName, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fireEventForUnrestrictedListeners(Event event) {
|
private void fireEventForUnrestrictedListeners(com.google.gerrit.server.events.Event event) {
|
||||||
for (EventListener listener : unrestrictedListeners) {
|
for (EventListener listener : unrestrictedListeners) {
|
||||||
listener.onEvent(event);
|
listener.onEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fireEvent(Change change, Event event, ReviewDb db)
|
private void fireEvent(Change change, com.google.gerrit.server.events.Event event,
|
||||||
throws OrmException {
|
ReviewDb db) throws OrmException {
|
||||||
for (EventListenerHolder holder : listeners.values()) {
|
for (EventListenerHolder holder : listeners.values()) {
|
||||||
if (isVisibleTo(change, holder.user, db)) {
|
if (isVisibleTo(change, holder.user, db)) {
|
||||||
holder.listener.onEvent(event);
|
holder.listener.onEvent(event);
|
||||||
@ -722,7 +742,32 @@ public class ChangeHookRunner implements ChangeHooks, EventDispatcher,
|
|||||||
fireEventForUnrestrictedListeners( event );
|
fireEventForUnrestrictedListeners( event );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fireEvent(Branch.NameKey branchName, Event event) {
|
private void fireEvent(Project.NameKey project, ProjectCreatedEvent event) {
|
||||||
|
for (EventListenerHolder holder : listeners.values()) {
|
||||||
|
if (isVisibleTo(project, event, holder.user)) {
|
||||||
|
holder.listener.onEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fireEventForUnrestrictedListeners(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fireEventForUnrestrictedListeners(ProjectCreatedEvent event) {
|
||||||
|
for (EventListener listener : unrestrictedListeners) {
|
||||||
|
listener.onEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isVisibleTo(Project.NameKey project, ProjectCreatedEvent event, CurrentUser user) {
|
||||||
|
ProjectState pe = projectCache.get(project);
|
||||||
|
if (pe == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ProjectControl pc = pe.controlFor(user);
|
||||||
|
return pc.controlForRef(event.getHeadName()).isVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fireEvent(Branch.NameKey branchName, com.google.gerrit.server.events.Event event) {
|
||||||
for (EventListenerHolder holder : listeners.values()) {
|
for (EventListenerHolder holder : listeners.values()) {
|
||||||
if (isVisibleTo(branchName, holder.user)) {
|
if (isVisibleTo(branchName, holder.user)) {
|
||||||
holder.listener.onEvent(event);
|
holder.listener.onEvent(event);
|
||||||
@ -995,4 +1040,10 @@ public class ChangeHookRunner implements ChangeHooks, EventDispatcher,
|
|||||||
super.runHook();
|
super.runHook();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNewProjectCreated(NewProjectCreatedListener.Event event) {
|
||||||
|
Project.NameKey project = new Project.NameKey(event.getProjectName());
|
||||||
|
doProjectCreatedHook(project, event.getHeadName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,4 +181,12 @@ public interface ChangeHooks {
|
|||||||
public void doHashtagsChangedHook(Change change, Account account,
|
public void doHashtagsChangedHook(Change change, Account account,
|
||||||
Set<String>added, Set<String> removed, Set<String> hashtags,
|
Set<String>added, Set<String> removed, Set<String> hashtags,
|
||||||
ReviewDb db) throws OrmException;
|
ReviewDb db) throws OrmException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fire the project created hook
|
||||||
|
*
|
||||||
|
* @param project The project that was created
|
||||||
|
* @param headName The head name of the created project
|
||||||
|
*/
|
||||||
|
public void doProjectCreatedHook(Project.NameKey project, String headName);
|
||||||
}
|
}
|
||||||
|
@ -113,6 +113,10 @@ public final class DisabledChangeHooks implements ChangeHooks, EventDispatcher,
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doProjectCreatedHook(Project.NameKey project, String headName) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postEvent(Change change, Event event, ReviewDb db) {
|
public void postEvent(Change change, Event event, ReviewDb db) {
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ public class EventTypes {
|
|||||||
registerClass(new ReviewerAddedEvent());
|
registerClass(new ReviewerAddedEvent());
|
||||||
registerClass(new PatchSetCreatedEvent());
|
registerClass(new PatchSetCreatedEvent());
|
||||||
registerClass(new TopicChangedEvent());
|
registerClass(new TopicChangedEvent());
|
||||||
|
registerClass(new ProjectCreatedEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Register an event.
|
/** Register an event.
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
// Copyright (C) 2015 The Android Open Source Project
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package com.google.gerrit.server.events;
|
||||||
|
|
||||||
|
import com.google.gerrit.reviewdb.client.Project;
|
||||||
|
|
||||||
|
public class ProjectCreatedEvent extends ProjectEvent {
|
||||||
|
public String projectName;
|
||||||
|
public String headName;
|
||||||
|
|
||||||
|
public ProjectCreatedEvent() {
|
||||||
|
super("project-created");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Project.NameKey getProjectNameKey() {
|
||||||
|
return new Project.NameKey(projectName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHeadName() {
|
||||||
|
return headName;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user