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 | 49 | def tag_name |
| 50 | 50 | @tag_name ||= data[:ref].gsub("refs/tags/", "") |
| 51 | 51 | end |
| 52 | - | |
| 52 | + | |
| 53 | + # Max 20 commits from push DESC | |
| 53 | 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 | 60 | end |
| 58 | 61 | |
| 59 | 62 | def ref_type |
| ... | ... | @@ -71,13 +74,15 @@ module Event::PushTrait |
| 71 | 74 | end |
| 72 | 75 | |
| 73 | 76 | def parent_commit |
| 74 | - commits.first.prev_commit | |
| 77 | + project.commit(commit_from) | |
| 75 | 78 | rescue => ex |
| 76 | 79 | nil |
| 77 | 80 | end |
| 78 | 81 | |
| 79 | 82 | def last_commit |
| 80 | - commits.last | |
| 83 | + project.commit(commit_to) | |
| 84 | + rescue => ex | |
| 85 | + nil | |
| 81 | 86 | end |
| 82 | 87 | |
| 83 | 88 | def push_with_commits? | ... | ... |
app/models/project/hooks_trait.rb
| 1 | 1 | module Project::HooksTrait |
| 2 | 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 | 6 | Event.create( |
| 7 | 7 | :project => self, |
| ... | ... | @@ -11,10 +11,9 @@ module Project::HooksTrait |
| 11 | 11 | ) |
| 12 | 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 | 15 | return true unless ref =~ /heads/ |
| 16 | 16 | branch_name = ref.gsub("refs/heads/", "") |
| 17 | - user = Key.find_by_identifier(author_key_id).user | |
| 18 | 17 | c_ids = self.commits_between(oldrev, newrev).map(&:id) |
| 19 | 18 | |
| 20 | 19 | # Update code for merge requests |
| ... | ... | @@ -29,36 +28,48 @@ module Project::HooksTrait |
| 29 | 28 | true |
| 30 | 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 | 32 | ref_parts = ref.split('/') |
| 34 | 33 | |
| 35 | 34 | # Return if this is not a push to a branch (e.g. new commits) |
| 36 | 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 | 39 | web_hooks.each { |web_hook| web_hook.execute(data) } |
| 41 | 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 | 53 | data = { |
| 46 | 54 | before: oldrev, |
| 47 | 55 | after: newrev, |
| 48 | 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 | 59 | repository: { |
| 52 | 60 | name: name, |
| 53 | 61 | url: web_url, |
| 54 | 62 | description: description, |
| 55 | 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 | 73 | data[:commits] << { |
| 63 | 74 | id: commit.id, |
| 64 | 75 | message: commit.safe_message, |
| ... | ... | @@ -73,5 +84,23 @@ module Project::HooksTrait |
| 73 | 84 | |
| 74 | 85 | data |
| 75 | 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 | 105 | end |
| 77 | 106 | end | ... | ... |
app/views/commits/compare.html.haml
app/views/dashboard/index.html.haml
| ... | ... | @@ -47,7 +47,7 @@ |
| 47 | 47 | - if @last_push && @last_push.valid_push? |
| 48 | 48 | .padded.prepend-top-20 |
| 49 | 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 | 51 | %ul.unstyled= render @last_push |
| 52 | 52 | |
| 53 | 53 | - if @merge_requests.any? | ... | ... |
app/views/events/_event_push.html.haml
| ... | ... | @@ -11,17 +11,17 @@ |
| 11 | 11 | ago. |
| 12 | 12 | |
| 13 | 13 | - if event.push_with_commits? |
| 14 | - - if event.commits.count > 1 | |
| 14 | + - if event.commits_count > 1 | |
| 15 | 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 | 17 | - project = event.project |
| 18 | 18 | %ul.unstyled.event_commits |
| 19 | - - if event.commits.size > 3 | |
| 19 | + - if event.commits_count > 3 | |
| 20 | 20 | - event.commits[0...2].each do |commit| |
| 21 | 21 | = render "events/commit", :commit => commit, :project => project |
| 22 | 22 | %li |
| 23 | 23 | %br |
| 24 | - \... and #{event.commits.size - 2} more commits | |
| 24 | + \... and #{event.commits_count - 2} more commits | |
| 25 | 25 | - else |
| 26 | 26 | - event.commits.each do |commit| |
| 27 | 27 | = render "events/commit", :commit => commit, :project => project | ... | ... |
app/workers/post_receive.rb
| ... | ... | @@ -8,13 +8,6 @@ class PostReceive |
| 8 | 8 | # Ignore push from non-gitlab users |
| 9 | 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 | 12 | end |
| 20 | 13 | end | ... | ... |
spec/models/project_hooks_spec.rb
| ... | ... | @@ -4,19 +4,20 @@ describe Project, "Hooks" do |
| 4 | 4 | let(:project) { Factory :project } |
| 5 | 5 | before do |
| 6 | 6 | @key = Factory :key, :user => project.owner |
| 7 | + @user = @key.user | |
| 7 | 8 | @key_id = @key.identifier |
| 8 | 9 | end |
| 9 | 10 | |
| 10 | 11 | describe "Post Receive Event" do |
| 11 | 12 | it "should create push event" do |
| 12 | 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 | 15 | event = Event.last |
| 15 | 16 | |
| 16 | 17 | event.should_not be_nil |
| 17 | 18 | event.project.should == project |
| 18 | 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 | 21 | end |
| 21 | 22 | end |
| 22 | 23 | |
| ... | ... | @@ -24,7 +25,7 @@ describe Project, "Hooks" do |
| 24 | 25 | context "with no web hooks" do |
| 25 | 26 | it "raises no errors" do |
| 26 | 27 | lambda { |
| 27 | - project.execute_web_hooks('oldrev', 'newrev', 'ref', @key_id) | |
| 28 | + project.execute_web_hooks('oldrev', 'newrev', 'ref', @user) | |
| 28 | 29 | }.should_not raise_error |
| 29 | 30 | end |
| 30 | 31 | end |
| ... | ... | @@ -40,7 +41,7 @@ describe Project, "Hooks" do |
| 40 | 41 | @webhook.should_receive(:execute).once |
| 41 | 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 | 45 | end |
| 45 | 46 | end |
| 46 | 47 | |
| ... | ... | @@ -52,12 +53,12 @@ describe Project, "Hooks" do |
| 52 | 53 | |
| 53 | 54 | it "when pushing a branch for the first time" do |
| 54 | 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 | 57 | end |
| 57 | 58 | |
| 58 | 59 | it "when pushing tags" do |
| 59 | 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 | 62 | end |
| 62 | 63 | end |
| 63 | 64 | |
| ... | ... | @@ -73,7 +74,7 @@ describe Project, "Hooks" do |
| 73 | 74 | # Fill nil/empty attributes |
| 74 | 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 | 78 | end |
| 78 | 79 | |
| 79 | 80 | subject { @data } |
| ... | ... | @@ -91,7 +92,6 @@ describe Project, "Hooks" do |
| 91 | 92 | it { should include(url: project.web_url) } |
| 92 | 93 | it { should include(description: project.description) } |
| 93 | 94 | it { should include(homepage: project.web_url) } |
| 94 | - it { should include(private: project.private?) } | |
| 95 | 95 | end |
| 96 | 96 | |
| 97 | 97 | context "with commits" do | ... | ... |
spec/models/project_spec.rb
| ... | ... | @@ -175,7 +175,7 @@ describe Project do |
| 175 | 175 | it "should close merge request if last commit from source branch was pushed to target branch" do |
| 176 | 176 | @merge_request.reloaded_commits |
| 177 | 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 | 179 | @merge_request.reload |
| 180 | 180 | @merge_request.merged.should be_true |
| 181 | 181 | @merge_request.closed.should be_true |
| ... | ... | @@ -183,7 +183,7 @@ describe Project do |
| 183 | 183 | |
| 184 | 184 | it "should update merge request commits with new one if pushed to source branch" do |
| 185 | 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 | 187 | @merge_request.reload |
| 188 | 188 | @merge_request.last_commit.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" |
| 189 | 189 | end | ... | ... |
spec/workers/post_receive_spec.rb
| ... | ... | @@ -29,14 +29,14 @@ describe PostReceive do |
| 29 | 29 | |
| 30 | 30 | it "asks the project to execute web hooks" do |
| 31 | 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 | 34 | PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id) |
| 35 | 35 | end |
| 36 | 36 | |
| 37 | 37 | it "asks the project to observe push/create event data" do |
| 38 | 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 | 41 | PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id) |
| 42 | 42 | end | ... | ... |