diff options
author | Gabriel Mazetto <gabriel@gitlab.com> | 2016-04-15 14:08:22 +0300 |
---|---|---|
committer | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2016-04-19 12:00:30 +0300 |
commit | ee1090e2b2bc7b3762f6e2775f3fd15e92ae212b (patch) | |
tree | 9df863f27349ca2a95d0e6f16d99b85d4806d992 | |
parent | 53a1d705fe536ad373faa77ba1ef5196ff49a98b (diff) |
Added System Hooks for push and tag_push
Code is based on Project Webhooks, removing deprecations and without
commits listing.
-rw-r--r-- | app/models/hooks/system_hook.rb | 6 | ||||
-rw-r--r-- | app/models/project.rb | 21 | ||||
-rw-r--r-- | app/services/git_push_service.rb | 6 | ||||
-rw-r--r-- | app/services/git_tag_push_service.rb | 6 | ||||
-rw-r--r-- | app/services/system_hooks_service.rb | 12 | ||||
-rw-r--r-- | doc/system_hooks/system_hooks.md | 77 | ||||
-rw-r--r-- | doc/web_hooks/web_hooks.md | 4 | ||||
-rw-r--r-- | lib/gitlab/push_data_builder.rb | 22 | ||||
-rw-r--r-- | spec/lib/gitlab/push_data_builder_spec.rb | 31 | ||||
-rw-r--r-- | spec/support/project_hook_data_shared_example.rb | 17 |
10 files changed, 181 insertions, 21 deletions
diff --git a/app/models/hooks/system_hook.rb b/app/models/hooks/system_hook.rb index c147d8762a9..bacd42ec60a 100644 --- a/app/models/hooks/system_hook.rb +++ b/app/models/hooks/system_hook.rb @@ -19,4 +19,10 @@ # class SystemHook < WebHook + scope :push_hooks, -> { where(push_events: true) } + scope :tag_push_hooks, -> { where(tag_push_events: true) } + + def async_execute(data, hook_name) + Sidekiq::Client.enqueue(SystemHookWorker, id, data, hook_name) + end end diff --git a/app/models/project.rb b/app/models/project.rb index 8f20922e3c5..e7dac23a122 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -831,8 +831,8 @@ class Project < ActiveRecord::Base end end - def hook_attrs - { + def hook_attrs(backward: true) + attrs = { name: name, description: description, web_url: web_url, @@ -843,12 +843,19 @@ class Project < ActiveRecord::Base visibility_level: visibility_level, path_with_namespace: path_with_namespace, default_branch: default_branch, - # Backward compatibility - homepage: web_url, - url: url_to_repo, - ssh_url: ssh_url_to_repo, - http_url: http_url_to_repo } + + # Backward compatibility + if backward + attrs.merge!({ + homepage: web_url, + url: url_to_repo, + ssh_url: ssh_url_to_repo, + http_url: http_url_to_repo + }) + end + + attrs end # Reset events cache related to this project diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb index dc74c02760b..25d8e2cf052 100644 --- a/app/services/git_push_service.rb +++ b/app/services/git_push_service.rb @@ -73,6 +73,7 @@ class GitPushService < BaseService @project.update_merge_requests(params[:oldrev], params[:newrev], params[:ref], current_user) EventCreateService.new.push(@project, current_user, build_push_data) + SystemHooksService.new.execute_hooks(build_push_data_system_hook.dup, :push_hooks) @project.execute_hooks(build_push_data.dup, :push_hooks) @project.execute_services(build_push_data.dup, :push_hooks) CreateCommitBuildsService.new.execute(@project, current_user, build_push_data) @@ -138,6 +139,11 @@ class GitPushService < BaseService build(@project, current_user, params[:oldrev], params[:newrev], params[:ref], push_commits) end + def build_push_data_system_hook + @push_data_system ||= Gitlab::PushDataBuilder. + build_system(@project, current_user, params[:oldrev], params[:newrev], params[:ref]) + end + def push_to_existing_branch? # Return if this is not a push to a branch (e.g. new commits) Gitlab::Git.branch_ref?(params[:ref]) && !Gitlab::Git.blank_ref?(params[:oldrev]) diff --git a/app/services/git_tag_push_service.rb b/app/services/git_tag_push_service.rb index c88c7672805..81ba68fa674 100644 --- a/app/services/git_tag_push_service.rb +++ b/app/services/git_tag_push_service.rb @@ -8,6 +8,7 @@ class GitTagPushService @push_data = build_push_data(oldrev, newrev, ref) EventCreateService.new.push(project, user, @push_data) + SystemHooksService.new.execute_hooks(build_system_push_data.dup, :tag_push_hooks) project.execute_hooks(@push_data.dup, :tag_push_hooks) project.execute_services(@push_data.dup, :tag_push_hooks) CreateCommitBuildsService.new.execute(project, @user, @push_data) @@ -35,4 +36,9 @@ class GitTagPushService Gitlab::PushDataBuilder. build(project, user, oldrev, newrev, ref, commits, message) end + + def build_system_push_data(oldrev, newrev, ref) + Gitlab::PushDataBuilder. + build_system(project, user, oldrev, newrev, ref) + end end diff --git a/app/services/system_hooks_service.rb b/app/services/system_hooks_service.rb index f0615ec7420..e43b5b51e5b 100644 --- a/app/services/system_hooks_service.rb +++ b/app/services/system_hooks_service.rb @@ -3,17 +3,13 @@ class SystemHooksService execute_hooks(build_event_data(model, event)) end - private - - def execute_hooks(data) - SystemHook.all.each do |sh| - async_execute_hook(sh, data, 'system_hooks') + def execute_hooks(data, hooks_scope = :all) + SystemHook.send(hooks_scope).each do |hook| + hook.async_execute(data, 'system_hooks') end end - def async_execute_hook(hook, data, hook_name) - Sidekiq::Client.enqueue(SystemHookWorker, hook.id, data, hook_name) - end + private def build_event_data(model, event) data = { diff --git a/doc/system_hooks/system_hooks.md b/doc/system_hooks/system_hooks.md index 612376e3a49..4c5a9e366cf 100644 --- a/doc/system_hooks/system_hooks.md +++ b/doc/system_hooks/system_hooks.md @@ -240,3 +240,80 @@ X-Gitlab-Event: System Hook "user_id": 41 } ``` + +## Push events + +Triggered when you push to the repository except when pushing tags. + +**Request header**: + +``` +X-Gitlab-Event: System Hook +``` + +**Request body:** + +```json +{ + "event_name": "push", + "before": "95790bf891e76fee5e1747ab589903a6a1f80f22", + "after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", + "ref": "refs/heads/master", + "checkout_sha": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", + "user_id": 4, + "user_name": "John Smith", + "user_email": "john@example.com", + "user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80", + "project_id": 15, + "project":{ + "name":"Diaspora", + "description":"", + "web_url":"http://example.com/mike/diaspora", + "avatar_url":null, + "git_ssh_url":"git@example.com:mike/diaspora.git", + "git_http_url":"http://example.com/mike/diaspora.git", + "namespace":"Mike", + "visibility_level":0, + "path_with_namespace":"mike/diaspora", + "default_branch":"master", + } +} +``` + +## Tag events + +Triggered when you create (or delete) tags to the repository. + +**Request header**: + +``` +X-Gitlab-Event: System Hook +``` + +**Request body:** + +```json +{ + "event_name": "tag_push", + "before": "0000000000000000000000000000000000000000", + "after": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7", + "ref": "refs/tags/v1.0.0", + "checkout_sha": "5937ac0a7beb003549fc5fd26fc247adbce4a52e", + "user_id": 1, + "user_name": "John Smith", + "user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80", + "project_id": 1, + "project":{ + "name":"Example", + "description":"", + "web_url":"http://example.com/jsmith/example", + "avatar_url":null, + "git_ssh_url":"git@example.com:jsmith/example.git", + "git_http_url":"http://example.com/jsmith/example.git", + "namespace":"Jsmith", + "visibility_level":0, + "path_with_namespace":"jsmith/example", + "default_branch":"master", + } +} +``` diff --git a/doc/web_hooks/web_hooks.md b/doc/web_hooks/web_hooks.md index 22e207b6d32..c1c51302e79 100644 --- a/doc/web_hooks/web_hooks.md +++ b/doc/web_hooks/web_hooks.md @@ -41,6 +41,7 @@ X-Gitlab-Event: Push Hook "before": "95790bf891e76fee5e1747ab589903a6a1f80f22", "after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", "ref": "refs/heads/master", + "checkout_sha": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", "user_id": 4, "user_name": "John Smith", "user_email": "john@example.com", @@ -118,9 +119,10 @@ X-Gitlab-Event: Tag Push Hook ```json { "object_kind": "tag_push", - "ref": "refs/tags/v1.0.0", "before": "0000000000000000000000000000000000000000", "after": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7", + "ref": "refs/tags/v1.0.0", + "checkout_sha": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7", "user_id": 1, "user_name": "John Smith", "user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80", diff --git a/lib/gitlab/push_data_builder.rb b/lib/gitlab/push_data_builder.rb index 97d1edab9c1..eb8e45040bc 100644 --- a/lib/gitlab/push_data_builder.rb +++ b/lib/gitlab/push_data_builder.rb @@ -36,7 +36,7 @@ module Gitlab commit.hook_attrs(with_changed_files: true) end - type = Gitlab::Git.tag_ref?(ref) ? "tag_push" : "push" + type = Gitlab::Git.tag_ref?(ref) ? 'tag_push' : 'push' # Hash to be passed as post_receive_data data = { @@ -62,6 +62,26 @@ module Gitlab data end + def build_system(project, user, oldrev, newrev, ref) + type = Gitlab::Git.tag_ref?(ref) ? 'tag_push' : 'push' + + data = { + event_name: type, + before: oldrev, + after: newrev, + ref: ref, + checkout_sha: checkout_sha(project.repository, newrev, ref), + 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(backward: false) + } + + data + end + # This method provide a sample data generated with # existing project and commits to test webhooks def build_sample(project, user) diff --git a/spec/lib/gitlab/push_data_builder_spec.rb b/spec/lib/gitlab/push_data_builder_spec.rb index 961022b9d12..d6fb65e6948 100644 --- a/spec/lib/gitlab/push_data_builder_spec.rb +++ b/spec/lib/gitlab/push_data_builder_spec.rb @@ -14,11 +14,11 @@ describe Gitlab::PushDataBuilder, lib: true do it { expect(data[:ref]).to eq('refs/heads/master') } it { expect(data[:commits].size).to eq(3) } it { expect(data[:total_commits_count]).to eq(3) } - it { expect(data[:commits].first[:added]).to eq(["gitlab-grack"]) } - it { expect(data[:commits].first[:modified]).to eq([".gitmodules"]) } + it { expect(data[:commits].first[:added]).to eq(['gitlab-grack']) } + it { expect(data[:commits].first[:modified]).to eq(['.gitmodules']) } it { expect(data[:commits].first[:removed]).to eq([]) } - include_examples 'project hook data' + include_examples 'project hook data with deprecateds' include_examples 'deprecated repository hook data' end @@ -37,9 +37,34 @@ describe Gitlab::PushDataBuilder, lib: true do it { expect(data[:commits]).to be_empty } it { expect(data[:total_commits_count]).to be_zero } + include_examples 'project hook data with deprecateds' + include_examples 'deprecated repository hook data' + it 'does not raise an error when given nil commits' do expect { described_class.build(spy, spy, spy, spy, spy, nil) }. not_to raise_error end end + + describe '.build_system' do + let(:data) do + described_class.build_system(project, user, Gitlab::Git::BLANK_SHA, + '8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b', + 'refs/tags/v1.1.0') + end + + it { expect(data).to be_a(Hash) } + it { expect(data[:before]).to eq(Gitlab::Git::BLANK_SHA) } + it { expect(data[:checkout_sha]).to eq('5937ac0a7beb003549fc5fd26fc247adbce4a52e') } + it { expect(data[:after]).to eq('8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b') } + it { expect(data[:ref]).to eq('refs/tags/v1.1.0') } + it { expect(data[:user_id]).to eq(user.id) } + it { expect(data[:user_name]).to eq(user.name) } + it { expect(data[:user_email]).to eq(user.email) } + it { expect(data[:user_avatar]).to eq(user.avatar_url) } + it { expect(data[:project_id]).to eq(project.id) } + it { expect(data[:project]).to be_a(Hash) } + + include_examples 'project hook data' + end end diff --git a/spec/support/project_hook_data_shared_example.rb b/spec/support/project_hook_data_shared_example.rb index 422083875d7..7dbaa6a6459 100644 --- a/spec/support/project_hook_data_shared_example.rb +++ b/spec/support/project_hook_data_shared_example.rb @@ -1,4 +1,4 @@ -RSpec.shared_examples 'project hook data' do |project_key: :project| +RSpec.shared_examples 'project hook data with deprecateds' do |project_key: :project| it 'contains project data' do expect(data[project_key][:name]).to eq(project.name) expect(data[project_key][:description]).to eq(project.description) @@ -17,6 +17,21 @@ RSpec.shared_examples 'project hook data' do |project_key: :project| end end +RSpec.shared_examples 'project hook data' do |project_key: :project| + it 'contains project data' do + expect(data[project_key][:name]).to eq(project.name) + expect(data[project_key][:description]).to eq(project.description) + expect(data[project_key][:web_url]).to eq(project.web_url) + expect(data[project_key][:avatar_url]).to eq(project.avatar_url) + expect(data[project_key][:git_http_url]).to eq(project.http_url_to_repo) + expect(data[project_key][:git_ssh_url]).to eq(project.ssh_url_to_repo) + expect(data[project_key][:namespace]).to eq(project.namespace.name) + expect(data[project_key][:visibility_level]).to eq(project.visibility_level) + expect(data[project_key][:path_with_namespace]).to eq(project.path_with_namespace) + expect(data[project_key][:default_branch]).to eq(project.default_branch) + end +end + RSpec.shared_examples 'deprecated repository hook data' do |project_key: :project| it 'contains deprecated repository data' do expect(data[:repository][:name]).to eq(project.name) |