Commit 85007434645c817e7674003bbdda0674287dd106

Authored by Dmitriy Zaporozhets
1 parent 95c23b2f

Post Receive Refactored. Service hooks also triggered now

app/roles/push_observer.rb
... ... @@ -2,45 +2,83 @@
2 2 #
3 3 # Triggered by PostReceive job
4 4 module PushObserver
5   - def observe_push(oldrev, newrev, ref, user)
  5 + # This method will be called after each post receive and only if the provided
  6 + # user is present in GitLab.
  7 + #
  8 + # All callbacks for post receive should be placed here.
  9 + def trigger_post_receive(oldrev, newrev, ref, user)
6 10 data = post_receive_data(oldrev, newrev, ref, user)
7 11  
8   - Event.create(
9   - project: self,
10   - action: Event::Pushed,
11   - data: data,
12   - author_id: data[:user_id]
13   - )
14   - end
  12 + # Create push event
  13 + self.observe_push(data)
15 14  
16   - def update_merge_requests(oldrev, newrev, ref, user)
17   - return true unless ref =~ /heads/
18   - branch_name = ref.gsub("refs/heads/", "")
19   - c_ids = self.commits_between(oldrev, newrev).map(&:id)
  15 + if push_to_branch? ref, oldrev
  16 + # Close merged MR
  17 + self.update_merge_requests(oldrev, newrev, ref, user)
20 18  
21   - # Update code for merge requests
22   - mrs = self.merge_requests.opened.find_all_by_branch(branch_name).all
23   - mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked }
  19 + # Execute web hooks
  20 + self.execute_hooks(data.dup)
24 21  
25   - # Close merge requests
26   - mrs = self.merge_requests.opened.where(target_branch: branch_name).all
27   - mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) }
28   - mrs.each { |merge_request| merge_request.merge!(user.id) }
  22 + # Execute project services
  23 + self.execute_services(data.dup)
  24 + end
29 25  
30   - true
  26 + # Create satellite
  27 + self.satellite.create unless self.satellite.exists?
  28 +
  29 + # Discover the default branch, but only if it hasn't already been set to
  30 + # something else
  31 + if default_branch.nil?
  32 + update_attributes(default_branch: discover_default_branch)
  33 + end
31 34 end
32 35  
33   - def execute_hooks(oldrev, newrev, ref, user)
  36 + def push_to_branch? ref, oldrev
34 37 ref_parts = ref.split('/')
35 38  
36 39 # Return if this is not a push to a branch (e.g. new commits)
37   - return if ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000"
  40 + !(ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000")
  41 + end
38 42  
39   - data = post_receive_data(oldrev, newrev, ref, user)
  43 + def observe_push(data)
  44 + Event.create(
  45 + project: self,
  46 + action: Event::Pushed,
  47 + data: data,
  48 + author_id: data[:user_id]
  49 + )
  50 + end
40 51  
  52 + def execute_hooks(data)
41 53 hooks.each { |hook| hook.execute(data) }
42 54 end
43 55  
  56 + def execute_services(data)
  57 + services.each do |service|
  58 +
  59 + # Call service hook for service if it has one
  60 + service.service_hook.execute if service.service_hook
  61 + end
  62 + end
  63 +
  64 + # Produce a hash of post-receive data
  65 + #
  66 + # data = {
  67 + # before: String,
  68 + # after: String,
  69 + # ref: String,
  70 + # user_id: String,
  71 + # user_name: String,
  72 + # repository: {
  73 + # name: String,
  74 + # url: String,
  75 + # description: String,
  76 + # homepage: String,
  77 + # },
  78 + # commits: Array,
  79 + # total_commits_count: Fixnum
  80 + # }
  81 + #
44 82 def post_receive_data(oldrev, newrev, ref, user)
45 83  
46 84 push_commits = commits_between(oldrev, newrev)
... ... @@ -87,27 +125,20 @@ module PushObserver
87 125 data
88 126 end
89 127  
90   - # This method will be called after each post receive and only if the provided
91   - # user is present in GitLab.
92   - #
93   - # All callbacks for post receive should be placed here.
94   - def trigger_post_receive(oldrev, newrev, ref, user)
95   - # Create push event
96   - self.observe_push(oldrev, newrev, ref, user)
97   -
98   - # Close merged MR
99   - self.update_merge_requests(oldrev, newrev, ref, user)
  128 + def update_merge_requests(oldrev, newrev, ref, user)
  129 + return true unless ref =~ /heads/
  130 + branch_name = ref.gsub("refs/heads/", "")
  131 + c_ids = self.commits_between(oldrev, newrev).map(&:id)
100 132  
101   - # Execute web hooks
102   - self.execute_hooks(oldrev, newrev, ref, user)
  133 + # Update code for merge requests
  134 + mrs = self.merge_requests.opened.find_all_by_branch(branch_name).all
  135 + mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked }
