diff options
Diffstat (limited to 'app/workers')
-rw-r--r-- | app/workers/all_queues.yml | 9 | ||||
-rw-r--r-- | app/workers/integrations/irker_worker.rb | 193 | ||||
-rw-r--r-- | app/workers/irker_worker.rb | 192 | ||||
-rw-r--r-- | app/workers/project_service_worker.rb | 2 |
4 files changed, 209 insertions, 187 deletions
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index a85d0b2c0ef..c1a4ea3a3d0 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -2407,6 +2407,15 @@ :weight: 1 :idempotent: false :tags: [] +- :name: integrations_irker + :worker_name: Integrations::IrkerWorker + :feature_category: :integrations + :has_external_dependencies: false + :urgency: :low + :resource_boundary: :unknown + :weight: 1 + :idempotent: false + :tags: [] - :name: invalid_gpg_signature_update :worker_name: InvalidGpgSignatureUpdateWorker :feature_category: :source_code_management diff --git a/app/workers/integrations/irker_worker.rb b/app/workers/integrations/irker_worker.rb new file mode 100644 index 00000000000..3152d68b372 --- /dev/null +++ b/app/workers/integrations/irker_worker.rb @@ -0,0 +1,193 @@ +# frozen_string_literal: true + +require 'json' +require 'socket' +require 'resolv' + +module Integrations + class IrkerWorker # rubocop:disable Scalability/IdempotentWorker + include ApplicationWorker + + data_consistency :always + sidekiq_options retry: 3 + feature_category :integrations + urgency :low + + def perform(project_id, channels, colors, push_data, settings) + # Establish connection to irker server + return false unless start_connection( + settings['server_host'], + settings['server_port'] + ) + + @project = Project.find(project_id) + @colors = colors + @channels = channels + + @repo_path = @project.full_path + @repo_name = push_data['repository']['name'] + @committer = push_data['user_name'] + @branch = push_data['ref'].gsub(%r{refs/[^/]*/}, '') + + if @colors + @repo_name = "\x0304#{@repo_name}\x0f" + @branch = "\x0305#{@branch}\x0f" + end + + # First messages are for branch creation/deletion + send_branch_updates(push_data) + + # Next messages are for commits + send_commits(push_data) + + close_connection + true + end + + private + + def start_connection(irker_server, irker_port) + ip_address = Resolv.getaddress(irker_server) + # handle IP6 addresses + domain = Resolv::IPv6::Regex.match?(ip_address) ? "[#{ip_address}]" : ip_address + + begin + Gitlab::UrlBlocker.validate!( + "irc://#{domain}", + allow_localhost: allow_local_requests?, + allow_local_network: allow_local_requests?, + schemes: ['irc']) + @socket = TCPSocket.new ip_address, irker_port + rescue Errno::ECONNREFUSED, Gitlab::UrlBlocker::BlockedUrlError => e + logger.fatal "Can't connect to Irker daemon: #{e}" + return false + end + + true + end + + def allow_local_requests? + Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services? + end + + def send_to_irker(privmsg) + to_send = { to: @channels, privmsg: privmsg } + + @socket.puts Gitlab::Json.dump(to_send) + end + + def close_connection + @socket.close + end + + def send_branch_updates(push_data) + message = + if Gitlab::Git.blank_ref?(push_data['before']) + new_branch_message + elsif Gitlab::Git.blank_ref?(push_data['after']) + delete_branch_message + end + + send_to_irker(message) + end + + def new_branch_message + newbranch = "#{Gitlab.config.gitlab.url}/#{@repo_path}/-/branches" + newbranch = "\x0302\x1f#{newbranch}\x0f" if @colors + + "[#{@repo_name}] #{@committer} has created a new branch #{@branch}: #{newbranch}" + end + + def delete_branch_message + "[#{@repo_name}] #{@committer} has deleted the branch #{@branch}" + end + + def send_commits(push_data) + return if push_data['total_commits_count'] == 0 + + # Next message is for number of commit pushed, if any + if Gitlab::Git.blank_ref?(push_data['before']) + # Tweak on push_data["before"] in order to have a nice compare URL + push_data['before'] = before_on_new_branch(push_data) + end + + send_commits_count(push_data) + + # One message per commit, limited by 3 messages (same limit as the + # github irc hook) + commits = push_data['commits'].first(3) + commits.each do |commit_attrs| + send_one_commit(commit_attrs) + end + end + + def before_on_new_branch(push_data) + commit = commit_from_id(push_data['commits'][0]['id']) + parents = commit.parents + + # Return old value if there's no new one + return push_data['before'] if parents.empty? + + # Or return the first parent-commit + parents[0].id + end + + def send_commits_count(push_data) + url = compare_url(push_data['before'], push_data['after']) + commits = colorize_commits(push_data['total_commits_count']) + new_commits = 'new commit'.pluralize(push_data['total_commits_count']) + + send_to_irker("[#{@repo_name}] #{@committer} pushed #{commits} #{new_commits} " \ + "to #{@branch}: #{url}") + end + + def compare_url(sha_before, sha_after) + sha1 = Commit.truncate_sha(sha_before) + sha2 = Commit.truncate_sha(sha_after) + compare_url = "#{Gitlab.config.gitlab.url}/#{@repo_path}/-/compare" \ + "/#{sha1}...#{sha2}" + + colorize_url(compare_url) + end + + def send_one_commit(commit_attrs) + commit = commit_from_id(commit_attrs['id']) + sha = colorize_sha(Commit.truncate_sha(commit_attrs['id'])) + author = commit_attrs['author']['name'] + files = colorize_nb_files(files_count(commit)) + title = commit.title + + send_to_irker("#{@repo_name}/#{@branch} #{sha} #{author} (#{files}): #{title}") + end + + def commit_from_id(id) + @project.commit(id) + end + + def files_count(commit) + diff_size = commit.raw_deltas.size + + "#{diff_size} file".pluralize(diff_size) + end + + def colorize_sha(sha) + sha = "\x0314#{sha}\x0f" if @colors + sha + end + + def colorize_nb_files(nb_files) + nb_files = "\x0312#{nb_files}\x0f" if @colors + nb_files + end + + def colorize_url(url) + url = "\x0302\x1f#{url}\x0f" if @colors + url + end + + def colorize_commits(commits) + commits = "\x02#{commits}\x0f" if @colors + commits + end + end +end diff --git a/app/workers/irker_worker.rb b/app/workers/irker_worker.rb index 4f51bb69b8c..a054021e418 100644 --- a/app/workers/irker_worker.rb +++ b/app/workers/irker_worker.rb @@ -1,189 +1,9 @@ # frozen_string_literal: true -require 'json' -require 'socket' -require 'resolv' - -class IrkerWorker # rubocop:disable Scalability/IdempotentWorker - include ApplicationWorker - - data_consistency :always - sidekiq_options retry: 3 - feature_category :integrations - urgency :low - - def perform(project_id, channels, colors, push_data, settings) - # Establish connection to irker server - return false unless start_connection(settings['server_host'], - settings['server_port']) - - @project = Project.find(project_id) - @colors = colors - @channels = channels - - @repo_path = @project.full_path - @repo_name = push_data['repository']['name'] - @committer = push_data['user_name'] - @branch = push_data['ref'].gsub(%r'refs/[^/]*/', '') - - if @colors - @repo_name = "\x0304#{@repo_name}\x0f" - @branch = "\x0305#{@branch}\x0f" - end - - # First messages are for branch creation/deletion - send_branch_updates(push_data) - - # Next messages are for commits - send_commits(push_data) - - close_connection - true - end - - private - - def start_connection(irker_server, irker_port) - ip_address = Resolv.getaddress(irker_server) - # handle IP6 addresses - domain = Resolv::IPv6::Regex.match?(ip_address) ? "[#{ip_address}]" : ip_address - - begin - Gitlab::UrlBlocker.validate!( - "irc://#{domain}", - allow_localhost: allow_local_requests?, - allow_local_network: allow_local_requests?, - schemes: ['irc']) - @socket = TCPSocket.new ip_address, irker_port - rescue Errno::ECONNREFUSED, Gitlab::UrlBlocker::BlockedUrlError => e - logger.fatal "Can't connect to Irker daemon: #{e}" - return false - end - - true - end - - def allow_local_requests? - Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services? - end - - def send_to_irker(privmsg) - to_send = { to: @channels, privmsg: privmsg } - - @socket.puts Gitlab::Json.dump(to_send) - end - - def close_connection - @socket.close - end - - def send_branch_updates(push_data) - message = - if Gitlab::Git.blank_ref?(push_data['before']) - new_branch_message - elsif Gitlab::Git.blank_ref?(push_data['after']) - delete_branch_message - end - - send_to_irker(message) - end - - def new_branch_message - newbranch = "#{Gitlab.config.gitlab.url}/#{@repo_path}/-/branches" - newbranch = "\x0302\x1f#{newbranch}\x0f" if @colors - - "[#{@repo_name}] #{@committer} has created a new branch #{@branch}: #{newbranch}" - end - - def delete_branch_message - "[#{@repo_name}] #{@committer} has deleted the branch #{@branch}" - end - - def send_commits(push_data) - return if push_data['total_commits_count'] == 0 - - # Next message is for number of commit pushed, if any - if Gitlab::Git.blank_ref?(push_data['before']) - # Tweak on push_data["before"] in order to have a nice compare URL - push_data['before'] = before_on_new_branch(push_data) - end - - send_commits_count(push_data) - - # One message per commit, limited by 3 messages (same limit as the - # github irc hook) - commits = push_data['commits'].first(3) - commits.each do |commit_attrs| - send_one_commit(commit_attrs) - end - end - - def before_on_new_branch(push_data) - commit = commit_from_id(push_data['commits'][0]['id']) - parents = commit.parents - - # Return old value if there's no new one - return push_data['before'] if parents.empty? - - # Or return the first parent-commit - parents[0].id - end - - def send_commits_count(push_data) - url = compare_url(push_data['before'], push_data['after']) - commits = colorize_commits(push_data['total_commits_count']) - new_commits = 'new commit'.pluralize(push_data['total_commits_count']) - - send_to_irker("[#{@repo_name}] #{@committer} pushed #{commits} #{new_commits} " \ - "to #{@branch}: #{url}") - end - - def compare_url(sha_before, sha_after) - sha1 = Commit.truncate_sha(sha_before) - sha2 = Commit.truncate_sha(sha_after) - compare_url = "#{Gitlab.config.gitlab.url}/#{@repo_path}/-/compare" \ - "/#{sha1}...#{sha2}" - - colorize_url(compare_url) - end - - def send_one_commit(commit_attrs) - commit = commit_from_id(commit_attrs['id']) - sha = colorize_sha(Commit.truncate_sha(commit_attrs['id'])) - author = commit_attrs['author']['name'] - files = colorize_nb_files(files_count(commit)) - title = commit.title - - send_to_irker("#{@repo_name}/#{@branch} #{sha} #{author} (#{files}): #{title}") - end - - def commit_from_id(id) - @project.commit(id) - end - - def files_count(commit) - diff_size = commit.raw_deltas.size - - "#{diff_size} file".pluralize(diff_size) - end - - def colorize_sha(sha) - sha = "\x0314#{sha}\x0f" if @colors - sha - end - - def colorize_nb_files(nb_files) - nb_files = "\x0312#{nb_files}\x0f" if @colors - nb_files - end - - def colorize_url(url) - url = "\x0302\x1f#{url}\x0f" if @colors - url - end - - def colorize_commits(commits) - commits = "\x02#{commits}\x0f" if @colors - commits - end +# This worker was renamed in 15.1, we can delete it in 15.2. +# See: https://gitlab.com/gitlab-org/gitlab/-/issues/364112 +# +# rubocop: disable Gitlab/NamespacedClass +# rubocop:disable Scalability/IdempotentWorker +class IrkerWorker < Integrations::IrkerWorker end diff --git a/app/workers/project_service_worker.rb b/app/workers/project_service_worker.rb index f45eec0bcd9..56ac4bc046a 100644 --- a/app/workers/project_service_worker.rb +++ b/app/workers/project_service_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # This worker was renamed in 15.1, we can delete it in 15.2. -# See: https://gitlab.com/gitlab-org/gitlab/-/issues/364107 +# See: https://gitlab.com/gitlab-org/gitlab/-/issues/364112 # # rubocop: disable Gitlab/NamespacedClass # rubocop: disable Scalability/IdempotentWorker |