Commit 57875720 authored by Valery Sizov's avatar Valery Sizov

Group level webhooks

parent 49901eb3
......@@ -4,6 +4,8 @@ v 7.9.0 (unreleased)
- Check if LDAP admin group exists before querying for user membership
- Use one custom header logo for all GitLab themes in appearance settings
- Escape wildcards when searching LDAP by group name.
v 7.9.0
- Group level Web Hooks
v 7.8.0
- Improved Jira issue closing integration
......
class Groups::HooksController < ApplicationController
# Authorize
before_filter :group
before_filter :authorize_admin_group!
respond_to :html
layout "group"
def index
@hooks = @group.hooks
@hook = GroupHook.new
end
def create
@hook = @group.hooks.new(hook_params)
@hook.save
if @hook.valid?
redirect_to group_hooks_path(@group)
else
@hooks = @group.hooks.select(&:persisted?)
render :index
end
end
def test
if @group.first_non_empty_project
status = TestHookService.new.execute(hook, current_user)
if status
flash[:notice] = 'Hook successfully executed.'
else
flash[:alert] = 'Hook execution failed. '\
'Ensure hook URL is correct and service is up.'
end
else
flash[:alert] = 'Hook execution failed. Ensure the group has a project with commits.'
end
redirect_to :back
end
def destroy
hook.destroy
redirect_to group_hooks_path(@group)
end
private
def hook
@hook ||= @group.hooks.find(params[:id])
end
def hook_params
params.require(:hook).permit(:url, :push_events, :issues_events, :merge_requests_events, :tag_push_events)
end
def group
@group ||= Group.find_by(path: params[:group_id])
end
def authorize_admin_group!
unless can?(current_user, :manage_group, group)
return render_404
end
end
end
......@@ -36,7 +36,7 @@ module GroupsHelper
def group_settings_page?
if current_controller?('groups')
current_action?('edit') || current_action?('projects')
elsif current_controller?('ldap_group_links') || current_controller?('audit_events')
elsif ['ldap_group_links', 'audit_events', 'hooks'].any?{ |c| current_controller? c }
true
else
false
......
......@@ -22,6 +22,7 @@ class Group < Namespace
has_many :project_group_links, dependent: :destroy
has_many :shared_projects, through: :project_group_links, source: :project
has_many :ldap_group_links, foreign_key: 'group_id', dependent: :destroy
has_many :hooks, dependent: :destroy, class_name: 'GroupHook'
validate :avatar_type, if: ->(user) { user.avatar_changed? }
validates :avatar, file_size: { maximum: 200.kilobytes.to_i }
......@@ -118,4 +119,8 @@ class Group < Namespace
def system_hook_service
SystemHooksService.new
end
def first_non_empty_project
projects.detect{ |project| !project.empty_repo? }
end
end
# == Schema Information
#
# Table name: web_hooks
#
# id :integer not null, primary key
# url :string(255)
# project_id :integer
# created_at :datetime
# updated_at :datetime
# type :string(255) default("ProjectHook")
# service_id :integer
# push_events :boolean default(TRUE), not null
# issues_events :boolean default(FALSE), not null
# merge_requests_events :boolean default(FALSE), not null
# tag_push_events :boolean default(FALSE)
#
class GroupHook < ProjectHook
belongs_to :group
end
......@@ -491,6 +491,9 @@ class Project < ActiveRecord::Base
hooks.send(hooks_scope).each do |hook|
hook.async_execute(data)
end
group.hooks.send(hooks_scope).each do |hook|
hook.async_execute(data)
end
end
def execute_services(data, hooks_scope = :push_hooks)
......
class TestHookService
def execute(hook, current_user)
data = Gitlab::PushDataBuilder.build_sample(hook.project, current_user)
data = Gitlab::PushDataBuilder.build_sample(project(hook), current_user)
hook.execute(data)
end
private
def project(hook)
if hook.is_a? GroupHook
hook.group.first_non_empty_project
else
hook.project
end
end
end
......@@ -15,6 +15,11 @@
%i.fa.fa-exchange
%span
LDAP Groups
= nav_link(controller: :hooks) do
= link_to group_hooks_path(@group) do
%i.fa.fa-link
%span
Web Hooks
= nav_link(controller: :audit_events) do
= link_to group_audit_events_path(@group) do
%i.fa.fa-file-text-o
......
%h3.page-title
Web hooks
%p.light
#{link_to "Web hooks ", help_page_path("web_hooks", "web_hooks"), class: "vlink"} can be
used for binding events when something is happening within any project inside this group.
%hr.clearfix
= form_for [@group, @hook], as: :hook, url: group_hooks_path(@group), html: { class: 'form-horizontal' } do |f|
-if @hook.errors.any?
.alert.alert-danger
- @hook.errors.full_messages.each do |msg|
%p= msg
.form-group
= f.label :url, "URL", class: 'control-label'
.col-sm-10
= f.text_field :url, class: "form-control", placeholder: 'http://example.com/trigger-ci.json'
.form-group
= f.label :url, "Trigger", class: 'control-label'
.col-sm-10
%div
= f.check_box :push_events, class: 'pull-left'
.prepend-left-20
= f.label :push_events, class: 'list-label' do
%strong Push events
%p.light
This url will be triggered by a push to the repository
%div
= f.check_box :tag_push_events, class: 'pull-left'
.prepend-left-20
= f.label :tag_push_events, class: 'list-label' do
%strong Tag push events
%p.light
This url will be triggered when a new tag is pushed to the repository
%div
= f.check_box :issues_events, class: 'pull-left'
.prepend-left-20
= f.label :issues_events, class: 'list-label' do
%strong Issues events
%p.light
This url will be triggered when an issue is created
%div
= f.check_box :merge_requests_events, class: 'pull-left'
.prepend-left-20
= f.label :merge_requests_events, class: 'list-label' do
%strong Merge Request events
%p.light
This url will be triggered when a merge request is created
.form-actions
= f.submit "Add Web Hook", class: "btn btn-create"
-if @hooks.any?
.panel.panel-default
.panel-heading
Web hooks (#{@hooks.count})
%ul.well-list
- @hooks.each do |hook|
%li
.pull-right
= link_to 'Test Hook', test_group_hook_path(@group, hook), class: "btn btn-small btn-grouped"
= link_to 'Remove', group_hook_path(@group, hook), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove btn-small btn-grouped"
.clearfix
%span.monospace= hook.url
%p
- %w(push_events tag_push_events issues_events merge_requests_events).each do |trigger|
- if hook.send(trigger)
%span.label.label-gray= trigger.titleize
......@@ -271,6 +271,12 @@ Gitlab::Application.routes.draw do
end
get "/audit_events" => "audit_events#group_log"
resources :hooks, only: [:index, :create, :destroy], constraints: { id: /\d+/ }, module: :groups do
member do
get :test
end
end
end
get 'unsubscribes/:email', to: 'unsubscribes#show', as: :unsubscribe
......
class AddGroupIdToWebHooks < ActiveRecord::Migration
def change
add_column :web_hooks, :group_id, :integer, after: :project_id
end
end
\ No newline at end of file
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150306023112) do
ActiveRecord::Schema.define(version: 20150312000132) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -556,6 +556,7 @@ ActiveRecord::Schema.define(version: 20150306023112) do
t.boolean "issues_events", default: false, null: false
t.boolean "merge_requests_events", default: false, null: false
t.boolean "tag_push_events", default: false
t.integer "group_id"
end
add_index "web_hooks", ["created_at", "id"], name: "index_web_hooks_on_created_at_and_id", using: :btree
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment