diff options
author | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2015-08-10 11:57:53 +0000 |
---|---|---|
committer | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2015-08-10 11:57:53 +0000 |
commit | 819d110cabfc2791e0e84bd89b9f87aef570c1db (patch) | |
tree | 1be66aa321fab0e6f1ab60b419e7f07a141ffa50 | |
parent | 3752172dcda1c655e61c1eec3d227732c3f535b2 (diff) | |
parent | 59e7b7a654dca0a537c50dfc59fbf5a33a03a345 (diff) | |
download | gitlab-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.rb | 67 | ||||
-rw-r--r-- | app/workers/post_receive.rb | 2 |
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? |