Class: Types::ProjectType

Inherits:
BaseObject
  • Object
show all
Includes:
Gitlab::Graphql::Authorize::AuthorizeResource, Namespaces::DeletableHelper
Defined in:
app/graphql/types/project_type.rb

Constant Summary

Constants included from Gitlab::Graphql::Authorize::AuthorizeResource

Gitlab::Graphql::Authorize::AuthorizeResource::ConfigurationError, Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Gitlab::Graphql::Authorize::AuthorizeResource

#authorize!, #authorized_find!, #authorized_resource?, #find_object, #raise_resource_not_available_error!

Methods included from Namespaces::DeletableHelper

#_additional_removed_items, #_deletion_scheduled_in_hierarchy_chain_message, #_parent_deletion_scheduled_message, #_permanently_delete_group_message, #_project_delete_button_shared_data, #_remove_group_warning, #_self_deletion_in_progress_message, #_self_deletion_scheduled_message, #confirm_remove_group_message, #delete_delayed_namespace_message, #delete_immediately_namespace_scheduled_for_deletion_message, #deletion_in_progress_or_scheduled_in_hierarchy_chain?, #group_confirm_modal_data, #permanent_deletion_date_formatted, #project_delete_delayed_button_data, #project_delete_immediately_button_data, #restore_namespace_path, #restore_namespace_scheduled_for_deletion_message, #restore_namespace_title, #self_or_ancestors_deletion_in_progress_or_scheduled_message

Methods inherited from BaseObject

accepts, assignable?, authorization, authorize, authorized?, #current_user, #id

Methods included from Gitlab::Graphql::Present

#present, #unpresented

Class Method Details

.authorization_scopesObject



14
15
16
# File 'app/graphql/types/project_type.rb', line 14

def self.authorization_scopes
  super + [:ai_workflows]
end

Instance Method Details

#ci_config_variables(ref:, fail_on_cache_miss: false) ⇒ Object



1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
# File 'app/graphql/types/project_type.rb', line 1041

def ci_config_variables(ref:, fail_on_cache_miss: false)
  result = ::Ci::ListConfigVariablesService.new(object, context[:current_user]).execute(ref)

  if result.nil? && fail_on_cache_miss
    raise_resource_not_available_error! "Failed to retrieve CI/CD variables from cache."
  end

  return if result.nil?

  result.map do |var_key, var_config|
    { key: var_key, **var_config }
  end
end

#ci_pipeline_creation_inputs(ref:) ⇒ Object



1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
# File 'app/graphql/types/project_type.rb', line 1030

def ci_pipeline_creation_inputs(ref:)
  response = ::Ci::PipelineCreation::FindPipelineInputsService.new(
    current_user: context[:current_user],
    project: object,
    ref: ref).execute

  raise Gitlab::Graphql::Errors::ArgumentError, response.message if response.error?

  response.payload[:inputs].all_inputs
end

#ci_pipeline_creation_request(request_id:) ⇒ Object



912
913
914
# File 'app/graphql/types/project_type.rb', line 912

def ci_pipeline_creation_request(request_id:)
  ::Ci::PipelineCreation::Requests.get_request(object, request_id)
end

#container_protection_tag_rulesObject



949
950
951
952
# File 'app/graphql/types/project_type.rb', line 949

def container_protection_tag_rules
  # Immutable tag rules are added in EE extension
  object.container_registry_protection_tag_rules.mutable
end

#container_repositories_countObject



1026
1027
1028
# File 'app/graphql/types/project_type.rb', line 1026

def container_repositories_count
  project.container_repositories.size
end

#edit_pathObject



1142
1143
1144
# File 'app/graphql/types/project_type.rb', line 1142

def edit_path
  ::Gitlab::Routing.url_helpers.edit_project_path(project)
end

#explore_catalog_pathObject



1012
1013
1014
1015
1016
# File 'app/graphql/types/project_type.rb', line 1012

def explore_catalog_path
  return unless project.catalog_resource

  Gitlab::Routing.url_helpers.explore_catalog_path(project.catalog_resource)
