gitlab-org--gitlab-foss/app/workers/post_receive.rb
Jonathon Reinhart ba781484c7 Add support for Git push options, specifically ci.skip
gitlab-org/gitlab-shell!166 added support for collecting push options
from the environment, and passing them along to the
/internal/post_receive API endpoint.

This change handles the new push_options JSON element in the payload,
and passes them on through to the GitPushService and GitTagPushService
services.

Futhermore, it adds support for the first push option, ci.skip.  With
this change, one can use 'git push -o ci.skip' to skip CI pipe
execution. Note that the pipeline is still created, but in the "skipped"
state, just like with the 'ci skip' commit message text.

Implements #18667
2018-12-31 13:57:53 -05:00

77 lines
2.3 KiB
Ruby

# frozen_string_literal: true
class PostReceive
include ApplicationWorker
def perform(gl_repository, identifier, changes, push_options = [])
project, is_wiki = Gitlab::GlRepository.parse(gl_repository)
if project.nil?
log("Triggered hook for non-existing project with gl_repository \"#{gl_repository}\"")
return false
end
changes = Base64.decode64(changes) unless changes.include?(' ')
# Use Sidekiq.logger so arguments can be correlated with execution
# time and thread ID's.
Sidekiq.logger.info "changes: #{changes.inspect}" if ENV['SIDEKIQ_LOG_ARGUMENTS']
post_received = Gitlab::GitPostReceive.new(project, identifier, changes, push_options)
if is_wiki
process_wiki_changes(post_received)
else
process_project_changes(post_received)
end
end
private
def process_project_changes(post_received)
changes = []
refs = Set.new
@user = post_received.identify
unless @user
log("Triggered hook for non-existing user \"#{post_received.identifier}\"")
return false
end
post_received.changes_refs do |oldrev, newrev, ref|
if Gitlab::Git.tag_ref?(ref)
GitTagPushService.new(
post_received.project,
@user,
oldrev: oldrev,
newrev: newrev,
ref: ref,
push_options: post_received.push_options).execute
elsif Gitlab::Git.branch_ref?(ref)
GitPushService.new(
post_received.project,
@user,
oldrev: oldrev,
newrev: newrev,
ref: ref,
push_options: post_received.push_options).execute
end
changes << Gitlab::DataBuilder::Repository.single_change(oldrev, newrev, ref)
refs << ref
end
after_project_changes_hooks(post_received, @user, refs.to_a, changes)
end
def after_project_changes_hooks(post_received, user, refs, changes)
hook_data = Gitlab::DataBuilder::Repository.update(post_received.project, user, changes, refs)
SystemHooksService.new.execute_hooks(hook_data, :repository_update_hooks)
end
def process_wiki_changes(post_received)
post_received.project.touch(:last_activity_at, :last_repository_updated_at)
end
def log(message)
Gitlab::GitLogger.error("POST-RECEIVE: #{message}")
end
end