1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
module ProjectPush
def observe_push(oldrev, newrev, ref, user)
data = post_receive_data(oldrev, newrev, ref, user)
Event.create(
project: self,
action: Event::Pushed,
data: data,
author_id: data[:user_id]
)
end
def update_merge_requests(oldrev, newrev, ref, user)
return true unless ref =~ /heads/
branch_name = ref.gsub("refs/heads/", "")
c_ids = self.commits_between(oldrev, newrev).map(&:id)
# Update code for merge requests
mrs = self.merge_requests.opened.find_all_by_branch(branch_name).all
mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked }
# Close merge requests
mrs = self.merge_requests.opened.where(target_branch: branch_name).all
mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) }
mrs.each { |merge_request| merge_request.merge!(user.id) }
true
end
def execute_hooks(oldrev, newrev, ref, user)
ref_parts = ref.split('/')
# Return if this is not a push to a branch (e.g. new commits)
return if ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000"
data = post_receive_data(oldrev, newrev, ref, user)
hooks.each { |hook| hook.execute(data) }
end
def post_receive_data(oldrev, newrev, ref, user)
push_commits = commits_between(oldrev, newrev)
# Total commits count
push_commits_count = push_commits.size
# Get latest 20 commits ASC
push_commits_limited = push_commits.last(20)
# Hash to be passed as post_receive_data
data = {
before: oldrev,
after: newrev,
ref: ref,
user_id: user.id,
user_name: user.name,
repository: {
name: name,
url: web_url,
description: description,
homepage: web_url,
},
commits: [],
total_commits_count: push_commits_count
}
# For perfomance purposes maximum 20 latest commits
# will be passed as post receive hook data.
#
push_commits_limited.each do |commit|
data[:commits] << {
id: commit.id,
message: commit.safe_message,
timestamp: commit.date.xmlschema,
url: "#{Gitlab.config.url}/#{code}/commits/#{commit.id}",
author: {
name: commit.author_name,
email: commit.author_email
}
}
end
data
end
# This method will be called after each post receive
# and only if user present in gitlab.
# All callbacks for post receive should be placed here
#
def trigger_post_receive(oldrev, newrev, ref, user)
# Create push event
self.observe_push(oldrev, newrev, ref, user)
# Close merged MR
self.update_merge_requests(oldrev, newrev, ref, user)
# Execute web hooks
self.execute_hooks(oldrev, newrev, ref, user)
# Create satellite
self.satellite.create unless self.satellite.exists?
end
end
|