end

#forks_countObject



998
999
1000
# File 'app/graphql/types/project_type.rb', line 998

def forks_count
  BatchLoader::GraphQL.wrap(object.forks_count)
end

#grafana_integrationObject



1146
1147
1148
# File 'app/graphql/types/project_type.rb', line 1146

def grafana_integration
  nil
end

#is_catalog_resourceObject

rubocop:disable Naming/PredicateName



1002
1003
1004
1005
1006
1007
1008
1009
1010
# File 'app/graphql/types/project_type.rb', line 1002

def is_catalog_resource # rubocop:disable Naming/PredicateName
  lazy_catalog_resource = BatchLoader::GraphQL.for(object.id).batch do |project_ids, loader|
    ::Ci::Catalog::Resource.for_projects(project_ids).each do |catalog_resource|
      loader.call(catalog_resource.project_id, catalog_resource)
    end
  end

  Gitlab::Graphql::Lazy.with_value(lazy_catalog_resource, &:present?)
end

#is_publishedObject

rubocop:disable Naming/PredicateName – disabled to match the field name.



1018
1019
1020
# File 'app/graphql/types/project_type.rb', line 1018

def is_published # rubocop:disable Naming/PredicateName -- disabled to match the field name.
  project&.catalog_resource&.published?
end

#job(id:) ⇒ Object



1055
1056
1057
1058
# File 'app/graphql/types/project_type.rb', line 1055

def job(id:)
  object.commit_statuses.find(id.model_id)
rescue ActiveRecord::RecordNotFound
end

#jobs_enabledObject



984
985
986
# File 'app/graphql/types/project_type.rb', line 984

def jobs_enabled
  object.feature_available?(:builds, context[:current_user])
end

#label(title:) ⇒ Object



940
941
942
943
944
945
946
947
# File 'app/graphql/types/project_type.rb', line 940

def label(title:)
  BatchLoader::GraphQL.for(title).batch(key: project) do |titles, loader, args|
    LabelsFinder
      .new(current_user, project: args[:key], title: titles)
      .execute
      .each { |label| loader.call(label.title, label) }
  end
end

#languagesObject



1081
1082
1083
# File 'app/graphql/types/project_type.rb', line 1081

def languages
  ::Projects::RepositoryLanguagesService.new(project, current_user).execute
end

#marked_for_deletion_onObject

marked_for_deletion_at is deprecated in our v5 REST API in favor of marked_for_deletion_on docs.gitlab.com/ee/api/projects.html#removals-in-api-v5



1130
1131
1132
# File 'app/graphql/types/project_type.rb', line 1130

def marked_for_deletion_on
  project.marked_for_deletion_at
end

#max_access_levelObject



1108
1109
1110
1111
1112
1113
1114
1115
1116
# File 'app/graphql/types/project_type.rb', line 1108

def max_access_level
  return Gitlab::Access::NO_ACCESS if current_user.nil?

  BatchLoader::GraphQL.for(object.id).batch do |project_ids, loader|
    current_user.max_member_access_for_project_ids(project_ids).each do |project_id, max_access_level|
      loader.call(project_id, max_access_level)
    end
  end
end

#open_issues_countObject



988
989
990
# File 'app/graphql/types/project_type.rb', line 988

def open_issues_count
  BatchLoader::GraphQL.wrap(object.open_issues_count) if object.feature_available?(:issues, context[:current_user])
end

#open_merge_requests_countObject



992
993
994
995
996
# File 'app/graphql/types/project_type.rb', line 992

def open_merge_requests_count
  return unless object.feature_available?(:merge_requests, context[:current_user])

  BatchLoader::GraphQL.wrap(object.open_merge_requests_count)
end

#organization_edit_pathObject



1118
1119
1120
1121
1122
1123
1124
1125
1126
# File 'app/graphql/types/project_type.rb', line 1118

def organization_edit_path
  return if project.organization.nil?

  ::Gitlab::Routing.url_helpers.edit_namespace_projects_organization_path(
    project.organization,
    id: project.to_param,
    namespace_id: project.namespace.to_param
  )
