diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-01-18 22:00:14 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-01-18 22:00:14 +0300 |
commit | 05f0ebba3a2c8ddf39e436f412dc2ab5bf1353b2 (patch) | |
tree | 11d0f2a6ec31c7793c184106cedc2ded3d9a2cc5 /lib/gitlab/github_import | |
parent | ec73467c23693d0db63a797d10194da9e72a74af (diff) |
Add latest changes from gitlab-org/gitlab@15-8-stable-eev15.8.0-rc42
Diffstat (limited to 'lib/gitlab/github_import')
-rw-r--r-- | lib/gitlab/github_import/client.rb | 12 | ||||
-rw-r--r-- | lib/gitlab/github_import/clients/proxy.rb | 14 | ||||
-rw-r--r-- | lib/gitlab/github_import/clients/search_repos.rb | 55 | ||||
-rw-r--r-- | lib/gitlab/github_import/importer/protected_branch_importer.rb | 51 | ||||
-rw-r--r-- | lib/gitlab/github_import/representation/protected_branch.rb | 19 |
5 files changed, 110 insertions, 41 deletions
diff --git a/lib/gitlab/github_import/client.rb b/lib/gitlab/github_import/client.rb index 065410693e5..1c9ca9f43a8 100644 --- a/lib/gitlab/github_import/client.rb +++ b/lib/gitlab/github_import/client.rb @@ -264,18 +264,6 @@ module Gitlab private - def collaborations_subquery - each_object(:repos, nil, { affiliation: 'collaborator' }) - .map { |repo| "repo:#{repo[:full_name]}" } - .join(' ') - end - - def organizations_subquery - each_object(:organizations) - .map { |org| "org:#{org[:login]}" } - .join(' ') - end - def with_retry Retriable.retriable(on: CLIENT_CONNECTION_ERROR, on_retry: on_retry) do yield diff --git a/lib/gitlab/github_import/clients/proxy.rb b/lib/gitlab/github_import/clients/proxy.rb index f6d1c8ed23c..b12df404640 100644 --- a/lib/gitlab/github_import/clients/proxy.rb +++ b/lib/gitlab/github_import/clients/proxy.rb @@ -10,24 +10,24 @@ module Gitlab @client = pick_client(access_token, client_options) end - def repos(search_text, pagination_options) + def repos(search_text, options) return { repos: filtered(client.repos, search_text) } if use_legacy? if use_graphql? - fetch_repos_via_graphql(search_text, pagination_options) + fetch_repos_via_graphql(search_text, options) else - fetch_repos_via_rest(search_text, pagination_options) + fetch_repos_via_rest(search_text, options) end end private - def fetch_repos_via_rest(search_text, pagination_options) - { repos: client.search_repos_by_name(search_text, pagination_options)[:items] } + def fetch_repos_via_rest(search_text, options) + { repos: client.search_repos_by_name(search_text, options)[:items] } end - def fetch_repos_via_graphql(search_text, pagination_options) - response = client.search_repos_by_name_graphql(search_text, pagination_options) + def fetch_repos_via_graphql(search_text, options) + response = client.search_repos_by_name_graphql(search_text, options) { repos: response.dig(:data, :search, :nodes), page_info: response.dig(:data, :search, :pageInfo) diff --git a/lib/gitlab/github_import/clients/search_repos.rb b/lib/gitlab/github_import/clients/search_repos.rb index bcd226087e7..b72e5ac7751 100644 --- a/lib/gitlab/github_import/clients/search_repos.rb +++ b/lib/gitlab/github_import/clients/search_repos.rb @@ -14,18 +14,17 @@ module Gitlab end def search_repos_by_name(name, options = {}) + search_query = search_repos_query(name, options) + with_retry do - octokit.search_repositories( - search_repos_query(str: name, type: :name), - options - ).to_h + octokit.search_repositories(search_query, options).to_h end end private def graphql_search_repos_body(name, options) - query = search_repos_query(str: name, type: :name) + query = search_repos_query(name, options) query = "query: \"#{query}\"" first = options[:first].present? ? ", first: #{options[:first]}" : '' after = options[:after].present? ? ", after: \"#{options[:after]}\"" : '' @@ -52,13 +51,49 @@ module Gitlab TEXT end - def search_repos_query(str:, type:, include_collaborations: true, include_orgs: true) - query = "#{str} in:#{type} is:public,private user:#{octokit.user.to_h[:login]}" + def search_repos_query(string, options = {}) + base = "#{string} in:name is:public,private" + + case options[:relation_type] + when 'organization' then organization_repos_query(base, options) + when 'collaborated' then collaborated_repos_query(base) + when 'owned' then owned_repos_query(base) + # TODO: remove after https://gitlab.com/gitlab-org/gitlab/-/issues/385113 get done + else legacy_all_repos_query(base) + end + end + + def organization_repos_query(search_string, options) + "#{search_string} org:#{options[:organization_login]}" + end + + def collaborated_repos_query(search_string) + "#{search_string} #{collaborations_subquery}" + end + + def owned_repos_query(search_string) + "#{search_string} user:#{octokit.user.to_h[:login]}" + end - query = [query, collaborations_subquery].join(' ') if include_collaborations - query = [query, organizations_subquery].join(' ') if include_orgs + def legacy_all_repos_query(search_string) + [ + search_string, + "user:#{octokit.user.to_h[:login]}", + collaborations_subquery, + organizations_subquery + ].join(' ') + end + + def collaborations_subquery + each_object(:repos, nil, { affiliation: 'collaborator' }) + .map { |repo| "repo:#{repo[:full_name]}" } + .join(' ') + end - query + def organizations_subquery + each_object(:organizations) + .map { |org| "org:#{org[:login]}" } + .join(' ') end end end diff --git a/lib/gitlab/github_import/importer/protected_branch_importer.rb b/lib/gitlab/github_import/importer/protected_branch_importer.rb index 801a0840c52..2077e0c6b11 100644 --- a/lib/gitlab/github_import/importer/protected_branch_importer.rb +++ b/lib/gitlab/github_import/importer/protected_branch_importer.rb @@ -4,7 +4,7 @@ module Gitlab module GithubImport module Importer class ProtectedBranchImporter - attr_reader :protected_branch, :project, :client + attr_reader :project # By default on GitHub, both developers and maintainers can merge # a PR into the protected branch @@ -18,6 +18,7 @@ module Gitlab @protected_branch = protected_branch @project = project @client = client + @user_finder = GithubImport::UserFinder.new(project, client) end def execute @@ -32,11 +33,13 @@ module Gitlab private + attr_reader :protected_branch, :user_finder + def params { name: protected_branch.id, - push_access_levels_attributes: [{ access_level: push_access_level }], - merge_access_levels_attributes: [{ access_level: merge_access_level }], + push_access_levels_attributes: push_access_levels_attributes, + merge_access_levels_attributes: merge_access_levels_attributes, allow_force_push: allow_force_push?, code_owner_approval_required: code_owner_approval_required? } @@ -55,7 +58,7 @@ module Gitlab end def code_owner_approval_required? - return false unless project.licensed_feature_available?(:code_owner_approval_required) + return false unless licensed_feature_available?(:code_owner_approval_required) return protected_branch.require_code_owner_reviews unless protected_on_gitlab? @@ -83,7 +86,7 @@ module Gitlab end def update_project_push_rule - return unless project.licensed_feature_available?(:push_rules) + return unless licensed_feature_available?(:push_rules) return unless protected_branch.required_signatures push_rule = project.push_rule || project.build_push_rule @@ -91,12 +94,34 @@ module Gitlab project.project_setting.update!(push_rule_id: push_rule.id) end - def push_access_level - if protected_branch.required_pull_request_reviews - Gitlab::Access::NO_ACCESS + def push_access_levels_attributes + if allowed_to_push_gitlab_user_ids.present? + @allowed_to_push_gitlab_user_ids.map { |user_id| { user_id: user_id } } + elsif protected_branch.required_pull_request_reviews + [{ access_level: Gitlab::Access::NO_ACCESS }] else - gitlab_access_level_for(:push) + [{ access_level: gitlab_access_level_for(:push) }] + end + end + + def merge_access_levels_attributes + [{ access_level: merge_access_level }] + end + + def allowed_to_push_gitlab_user_ids + return if protected_branch.allowed_to_push_users.empty? || + !licensed_feature_available?(:protected_refs_for_users) + + @allowed_to_push_gitlab_user_ids = [] + + protected_branch.allowed_to_push_users.each do |github_user_data| + gitlab_user_id = user_finder.user_id_for(github_user_data) + next unless gitlab_user_id + + @allowed_to_push_gitlab_user_ids << gitlab_user_id end + + @allowed_to_push_gitlab_user_ids &= project_member_ids end # Gets the strictest merge_access_level between GitHub and GitLab @@ -155,6 +180,14 @@ module Gitlab ProtectedBranch::MergeAccessLevel::GITLAB_DEFAULT_ACCESS_LEVEL end + + def licensed_feature_available?(feature) + project.licensed_feature_available?(feature) + end + + def project_member_ids + project.authorized_users.map(&:id) + end end end end diff --git a/lib/gitlab/github_import/representation/protected_branch.rb b/lib/gitlab/github_import/representation/protected_branch.rb index d2a52b64bbf..eb9dd3bc247 100644 --- a/lib/gitlab/github_import/representation/protected_branch.rb +++ b/lib/gitlab/github_import/representation/protected_branch.rb @@ -10,7 +10,7 @@ module Gitlab attr_reader :attributes expose_attribute :id, :allow_force_pushes, :required_conversation_resolution, :required_signatures, - :required_pull_request_reviews, :require_code_owner_reviews + :required_pull_request_reviews, :require_code_owner_reviews, :allowed_to_push_users # Builds a Branch Protection info from a GitHub API response. # Resource structure details: @@ -19,6 +19,12 @@ module Gitlab def self.from_api_response(branch_protection, _additional_object_data = {}) branch_name = branch_protection[:url].match(%r{/branches/(\S{1,255})/protection$})[1] + allowed_to_push_users = branch_protection.dig(:required_pull_request_reviews, + :bypass_pull_request_allowances, + :users) + allowed_to_push_users &&= allowed_to_push_users.map do |u| + Representation::User.from_api_response(u) + end hash = { id: branch_name, allow_force_pushes: branch_protection.dig(:allow_force_pushes, :enabled), @@ -26,7 +32,8 @@ module Gitlab required_signatures: branch_protection.dig(:required_signatures, :enabled), required_pull_request_reviews: branch_protection[:required_pull_request_reviews].present?, require_code_owner_reviews: branch_protection.dig(:required_pull_request_reviews, - :require_code_owner_reviews).present? + :require_code_owner_reviews).present?, + allowed_to_push_users: allowed_to_push_users.to_a } new(hash) @@ -34,7 +41,13 @@ module Gitlab # Builds a new Protection using a Hash that was built from a JSON payload. def self.from_json_hash(raw_hash) - new(Representation.symbolize_hash(raw_hash)) + hash = Representation.symbolize_hash(raw_hash) + + hash[:allowed_to_push_users].map! do |u| + Representation::User.from_json_hash(u) + end + + new(hash) end # attributes - A Hash containing the raw Protection details. The keys of this |