class Gitlabci::Bundle::Update::Mr::Client
Constants
- BRANCH_PREFIX
- MAX_RETRY_COUNT
- TITLE_PREFIX
Public Class Methods
@param gitlab_api_endpoint [String] @param gitlab_api_private_token [String] @param project_name [String] @param branch [String] @param author_email [String] @param author_name [String]
# File lib/gitlabci/bundle/update/mr/client.rb, line 18 def initialize(gitlab_api_endpoint:, gitlab_api_private_token:, project_name:, branch:, author_email:, author_name:) @gitlab = Gitlab.client(endpoint: gitlab_api_endpoint, private_token: gitlab_api_private_token) @project_name = project_name @branch = branch @author_email = author_email @author_name = author_name end
Public Instance Methods
@param lockfile [String]
# File lib/gitlabci/bundle/update/mr/client.rb, line 67 def commit_gemfile_lock(lockfile) @gitlab.create_commit( @project_name, new_branch, "$ bundle update && bundle update --ruby", [ { action: "update", file_path: lockfile_name, content: lockfile, }, ], start_branch: @branch, author_email: @author_email, author_name: @author_name, ) end
@param description [String] @param mr_labels [Array<String>] @param assignee_ids [Array<Integer>]
@see docs.gitlab.com/ee/api/merge_requests.html#create-mr
# File lib/gitlabci/bundle/update/mr/client.rb, line 90 def create_merge_request(description:, mr_labels:, assignee_ids:) params = { source_branch: new_branch, target_branch: @branch, remove_source_branch: true, description: description, } unless mr_labels.empty? params[:labels] = mr_labels.join(",") end if assignee_ids.length == 1 params[:assignee_id] = assignee_ids[0] elsif assignee_ids.length >= 2 params[:assignee_ids] = assignee_ids end @gitlab.create_merge_request( @project_name, "#{TITLE_PREFIX}#{current_time.strftime("%Y-%m-%d %H:%M:%S %Z")}", params, ) end
@param username [String]
@return [Gitlab::ObjectifiedHash] @return [nil] User isn't found
@see docs.gitlab.com/ee/api/users.html#for-normal-users
# File lib/gitlabci/bundle/update/mr/client.rb, line 141 def find_by_username(username) @gitlab.users(username: username).first end
@param username [String]
@return [Gitlab::ObjectifiedHash]
@raise [Gitlabci::Bundle::Update::Mr::NotFoundUserError]
@see docs.gitlab.com/ee/api/users.html#for-normal-users
# File lib/gitlabci/bundle/update/mr/client.rb, line 152 def find_by_username!(username) user = find_by_username(username) unless user raise NotFoundUserError, "#{username} isn't found" end user end
@param old_lockfile [String] @param new_lockfile [String]
@return [String]
# File lib/gitlabci/bundle/update/mr/client.rb, line 119 def merge_request_description(old_lockfile, new_lockfile) compare_linker = CompareLinker.new("dummy", "dummy") compare_linker.formatter = CompareLinker::Formatter::Markdown.new compare_links = compare_linker. make_compare_links_from_lockfiles(Bundler::LockfileParser.new(old_lockfile), Bundler::LockfileParser.new(new_lockfile)). to_a.join("\n") <<~MARKDOWN **Updated RubyGems:** #{compare_links} Powered by [gitlabci-bundle-update-mr](https://rubygems.org/gems/gitlabci-bundle-update-mr) MARKDOWN end
@param allow_dup_mr [Boolean] @param mr_labels [Array<String>] @param update_bundled_with [Boolean] @param merge_when_pipeline_succeeds [Boolean] @param assignees [Array<String>]
# File lib/gitlabci/bundle/update/mr/client.rb, line 33 def perform(allow_dup_mr:, mr_labels:, update_bundled_with:, merge_when_pipeline_succeeds:, assignees:) if !allow_dup_mr && exists_bundle_update_mr? puts "Skip because it has already existed." return end assignee_ids = get_assignee_ids(assignees) old_lockfile = File.read(lockfile_name) system!("bundle update") system!("bundle update --ruby") restore_bundled_with unless update_bundled_with new_lockfile = File.read(lockfile_name) if old_lockfile == new_lockfile puts "#{lockfile_name} is not updated" return end commit_gemfile_lock(new_lockfile) description = merge_request_description(old_lockfile, new_lockfile) mr = create_merge_request(description: description, mr_labels: mr_labels, assignee_ids: assignee_ids) puts "MR is created: #{mr.web_url}" if merge_when_pipeline_succeeds accept_merge_request(mr.iid) puts "Set merge_when_pipeline_succeeds to #{mr.web_url}" end end
Private Instance Methods
# File lib/gitlabci/bundle/update/mr/client.rb, line 209 def accept_merge_request(mr_id) with_retry do @gitlab.accept_merge_request(@project_name, mr_id, merge_when_pipeline_succeeds: true, should_remove_source_branch: true) end end
# File lib/gitlabci/bundle/update/mr/client.rb, line 196 def current_time @current_time ||= Time.now end
# File lib/gitlabci/bundle/update/mr/client.rb, line 204 def exists_bundle_update_mr? merge_requests = @gitlab.merge_requests(@project_name, state: "opened", target_branch: @branch, search: TITLE_PREFIX.strip) merge_requests.any? {|mr| mr.title.start_with?(TITLE_PREFIX) && mr.source_branch.start_with?(BRANCH_PREFIX) } end
# File lib/gitlabci/bundle/update/mr/client.rb, line 180 def gemfile_name return @gemfile_name if @gemfile_name @gemfile_name = ENV["BUNDLE_GEMFILE"] || "Gemfile" if @gemfile_name.start_with?("#{Dir.pwd}/") @gemfile_name = @gemfile_name.gsub("#{Dir.pwd}/", "") end @gemfile_name end
# File lib/gitlabci/bundle/update/mr/client.rb, line 232 def get_assignee_ids(assignees) assignees.map do |username| user = find_by_username!(username) user.id end end
# File lib/gitlabci/bundle/update/mr/client.rb, line 192 def lockfile_name "#{gemfile_name}.lock" end
# File lib/gitlabci/bundle/update/mr/client.rb, line 200 def new_branch "#{BRANCH_PREFIX}#{current_time.strftime("%Y%m%d%H%M%S")}" end
# File lib/gitlabci/bundle/update/mr/client.rb, line 170 def restore_bundled_with RestoreBundledWith::CLI.new.invoke( :restore, [], { lockfile: lockfile_name, }, ) end
# File lib/gitlabci/bundle/update/mr/client.rb, line 164 def system!(command) # NOTE: system(exception: true) requires Ruby 2.6+ ret = system(command) raise "`#{command}` is failed" unless ret end
# File lib/gitlabci/bundle/update/mr/client.rb, line 215 def with_retry retry_count ||= 0 yield rescue Gitlab::Error::MethodNotAllowed, Gitlab::Error::NotAcceptable => e retry_count += 1 if retry_count > MAX_RETRY_COUNT raise e end puts "Error is occurred and auto retry (#{retry_count}/#{MAX_RETRY_COUNT}): #{e}" sleep 1 retry end