end

#pages_force_httpsObject



916
917
918
# File 'app/graphql/types/project_type.rb', line 916

def pages_force_https
  project.pages_https_only?
end

#pages_use_unique_domainObject



920
921
922
923
924
925
926
927
928
929
930
# File 'app/graphql/types/project_type.rb', line 920

def pages_use_unique_domain
  lazy_project_settings = BatchLoader::GraphQL.for(object.id).batch do |project_ids, loader|
    ::ProjectSetting.for_projects(project_ids).each do |project_setting|
      loader.call(project_setting.project_id, project_setting)
    end
  end

  Gitlab::Graphql::Lazy.with_value(lazy_project_settings) do |settings|
    (settings || object.project_setting).pages_unique_domain_enabled?
  end
end

#permanent_deletion_dateObject



1134
1135
1136
# File 'app/graphql/types/project_type.rb', line 1134

def permanent_deletion_date
  permanent_deletion_date_formatted(project) || permanent_deletion_date_formatted
end

#protectable_branchesObject



932
933
934
# File 'app/graphql/types/project_type.rb', line 932

def protectable_branches
  ProtectableDropdown.new(project, :branches).protectable_ref_names
end

#sast_ci_configurationObject



1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
# File 'app/graphql/types/project_type.rb', line 1060

def sast_ci_configuration
  return unless Ability.allowed?(current_user, :read_code, object)

  if project.repository.empty?
    raise Gitlab::Graphql::Errors::MutationError,
      _(format('You must %s before using Security features.', add_file_docs_link.html_safe)).html_safe
  end

  ::Security::CiConfiguration::SastParserService.new(object).configuration
end

#service_desk_addressObject



1071
1072
1073
1074
1075
# File 'app/graphql/types/project_type.rb', line 1071

def service_desk_address
  return unless Ability.allowed?(current_user, :admin_issue, project)

  ::ServiceDesk::Emails.new(object).address
end

#service_desk_enabledObject



1077
1078
1079
# File 'app/graphql/types/project_type.rb', line 1077

def service_desk_enabled
  ::ServiceDesk.enabled?(project)
end

#statisticsObject



1022
1023
1024
# File 'app/graphql/types/project_type.rb', line 1022

def statistics
  Gitlab::Graphql::Loaders::BatchProjectStatisticsLoader.new(object.id).find
end

#statistics_details_pathsObject



1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
# File 'app/graphql/types/project_type.rb', line 1095

def statistics_details_paths
  root_ref = project.repository.root_ref || project.default_branch_or_main

  {
    repository: Gitlab::Routing.url_helpers.project_tree_url(project, root_ref),
    wiki: Gitlab::Routing.url_helpers.project_wikis_pages_url(project),
    build_artifacts: Gitlab::Routing.url_helpers.project_artifacts_url(project),
    packages: Gitlab::Routing.url_helpers.project_packages_url(project),
    snippets: Gitlab::Routing.url_helpers.project_snippets_url(project),
    container_registry: Gitlab::Routing.url_helpers.project_container_registry_index_url(project)
  }
end

#timelog_categoriesObject



936
937
938
# File 'app/graphql/types/project_type.rb', line 936

def timelog_categories
  object.project_namespace.timelog_categories if Feature.enabled?(:timelog_categories)
end

#visible_forks(minimum_access_level: nil) ⇒ Object



1085
1086
1087
1088
1089
1090
1091
1092
1093
# File 'app/graphql/types/project_type.rb', line 1085

def visible_forks(minimum_access_level: nil)
  if minimum_access_level.nil?
    object.forks.public_or_visible_to_user(current_user)
  else
    return [] if current_user.nil?

    object.forks.visible_to_user_and_access_level(current_user, minimum_access_level)
  end
end

#web_pathObject



1138
1139
1140
# File 'app/graphql/types/project_type.rb', line 1138

def web_path
  ::Gitlab::Routing.url_helpers.project_path(project)
end