diff options
Diffstat (limited to 'app/services/git')
-rw-r--r-- | app/services/git/branch_hooks_service.rb | 2 | ||||
-rw-r--r-- | app/services/git/wiki_push_service.rb | 57 | ||||
-rw-r--r-- | app/services/git/wiki_push_service/change.rb | 67 |
3 files changed, 124 insertions, 2 deletions
diff --git a/app/services/git/branch_hooks_service.rb b/app/services/git/branch_hooks_service.rb index e1cc1f8c834..92e7702727c 100644 --- a/app/services/git/branch_hooks_service.rb +++ b/app/services/git/branch_hooks_service.rb @@ -112,7 +112,7 @@ module Git end def enqueue_update_signatures - unsigned = unsigned_x509_shas(commits) & unsigned_gpg_shas(commits) + unsigned = unsigned_x509_shas(limited_commits) & unsigned_gpg_shas(limited_commits) return if unsigned.empty? signable = Gitlab::Git::Commit.shas_with_signatures(project.repository, unsigned) diff --git a/app/services/git/wiki_push_service.rb b/app/services/git/wiki_push_service.rb index d4267d4a3c5..8bdbc28f3e8 100644 --- a/app/services/git/wiki_push_service.rb +++ b/app/services/git/wiki_push_service.rb @@ -2,8 +2,63 @@ module Git class WikiPushService < ::BaseService + # Maximum number of change events we will process on any single push + MAX_CHANGES = 100 + def execute - # This is used in EE + process_changes + end + + private + + def process_changes + return unless can_process_wiki_events? + + push_changes.take(MAX_CHANGES).each do |change| # rubocop:disable CodeReuse/ActiveRecord + next unless change.page.present? + + response = create_event_for(change) + log_error(response.message) if response.error? + end + end + + def can_process_wiki_events? + Feature.enabled?(:wiki_events) && Feature.enabled?(:wiki_events_on_git_push, project) + end + + def push_changes + default_branch_changes.flat_map do |change| + raw_changes(change).map { |raw| Git::WikiPushService::Change.new(wiki, change, raw) } + end + end + + def raw_changes(change) + wiki.repository.raw.raw_changes_between(change[:oldrev], change[:newrev]) + end + + def wiki + project.wiki + end + + def create_event_for(change) + event_service.execute(change.last_known_slug, change.page, change.event_action) + end + + def event_service + @event_service ||= WikiPages::EventCreateService.new(current_user) + end + + def on_default_branch?(change) + project.wiki.default_branch == ::Gitlab::Git.branch_name(change[:ref]) + end + + # See: [Gitlab::GitPostReceive#changes] + def changes + params[:changes] || [] + end + + def default_branch_changes + @default_branch_changes ||= changes.select { |change| on_default_branch?(change) } end end end diff --git a/app/services/git/wiki_push_service/change.rb b/app/services/git/wiki_push_service/change.rb new file mode 100644 index 00000000000..8685850165a --- /dev/null +++ b/app/services/git/wiki_push_service/change.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +module Git + class WikiPushService + class Change + include Gitlab::Utils::StrongMemoize + + # @param [ProjectWiki] wiki + # @param [Hash] change - must have keys `:oldrev` and `:newrev` + # @param [Gitlab::Git::RawDiffChange] raw_change + def initialize(project_wiki, change, raw_change) + @wiki, @raw_change, @change = project_wiki, raw_change, change + end + + def page + strong_memoize(:page) { wiki.find_page(slug, revision) } + end + + # See [Gitlab::Git::RawDiffChange#extract_operation] for the + # definition of the full range of operation values. + def event_action + case raw_change.operation + when :added + Event::CREATED + when :deleted + Event::DESTROYED + else + Event::UPDATED + end + end + + def last_known_slug + strip_extension(raw_change.old_path || raw_change.new_path) + end + + private + + attr_reader :raw_change, :change, :wiki + + def filename + return raw_change.old_path if deleted? + + raw_change.new_path + end + + def slug + strip_extension(filename) + end + + def revision + return change[:oldrev] if deleted? + + change[:newrev] + end + + def deleted? + raw_change.operation == :deleted + end + + def strip_extension(filename) + return unless filename + + File.basename(filename, File.extname(filename)) + end + end + end +end |