103 136  
104   - # Create satellite
105   - self.satellite.create unless self.satellite.exists?
  137 + # Close merge requests
  138 + mrs = self.merge_requests.opened.where(target_branch: branch_name).all
  139 + mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) }
  140 + mrs.each { |merge_request| merge_request.merge!(user.id) }
106 141  
107   - # Discover the default branch, but only if it hasn't already been set to
108   - # something else
109   - if default_branch.nil?
110   - update_attributes(default_branch: discover_default_branch)
111   - end
  142 + true
112 143 end
113 144 end
... ...
spec/models/project_hooks_spec.rb
... ... @@ -11,13 +11,15 @@ describe Project, "Hooks" do
11 11 describe "Post Receive Event" do
12 12 it "should create push event" do
13 13 oldrev, newrev, ref = '00000000000000000000000000000000', 'newrev', 'refs/heads/master'
14   - project.observe_push(oldrev, newrev, ref, @user)
  14 + data = project.post_receive_data(oldrev, newrev, ref, @user)
  15 +
  16 + project.observe_push(data)
15 17 event = Event.last
16 18  
17 19 event.should_not be_nil
18 20 event.project.should == project
19 21 event.action.should == Event::Pushed
20   - event.data == project.post_receive_data(oldrev, newrev, ref, @user)
  22 + event.data.should == data
21 23 end
22 24 end
23 25  
... ... @@ -25,7 +27,7 @@ describe Project, "Hooks" do
25 27 context "with no web hooks" do
26 28 it "raises no errors" do
27 29 lambda {
28   - project.execute_hooks('oldrev', 'newrev', 'ref', @user)
  30 + project.execute_hooks({})
29 31 }.should_not raise_error
30 32 end
31 33 end
... ... @@ -41,7 +43,7 @@ describe Project, "Hooks" do
41 43 @project_hook.should_receive(:execute).once
42 44 @project_hook_2.should_receive(:execute).once
43 45  
44   - project.execute_hooks('oldrev', 'newrev', 'refs/heads/master', @user)
  46 + project.trigger_post_receive('oldrev', 'newrev', 'refs/heads/master', @user)
45 47 end
46 48 end
47 49  
... ... @@ -53,12 +55,12 @@ describe Project, "Hooks" do
53 55  
54 56 it "when pushing a branch for the first time" do
55 57 @project_hook.should_not_receive(:execute)
56   - project.execute_hooks('00000000000000000000000000000000', 'newrev', 'refs/heads/master', @user)
  58 + project.trigger_post_receive('00000000000000000000000000000000', 'newrev', 'refs/heads/master', @user)
57 59 end
58 60  
59 61 it "when pushing tags" do
60 62 @project_hook.should_not_receive(:execute)
61   - project.execute_hooks('oldrev', 'newrev', 'refs/tags/v1.0.0', @user)
  63 + project.trigger_post_receive('oldrev', 'newrev', 'refs/tags/v1.0.0', @user)
62 64 end
63 65 end
64 66  
... ...
spec/workers/post_receive_spec.rb
... ... @@ -27,16 +27,12 @@ describe PostReceive do
27 27 PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id).should be_false
28 28 end
29 29  
30   - it "asks the project to execute web hooks" do
  30 + it "asks the project to trigger all hooks" do
31 31 Project.stub(find_by_path: project)
32   - project.should_receive(:execute_hooks).with('sha-old', 'sha-new', 'refs/heads/master', project.owner)
33   -
34   - PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id)
35   - end
36   -
37   - it "asks the project to observe push/create event data" do
38   - Project.stub(find_by_path: project)
39   - project.should_receive(:observe_push).with('sha-old', 'sha-new', 'refs/heads/master', project.owner)
  32 + project.should_receive(:execute_hooks)
  33 + project.should_receive(:execute_services)
  34 + project.should_receive(:update_merge_requests)
  35 + project.should_receive(:observe_push)
40 36  
41 37 PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id)
42 38 end
... ...