Commit 897da534fa7ab3b2280bfea05c5da4b57e3b8612
1 parent
eb2c1cd2
Exists in
master
and in
4 other branches
Fix issues with push 600+ commits. refactored, improved push events
Showing
9 changed files
with
72 additions
and
45 deletions
Show diff stats
app/models/event/push_trait.rb
@@ -49,11 +49,14 @@ module Event::PushTrait | @@ -49,11 +49,14 @@ module Event::PushTrait | ||
49 | def tag_name | 49 | def tag_name |
50 | @tag_name ||= data[:ref].gsub("refs/tags/", "") | 50 | @tag_name ||= data[:ref].gsub("refs/tags/", "") |
51 | end | 51 | end |
52 | - | 52 | + |
53 | + # Max 20 commits from push DESC | ||
53 | def commits | 54 | def commits |
54 | - @commits ||= data[:commits].map do |commit| | ||
55 | - project.commit(commit["id"]) | ||
56 | - end | 55 | + @commits ||= data[:commits].map { |commit| project.commit(commit[:id]) }.reverse |
56 | + end | ||
57 | + | ||
58 | + def commits_count | ||
59 | + data[:total_commits_count] || commits.count || 0 | ||
57 | end | 60 | end |
58 | 61 | ||
59 | def ref_type | 62 | def ref_type |
@@ -71,13 +74,15 @@ module Event::PushTrait | @@ -71,13 +74,15 @@ module Event::PushTrait | ||
71 | end | 74 | end |
72 | 75 | ||
73 | def parent_commit | 76 | def parent_commit |
74 | - commits.first.prev_commit | 77 | + project.commit(commit_from) |
75 | rescue => ex | 78 | rescue => ex |
76 | nil | 79 | nil |
77 | end | 80 | end |
78 | 81 | ||
79 | def last_commit | 82 | def last_commit |
80 | - commits.last | 83 | + project.commit(commit_to) |
84 | + rescue => ex | ||
85 | + nil | ||
81 | end | 86 | end |
82 | 87 | ||
83 | def push_with_commits? | 88 | def push_with_commits? |
app/models/project/hooks_trait.rb
1 | module Project::HooksTrait | 1 | module Project::HooksTrait |
2 | as_trait do | 2 | as_trait do |
3 | - def observe_push(oldrev, newrev, ref, author_key_id) | ||
4 | - data = web_hook_data(oldrev, newrev, ref, author_key_id) | 3 | + def observe_push(oldrev, newrev, ref, user) |
4 | + data = post_receive_data(oldrev, newrev, ref, user) | ||
5 | 5 | ||
6 | Event.create( | 6 | Event.create( |
7 | :project => self, | 7 | :project => self, |
@@ -11,10 +11,9 @@ module Project::HooksTrait | @@ -11,10 +11,9 @@ module Project::HooksTrait | ||
11 | ) | 11 | ) |
12 | end | 12 | end |
13 | 13 | ||
14 | - def update_merge_requests(oldrev, newrev, ref, author_key_id) | 14 | + def update_merge_requests(oldrev, newrev, ref, user) |
15 | return true unless ref =~ /heads/ | 15 | return true unless ref =~ /heads/ |
16 | branch_name = ref.gsub("refs/heads/", "") | 16 | branch_name = ref.gsub("refs/heads/", "") |
17 | - user = Key.find_by_identifier(author_key_id).user | ||
18 | c_ids = self.commits_between(oldrev, newrev).map(&:id) | 17 | c_ids = self.commits_between(oldrev, newrev).map(&:id) |
19 | 18 | ||
20 | # Update code for merge requests | 19 | # Update code for merge requests |
@@ -29,36 +28,48 @@ module Project::HooksTrait | @@ -29,36 +28,48 @@ module Project::HooksTrait | ||
29 | true | 28 | true |
30 | end | 29 | end |
31 | 30 | ||
32 | - def execute_web_hooks(oldrev, newrev, ref, author_key_id) | 31 | + def execute_web_hooks(oldrev, newrev, ref, user) |
33 | ref_parts = ref.split('/') | 32 | ref_parts = ref.split('/') |
34 | 33 | ||
35 | # Return if this is not a push to a branch (e.g. new commits) | 34 | # Return if this is not a push to a branch (e.g. new commits) |
36 | return if ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000" | 35 | return if ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000" |
37 | 36 | ||
38 | - data = web_hook_data(oldrev, newrev, ref, author_key_id) | 37 | + data = post_receive_data(oldrev, newrev, ref, user) |
39 | 38 | ||
40 | web_hooks.each { |web_hook| web_hook.execute(data) } | 39 | web_hooks.each { |web_hook| web_hook.execute(data) } |
41 | end | 40 | end |
42 | 41 | ||
43 | - def web_hook_data(oldrev, newrev, ref, author_key_id) | ||
44 | - key = Key.find_by_identifier(author_key_id) | 42 | + def post_receive_data(oldrev, newrev, ref, user) |
43 | + | ||
44 | + push_commits = commits_between(oldrev, newrev) | ||
45 | + | ||
46 | + # Total commits count | ||
47 | + push_commits_count = push_commits.size | ||
48 | + | ||
49 | + # Get latest 20 commits ASC | ||
50 | + push_commits_limited = push_commits.last(20) | ||
51 | + | ||
52 | + # Hash to be passed as post_receive_data | ||
45 | data = { | 53 | data = { |
46 | before: oldrev, | 54 | before: oldrev, |
47 | after: newrev, | 55 | after: newrev, |
48 | ref: ref, | 56 | ref: ref, |
49 | - user_id: key.user.id, | ||
50 | - user_name: key.user_name, | 57 | + user_id: user.id, |
58 | + user_name: user.name, | ||
51 | repository: { | 59 | repository: { |
52 | name: name, | 60 | name: name, |
53 | url: web_url, | 61 | url: web_url, |
54 | description: description, | 62 | description: description, |
55 | homepage: web_url, | 63 | homepage: web_url, |
56 | - private: private? | ||
57 | }, | 64 | }, |
58 | - commits: [] | 65 | + commits: [], |
66 | + total_commits_count: push_commits_count | ||
59 | } | 67 | } |
60 | 68 | ||
61 | - commits_between(oldrev, newrev).each do |commit| | 69 | + # For perfomance purposes maximum 20 latest commits |
70 | + # will be passed as post receive hook data. | ||
71 | + # | ||
72 | + push_commits_limited.each do |commit| | ||
62 | data[:commits] << { | 73 | data[:commits] << { |
63 | id: commit.id, | 74 | id: commit.id, |
64 | message: commit.safe_message, | 75 | message: commit.safe_message, |
@@ -73,5 +84,23 @@ module Project::HooksTrait | @@ -73,5 +84,23 @@ module Project::HooksTrait | ||
73 | 84 | ||
74 | data | 85 | data |
75 | end | 86 | end |
87 | + | ||
88 | + | ||
89 | + # This method will be called after each post receive | ||
90 | + # and only if autor_key_id present in gitlab. | ||
91 | + # All callbacks for post receive should be placed here | ||
92 | + # | ||
93 | + def trigger_post_receive(oldrev, newrev, ref, author_key_id) | ||
94 | + user = Key.find_by_identifier(author_key_id).user | ||
95 | + | ||
96 | + # Create push event | ||
97 | + self.observe_push(oldrev, newrev, ref, user) | ||
98 | + | ||
99 | + # Close merged MR | ||
100 | + self.update_merge_requests(oldrev, newrev, ref, user) | ||
101 | + | ||
102 | + # Execute web hooks | ||
103 | + self.execute_web_hooks(oldrev, newrev, ref, user) | ||
104 | + end | ||
76 | end | 105 | end |
77 | end | 106 | end |
app/views/commits/compare.html.haml
app/views/dashboard/index.html.haml
@@ -47,7 +47,7 @@ | @@ -47,7 +47,7 @@ | ||
47 | - if @last_push && @last_push.valid_push? | 47 | - if @last_push && @last_push.valid_push? |
48 | .padded.prepend-top-20 | 48 | .padded.prepend-top-20 |
49 | %h5 | 49 | %h5 |
50 | - %small Latest push was to the #{@last_push.branch_name} branch of #{@last_push.project.name}: | 50 | + %small Latest push was to the #{@last_push.ref_name} #{@last_push.ref_type} of #{@last_push.project.name}: |
51 | %ul.unstyled= render @last_push | 51 | %ul.unstyled= render @last_push |
52 | 52 | ||
53 | - if @merge_requests.any? | 53 | - if @merge_requests.any? |
app/views/events/_event_push.html.haml
@@ -11,17 +11,17 @@ | @@ -11,17 +11,17 @@ | ||
11 | ago. | 11 | ago. |
12 | 12 | ||
13 | - if event.push_with_commits? | 13 | - if event.push_with_commits? |
14 | - - if event.commits.count > 1 | 14 | + - if event.commits_count > 1 |
15 | = link_to compare_project_commits_path(event.project, :from => event.parent_commit.id, :to => event.last_commit.id) do | 15 | = link_to compare_project_commits_path(event.project, :from => event.parent_commit.id, :to => event.last_commit.id) do |
16 | - %strong #{event.commits.first.id[0..7]}...#{event.last_commit.id[0..7]} | 16 | + %strong #{event.parent_commit.id[0..7]}...#{event.last_commit.id[0..7]} |
17 | - project = event.project | 17 | - project = event.project |
18 | %ul.unstyled.event_commits | 18 | %ul.unstyled.event_commits |
19 | - - if event.commits.size > 3 | 19 | + - if event.commits_count > 3 |
20 | - event.commits[0...2].each do |commit| | 20 | - event.commits[0...2].each do |commit| |
21 | = render "events/commit", :commit => commit, :project => project | 21 | = render "events/commit", :commit => commit, :project => project |
22 | %li | 22 | %li |
23 | %br | 23 | %br |
24 | - \... and #{event.commits.size - 2} more commits | 24 | + \... and #{event.commits_count - 2} more commits |
25 | - else | 25 | - else |
26 | - event.commits.each do |commit| | 26 | - event.commits.each do |commit| |
27 | = render "events/commit", :commit => commit, :project => project | 27 | = render "events/commit", :commit => commit, :project => project |
app/workers/post_receive.rb
@@ -8,13 +8,6 @@ class PostReceive | @@ -8,13 +8,6 @@ class PostReceive | ||
8 | # Ignore push from non-gitlab users | 8 | # Ignore push from non-gitlab users |
9 | return false unless Key.find_by_identifier(author_key_id) | 9 | return false unless Key.find_by_identifier(author_key_id) |
10 | 10 | ||
11 | - # Create push event | ||
12 | - project.observe_push(oldrev, newrev, ref, author_key_id) | ||
13 | - | ||
14 | - # Close merged MR | ||
15 | - project.update_merge_requests(oldrev, newrev, ref, author_key_id) | ||
16 | - | ||
17 | - # Execute web hooks | ||
18 | - project.execute_web_hooks(oldrev, newrev, ref, author_key_id) | 11 | + project.trigger_post_receive(oldrev, newrev, ref, author_key_id) |
19 | end | 12 | end |
20 | end | 13 | end |
spec/models/project_hooks_spec.rb
@@ -4,19 +4,20 @@ describe Project, "Hooks" do | @@ -4,19 +4,20 @@ describe Project, "Hooks" do | ||
4 | let(:project) { Factory :project } | 4 | let(:project) { Factory :project } |
5 | before do | 5 | before do |
6 | @key = Factory :key, :user => project.owner | 6 | @key = Factory :key, :user => project.owner |
7 | + @user = @key.user | ||
7 | @key_id = @key.identifier | 8 | @key_id = @key.identifier |
8 | end | 9 | end |
9 | 10 | ||
10 | describe "Post Receive Event" do | 11 | describe "Post Receive Event" do |
11 | it "should create push event" do | 12 | it "should create push event" do |
12 | oldrev, newrev, ref = '00000000000000000000000000000000', 'newrev', 'refs/heads/master' | 13 | oldrev, newrev, ref = '00000000000000000000000000000000', 'newrev', 'refs/heads/master' |
13 | - project.observe_push(oldrev, newrev, ref, @key_id) | 14 | + project.observe_push(oldrev, newrev, ref, @user) |
14 | event = Event.last | 15 | event = Event.last |
15 | 16 | ||
16 | event.should_not be_nil | 17 | event.should_not be_nil |
17 | event.project.should == project | 18 | event.project.should == project |
18 | event.action.should == Event::Pushed | 19 | event.action.should == Event::Pushed |
19 | - event.data == project.web_hook_data(oldrev, newrev, ref, @key_id) | 20 | + event.data == project.post_receive_data(oldrev, newrev, ref, @user) |
20 | end | 21 | end |
21 | end | 22 | end |
22 | 23 | ||
@@ -24,7 +25,7 @@ describe Project, "Hooks" do | @@ -24,7 +25,7 @@ describe Project, "Hooks" do | ||
24 | context "with no web hooks" do | 25 | context "with no web hooks" do |
25 | it "raises no errors" do | 26 | it "raises no errors" do |
26 | lambda { | 27 | lambda { |
27 | - project.execute_web_hooks('oldrev', 'newrev', 'ref', @key_id) | 28 | + project.execute_web_hooks('oldrev', 'newrev', 'ref', @user) |
28 | }.should_not raise_error | 29 | }.should_not raise_error |
29 | end | 30 | end |
30 | end | 31 | end |
@@ -40,7 +41,7 @@ describe Project, "Hooks" do | @@ -40,7 +41,7 @@ describe Project, "Hooks" do | ||
40 | @webhook.should_receive(:execute).once | 41 | @webhook.should_receive(:execute).once |
41 | @webhook_2.should_receive(:execute).once | 42 | @webhook_2.should_receive(:execute).once |
42 | 43 | ||
43 | - project.execute_web_hooks('oldrev', 'newrev', 'refs/heads/master', @key_id) | 44 | + project.execute_web_hooks('oldrev', 'newrev', 'refs/heads/master', @user) |
44 | end | 45 | end |
45 | end | 46 | end |
46 | 47 | ||
@@ -52,12 +53,12 @@ describe Project, "Hooks" do | @@ -52,12 +53,12 @@ describe Project, "Hooks" do | ||
52 | 53 | ||
53 | it "when pushing a branch for the first time" do | 54 | it "when pushing a branch for the first time" do |
54 | @webhook.should_not_receive(:execute) | 55 | @webhook.should_not_receive(:execute) |
55 | - project.execute_web_hooks('00000000000000000000000000000000', 'newrev', 'refs/heads/master', @key_id) | 56 | + project.execute_web_hooks('00000000000000000000000000000000', 'newrev', 'refs/heads/master', @user) |
56 | end | 57 | end |
57 | 58 | ||
58 | it "when pushing tags" do | 59 | it "when pushing tags" do |
59 | @webhook.should_not_receive(:execute) | 60 | @webhook.should_not_receive(:execute) |
60 | - project.execute_web_hooks('oldrev', 'newrev', 'refs/tags/v1.0.0', @key_id) | 61 | + project.execute_web_hooks('oldrev', 'newrev', 'refs/tags/v1.0.0', @user) |
61 | end | 62 | end |
62 | end | 63 | end |
63 | 64 | ||
@@ -73,7 +74,7 @@ describe Project, "Hooks" do | @@ -73,7 +74,7 @@ describe Project, "Hooks" do | ||
73 | # Fill nil/empty attributes | 74 | # Fill nil/empty attributes |
74 | project.description = "This is a description" | 75 | project.description = "This is a description" |
75 | 76 | ||
76 | - @data = project.web_hook_data(@oldrev, @newrev, @ref, @key_id) | 77 | + @data = project.post_receive_data(@oldrev, @newrev, @ref, @user) |
77 | end | 78 | end |
78 | 79 | ||
79 | subject { @data } | 80 | subject { @data } |
@@ -91,7 +92,6 @@ describe Project, "Hooks" do | @@ -91,7 +92,6 @@ describe Project, "Hooks" do | ||
91 | it { should include(url: project.web_url) } | 92 | it { should include(url: project.web_url) } |
92 | it { should include(description: project.description) } | 93 | it { should include(description: project.description) } |
93 | it { should include(homepage: project.web_url) } | 94 | it { should include(homepage: project.web_url) } |
94 | - it { should include(private: project.private?) } | ||
95 | end | 95 | end |
96 | 96 | ||
97 | context "with commits" do | 97 | context "with commits" do |
spec/models/project_spec.rb
@@ -175,7 +175,7 @@ describe Project do | @@ -175,7 +175,7 @@ describe Project do | ||
175 | it "should close merge request if last commit from source branch was pushed to target branch" do | 175 | it "should close merge request if last commit from source branch was pushed to target branch" do |
176 | @merge_request.reloaded_commits | 176 | @merge_request.reloaded_commits |
177 | @merge_request.last_commit.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" | 177 | @merge_request.last_commit.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" |
178 | - project.update_merge_requests("8716fc78f3c65bbf7bcf7b574febd583bc5d2812", "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a", "refs/heads/stable", @key.identifier) | 178 | + project.update_merge_requests("8716fc78f3c65bbf7bcf7b574febd583bc5d2812", "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a", "refs/heads/stable", @key.user) |
179 | @merge_request.reload | 179 | @merge_request.reload |
180 | @merge_request.merged.should be_true | 180 | @merge_request.merged.should be_true |
181 | @merge_request.closed.should be_true | 181 | @merge_request.closed.should be_true |
@@ -183,7 +183,7 @@ describe Project do | @@ -183,7 +183,7 @@ describe Project do | ||
183 | 183 | ||
184 | it "should update merge request commits with new one if pushed to source branch" do | 184 | it "should update merge request commits with new one if pushed to source branch" do |
185 | @merge_request.last_commit.should == nil | 185 | @merge_request.last_commit.should == nil |
186 | - project.update_merge_requests("8716fc78f3c65bbf7bcf7b574febd583bc5d2812", "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a", "refs/heads/master", @key.identifier) | 186 | + project.update_merge_requests("8716fc78f3c65bbf7bcf7b574febd583bc5d2812", "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a", "refs/heads/master", @key.user) |
187 | @merge_request.reload | 187 | @merge_request.reload |
188 | @merge_request.last_commit.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" | 188 | @merge_request.last_commit.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" |
189 | end | 189 | end |
spec/workers/post_receive_spec.rb
@@ -29,14 +29,14 @@ describe PostReceive do | @@ -29,14 +29,14 @@ describe PostReceive do | ||
29 | 29 | ||
30 | it "asks the project to execute web hooks" do | 30 | it "asks the project to execute web hooks" do |
31 | Project.stub(find_by_path: project) | 31 | Project.stub(find_by_path: project) |
32 | - project.should_receive(:execute_web_hooks).with('sha-old', 'sha-new', 'refs/heads/master', key_id) | 32 | + project.should_receive(:execute_web_hooks).with('sha-old', 'sha-new', 'refs/heads/master', project.owner) |
33 | 33 | ||
34 | PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id) | 34 | PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id) |
35 | end | 35 | end |
36 | 36 | ||
37 | it "asks the project to observe push/create event data" do | 37 | it "asks the project to observe push/create event data" do |
38 | Project.stub(find_by_path: project) | 38 | Project.stub(find_by_path: project) |
39 | - project.should_receive(:observe_push).with('sha-old', 'sha-new', 'refs/heads/master', key_id) | 39 | + project.should_receive(:observe_push).with('sha-old', 'sha-new', 'refs/heads/master', project.owner) |
40 | 40 | ||
41 | PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id) | 41 | PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id) |
42 | end | 42 | end |