Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2015-08-10 11:54:42 +0300
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2015-08-10 11:54:42 +0300
commit99585a738cdf119ca59ce932b4ac0f278f6fda88 (patch)
tree9a9389597398b9246fd056c931bbfa53c2c1a6ea /app/services
parentfb6f8d9198a7dbbd2dabf731ad0c9c8010a3f9f4 (diff)
Trigger post-receive hoooks when commits are made by GitLab
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Diffstat (limited to 'app/services')
-rw-r--r--app/services/post_commit_service.rb65
1 files changed, 64 insertions, 1 deletions
diff --git a/app/services/post_commit_service.rb b/app/services/post_commit_service.rb
index 7d7e5fbc32e..aa9a807b7d2 100644
--- a/app/services/post_commit_service.rb
+++ b/app/services/post_commit_service.rb
@@ -1,8 +1,71 @@
class PostCommitService < BaseService
+ include Gitlab::Popen
+
+ attr_reader :changes
+
def execute(sha, branch)
commit = repository.commit(sha)
full_ref = 'refs/heads/' + branch
old_sha = commit.parent_id || Gitlab::Git::BLANK_SHA
- GitPushService.new.execute(project, current_user, old_sha, sha, full_ref)
+
+ @changes = "#{old_sha} #{sha} #{full_ref}"
+ post_receive(@changes, repository.path_to_repo)
+ end
+
+ private
+
+ def post_receive(changes, repo_path)
+ hook = hook_file('post-receive', repo_path)
+ return true if hook.nil?
+ call_receive_hook(hook, changes) ? true : false
+ end
+
+ def call_receive_hook(hook, changes)
+ # function will return true if succesful
+ exit_status = false
+
+ vars = {
+ 'GL_ID' => Gitlab::ShellEnv.gl_id(current_user),
+ 'PWD' => repository.path_to_repo
+ }
+
+ options = {
+ chdir: repository.path_to_repo
+ }
+
+ # we combine both stdout and stderr as we don't know what stream
+ # will be used by the custom hook
+ Open3.popen2e(vars, hook, options) do |stdin, stdout_stderr, wait_thr|
+ exit_status = true
+ stdin.sync = true
+
+ # in git, pre- and post- receive hooks may just exit without
+ # reading stdin. We catch the exception to avoid a broken pipe
+ # warning
+ begin
+ # inject all the changes as stdin to the hook
+ changes.lines do |line|
+ stdin.puts (line)
+ end
+ rescue Errno::EPIPE
+ end
+
+ # need to close stdin before reading stdout
+ stdin.close
+
+ # only output stdut_stderr if scripts doesn't return 0
+ unless wait_thr.value == 0
+ exit_status = false
+ stdout_stderr.each_line { |line| puts line }
+ end
+ end
+
+ exit_status
+ end
+
+ def hook_file(hook_type, repo_path)
+ hook_path = File.join(repo_path.strip, 'hooks')
+ hook_file = "#{hook_path}/#{hook_type}"
+ hook_file if File.exist?(hook_file)
end
end