Commit 1f9f6f3a authored by Gabriel Mazetto's avatar Gabriel Mazetto Committed by Robert Speicher

Added repository_update hook

parent 0deabec5
class SystemHook < WebHook
scope :repository_update_hooks, -> { where(repository_update_events: true) }
def async_execute(data, hook_name)
Sidekiq::Client.enqueue(SystemHookWorker, id, data, hook_name)
end
......
......@@ -10,6 +10,7 @@ class WebHook < ActiveRecord::Base
default_value_for :tag_push_events, false
default_value_for :build_events, false
default_value_for :pipeline_events, false
default_value_for :repository_update_events, false
default_value_for :enable_ssl_verification, true
scope :push_hooks, -> { where(push_events: true) }
......
......@@ -36,13 +36,32 @@ class PostReceive
end
process_project_changes(post_received)
process_repository_update(post_received)
end
end
def process_project_changes(post_received)
post_received.changes.each do |change|
oldrev, newrev, ref = change.strip.split(' ')
def process_repository_update(post_received)
changes = []
refs = Set.new
post_received.changes_refs do |oldrev, newrev, ref|
@user ||= post_received.identify(newrev)
unless @user
log("Triggered hook for non-existing user \"#{post_received.identifier}\"")
return false
end
changes << Gitlab::DataBuilder::Repository.single_change(oldrev, newrev, ref)
refs << ref
end
hook_data = Gitlab::DataBuilder::Repository.update(post_received.project, @user, changes, refs.to_a)
SystemHooksService.new.execute_hooks(hook_data, :repository_update_hooks)
end
def process_project_changes(post_received)
post_received.changes_refs do |oldrev, newrev, ref|
@user ||= post_received.identify(newrev)
unless @user
......
class AddRepositoryUpdateEventsToWebHooks < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_column_with_default :web_hooks, :repository_update_events, :boolean, default: false, allow_null: false
end
def down
remove_column :web_hooks, :repository_update_events
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20170504102911) do
ActiveRecord::Schema.define(version: 20170505133904) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -1606,6 +1606,7 @@ ActiveRecord::Schema.define(version: 20170504102911) do
t.string "token"
t.boolean "pipeline_events", default: false, null: false
t.boolean "confidential_issues_events", default: false, null: false
t.boolean "repository_update_events", default: false, null: false
end
add_index "web_hooks", ["project_id"], name: "index_web_hooks_on_project_id", using: :btree
......
module Gitlab
module DataBuilder
module Repository
extend self
# Produce a hash of post-receive data
def update(project, user, changes, refs)
{
event_name: 'repository_update',
user_id: user.id,
user_name: user.name,
user_email: user.email,
user_avatar: user.avatar_url,
project_id: project.id,
project: project.hook_attrs,
changes: changes,
refs: refs
}
end
# Produce a hash of partial data for a single change
def single_change(oldrev, newrev, ref)
{
before: oldrev,
after: newrev,
ref: ref
}
end
end
end
end
......@@ -13,6 +13,16 @@ module Gitlab
super(identifier, project, revision)
end
def changes_refs
return enum_for(:changes_refs) unless block_given?
changes.each do |change|
oldrev, newrev, ref = change.strip.split(' ')
yield oldrev, newrev, ref
end
end
private
def deserialize_changes(changes)
......
......@@ -317,6 +317,7 @@ ProjectHook:
- token
- group_id
- confidential_issues_events
- repository_update_events
ProtectedBranch:
- id
- project_id
......
......@@ -105,4 +105,12 @@ describe SystemHook, models: true do
).once
end
end
describe '.repository_update_hooks' do
it 'returns hooks for repository update events only' do
hook = create(:system_hook, repository_update_events: true)
create(:system_hook, repository_update_events: false)
expect(SystemHook.repository_update_hooks).to eq([hook])
end
end
end
......@@ -9,7 +9,7 @@ describe PostReceive do
let(:key) { create(:key, user: project.owner) }
let(:key_id) { key.shell_id }
context "as a resque worker" do
context "as a sidekiq worker" do
it "reponds to #perform" do
expect(described_class.new).to respond_to(:perform)
end
......@@ -93,6 +93,27 @@ describe PostReceive do
end
end
describe '#process_repository_update' do
let(:changes) {'123456 789012 refs/heads/tést'}
let(:fake_hook_data) do
{ event_name: 'repository_update' }
end
before do
allow_any_instance_of(Gitlab::GitPostReceive).to receive(:identify).and_return(project.owner)
allow_any_instance_of(Gitlab::DataBuilder::Repository).to receive(:update).and_return(fake_hook_data)
# silence hooks so we can isolate
allow_any_instance_of(Key).to receive(:post_create_hook).and_return(true)
allow(subject).to receive(:process_project_changes).and_return(true)
end
it 'calls SystemHooksService' do
expect_any_instance_of(SystemHooksService).to receive(:execute_hooks).with(fake_hook_data, :repository_update_hooks).and_return(true)
subject.perform(pwd(project), key_id, base64_changes)
end
end
context "webhook" do
it "fetches the correct project" do
expect(Project).to receive(:find_by).with(id: project.id.to_s)
......
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