summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2015-08-10 11:57:53 +0000
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2015-08-10 11:57:53 +0000
commit819d110cabfc2791e0e84bd89b9f87aef570c1db (patch)
tree1be66aa321fab0e6f1ab60b419e7f07a141ffa50
parent3752172dcda1c655e61c1eec3d227732c3f535b2 (diff)
parent59e7b7a654dca0a537c50dfc59fbf5a33a03a345 (diff)
downloadgitlab-ce-819d110cabfc2791e0e84bd89b9f87aef570c1db.tar.gz
Merge branch 'trigger-hooks' into 'master'
Trigger post-receive hooks after commits are made by GitLab Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> See merge request !1127
-rw-r--r--app/services/post_commit_service.rb67
-rw-r--r--app/workers/post_receive.rb2
2 files changed, 66 insertions, 3 deletions
diff --git a/app/services/post_commit_service.rb b/app/services/post_commit_service.rb
index 7d7e5fbc32e..8592c8d238b 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, :repo_path
+
def execute(sha, branch)
commit = repository.commit(sha)
- full_ref = 'refs/heads/' + branch
+ full_ref = Gitlab::Git::BRANCH_REF_PREFIX + 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}"
+ @repo_path = repository.path_to_repo
+
+ post_receive
+ end
+
+ private
+
+ def post_receive
+ hook = hook_file('post-receive', repo_path)
+ return true if hook.nil?
+ call_receive_hook(hook)
+ end
+
+ def call_receive_hook(hook)
+ # function will return true if succesful
+ exit_status = false
+
+ vars = {
+ 'GL_ID' => Gitlab::ShellEnv.gl_id(current_user),
+ 'PWD' => repo_path
+ }
+
+ options = {
+ chdir: repo_path
+ }
+
+ # 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
+ 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
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index 33d8cc8861b..994b8e8ed38 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -45,7 +45,7 @@ class PostReceive
def utf8_encode_changes(changes)
changes = changes.dup
-
+
changes.force_encoding("UTF-8")
return changes if changes.valid_encoding?