Class: Project
- Inherits:
-
ApplicationRecord
show all
- Extended by:
- Gitlab::Cache::RequestCache, Gitlab::ConfigHelper, Gitlab::Utils::Override
- Includes:
- AccessRequestable, AfterCommitQueue, Avatarable, BatchDestroyDependentAssociations, BlocksUnsafeSerialization, BulkMemberAccessLoad, BulkUsersByEmailLoad, CacheMarkdownField, CanMoveRepositoryStorage, CaseSensitivity, ChronicDurationAttribute, DeploymentPlatform, EachBatch, FastDestroyAll::Helpers, FeatureGate, FromUnion, Gitlab::ConfigHelper, Gitlab::SQL::Pattern, Gitlab::Utils::StrongMemoize, Gitlab::VisibilityLevel, GitlabRoutingHelper, GroupDescendant, HasRepository, HasWiki, Importable, Namespaces::AdjournedDeletable, OptionallySearch, Presentable, ProjectAPICompatibility, ProjectFeaturesCompatibility, Repositories::CanHousekeepRepository, Routable, RunnerTokenExpirationInterval, SafelyChangeColumnDefault, SelectForProjectAuthorization, Sortable, Subquery, Todoable, TokenAuthenticatable, UpdatedAtFilterable, UseSqlFunctionForPrimaryKeyLookups, ValidAttribute, WebHooks::HasWebHooks, WithUploads, WorkItems::Parent
- Defined in:
- app/models/project.rb
Constant Summary
collapse
- BoardLimitExceeded =
Class.new(StandardError)
- ExportLimitExceeded =
Class.new(StandardError)
- ExportAlreadyInProgress =
Class.new(StandardError)
- EPOCH_CACHE_EXPIRATION =
30.days
- STATISTICS_ATTRIBUTE =
'repositories_count'
- UNKNOWN_IMPORT_URL =
'http://unknown.git'
- LATEST_STORAGE_VERSION =
Hashed Storage versions handle rolling out new storage to project and dependents models: nil: legacy 1: repository 2: attachments
2
- HASHED_STORAGE_FEATURES =
{
repository: 1,
attachments: 2
}.freeze
- VALID_IMPORT_PORTS =
[80, 443].freeze
- VALID_IMPORT_PROTOCOLS =
%w[http https git].freeze
- VALID_MIRROR_PORTS =
[22, 80, 443].freeze
- VALID_MIRROR_PROTOCOLS =
%w[http https ssh git].freeze
- SORTING_PREFERENCE_FIELD =
:projects_sort
- MAX_BUILD_TIMEOUT =
1.month
- GL_REPOSITORY_TYPES =
[Gitlab::GlRepository::PROJECT, Gitlab::GlRepository::WIKI, Gitlab::GlRepository::DESIGN].freeze
- MAX_SUGGESTIONS_TEMPLATE_LENGTH =
255
- MAX_COMMIT_TEMPLATE_LENGTH =
500
- MAX_MERGE_REQUEST_TITLE_REGEX =
255
- MAX_MERGE_REQUEST_TITLE_REGEX_DESCRIPTION =
255
- INSTANCE_RUNNER_RUNNING_JOBS_MAX_BUCKET =
5
- DEFAULT_MERGE_COMMIT_TEMPLATE =
<<~MSG.rstrip.freeze
Merge branch '%{source_branch}' into '%{target_branch}'
%{title}
%{issues}
See merge request %{reference}
MSG
- DEFAULT_SQUASH_COMMIT_TEMPLATE =
'%{title}'
- PROJECT_FEATURES_DEFAULTS =
{
issues: gitlab_config_features.issues,
merge_requests: gitlab_config_features.merge_requests,
builds: gitlab_config_features.builds,
wiki: gitlab_config_features.wiki,
snippets: gitlab_config_features.snippets
}.freeze
- PROJECT_ACTIVITY_ATTRIBUTES =
List of attributes that, when updated, should be considered as Project Activity
%w[description name].freeze
BlocksUnsafeSerialization::UnsafeSerializationError
Routing::PseudonymizationHelper::PSEUDONOMIZED_GROUP, Routing::PseudonymizationHelper::PSEUDONOMIZED_ID, Routing::PseudonymizationHelper::PSEUDONOMIZED_NAMESPACE, Routing::PseudonymizationHelper::PSEUDONOMIZED_PROJECT, Routing::PseudonymizationHelper::PSEUDONOMIZED_USERNAME
BatchDestroyDependentAssociations::DEPENDENT_ASSOCIATIONS_BATCH_SIZE
Constants included
from WithUploads
WithUploads::FILE_UPLOADERS
Gitlab::SQL::Pattern::MIN_CHARS_FOR_PARTIAL_MATCHING, Gitlab::SQL::Pattern::REGEX_QUOTED_TERM
CanMoveRepositoryStorage::RepositoryReadOnlyError
WebHooks::HasWebHooks::WEB_HOOK_CACHE_EXPIRY
CacheMarkdownField::INVALIDATED_BY
Constants included
from Avatarable
Avatarable::ALLOWED_IMAGE_SCALER_WIDTHS, Avatarable::COMBINED_AVATAR_SIZES, Avatarable::COMBINED_AVATAR_SIZES_RETINA, Avatarable::GROUP_AVATAR_SIZES, Avatarable::MAXIMUM_FILE_SIZE, Avatarable::PROJECT_AVATAR_SIZES, Avatarable::USER_AVATAR_SIZES
Gitlab::VisibilityLevel::INTERNAL, Gitlab::VisibilityLevel::LEVELS_FOR_ADMINS, Gitlab::VisibilityLevel::PRIVATE, Gitlab::VisibilityLevel::PUBLIC
ApplicationRecord::MAX_PLUCK
HasCheckConstraints::NOT_NULL_CHECK_PATTERN
ResetOnColumnErrors::MAX_RESET_PERIOD
Instance Attribute Summary collapse
#request_cache_key_block
Attributes included from Importable
#importing, #user_contributions
#skip_markdown_cache_validation
Class Method Summary
collapse
Instance Method Summary
collapse
-
#access_request_approvers_to_be_notified ⇒ Object
-
#active_runners ⇒ Object
-
#active_webide_pipelines(user:) ⇒ Object
-
#add_export_job(current_user:, after_export_strategy: nil, params: {}) ⇒ Object
-
#add_import_job ⇒ Object
-
#after_change_head_branch_does_not_exist(branch) ⇒ Object
-
#after_create_default_branch ⇒ Object
rubocop: disable CodeReuse/ServiceClass.
-
#after_import ⇒ Object
-
#after_repository_change_head ⇒ Object
-
#all_available_runners ⇒ Object
-
#all_clusters ⇒ Object
-
#all_pipelines ⇒ Object
-
#all_runners ⇒ Object
-
#allow_iframes_in_markdown_feature_flag_enabled? ⇒ Boolean
-
#allowed_to_share_with_group? ⇒ Boolean
-
#allows_multiple_merge_request_assignees? ⇒ Boolean
-
#allows_multiple_merge_request_reviewers? ⇒ Boolean
-
#analytics_enabled? ⇒ Boolean
-
#ancestors(hierarchy_order: nil) ⇒ Object
(also: #group_and_ancestors)
-
#ancestors_archived? ⇒ Boolean
-
#ancestors_upto(top = nil, hierarchy_order: nil) ⇒ Object
returns all ancestor-groups upto but excluding the given namespace when no namespace is given, all ancestors upto the top are returned.
-
#ancestors_upto_ids ⇒ Object
-
#any_branch_allows_collaboration?(user) ⇒ Boolean
-
#any_import_in_progress? ⇒ Boolean
Determine whether any kind of import is in progress.
-
#any_lfs_file_locks? ⇒ Boolean
-
#any_online_runners?(&block) ⇒ Boolean
-
#api_variables ⇒ Object
-
#archived ⇒ Object
(also: #self_archived?)
-
#assigning_role_too_high?(current_user, access_level) ⇒ Boolean
-
#auto_cancel_pending_pipelines? ⇒ Boolean
-
#auto_devops_enabled? ⇒ Boolean
-
#auto_devops_variables ⇒ Object
-
#autoclose_referenced_issues ⇒ Object
-
#available_shared_runners ⇒ Object
-
#avatar_in_git ⇒ Object
-
#avatar_url(**args) ⇒ Object
-
#badges ⇒ Object
-
#batch_loaded_environment_by_name(name) ⇒ Object
-
#beautified_import_status_name ⇒ Object
-
#bitbucket_import? ⇒ Boolean
-
#bitbucket_server_import? ⇒ Boolean
-
#bots ⇒ Object
-
#branch_allows_collaboration?(user, branch_name) ⇒ Boolean
-
#build_commit_note(commit) ⇒ Object
-
#build_or_assign_import_data(data: nil, credentials: nil) ⇒ Object
-
#builds_enabled? ⇒ Boolean
-
#can_create_custom_domains? ⇒ Boolean
-
#can_create_new_ref_commits? ⇒ Boolean
-
#can_suggest_reviewers? ⇒ Boolean
-
#certificate_based_clusters_enabled? ⇒ Boolean
-
#changing_shared_runners_enabled_is_allowed ⇒ Object
-
#check_personal_projects_limit ⇒ Object
-
#check_repository_path_availability ⇒ Object
Check if repository already exists on disk.
-
#ci_allow_fork_pipelines_to_run_in_parent_project? ⇒ Boolean
-
#ci_config_for(sha) ⇒ Object
-
#ci_config_path=(value) ⇒ Object
-
#ci_config_path_or_default ⇒ Object
-
#ci_display_pipeline_variables? ⇒ Boolean
-
#ci_forward_deployment_enabled? ⇒ Boolean
-
#ci_forward_deployment_rollback_allowed? ⇒ Boolean
-
#ci_inbound_job_token_scope_enabled? ⇒ Boolean
-
#ci_integration ⇒ Object
-
#ci_integrations ⇒ Object
rubocop: enable CodeReuse/ServiceClass.
-
#ci_outbound_job_token_scope_enabled? ⇒ Boolean
-
#ci_pipelines ⇒ Object
-
#ci_push_repository_for_job_token_allowed? ⇒ Boolean
-
#ci_template_variables ⇒ Object
-
#cleanup ⇒ Object
(also: #reload_repository!)
-
#closest_setting(name) ⇒ Object
-
#code ⇒ Object
For compatibility with old code.
-
#commit_notes ⇒ Object
Used by Import/Export to export commit notes.
-
#container_registry_enabled? ⇒ Boolean
(also: #container_registry_enabled)
-
#container_registry_url ⇒ Object
-
#container_registry_variables ⇒ Object
-
#container_repositories_size ⇒ Object
-
#create_labels ⇒ Object
rubocop: disable CodeReuse/ServiceClass.
-
#create_repository(force: false, default_branch: nil, object_format: nil) ⇒ Object
-
#crm_enabled? ⇒ Boolean
-
#crm_group ⇒ Object
-
#default_branch_or_main ⇒ Object
-
#default_branch_protected? ⇒ Boolean
-
#default_environment ⇒ Object
-
#default_issues_tracker? ⇒ Boolean
-
#default_merge_request_target ⇒ Object
-
#default_pipeline_lock ⇒ Object
-
#dependency_proxy_variables ⇒ Object
-
#deploy_token_create_url(opts = {}) ⇒ Object
-
#deploy_token_revoke_url_for(token) ⇒ Object
-
#deployment_variables(environment:, kubernetes_namespace: nil) ⇒ Object
-
#deprecated_owner ⇒ Object
-
#design_management_enabled? ⇒ Boolean
LFS and hashed repository storage are required for using Design Management.
-
#design_repository ⇒ Object
-
#destroy_deployment_by_id(deployment_id) ⇒ Object
-
#disabled_integrations ⇒ Object
Returns a list of integration names that should be disabled at the project-level.
-
#drop_visibility_level! ⇒ Object
-
#emails_disabled? ⇒ Boolean
-
#enable_ci ⇒ Object
-
#enforce_auth_checks_on_uploads? ⇒ Boolean
-
#enforced_runner_token_expiration_interval ⇒ Object
-
#enqueue_record_project_target_platforms ⇒ Object
-
#ensure_pool_repository ⇒ Object
Ensures project has a pool repository without exposing private creation logic.
-
#ensure_repository ⇒ Object
-
#environments_for_scope(scope) ⇒ Object
-
#execute_hooks(data, hooks_scope = :push_hooks) ⇒ Object
rubocop: disable CodeReuse/ServiceClass.
-
#execute_integrations(data, hooks_scope = :push_hooks, skip_ci: false) ⇒ Object
-
#expire_caches_before_rename(old_path) ⇒ Object
Expires various caches before a project is renamed.
-
#export_archive_exists?(user) ⇒ Boolean
-
#export_enqueued?(user) ⇒ Boolean
-
#export_failed?(user) ⇒ Boolean
-
#export_file(user) ⇒ Object
-
#export_file_exists?(user) ⇒ Boolean
-
#export_in_progress?(user) ⇒ Boolean
-
#export_path ⇒ Object
-
#export_status(user) ⇒ Object
-
#extended_prat_expiry_webhooks_execute? ⇒ Boolean
-
#external_authorization_classification_label ⇒ Object
-
#external_import? ⇒ Boolean
-
#external_issue_reference_pattern ⇒ Object
-
#external_issue_tracker ⇒ Object
-
#external_references_supported? ⇒ Boolean
-
#external_wiki ⇒ Object
-
#feature_available?(feature, user = nil) ⇒ Boolean
-
#feature_flags_client_token ⇒ Object
-
#feature_usage ⇒ Object
-
#ff_merge_must_be_possible? ⇒ Boolean
-
#find_or_create_design_management_repository ⇒ Object
-
#find_or_initialize_integration(name) ⇒ Object
-
#find_or_initialize_integrations ⇒ Object
-
#first_auto_devops_config ⇒ Object
-
#first_owner ⇒ Object
-
#fork_source ⇒ Object
-
#forked? ⇒ Boolean
-
#forked_from?(other_project) ⇒ Boolean
-
#forking_enabled? ⇒ Boolean
-
#forks_count ⇒ Object
rubocop: disable CodeReuse/ServiceClass.
-
#full_path_before_last_save ⇒ Object
-
#full_path_slug ⇒ Object
-
#get_issue(issue_id, current_user) ⇒ Object
-
#git_garbage_collect_worker_klass ⇒ Object
-
#git_objects_poolable? ⇒ Boolean
Git objects are only poolable when the project is or has: - Hashed storage -> The object pool will have a remote to its members, using relative paths.
-
#git_transfer_in_progress? ⇒ Boolean
-
#gitea_import? ⇒ Boolean
-
#github_enterprise_import? ⇒ Boolean
-
#github_import? ⇒ Boolean
-
#gitlab_deploy_token ⇒ Object
-
#gitlab_project_import? ⇒ Boolean
-
#gitlab_project_migration? ⇒ Boolean
-
#glql_load_on_click_feature_flag_enabled? ⇒ Boolean
-
#group_group_links ⇒ Object
-
#group_protected_branches ⇒ Object
-
#group_runners ⇒ Object
-
#group_runners_enabled? ⇒ Boolean
-
#has_active_hooks?(hooks_scope = :push_hooks) ⇒ Boolean
-
#has_active_integrations?(hooks_scope = :push_hooks) ⇒ Boolean
-
#has_auto_devops_implicitly_disabled? ⇒ Boolean
-
#has_auto_devops_implicitly_enabled? ⇒ Boolean
-
#has_ci? ⇒ Boolean
-
#has_ci_config_file? ⇒ Boolean
-
#has_container_registry_protected_tag_rules?(action:, access_level:) ⇒ Boolean
-
#has_container_registry_tags? ⇒ Boolean
-
#has_pool_repository? ⇒ Boolean
-
#has_remote_mirror? ⇒ Boolean
-
#has_wiki? ⇒ Boolean
-
#hashed_storage?(feature) ⇒ Boolean
Check if Hashed Storage is enabled for the project with at least informed feature rolled out.
-
#hook_attrs(backward: true) ⇒ Object
-
#human_import_status_name ⇒ Object
-
#human_merge_method ⇒ Object
-
#import? ⇒ Boolean
-
#import_checksums ⇒ Object
-
#import_export_shared ⇒ Object
-
#import_export_upload_by_user(user) ⇒ Object
-
#import_failed? ⇒ Boolean
-
#import_finished? ⇒ Boolean
-
#import_in_progress? ⇒ Boolean
-
#import_scheduled? ⇒ Boolean
-
#import_started? ⇒ Boolean
-
#import_status ⇒ Object
-
#import_url=(value) ⇒ Object
-
#in_fork_network_of?(other_project) ⇒ Boolean
-
#inactive? ⇒ Boolean
-
#initial_push_to_default_branch_allowed_for_developer? ⇒ Boolean
-
#initialize(attributes = nil) ⇒ Project
constructor
A new instance of Project.
-
#instance_runner_running_jobs_count ⇒ Object
-
#invalidate_personal_projects_count_of_owner ⇒ Object
-
#issue_exists?(issue_id) ⇒ Boolean
-
#issues_enabled? ⇒ Boolean
-
#items_for(entity) ⇒ Object
-
#jenkins_integration_active? ⇒ Boolean
-
#jira_import? ⇒ Boolean
-
#jira_import_status ⇒ Object
-
#jira_subscription_exists? ⇒ Boolean
-
#keep_latest_artifact? ⇒ Boolean
-
#keep_latest_artifacts_available? ⇒ Boolean
-
#last_activity ⇒ Object
-
#latest_jira_import ⇒ Object
-
#latest_pipeline(ref = default_branch, sha = nil, source = nil) ⇒ Object
-
#latest_pipelines(ref: default_branch, sha: nil, limit: nil, source: nil) ⇒ Object
-
#latest_successful_build_for_ref(job_name, ref = default_branch) ⇒ Object
ref can’t be HEAD, can only be branch/tag name.
-
#latest_successful_build_for_ref!(job_name, ref = default_branch) ⇒ Object
-
#latest_successful_build_for_sha(job_name, sha) ⇒ Object
-
#latest_successful_pipeline_for(ref = nil) ⇒ Object
-
#latest_successful_pipeline_for_default_branch ⇒ Object
-
#latest_unscheduled_pipeline(ref = default_branch, sha = nil) ⇒ Object
-
#latest_unscheduled_pipelines(ref: default_branch, sha: nil) ⇒ Object
-
#leave_pool_repository ⇒ Object
-
#legacy_storage? ⇒ Boolean
rubocop: enable CodeReuse/ServiceClass.
-
#lfs_enabled? ⇒ Boolean
(also: #lfs_enabled)
-
#lfs_file_locks_changed_epoch ⇒ Object
-
#lfs_objects_for_repository_types(*types) ⇒ Object
-
#lfs_objects_oids(oids: []) ⇒ Object
-
#lfs_objects_oids_from_fork_source(oids: []) ⇒ Object
-
#licensed_ai_features_available? ⇒ Boolean
-
#licensed_feature_available?(_feature) ⇒ Boolean
Overridden in EE::Project.
-
#licensed_features ⇒ Object
-
#limited_protected_branches(limit) ⇒ Object
-
#link_pool_repository ⇒ Object
-
#log_import_activity(job_id, type: :import) ⇒ Object
-
#mark_pages_onboarding_complete ⇒ Object
-
#mark_remote_mirrors_for_removal ⇒ Object
-
#mark_stuck_remote_mirrors_as_failed! ⇒ Object
-
#markdown_placeholders_feature_flag_enabled? ⇒ Boolean
-
#marked_for_deletion_on ⇒ Object
-
#max_attachment_size ⇒ Object
-
#member(user) ⇒ Object
-
#members_among(users) ⇒ Object
Filters ‘users` to return only authorized users of the project.
-
#membership_locked? ⇒ Boolean
-
#merge_base_commit(first_commit_id, second_commit_id) ⇒ Object
-
#merge_commit_template_or_default ⇒ Object
-
#merge_commit_template_or_default=(value) ⇒ Object
-
#merge_method ⇒ Object
-
#merge_method=(method) ⇒ Object
-
#merge_requests_allowing_push_to_user(user) ⇒ Object
-
#merge_requests_enabled? ⇒ Boolean
-
#merge_trains_enabled? ⇒ Boolean
-
#mr_can_target_upstream? ⇒ Boolean
-
#multiple_issue_boards_available? ⇒ Boolean
-
#new_issuable_address(author, address_type) ⇒ Object
-
#no_import? ⇒ Boolean
-
#notify_project_import_complete? ⇒ Boolean
-
#on_demand_dast_available? ⇒ Boolean
-
#open_issues_count(current_user = nil) ⇒ Object
rubocop: disable CodeReuse/ServiceClass.
-
#open_merge_requests_count(_current_user = nil) ⇒ Object
rubocop: disable CodeReuse/ServiceClass.
-
#operations_enabled? ⇒ Boolean
-
#origin_merge_requests ⇒ Object
-
#override_pipeline_variables_allowed?(access_level, user) ⇒ Boolean
-
#owner ⇒ Object
rubocop: enable CodeReuse/ServiceClass.
-
#owner_entity ⇒ Object
-
#owner_entity_name ⇒ Object
-
#owners ⇒ Object
-
#packages_cleanup_policy ⇒ Object
-
#packages_policy_subject ⇒ Object
-
#pages_access_control_forced_by_ancestor? ⇒ Boolean
-
#pages_deployed? ⇒ Boolean
-
#pages_domain_present?(domain_url) ⇒ Boolean
-
#pages_enabled? ⇒ Boolean
-
#pages_hostname(options = nil) ⇒ Object
-
#pages_https_only ⇒ Object
-
#pages_https_only? ⇒ Boolean
-
#pages_show_onboarding? ⇒ Boolean
-
#pages_unique_domain_enabled? ⇒ Boolean
-
#pages_url(options = nil) ⇒ Object
-
#pages_url_builder(options = nil) ⇒ Object
-
#pages_variables ⇒ Object
-
#parent_changed? ⇒ Boolean
-
#parent_groups ⇒ Object
-
#parent_organization_match ⇒ Object
-
#path_availability ⇒ Object
-
#personal? ⇒ Boolean
-
#personal_namespace_holder?(user) ⇒ Boolean
-
#placeholder_reference_store ⇒ Object
-
#predefined_ci_server_variables ⇒ Object
rubocop: enable Metrics/AbcSize.
-
#predefined_project_variables ⇒ Object
-
#predefined_variables ⇒ Object
-
#preload_protected_branches ⇒ Object
-
#private_pages? ⇒ Boolean
-
#project_id ⇒ Object
-
#project_setting ⇒ Object
-
#protected_for?(ref) ⇒ Boolean
-
#public_pages? ⇒ Boolean
-
#public_path_for_source_path(path, commit_sha) ⇒ Object
-
#readme_url ⇒ Object
-
#reconcile_shared_runners_setting! ⇒ Object
-
#refresh_lfs_file_locks_changed_epoch ⇒ Object
-
#refreshing_build_artifacts_size? ⇒ Boolean
-
#regeneration_in_progress?(user) ⇒ Boolean
-
#related_group_ids ⇒ Object
-
#remote_mirror_available? ⇒ Boolean
-
#remove_export_for_user(user) ⇒ Object
-
#remove_exports ⇒ Object
-
#remove_import_data ⇒ Object
This method is overridden in EE::Project model.
-
#remove_private_deploy_keys ⇒ Object
-
#renamed? ⇒ Boolean
-
#repository ⇒ Object
-
#repository_object_format ⇒ Object
-
#reset_cache_and_import_attrs ⇒ Object
-
#reset_counters_and_iids ⇒ Object
-
#resource_parent ⇒ Object
-
#restrict_user_defined_variables? ⇒ Boolean
-
#root_group ⇒ Object
-
#root_namespace ⇒ Object
-
#route_map_for(commit_sha) ⇒ Object
-
#runners_token ⇒ Object
-
#safe_import_url(masked: true) ⇒ String
Returns sanitized import URL.
-
#saved? ⇒ Boolean
-
#security_training_available? ⇒ Boolean
-
#self_and_ancestors_ids ⇒ Object
-
#self_deletion_in_progress? ⇒ Boolean
-
#self_deletion_in_progress_or_hidden? ⇒ Boolean
-
#self_or_ancestors_archived? ⇒ Boolean
-
#self_or_root_group_ids ⇒ Object
for projects that are part of user namespace, return project.
-
#send_move_instructions(old_path_with_namespace) ⇒ Object
rubocop: disable CodeReuse/ServiceClass.
-
#set_project_feature_defaults ⇒ Object
Remove along with ProjectFeaturesCompatibility module.
-
#share_with_group_enabled? ⇒ Boolean
-
#shared_runners ⇒ Object
-
#shared_runners_available? ⇒ Boolean
-
#shared_runners_setting_conflicting_with_group? ⇒ Boolean
-
#should_validate_visibility_level? ⇒ Boolean
-
#show_default_award_emojis? ⇒ Boolean
-
#snippets_enabled? ⇒ Boolean
-
#snippets_visible?(user = nil) ⇒ Boolean
-
#squash_commit_template_or_default ⇒ Object
-
#squash_commit_template_or_default=(value) ⇒ Object
-
#storage ⇒ Object
-
#storage_upgradable? ⇒ Boolean
-
#storage_version=(value) ⇒ Object
-
#suggested_reviewers_available? ⇒ Boolean
-
#supports_lock_on_merge? ⇒ Boolean
-
#supports_saved_replies? ⇒ Boolean
-
#swap_pool_repository! ⇒ Object
After repository is moved from shard to shard, disconnect it from the previous object pool and connect to the new pool.
-
#team ⇒ Object
-
#template_source? ⇒ Boolean
-
#to_human_reference(from = nil) ⇒ Object
-
#to_param ⇒ Object
-
#to_reference(from = nil, full: false) ⇒ Object
Produce a valid reference (see Referable#to_reference).
-
#to_reference_base(from = nil, full: false, absolute_path: false) ⇒ Object
‘from` argument can be a Namespace or Project.
-
#toggle_ci_cd_settings!(settings_attribute) ⇒ Object
-
#track_project_repository ⇒ Object
-
#triggered_hooks(hooks_scope, data) ⇒ Object
rubocop: enable CodeReuse/ServiceClass.
-
#unsafe_import_url ⇒ String
WARNING - This method returns sensitive userinfo credentials of the import URL.
-
#update_project_counter_caches ⇒ Object
-
#update_remote_mirrors ⇒ Object
-
#updating_remote_mirror? ⇒ Boolean
-
#uploads_sharding_key ⇒ Object
-
#valid_lfs_oids(oids_to_check) ⇒ Object
-
#valid_runners_token?(token) ⇒ Boolean
-
#validate_pages_https_only ⇒ Object
-
#visibility_level_allowed?(level = self.visibility_level) ⇒ Boolean
-
#visibility_level_allowed_as_fork ⇒ Object
-
#visibility_level_allowed_as_fork?(level = self.visibility_level) ⇒ Boolean
rubocop: enable CodeReuse/ServiceClass.
-
#visibility_level_allowed_by_namespace ⇒ Object
-
#visibility_level_allowed_by_namespace?(level = self.visibility_level) ⇒ Boolean
-
#visibility_level_field ⇒ Object
-
#visible_group_links(for_user:) ⇒ Object
-
#warn_about_potentially_unwanted_characters? ⇒ Boolean
-
#wiki_enabled? ⇒ Boolean
-
#work_item_tasks_on_boards_feature_flag_enabled? ⇒ Boolean
-
#work_items_consolidated_list_enabled?(user = nil) ⇒ Boolean
extended, request_cache, request_cache_key
extended, extensions, included, method_added, override, prepended, queue_verification, verify!
gitlab_config, gitlab_config_features
#ancestor_scheduled_for_deletion?, #deletion_adjourned_period, #deletion_in_progress_or_scheduled_in_hierarchy_chain?, #first_scheduled_for_deletion_in_hierarchy_chain, #scheduled_for_deletion_in_hierarchy_chain?, #self_deletion_scheduled?, #self_deletion_scheduled_deletion_created_on
#serializable_hash
#effective_runner_token_expiration_interval, #effective_runner_token_expiration_interval_human_readable, #enforced_runner_token_expiration_interval_human_readable
#package_path
#masked_page_url, #masked_query_params, #masked_referrer_url, #referrer_params
#graphql_etag_pipeline_path, #graphql_etag_pipeline_sha_path, #graphql_etag_project_on_demand_scan_counts_path
#group_wiki_page_url, #project_wiki_page_url, #wiki_page_path, #wiki_path
#gitlab_raw_snippet_blob_url, #gitlab_raw_snippet_url, #gitlab_snippet_note_path, #gitlab_snippet_notes_path, #gitlab_snippet_path, #gitlab_snippet_url, #gitlab_toggle_award_emoji_snippet_note_path, #preview_markdown_path, #toggle_award_emoji_personal_snippet_path, #toggle_award_emoji_project_project_snippet_path, #toggle_award_emoji_project_project_snippet_url
#edit_pipeline_schedule_path, #pipeline_schedule_path, #pipeline_schedules_path, #play_pipeline_schedule_path, #take_ownership_pipeline_schedule_path
#artifacts_action_path, #expose_fast_artifacts_path, #fast_browse_project_job_artifacts_path, #fast_download_project_job_artifacts_path, #fast_keep_project_job_artifacts_path
#source_members_url
#approve_access_request_group_member_path, #group_member_path, #group_members_url, #leave_group_members_path, #request_access_group_members_path, #resend_invite_group_member_path
#approve_access_request_project_member_path, #leave_project_members_path, #project_member_path, #project_members_url, #request_access_project_members_path, #resend_invite_project_member_path
#commit_url, #commits_url, #edit_milestone_path, #environment_delete_path, #environment_path, #issue_path, #issue_url, #merge_request_path, #merge_request_url, #pipeline_job_url, #pipeline_path, #pipeline_url, #project_commits_path, #project_ref_path, #project_tree_path, #release_url, #toggle_subscription_path, #work_item_url
#expose_path, #expose_url, #issues_available?, #mrs_available?, #project_feature_string_access_level
#all_protocols_enabled?, #allowed_protocols_present?, #anti_spam_service_enabled?, #custom_admin_roles_available?, #deletion_protection_data, #deprecated_attributes, #enabled_protocol, #enabled_protocol_button, #expanded_by_default?, #external_authorization_allow_token_help_text, #external_authorization_client_certificate_help_text, #external_authorization_client_key_help_text, #external_authorization_client_pass_help_text, #external_authorization_client_url_help_text, #external_authorization_description, #external_authorization_service_attributes, #external_authorization_timeout_help_text, #external_authorization_url_help_text, #global_search_settings_checkboxes, #http_enabled?, #import_sources_checkboxes, #instance_clusters_enabled?, #integration_expanded?, #key_restriction_options_for_select, #kroki_available_formats, #oauth_providers_checkboxes, #pending_user_count, #registration_features_can_be_prompted?, #repository_storages_options_json, #restricted_level_checkboxes, #runner_token_expiration_interval_attributes, #sidekiq_job_limiter_mode_help_text, #sidekiq_job_limiter_modes_for_select, #signup_enabled?, #signup_form_data, #ssh_enabled?, #storage_weights, #user_oauth_applications?, #valid_runner_registrars, #visible_attributes, #vscode_extension_marketplace_settings_description, #vscode_extension_marketplace_settings_view
#able_to_see_forks_count?, #able_to_see_issues?, #able_to_see_merge_requests?, #any_projects?, #archiving_available?, #author_content_tag, #autodeploy_flash_notice, #badge_count, #branch_rules_path, #can_admin_associated_clusters?, #can_change_visibility_level?, #can_disable_emails?, #can_push_code?, #can_set_diff_preview_in_email?, #can_view_branch_rules?, #clusters_deprecation_alert_message, #dashboard_projects_app_data, #delete_confirm_phrase, #directory?, #error_tracking_setting_project_json, #explore_projects_tab?, #external_classification_label_help_message, #fork_button_data_attributes, #hidden_issue_icon, #home_panel_data_attributes, #http_clone_url_to_repo, #import_from_bitbucket_message, #inactive_project_deletion_date, #issue_css_classes, #issue_manual_ordering_class, #last_pipeline_from_status_cache, #last_push_event, #link_to_autodeploy_doc, #link_to_data_loss_doc, #link_to_member, #link_to_member_avatar, #link_to_namespace_change_doc, #link_to_project, #load_catalog_resources, #load_pipeline_status, #localized_project_human_access, #no_password_message, #notification_data_attributes, #project_archive_settings_app_data, #project_can_be_shared?, #project_classes, #project_coverage_chart_data_attributes, #project_incident_management_setting, #project_license_name, #project_pages_domain_choices, #project_permissions_panel_data, #project_unarchive_settings_app_data, #projects_filtered_search_and_sort_app_data, #push_project_breadcrumbs, #push_to_create_project_command, #remote_mirror_setting_enabled?, #remove_fork_project_confirm_json, #remove_fork_project_description_message, #remove_fork_project_warning_message, #remove_project_message, #show_archived_badge?, #show_auto_devops_implicitly_enabled_banner?, #show_clusters_alert?, #show_count?, #show_dashboard_projects_welcome_page?, #show_inactive_project_deletion_banner?, #show_invalid_gpg_key_message?, #show_lfs_misconfiguration_banner?, #show_mobile_devops_project_promo?, #show_no_password_message?, #show_no_ssh_key_message?, #show_terraform_banner?, #show_xcode_link?, #ssh_clone_url_to_repo, #star_count_data_attributes, #transfer_project_confirm_button, #transfer_project_message, #visibility_level_content, #visible_fork_source, #vue_fork_divergence_data, #xcode_uri_to_repo
#can?, #can_all?, #can_any?
#create_mr_button?, #create_mr_path, #project_compare_selector_data, #target_projects
#increment_pushes_since_gc, #pushes_since_gc, #reset_pushes_since_gc
#flipper_id
#dependent_associations_to_destroy, #destroy_dependent_associations_in_batches
#retrieve_upload
#perform_fast_destroy
#run_after_commit, #run_after_commit_or_now
#chronic_duration_attributes, #output_chronic_duration_attribute
#deployment_platform
split_query_to_search_terms
build_hierarchy, #hierarchy
Methods included from Routable
#build_full_path, find_by_full_path, #full_name, #full_path, #full_path_components, #owned_by?
#reference_counter, #set_repository_read_only!, #set_repository_writable!
#any_hook_failed?, #cache_web_hook_failure, #fetch_web_hook_failure, #get_web_hook_failure, #last_failure_redis_key, #last_webhook_failure, #update_last_webhook_failure, #web_hook_failure_redis_key
Methods included from HasWiki
#create_wiki, #wiki, #wiki_repository_exists?
#branch_exists?, #commit, #commit_by, #commits_by, #default_branch, #default_branch_from_group_preferences, #default_branch_from_preferences, #empty_repo?, #full_path, #http_url_to_repo, #lfs_http_url_to_repo, #ref_exists?, #reload_default_branch, #repo_exists?, #repository_exists?, #repository_size_checker, #root_ref?, #ssh_url_to_repo, #url_to_repo, #valid_repo?, #web_url
#gitlab_shell
Methods included from Referable
#referable_inspect, #reference_link_text
#present
#analytics_access_level=, #builds_access_level=, #builds_enabled=, #container_registry_access_level=, #container_registry_enabled=, #environments_access_level=, #feature_flags_access_level=, #forking_access_level=, #infrastructure_access_level=, #issues_access_level=, #issues_enabled=, #merge_requests_access_level=, #merge_requests_enabled=, #metrics_dashboard_access_level=, #model_experiments_access_level=, #model_registry_access_level=, #monitor_access_level=, #operations_access_level=, #package_registry_access_level=, #pages_access_level=, #releases_access_level=, #repository_access_level=, #security_and_compliance_access_level=, #security_and_compliance_enabled=, #snippets_access_level=, #snippets_enabled=, #wiki_access_level=, #wiki_enabled=
#auto_devops_deploy_strategy=, #auto_devops_enabled=, #build_git_strategy=
#valid_attribute?
#attribute_invalidated?, #banzai_render_context, #cached_html_for, #cached_html_up_to_date?, #can_cache_field?, #invalidated_markdown_cache?, #latest_cached_markdown_version, #mentionable_attributes_changed?, #mentioned_filtered_user_ids_for, #parent_user, #refresh_markdown_cache, #refresh_markdown_cache!, #rendered_field_content, #skip_project_check?, #store_mentions!, #store_mentions?, #store_mentions_after_commit?, #updated_cached_html_for
Methods included from Avatarable
#avatar_path, #avatar_type, #uncached_avatar_path, #upload_paths
#request_access
allowed_for?, allowed_level?, allowed_levels, allowed_levels_for_user, closest_allowed_level, #internal?, level_name, level_value, levels_for_user, non_restricted_level?, options, #private?, #public?, public_visibility_restricted?, restricted_level?, string_level, string_options, string_values, valid_level?, #visibility, #visibility=, #visibility_attribute_present?, #visibility_attribute_value, #visibility_level_attributes, #visibility_level_previous_changes, #visibility_level_value
===, cached_column_list, #create_or_load_association, current_transaction, declarative_enum, default_select_columns, delete_all_returning, #deleted_from_database?, id_in, id_not_in, iid_in, nullable_column?, primary_key_in, #readable_by?, safe_ensure_unique, safe_find_or_create_by, safe_find_or_create_by!, sharding_keys, #to_ability_name, underscore, where_exists, where_not_exists, with_fast_read_statement_timeout, without_order
#reset_on_union_error, #reset_on_unknown_attribute_error
#serializable_hash
Constructor Details
#initialize(attributes = nil) ⇒ Project
Returns a new instance of Project.
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
|
# File 'app/models/project.rb', line 1328
def initialize(attributes = nil)
attributes ||= {}
unless visibility_attribute_present?(attributes)
attributes[:visibility_level] = Gitlab::CurrentSettings.default_project_visibility
end
@init_attributes = attributes
super
end
|
Instance Attribute Details
#old_path_with_namespace ⇒ Object
Returns the value of attribute old_path_with_namespace.
180
181
182
|
# File 'app/models/project.rb', line 180
def old_path_with_namespace
@old_path_with_namespace
end
|
#pipeline_status ⇒ Object
Lazy loading of the ‘pipeline_status` attribute
#skip_disk_validation ⇒ Object
Returns the value of attribute skip_disk_validation.
183
184
185
|
# File 'app/models/project.rb', line 183
def skip_disk_validation
@skip_disk_validation
end
|
#template_name ⇒ Object
Returns the value of attribute template_name.
181
182
183
|
# File 'app/models/project.rb', line 181
def template_name
@template_name
end
|
#topic_list ⇒ Object
3445
3446
3447
|
# File 'app/models/project.rb', line 3445
def topic_list
self.topics.map(&:name)
end
|
Class Method Details
.by_pages_enabled_unique_domain(domain) ⇒ Object
1306
1307
1308
1309
1310
1311
1312
1313
|
# File 'app/models/project.rb', line 1306
def by_pages_enabled_unique_domain(domain)
without_deleted
.joins(:project_setting)
.find_by(project_setting: {
pages_unique_domain_enabled: true,
pages_unique_domain: domain
})
end
|
.cached_count ⇒ Object
1254
1255
1256
1257
1258
|
# File 'app/models/project.rb', line 1254
def cached_count
Rails.cache.fetch('total_project_count', expires_in: 5.minutes) do
Project.count
end
end
|
.cascading_with_parent_namespace(attribute) ⇒ Object
Define two instance methods:
These functions will be overridden in EE to make sense afterwards
1083
1084
1085
1086
1087
1088
1089
1090
1091
|
# File 'app/models/project.rb', line 1083
def self.cascading_with_parent_namespace(attribute)
define_method("#{attribute}?") do |inherit_group_setting: false|
self.public_send(attribute) end
define_method("#{attribute}_locked?") do
false
end
end
|
.eager_load_namespace_and_owner ⇒ Object
1044
1045
1046
|
# File 'app/models/project.rb', line 1044
def self.eager_load_namespace_and_owner
includes(namespace: :owner)
end
|
.filter_by_feature_visibility(feature, user) ⇒ Object
This scope returns projects where user has access to both the project and the feature.
.filter_out_public_projects_with_unauthorized_private_repos(projects, user) ⇒ Object
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
|
# File 'app/models/project.rb', line 1108
def self.filter_out_public_projects_with_unauthorized_private_repos(projects, user)
public_projects_with_private_repos = projects.with_project_feature.where(
visibility_level: Gitlab::VisibilityLevel::PUBLIC,
project_features: { repository_access_level: ProjectFeature::PRIVATE }
).pluck(:id)
return projects unless public_projects_with_private_repos.present?
authorized_public_projects_with_private_repos = projects.filter_by_feature_visibility(
:repository, user
)
rejected_projects_with_private_repos = (
public_projects_with_private_repos - authorized_public_projects_with_private_repos.pluck(:id)
)
projects.where.not(id: rejected_projects_with_private_repos)
end
|
.find_by_url(url) ⇒ Object
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
|
# File 'app/models/project.rb', line 1275
def find_by_url(url)
uri = URI(url)
return unless uri.host == Gitlab.config.gitlab.host
match = Rails.application.routes.recognize_path(url)
return if match[:unmatched_route].present?
return if match[:namespace_id].blank? || match[:id].blank?
find_by_full_path(match.values_at(:namespace_id, :id).join("/"))
rescue ActionController::RoutingError, URI::InvalidURIError
nil
end
|
.group_by_namespace_traversal_ids(project_batch) ⇒ Object
1319
1320
1321
1322
1323
1324
1325
|
# File 'app/models/project.rb', line 1319
def group_by_namespace_traversal_ids(project_batch)
by_ids(project_batch)
.with_namespace
.pluck(:id, 'namespaces.traversal_ids')
.group_by(&:last)
.transform_values { |projects| projects.map(&:first) }
end
|
.group_ids ⇒ Object
1260
1261
1262
|
# File 'app/models/project.rb', line 1260
def group_ids
joins(:namespace).where(namespaces: { type: Group.sti_name }).select(:namespace_id)
end
|
.ids_with_issuables_available_for(user) ⇒ Object
Returns ids of projects with issuables available for given user
Used on queries to find milestones or labels which user can see For example: Milestone.where(project_id: ids_with_issuables_available_for(user))
1268
1269
1270
1271
1272
1273
|
# File 'app/models/project.rb', line 1268
def ids_with_issuables_available_for(user)
with_issues_enabled = with_issues_available_for_user(user).select(:id)
with_merge_requests_enabled = with_merge_requests_available_for_user(user).select(:id)
from_union([with_issues_enabled, with_merge_requests_enabled]).select(:id)
end
|
.inactive ⇒ Object
1141
1142
1143
1144
1145
1146
1147
1148
1149
|
# File 'app/models/project.rb', line 1141
def self.inactive
project_statistics = ::ProjectStatistics.arel_table
minimum_size_mb = ::Gitlab::CurrentSettings.inactive_projects_min_size_mb.megabytes
last_activity_cutoff = ::Gitlab::CurrentSettings.inactive_projects_send_warning_email_after_months.months.ago
joins(:statistics)
.where((project_statistics[:storage_size]).gt(minimum_size_mb))
.where('last_activity_at < ?', last_activity_cutoff)
end
|
.integration_association_name(name) ⇒ Object
215
216
217
|
# File 'app/models/project.rb', line 215
def self.integration_association_name(name)
"#{name}_integration"
end
|
.markdown_reference_pattern ⇒ Object
Pattern used to extract ‘namespace/project>` project references from text. ’>‘ or its escaped form (’>‘) are checked for because ’>‘ is sometimes escaped when the reference comes from an external source.
1241
1242
1243
1244
1245
1246
1247
|
# File 'app/models/project.rb', line 1241
def markdown_reference_pattern
@markdown_reference_pattern ||=
%r{
#{reference_pattern}
(#{reference_postfix}|#{reference_postfix_escaped})
}x
end
|
.project_features_defaults ⇒ Object
.project_namespace_for(id:) ⇒ Object
1315
1316
1317
|
# File 'app/models/project.rb', line 1315
def project_namespace_for(id:)
find_by(id: id)&.project_namespace
end
|
.projects_user_can(projects, user, action) ⇒ Object
1102
1103
1104
1105
1106
|
# File 'app/models/project.rb', line 1102
def self.projects_user_can(projects, user, action)
DeclarativePolicy.user_scope do
projects.select { |project| Ability.allowed?(user, action, project) }
end
end
|
.public_or_visible_to_user(user = nil, min_access_level = nil) ⇒ Object
Returns a collection of projects that is either public or visible to the logged in user.
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
|
# File 'app/models/project.rb', line 1050
def self.public_or_visible_to_user(user = nil, min_access_level = nil)
min_access_level = nil if user&.can_read_all_resources?
return public_to_user unless user
if user.is_a?(DeployToken)
where(id: user.accessible_projects)
else
where(
'EXISTS (?) OR projects.visibility_level IN (?)',
user.authorizations_for_projects(min_access_level: min_access_level),
self.visibility_levels_for_user(user)
)
end
end
|
.reference_pattern ⇒ Object
rubocop:enable Metrics/CyclomaticComplexity
.reference_postfix ⇒ Object
1230
1231
1232
|
# File 'app/models/project.rb', line 1230
def reference_postfix
'>'
end
|
.reference_postfix_escaped ⇒ Object
1234
1235
1236
|
# File 'app/models/project.rb', line 1234
def reference_postfix_escaped
'>'
end
|
.search(query, include_namespace: false, use_minimum_char_limit: true) ⇒ Object
Searches for a list of projects based on the query given in ‘query`.
On PostgreSQL this method uses “ILIKE” to perform a case-insensitive search.
query - The search query as a String.
1170
1171
1172
1173
1174
1175
1176
1177
1178
|
# File 'app/models/project.rb', line 1170
def search(query, include_namespace: false, use_minimum_char_limit: true)
if include_namespace
joins(:route).fuzzy_search(query, [Route.arel_table[:path], Route.arel_table[:name], :description],
use_minimum_char_limit: use_minimum_char_limit)
.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/421843')
else
fuzzy_search(query, [:path, :name, :description], use_minimum_char_limit: use_minimum_char_limit)
end
end
|
.search_by_title(query) ⇒ Object
1180
1181
1182
|
# File 'app/models/project.rb', line 1180
def search_by_title(query)
non_archived.fuzzy_search(query, [:name])
end
|
.sort_by_attribute(method) ⇒ Object
rubocop:disable Metrics/CyclomaticComplexity – stick to existing implementation for sort params:
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
|
# File 'app/models/project.rb', line 1189
def sort_by_attribute(method)
case method.to_s
when 'storage_size_desc' then sorted_by_storage_size_desc
when 'storage_size_asc' then sorted_by_storage_size_asc
when 'repository_size_desc' then sorted_by_repository_size_desc
when 'repository_size_asc' then sorted_by_repository_size_asc
when 'snippets_size_desc'then sorted_by_snippets_size_desc
when 'snippets_size_asc'then sorted_by_snippets_size_asc
when 'build_artifacts_size_desc' then sorted_by_build_artifacts_size_desc
when 'build_artifacts_size_asc'then sorted_by_build_artifacts_size_asc
when 'lfs_objects_size_desc'then sorted_by_lfs_objects_size_desc
when 'lfs_objects_size_asc' then sorted_by_lfs_objects_size_asc
when 'packages_size_desc' then sorted_by_packages_size_desc
when 'packages_size_asc' then sorted_by_packages_size_asc
when 'wiki_size_desc' then sorted_by_wiki_size_desc
when 'wiki_size_asc'then sorted_by_wiki_size_asc
when 'container_registry_size_desc' then sorted_by_container_registry_size_desc
when 'container_registry_size_asc' then sorted_by_container_registry_size_asc
when 'latest_activity_desc' then sorted_by_updated_desc
when 'latest_activity_asc' then sorted_by_updated_asc
when 'path_desc'then sorted_by_path_desc
when 'path_asc' then sorted_by_path_asc
when 'full_path_desc'then sorted_by_full_path_desc
when 'full_path_asc' then sorted_by_full_path_asc
when 'stars_desc' then sorted_by_stars_desc
when 'stars_asc' then sorted_by_stars_asc
else
order_by(method)
end
end
|
.trending ⇒ Object
1249
1250
1251
1252
|
# File 'app/models/project.rb', line 1249
def trending
joins('INNER JOIN trending_projects ON projects.id = trending_projects.project_id')
.reorder('trending_projects.id ASC')
end
|
.visibility_levels ⇒ Object
.visibility_levels_for_user(user) ⇒ Object
Auditors can :read_all_resources while admins can :read_all_resources and read_admin_projects. In EE, a regular user can read_admin_projects through custom admin roles.
.with_api_entity_associations ⇒ Object
1022
1023
1024
|
# File 'app/models/project.rb', line 1022
def self.with_api_entity_associations
preload(:project_feature, :route, :topics, :group, :timelogs, namespace: [:route, :owner])
end
|
.with_feature_available_for_user(feature, user) ⇒ Object
.with_slack_application_disabled ⇒ Object
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
|
# File 'app/models/project.rb', line 1030
def self.with_slack_application_disabled
with_active_slack = Integration.active.by_name(:gitlab_slack_application)
join_contraint = arel_table[:id].eq(Integration.arel_table[:project_id])
constraint = with_active_slack.where_clause.send(:predicates).reduce(join_contraint) { |a, b| a.and(b) }
join = arel_table.join(Integration.arel_table, Arel::Nodes::OuterJoin).on(constraint).join_sources
joins(join).where(integrations: { id: nil })
rescue Integration::UnknownType
all
end
|
.with_web_entity_associations ⇒ Object
1026
1027
1028
|
# File 'app/models/project.rb', line 1026
def self.with_web_entity_associations
preload(:project_feature, :route, :creator, group: :parent, namespace: [:route, :owner, :namespace_settings, :namespace_settings_with_ancestors_inherited_settings])
end
|
.without_integration(integration) ⇒ Object
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
|
# File 'app/models/project.rb', line 1290
def without_integration(integration)
integrations = Integration
.select('1')
.where("#{Integration.table_name}.project_id = projects.id")
.where(type: integration.type)
Project
.where('NOT EXISTS (?)', integrations)
.where(pending_delete: false)
.where(archived: false)
end
|
.wrap_with_cte(collection) ⇒ Object
1136
1137
1138
1139
|
# File 'app/models/project.rb', line 1136
def self.wrap_with_cte(collection)
cte = Gitlab::SQL::CTE.new(:projects_cte, collection)
Project.with(cte.to_arel).from(cte.alias_to(Project.arel_table))
end
|
Instance Method Details
#access_request_approvers_to_be_notified ⇒ Object
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
|
# File 'app/models/project.rb', line 3226
def access_request_approvers_to_be_notified
access_request_approvers = members.owners_and_maintainers
recipients = access_request_approvers.connected_to_user.order_recent_sign_in.limit(Member::ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT)
if recipients.blank?
recipients = group.access_request_approvers_to_be_notified
end
recipients
end
|
#active_runners ⇒ Object
2535
2536
2537
2538
2539
|
# File 'app/models/project.rb', line 2535
def active_runners
strong_memoize(:active_runners) do
all_available_runners.active
end
end
|
#active_webide_pipelines(user:) ⇒ Object
1450
1451
1452
|
# File 'app/models/project.rb', line 1450
def active_webide_pipelines(user:)
webide_pipelines.running_or_pending.for_user(user)
end
|
#add_export_job(current_user:, after_export_strategy: nil, params: {}) ⇒ Object
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
|
# File 'app/models/project.rb', line 2680
def add_export_job(current_user:, after_export_strategy: nil, params: {})
check_project_export_limit!
check_duplicate_export!(current_user)
params[:exported_by_admin] = current_user.can_admin_all_resources?
job_id = Projects::ImportExport::CreateRelationExportsWorker
.perform_async(current_user.id, self.id, after_export_strategy, params)
if job_id
Gitlab::AppLogger.info "Export job started for project ID #{self.id} with job ID #{job_id}"
else
Gitlab::AppLogger.error "Export job failed to start for project ID #{self.id}"
end
end
|
#add_import_job ⇒ Object
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
|
# File 'app/models/project.rb', line 1678
def add_import_job
job_id =
if forked?
RepositoryForkWorker.perform_async(id)
else
RepositoryImportWorker.perform_async(self.id)
end
log_import_activity(job_id)
job_id
end
|
#after_change_head_branch_does_not_exist(branch) ⇒ Object
3450
3451
3452
|
# File 'app/models/project.rb', line 3450
def after_change_head_branch_does_not_exist(branch)
self.errors.add(:base, _("Could not change HEAD: branch '%{branch}' does not exist") % { branch: branch })
end
|
#after_create_default_branch ⇒ Object
rubocop: disable CodeReuse/ServiceClass
#after_import ⇒ Object
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
|
# File 'app/models/project.rb', line 2630
def after_import
repository.expire_content_cache
repository.remove_prohibited_refs
wiki.repository.expire_content_cache
DetectRepositoryLanguagesWorker.perform_async(id)
ProjectCacheWorker.perform_async(self.id, [], %w[repository_size wiki_size])
AuthorizedProjectUpdate::ProjectRecalculateWorker.perform_async(id)
enqueue_record_project_target_platforms
reset_counters_and_iids
import_state&.finish
after_create_default_branch
join_pool_repository
refresh_markdown_cache!
end
|
#after_repository_change_head ⇒ Object
2395
2396
2397
2398
2399
|
# File 'app/models/project.rb', line 2395
def after_repository_change_head
ProjectCacheWorker.perform_async(self.id, [], %w[commit_count])
super
end
|
#all_available_runners ⇒ Object
2531
2532
2533
|
# File 'app/models/project.rb', line 2531
def all_available_runners
Ci::Runner.from_union([runners, group_runners, available_shared_runners])
end
|
#all_clusters ⇒ Object
2129
2130
2131
2132
2133
2134
|
# File 'app/models/project.rb', line 2129
def all_clusters
group_clusters = Clusters::Cluster.joins(:groups).where(cluster_groups: { group_id: ancestors_upto })
instance_clusters = Clusters::Cluster.instance_type
Clusters::Cluster.from_union([clusters, group_clusters, instance_clusters])
end
|
#all_pipelines ⇒ Object
1434
1435
1436
1437
1438
1439
1440
|
# File 'app/models/project.rb', line 1434
def all_pipelines
if builds_enabled?
super
else
super.external
end
end
|
#all_runners ⇒ Object
2527
2528
2529
|
# File 'app/models/project.rb', line 2527
def all_runners
Ci::Runner.from_union([runners, group_runners, shared_runners])
end
|
#allow_iframes_in_markdown_feature_flag_enabled? ⇒ Boolean
3526
3527
3528
|
# File 'app/models/project.rb', line 3526
def allow_iframes_in_markdown_feature_flag_enabled?
group&.allow_iframes_in_markdown_feature_flag_enabled? || Feature.enabled?(:allow_iframes_in_markdown, self, type: :wip)
end
|
#allowed_to_share_with_group? ⇒ Boolean
2420
2421
2422
|
# File 'app/models/project.rb', line 2420
def allowed_to_share_with_group?
share_with_group_enabled?
end
|
#allows_multiple_merge_request_assignees? ⇒ Boolean
3626
3627
3628
|
# File 'app/models/project.rb', line 3626
def allows_multiple_merge_request_assignees?
false
end
|
#allows_multiple_merge_request_reviewers? ⇒ Boolean
3631
3632
3633
|
# File 'app/models/project.rb', line 3631
def allows_multiple_merge_request_reviewers?
false
end
|
#analytics_enabled? ⇒ Boolean
2473
2474
2475
|
# File 'app/models/project.rb', line 2473
def analytics_enabled?
!!project_feature&.analytics_enabled?
end
|
#ancestors(hierarchy_order: nil) ⇒ Object
Also known as:
group_and_ancestors
1482
1483
1484
|
# File 'app/models/project.rb', line 1482
def ancestors(hierarchy_order: nil)
group&.self_and_ancestors(hierarchy_order: hierarchy_order) || Group.none
end
|
#ancestors_archived? ⇒ Boolean
3038
3039
3040
|
# File 'app/models/project.rb', line 3038
def ancestors_archived?
ancestors.archived.exists?
end
|
#ancestors_upto(top = nil, hierarchy_order: nil) ⇒ Object
returns all ancestor-groups upto but excluding the given namespace when no namespace is given, all ancestors upto the top are returned
1477
1478
1479
1480
|
# File 'app/models/project.rb', line 1477
def ancestors_upto(top = nil, hierarchy_order: nil)
Gitlab::ObjectHierarchy.new(Group.where(id: namespace_id))
.base_and_ancestors(upto: top, hierarchy_order: hierarchy_order)
end
|
#ancestors_upto_ids ⇒ Object
1493
1494
1495
|
# File 'app/models/project.rb', line 1493
def ancestors_upto_ids(...)
ancestors_upto(...).pluck(:id)
end
|
#any_branch_allows_collaboration?(user) ⇒ Boolean
3116
3117
3118
|
# File 'app/models/project.rb', line 3116
def any_branch_allows_collaboration?(user)
fetch_branch_allows_collaboration(user)
end
|
#any_import_in_progress? ⇒ Boolean
Determine whether any kind of import is in progress.
-
Full file import
-
Relation import
-
Direct Transfer
1836
1837
1838
1839
1840
1841
1842
|
# File 'app/models/project.rb', line 1836
def any_import_in_progress?
last_relation_import_tracker = relation_import_trackers.last
(last_relation_import_tracker&.started? && !last_relation_import_tracker.stale?) ||
import_started? ||
BulkImports::Entity.with_status(:started).where(project_id: id).any?
end
|
#any_lfs_file_locks? ⇒ Boolean
3148
3149
3150
|
# File 'app/models/project.rb', line 3148
def any_lfs_file_locks?
lfs_file_locks.any?
end
|
#any_online_runners?(&block) ⇒ Boolean
2541
2542
2543
|
# File 'app/models/project.rb', line 2541
def any_online_runners?(&block)
online_runners_with_tags.any?(&block)
end
|
#archived ⇒ Object
Also known as:
self_archived?
3028
3029
3030
|
# File 'app/models/project.rb', line 3028
def archived
super && !self_deletion_scheduled?
end
|
#assigning_role_too_high?(current_user, access_level) ⇒ Boolean
3701
3702
3703
3704
3705
3706
3707
3708
|
# File 'app/models/project.rb', line 3701
def assigning_role_too_high?(current_user, access_level)
return false unless access_level
return false if current_user.can_admin_all_resources?
max_access_level = max_member_access_for_user(current_user)
!Gitlab::Access.level_encompasses?(current_access_level: max_access_level, level_to_assign: access_level)
end
|
#auto_cancel_pending_pipelines? ⇒ Boolean
3153
3154
3155
|
# File 'app/models/project.rb', line 3153
def auto_cancel_pending_pipelines?
auto_cancel_pending_pipelines == 'enabled'
end
|
#auto_devops_enabled? ⇒ Boolean
1511
1512
1513
1514
1515
1516
1517
|
# File 'app/models/project.rb', line 1511
def auto_devops_enabled?
if auto_devops&.enabled.nil?
has_auto_devops_implicitly_enabled?
else
auto_devops.enabled?
end
end
|
#auto_devops_variables ⇒ Object
2944
2945
2946
2947
2948
|
# File 'app/models/project.rb', line 2944
def auto_devops_variables
return [] unless auto_devops_enabled?
(auto_devops || build_auto_devops)&.predefined_variables
end
|
#autoclose_referenced_issues ⇒ Object
1462
1463
1464
1465
1466
|
# File 'app/models/project.rb', line 1462
def autoclose_referenced_issues
return true if super.nil?
super
end
|
#available_shared_runners ⇒ Object
2519
2520
2521
|
# File 'app/models/project.rb', line 2519
def available_shared_runners
@available_shared_runners ||= shared_runners_available? ? shared_runners : Ci::Runner.none
end
|
#avatar_in_git ⇒ Object
2116
2117
2118
|
# File 'app/models/project.rb', line 2116
def avatar_in_git
repository.avatar
end
|
#avatar_url(**args) ⇒ Object
2120
2121
2122
|
# File 'app/models/project.rb', line 2120
def avatar_url(**args)
Gitlab::Routing.url_helpers.project_avatar_url(self) if avatar_in_git
end
|
#badges ⇒ Object
3099
3100
3101
3102
3103
|
# File 'app/models/project.rb', line 3099
def badges
return project_badges unless group
Badge.from_union([project_badges, GroupBadge.where(group: group.self_and_ancestors)])
end
|
#batch_loaded_environment_by_name(name) ⇒ Object
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
|
# File 'app/models/project.rb', line 3299
def batch_loaded_environment_by_name(name)
BatchLoader.for(name).batch(key: id) do |names, loader, args|
Environment.where(name: names, project: args[:key]).find_each do |environment|
loader.call(environment.name, environment)
end
end
end
|
#beautified_import_status_name ⇒ Object
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
|
# File 'app/models/project.rb', line 1666
def beautified_import_status_name
if import_finished?
return 'completed' unless import_checksums.present?
fetched = import_checksums['fetched']
imported = import_checksums['imported']
fetched.keys.any? { |key| fetched[key] != imported[key] } ? 'partially completed' : 'completed'
else
import_status
end
end
|
#bitbucket_import? ⇒ Boolean
1819
1820
1821
|
# File 'app/models/project.rb', line 1819
def bitbucket_import?
import_type == 'bitbucket'
end
|
#bitbucket_server_import? ⇒ Boolean
1823
1824
1825
|
# File 'app/models/project.rb', line 1823
def bitbucket_server_import?
import_type == 'bitbucket_server'
end
|
#bots ⇒ Object
2374
2375
2376
|
# File 'app/models/project.rb', line 2374
def bots
users.project_bot
end
|
#branch_allows_collaboration?(user, branch_name) ⇒ Boolean
3120
3121
3122
|
# File 'app/models/project.rb', line 3120
def branch_allows_collaboration?(user, branch_name)
fetch_branch_allows_collaboration(user, branch_name)
end
|
#build_commit_note(commit) ⇒ Object
2017
2018
2019
|
# File 'app/models/project.rb', line 2017
def build_commit_note(commit)
notes.new(commit_id: commit.id, noteable_type: 'Commit')
end
|
#build_or_assign_import_data(data: nil, credentials: nil) ⇒ Object
1776
1777
1778
1779
1780
1781
1782
1783
|
# File 'app/models/project.rb', line 1776
def build_or_assign_import_data(data: nil, credentials: nil)
project_import_data = import_data || build_import_data
project_import_data.merge_data(data.to_h) if data
project_import_data.merge_credentials(credentials.to_h) if credentials
project_import_data
end
|
#builds_enabled? ⇒ Boolean
2449
2450
2451
|
# File 'app/models/project.rb', line 2449
def builds_enabled?
!!project_feature&.builds_enabled?
end
|
#can_create_custom_domains? ⇒ Boolean
3569
3570
3571
3572
3573
|
# File 'app/models/project.rb', line 3569
def can_create_custom_domains?
return true if Gitlab::CurrentSettings.max_pages_custom_domains_per_project == 0
pages_domains.count < Gitlab::CurrentSettings.max_pages_custom_domains_per_project
end
|
#can_create_new_ref_commits? ⇒ Boolean
3064
3065
3066
|
# File 'app/models/project.rb', line 3064
def can_create_new_ref_commits?
merge_method != :merge
end
|
#can_suggest_reviewers? ⇒ Boolean
3580
3581
3582
|
# File 'app/models/project.rb', line 3580
def can_suggest_reviewers?
false
end
|
#certificate_based_clusters_enabled? ⇒ Boolean
1363
1364
1365
|
# File 'app/models/project.rb', line 1363
def certificate_based_clusters_enabled?
!!namespace&.certificate_based_clusters_enabled?
end
|
#changing_shared_runners_enabled_is_allowed ⇒ Object
1934
1935
1936
1937
1938
1939
1940
|
# File 'app/models/project.rb', line 1934
def changing_shared_runners_enabled_is_allowed
return unless new_record? || changes.has_key?(:shared_runners_enabled)
if shared_runners_setting_conflicting_with_group?
errors.add(:shared_runners_enabled, _('cannot be enabled because parent group does not allow it'))
end
end
|
#check_personal_projects_limit ⇒ Object
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
|
# File 'app/models/project.rb', line 1875
def check_personal_projects_limit
return if !creator || creator.can_create_project? ||
namespace.kind == 'group'
limit = creator.projects_limit
error =
if limit == 0
_('You cannot create projects in your personal namespace. Contact your GitLab administrator.')
else
_("You've reached your limit of %{limit} projects created. Contact your GitLab administrator.")
end
self.errors.add(:limit_reached, error % { limit: limit })
end
|
#check_repository_path_availability ⇒ Object
Check if repository already exists on disk
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
|
# File 'app/models/project.rb', line 2289
def check_repository_path_availability
return true if skip_disk_validation
return false unless repository_storage
if legacy_storage? && repository_with_same_path_already_exists?
errors.add(:base, _('There is already a repository with that name on disk'))
return false
end
true
rescue GRPC::Internal false
end
|
#ci_allow_fork_pipelines_to_run_in_parent_project? ⇒ Boolean
3389
3390
3391
3392
3393
|
# File 'app/models/project.rb', line 3389
def ci_allow_fork_pipelines_to_run_in_parent_project?
return false unless ci_cd_settings
ci_cd_settings.allow_fork_pipelines_to_run_in_parent_project?
end
|
#ci_config_for(sha) ⇒ Object
3357
3358
3359
|
# File 'app/models/project.rb', line 3357
def ci_config_for(sha)
repository.blob_data_at(sha, ci_config_path_or_default)
end
|
#ci_config_path=(value) ⇒ Object
1716
1717
1718
1719
|
# File 'app/models/project.rb', line 1716
def ci_config_path=(value)
super(value&.delete("\0"))
end
|
#ci_config_path_or_default ⇒ Object
3353
3354
3355
|
# File 'app/models/project.rb', line 3353
def ci_config_path_or_default
ci_config_path.presence || Ci::Pipeline::DEFAULT_CONFIG_PATH
end
|
#ci_display_pipeline_variables? ⇒ Boolean
3371
3372
3373
3374
3375
|
# File 'app/models/project.rb', line 3371
def ci_display_pipeline_variables?
return false unless ci_cd_settings
ci_cd_settings.display_pipeline_variables?
end
|
#ci_forward_deployment_enabled? ⇒ Boolean
3377
3378
3379
3380
3381
|
# File 'app/models/project.rb', line 3377
def ci_forward_deployment_enabled?
return false unless ci_cd_settings
ci_cd_settings.forward_deployment_enabled?
end
|
#ci_forward_deployment_rollback_allowed? ⇒ Boolean
3383
3384
3385
3386
3387
|
# File 'app/models/project.rb', line 3383
def ci_forward_deployment_rollback_allowed?
return false unless ci_cd_settings
ci_cd_settings.forward_deployment_rollback_allowed?
end
|
#ci_inbound_job_token_scope_enabled? ⇒ Boolean
3401
3402
3403
3404
3405
3406
3407
|
# File 'app/models/project.rb', line 3401
def ci_inbound_job_token_scope_enabled?
return true unless ci_cd_settings
return true if ::Gitlab::CurrentSettings.enforce_ci_inbound_job_token_scope_enabled?
ci_cd_settings.inbound_job_token_scope_enabled?
end
|
#ci_integration ⇒ Object
2112
2113
2114
|
# File 'app/models/project.rb', line 2112
def ci_integration
@ci_integration ||= ci_integrations.reorder(nil).find_by(active: true)
end
|
#ci_integrations ⇒ Object
rubocop: enable CodeReuse/ServiceClass
2108
2109
2110
|
# File 'app/models/project.rb', line 2108
def ci_integrations
integrations.where(category: :ci)
end
|
#ci_outbound_job_token_scope_enabled? ⇒ Boolean
3395
3396
3397
3398
3399
|
# File 'app/models/project.rb', line 3395
def ci_outbound_job_token_scope_enabled?
return false unless ci_cd_settings
ci_cd_settings.job_token_scope_enabled?
end
|
#ci_pipelines ⇒ Object
1442
1443
1444
1445
1446
1447
1448
|
# File 'app/models/project.rb', line 1442
def ci_pipelines
if builds_enabled?
super
else
super.external
end
end
|
#ci_push_repository_for_job_token_allowed? ⇒ Boolean
3421
3422
3423
3424
3425
|
# File 'app/models/project.rb', line 3421
def ci_push_repository_for_job_token_allowed?
return false unless ci_cd_settings
ci_cd_settings.push_repository_for_job_token_allowed?
end
|
#ci_template_variables ⇒ Object
2868
2869
2870
2871
2872
|
# File 'app/models/project.rb', line 2868
def ci_template_variables
Gitlab::Ci::Variables::Collection.new.tap do |variables|
variables.append(key: 'CI_TEMPLATE_REGISTRY_HOST', value: 'registry.gitlab.com')
end
end
|
#cleanup ⇒ Object
Also known as:
reload_repository!
1564
1565
1566
|
# File 'app/models/project.rb', line 1564
def cleanup
@repository = nil
end
|
#closest_setting(name) ⇒ Object
3238
3239
3240
3241
3242
3243
|
# File 'app/models/project.rb', line 3238
def closest_setting(name)
setting = read_attribute(name)
setting = closest_namespace_setting(name) if setting.nil?
setting = app_settings_for(name) if setting.nil?
setting
end
|
#code ⇒ Object
For compatibility with old code
2125
2126
2127
|
# File 'app/models/project.rb', line 2125
def code
path
end
|
#commit_notes ⇒ Object
Used by Import/Export to export commit notes
1722
1723
1724
|
# File 'app/models/project.rb', line 1722
def commit_notes
notes.where(noteable_type: "Commit")
end
|
#container_registry_enabled? ⇒ Boolean
Also known as:
container_registry_enabled
2502
2503
2504
|
# File 'app/models/project.rb', line 2502
def container_registry_enabled?
!!project_feature&.container_registry_enabled?
end
|
#container_registry_url ⇒ Object
1570
1571
1572
1573
1574
|
# File 'app/models/project.rb', line 1570
def container_registry_url
if Gitlab.config.registry.enabled
"#{Gitlab.config.registry.host_port}/#{full_path.downcase}"
end
end
|
#container_registry_variables ⇒ Object
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
|
# File 'app/models/project.rb', line 2892
def container_registry_variables
Gitlab::Ci::Variables::Collection.new.tap do |variables|
break variables unless Gitlab.config.registry.enabled
variables.append(key: 'CI_REGISTRY', value: Gitlab.config.registry.host_port)
if container_registry_enabled?
variables.append(key: 'CI_REGISTRY_IMAGE', value: container_registry_url)
end
end
end
|
#container_repositories_size ⇒ Object
#create_labels ⇒ Object
rubocop: disable CodeReuse/ServiceClass
2097
2098
2099
2100
2101
2102
2103
2104
2105
|
# File 'app/models/project.rb', line 2097
def create_labels
Label.templates.for_organization(organization).each do |label|
params = label.attributes
.slice(*Label.column_names)
.except('id', 'template', 'created_at', 'updated_at', 'type', 'organization_id')
Labels::FindOrCreateService.new(nil, self, params).execute(skip_authorization: true)
end
end
|
#create_repository(force: false, default_branch: nil, object_format: nil) ⇒ Object
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
|
# File 'app/models/project.rb', line 2318
def create_repository(force: false, default_branch: nil, object_format: nil)
return if forked? && !force
repository.create_repository(default_branch, object_format: object_format)
repository.after_create
true
rescue StandardError => e
Gitlab::ErrorTracking.track_exception(e, project: { id: id, full_path: full_path, disk_path: disk_path })
errors.add(:base, _('Failed to create repository'))
false
end
|
#crm_enabled? ⇒ Boolean
3589
3590
3591
3592
3593
|
# File 'app/models/project.rb', line 3589
def crm_enabled?
return false unless group
group.crm_enabled?
end
|
#crm_group ⇒ Object
3595
3596
3597
3598
3599
|
# File 'app/models/project.rb', line 3595
def crm_group
return unless group
group.crm_group
end
|
#default_branch_or_main ⇒ Object
3347
3348
3349
3350
3351
|
# File 'app/models/project.rb', line 3347
def default_branch_or_main
return default_branch if default_branch
Gitlab::DefaultBranch.value(object: self)
end
|
#default_branch_protected? ⇒ Boolean
3281
3282
3283
3284
3285
|
# File 'app/models/project.rb', line 3281
def default_branch_protected?
branch_protection = Gitlab::Access::DefaultBranchProtection.new(self.namespace.default_branch_protection_settings)
!branch_protection.developer_can_push?
end
|
#default_environment ⇒ Object
2904
2905
2906
2907
2908
2909
2910
2911
|
# File 'app/models/project.rb', line 2904
def default_environment
production_first = Arel.sql("(CASE WHEN name = 'production' THEN 0 ELSE 1 END), id ASC")
environments
.with_state(:available)
.reorder(production_first)
.first
end
|
#default_issues_tracker? ⇒ Boolean
2047
2048
2049
|
# File 'app/models/project.rb', line 2047
def default_issues_tracker?
!external_issue_tracker
end
|
#default_merge_request_target ⇒ Object
2975
2976
2977
2978
2979
2980
|
# File 'app/models/project.rb', line 2975
def default_merge_request_target
return self if project_setting.mr_default_target_self
return self unless mr_can_target_upstream?
forked_from_project
end
|
#default_pipeline_lock ⇒ Object
1454
1455
1456
1457
1458
1459
1460
|
# File 'app/models/project.rb', line 1454
def default_pipeline_lock
if keep_latest_artifacts_available?
return :artifacts_locked
end
:unlocked
end
|
#dependency_proxy_variables ⇒ Object
#deploy_token_create_url(opts = {}) ⇒ Object
3273
3274
3275
|
# File 'app/models/project.rb', line 3273
def deploy_token_create_url(opts = {})
Gitlab::Routing.url_helpers.create_deploy_token_project_settings_repository_path(self, opts)
end
|
#deploy_token_revoke_url_for(token) ⇒ Object
3277
3278
3279
|
# File 'app/models/project.rb', line 3277
def deploy_token_revoke_url_for(token)
Gitlab::Routing.url_helpers.revoke_project_deploy_token_path(self, token)
end
|
#deployment_variables(environment:, kubernetes_namespace: nil) ⇒ Object
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
|
# File 'app/models/project.rb', line 2932
def deployment_variables(environment:, kubernetes_namespace: nil)
platform = deployment_platform(environment: environment)
return [] unless platform.present?
platform.predefined_variables(
project: self,
environment_name: environment,
kubernetes_namespace: kubernetes_namespace
)
end
|
#deprecated_owner ⇒ Object
2162
2163
2164
2165
2166
|
# File 'app/models/project.rb', line 2162
def deprecated_owner
group || namespace.try(:owner)
end
|
#design_management_enabled? ⇒ Boolean
LFS and hashed repository storage are required for using Design Management.
1542
1543
1544
|
# File 'app/models/project.rb', line 1542
def design_management_enabled?
lfs_enabled? && hashed_storage?(:repository)
end
|
#design_repository ⇒ Object
1558
1559
1560
1561
1562
|
# File 'app/models/project.rb', line 1558
def design_repository
strong_memoize(:design_repository) do
find_or_create_design_management_repository.repository
end
end
|
#destroy_deployment_by_id(deployment_id) ⇒ Object
3565
3566
3567
|
# File 'app/models/project.rb', line 3565
def destroy_deployment_by_id(deployment_id)
deployments.where(id: deployment_id).fast_destroy_all
end
|
#disabled_integrations ⇒ Object
Returns a list of integration names that should be disabled at the project-level. Globally disabled integrations should go in Integration.disabled_integration_names.
2085
2086
2087
|
# File 'app/models/project.rb', line 2085
def disabled_integrations
%w[zentao]
end
|
#drop_visibility_level! ⇒ Object
3245
3246
3247
3248
3249
3250
3251
3252
3253
|
# File 'app/models/project.rb', line 3245
def drop_visibility_level!
if group && group.visibility_level < visibility_level
self.visibility_level = group.visibility_level
end
if Gitlab::CurrentSettings.restricted_visibility_levels.include?(visibility_level)
self.visibility_level = Gitlab::VisibilityLevel::PRIVATE
end
end
|
#emails_disabled? ⇒ Boolean
1497
1498
1499
1500
|
# File 'app/models/project.rb', line 1497
def emails_disabled?
!emails_enabled?
end
|
#enable_ci ⇒ Object
2507
2508
2509
|
# File 'app/models/project.rb', line 2507
def enable_ci
project_feature.update_attribute(:builds_access_level, ProjectFeature::ENABLED)
end
|
#enforce_auth_checks_on_uploads? ⇒ Boolean
1398
1399
1400
|
# File 'app/models/project.rb', line 1398
def enforce_auth_checks_on_uploads?
!!project_setting&.enforce_auth_checks_on_uploads?
end
|
#enforced_runner_token_expiration_interval ⇒ Object
3468
3469
3470
3471
3472
3473
3474
3475
3476
|
# File 'app/models/project.rb', line 3468
def enforced_runner_token_expiration_interval
group_settings = NamespaceSetting.where(namespace_id: parent_groups)
group_interval = group_settings.where.not(project_runner_token_expiration_interval: nil).minimum(:project_runner_token_expiration_interval)&.seconds
[
Gitlab::CurrentSettings.project_runner_token_expiration_interval&.seconds,
group_interval
].compact.min
end
|
#ensure_pool_repository ⇒ Object
Ensures project has a pool repository without exposing private creation logic
3697
3698
3699
|
# File 'app/models/project.rb', line 3697
def ensure_pool_repository
pool_repository || create_new_pool_repository
end
|
#ensure_repository ⇒ Object
2415
2416
2417
|
# File 'app/models/project.rb', line 2415
def ensure_repository
create_repository(force: true) unless repository_exists?
end
|
#environments_for_scope(scope) ⇒ Object
3293
3294
3295
3296
3297
|
# File 'app/models/project.rb', line 3293
def environments_for_scope(scope)
quoted_scope = ::Gitlab::SQL::Glob.q(scope)
environments.where("name LIKE (#{::Gitlab::SQL::Glob.to_like(quoted_scope)})") end
|
#execute_hooks(data, hooks_scope = :push_hooks) ⇒ Object
rubocop: disable CodeReuse/ServiceClass
2186
2187
2188
2189
2190
2191
|
# File 'app/models/project.rb', line 2186
def execute_hooks(data, hooks_scope = :push_hooks)
run_after_commit_or_now do
triggered_hooks(hooks_scope, data).execute
SystemHooksService.new.execute_hooks(data, hooks_scope)
end
end
|
#execute_integrations(data, hooks_scope = :push_hooks, skip_ci: false) ⇒ Object
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
|
# File 'app/models/project.rb', line 2210
def execute_integrations(data, hooks_scope = :push_hooks, skip_ci: false)
run_after_commit_or_now do
association("#{hooks_scope}_integrations").reader.each do |integration|
next if skip_ci && integration.ci?
integration.async_execute(data)
end
end
end
|
#expire_caches_before_rename(old_path) ⇒ Object
Expires various caches before a project is renamed.
2278
2279
2280
2281
2282
2283
2284
2285
2286
|
# File 'app/models/project.rb', line 2278
def expire_caches_before_rename(old_path)
project_repo = Repository.new(old_path, self, shard: repository_storage)
wiki_repo = Repository.new("#{old_path}#{Gitlab::GlRepository::WIKI.path_suffix}", self, shard: repository_storage, repo_type: Gitlab::GlRepository::WIKI)
design_repo = Repository.new("#{old_path}#{Gitlab::GlRepository::DESIGN.path_suffix}", self, shard: repository_storage, repo_type: Gitlab::GlRepository::DESIGN)
[project_repo, wiki_repo, design_repo].each do |repo|
repo.before_delete if repo.exists?
end
end
|
#export_archive_exists?(user) ⇒ Boolean
2769
2770
2771
|
# File 'app/models/project.rb', line 2769
def export_archive_exists?(user)
import_export_upload_by_user(user)&.export_archive_exists?
end
|
#export_enqueued?(user) ⇒ Boolean
2728
2729
2730
2731
2732
|
# File 'app/models/project.rb', line 2728
def export_enqueued?(user)
strong_memoize(:export_enqueued) do
::Projects::ExportJobFinder.new(self, user, { status: :queued }).execute.present?
end
end
|
#export_failed?(user) ⇒ Boolean
2734
2735
2736
2737
2738
|
# File 'app/models/project.rb', line 2734
def export_failed?(user)
strong_memoize(:export_failed) do
::Projects::ExportJobFinder.new(self, user, { status: :failed }).execute.present?
end
end
|
#export_file(user) ⇒ Object
2773
2774
2775
|
# File 'app/models/project.rb', line 2773
def export_file(user)
import_export_upload_by_user(user)&.export_file
end
|
#export_file_exists?(user) ⇒ Boolean
2765
2766
2767
|
# File 'app/models/project.rb', line 2765
def export_file_exists?(user)
import_export_upload_by_user(user)&.export_file_exists?
end
|
#export_in_progress?(user) ⇒ Boolean
2722
2723
2724
2725
2726
|
# File 'app/models/project.rb', line 2722
def export_in_progress?(user)
strong_memoize(:export_in_progress) do
::Projects::ExportJobFinder.new(self, user, { status: :started }).execute.present?
end
end
|
#export_path ⇒ Object
2700
2701
2702
2703
2704
|
# File 'app/models/project.rb', line 2700
def export_path
return unless namespace.present? || hashed_storage?(:repository)
import_export_shared.archive_path
end
|
#export_status(user) ⇒ Object
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
|
# File 'app/models/project.rb', line 2706
def export_status(user)
if regeneration_in_progress?(user)
:regeneration_in_progress
elsif export_enqueued?(user)
:queued
elsif export_in_progress?(user)
:started
elsif export_file_exists?(user)
:finished
elsif export_failed?(user)
:failed
else
:none
end
end
|
#extended_prat_expiry_webhooks_execute? ⇒ Boolean
1406
1407
1408
|
# File 'app/models/project.rb', line 1406
def extended_prat_expiry_webhooks_execute?
!!project_setting&.extended_prat_expiry_webhooks_execute?
end
|
#external_authorization_classification_label ⇒ Object
#external_import? ⇒ Boolean
1789
1790
1791
|
# File 'app/models/project.rb', line 1789
def external_import?
safe_import_url.present?
end
|
#external_issue_reference_pattern ⇒ Object
2043
2044
2045
|
# File 'app/models/project.rb', line 2043
def external_issue_reference_pattern
external_issue_tracker.reference_pattern(only_long: issues_enabled?)
end
|
#external_issue_tracker ⇒ Object
2051
2052
2053
2054
2055
2056
2057
|
# File 'app/models/project.rb', line 2051
def external_issue_tracker
cache_has_external_issue_tracker if has_external_issue_tracker.nil?
return unless has_external_issue_tracker?
@external_issue_tracker ||= integrations.external_issue_trackers.first
end
|
#external_references_supported? ⇒ Boolean
2059
2060
2061
|
# File 'app/models/project.rb', line 2059
def external_references_supported?
external_issue_tracker&.support_cross_reference?
end
|
#external_wiki ⇒ Object
2067
2068
2069
2070
2071
2072
2073
|
# File 'app/models/project.rb', line 2067
def external_wiki
cache_has_external_wiki if has_external_wiki.nil?
return unless has_external_wiki?
@external_wiki ||= integrations.external_wikis.first
end
|
#feature_available?(feature, user = nil) ⇒ Boolean
2445
2446
2447
|
# File 'app/models/project.rb', line 2445
def feature_available?(feature, user = nil)
!!project_feature&.feature_available?(feature, user)
end
|
#feature_flags_client_token ⇒ Object
3361
3362
3363
3364
|
# File 'app/models/project.rb', line 3361
def feature_flags_client_token
instance = operations_feature_flags_client || create_operations_feature_flags_client!
instance.token
end
|
#feature_usage ⇒ Object
2239
2240
2241
|
# File 'app/models/project.rb', line 2239
def feature_usage
super.presence || build_feature_usage
end
|
#ff_merge_must_be_possible? ⇒ Boolean
3082
3083
3084
|
# File 'app/models/project.rb', line 3082
def ff_merge_must_be_possible?
self.merge_requests_ff_only_enabled || self.merge_requests_rebase_enabled
end
|
#find_or_create_design_management_repository ⇒ Object
1554
1555
1556
|
# File 'app/models/project.rb', line 1554
def find_or_create_design_management_repository
design_management_repository || create_design_management_repository
end
|
#find_or_initialize_integration(name) ⇒ Object
2089
2090
2091
2092
2093
2094
|
# File 'app/models/project.rb', line 2089
def find_or_initialize_integration(name)
return if disabled_integrations.include?(name)
return if Integration.available_integration_names(include_instance_specific: false).exclude?(name)
find_integration(integrations, name) || build_from_instance(name) || build_integration(name)
end
|
#find_or_initialize_integrations ⇒ Object
2075
2076
2077
2078
2079
2080
2081
|
# File 'app/models/project.rb', line 2075
def find_or_initialize_integrations
Integration
.available_integration_names(include_instance_specific: false)
.difference(disabled_integrations)
.map { find_or_initialize_integration(_1) }
.sort_by { |int| int.title.downcase }
end
|
#first_auto_devops_config ⇒ Object
1535
1536
1537
1538
1539
|
# File 'app/models/project.rb', line 1535
def first_auto_devops_config
return namespace.first_auto_devops_config if auto_devops&.enabled.nil?
{ scope: :project, status: auto_devops&.enabled || Feature.enabled?(:force_autodevops_on_by_default, self) }
end
|
#first_owner ⇒ Object
2175
2176
2177
2178
2179
2180
2181
2182
2183
|
# File 'app/models/project.rb', line 2175
def first_owner
obj = owner
if obj.respond_to?(:first_owner)
obj.first_owner
else
obj
end
end
|
#fork_source ⇒ Object
2247
2248
2249
2250
2251
|
# File 'app/models/project.rb', line 2247
def fork_source
return unless forked?
forked_from_project || fork_network&.root_project
end
|
#forked? ⇒ Boolean
2243
2244
2245
|
# File 'app/models/project.rb', line 2243
def forked?
fork_network && fork_network.root_project != self
end
|
#forked_from?(other_project) ⇒ Boolean
2401
2402
2403
|
# File 'app/models/project.rb', line 2401
def forked_from?(other_project)
forked? && forked_from_project == other_project
end
|
#forking_enabled? ⇒ Boolean
2461
2462
2463
|
# File 'app/models/project.rb', line 2461
def forking_enabled?
!!project_feature&.forking_enabled?
end
|
#forks_count ⇒ Object
rubocop: disable CodeReuse/ServiceClass
3004
3005
3006
3007
3008
3009
3010
3011
3012
|
# File 'app/models/project.rb', line 3004
def forks_count
BatchLoader.for(self).batch do |projects, loader|
fork_count_per_project = ::Projects::BatchForksCountService.new(projects).refresh_cache_and_retrieve_data
fork_count_per_project.each do |project, count|
loader.call(project, count)
end
end
end
|
#full_path_before_last_save ⇒ Object
2994
2995
2996
|
# File 'app/models/project.rb', line 2994
def full_path_before_last_save
File.join(namespace.full_path, path_before_last_save)
end
|
#full_path_slug ⇒ Object
2777
2778
2779
|
# File 'app/models/project.rb', line 2777
def full_path_slug
Gitlab::Utils.slugify(full_path.to_s)
end
|
#get_issue(issue_id, current_user) ⇒ Object
2029
2030
2031
2032
2033
2034
2035
2036
2037
|
# File 'app/models/project.rb', line 2029
def get_issue(issue_id, current_user)
issue = IssuesFinder.new(current_user, project_id: id).find_by(iid: issue_id) if issues_enabled?
if issue
issue
elsif external_issue_tracker
ExternalIssue.new(issue_id, self)
end
end
|
#git_garbage_collect_worker_klass ⇒ Object
#git_objects_poolable? ⇒ Boolean
Git objects are only poolable when the project is or has:
-
Hashed storage -> The object pool will have a remote to its members, using relative paths.
If the repository path changes we would have to update the remote.
-
not private -> The visibility level or repository access level has to be greater than private
to prevent fetching objects that might not exist
-
Repository -> Else the disk path will be empty, and there’s nothing to pool
#git_transfer_in_progress? ⇒ Boolean
3087
3088
3089
3090
3091
|
# File 'app/models/project.rb', line 3087
def git_transfer_in_progress?
GL_REPOSITORY_TYPES.any? do |type|
reference_counter(type: type).value > 0
end
end
|
#gitea_import? ⇒ Boolean
1811
1812
1813
|
# File 'app/models/project.rb', line 1811
def gitea_import?
import_type == 'gitea'
end
|
#github_enterprise_import? ⇒ Boolean
1827
1828
1829
1830
|
# File 'app/models/project.rb', line 1827
def github_enterprise_import?
github_import? &&
URI.parse(safe_import_url).host != URI.parse(Octokit::Default::API_ENDPOINT).host
end
|
#github_import? ⇒ Boolean
1815
1816
1817
|
# File 'app/models/project.rb', line 1815
def github_import?
import_type == 'github'
end
|
#gitlab_deploy_token ⇒ Object
3142
3143
3144
3145
3146
|
# File 'app/models/project.rb', line 3142
def gitlab_deploy_token
strong_memoize(:gitlab_deploy_token) do
deploy_tokens.gitlab_deploy_token || group&.gitlab_deploy_token
end
end
|
#gitlab_project_import? ⇒ Boolean
1803
1804
1805
|
# File 'app/models/project.rb', line 1803
def gitlab_project_import?
import_type == 'gitlab_project'
end
|
#gitlab_project_migration? ⇒ Boolean
1807
1808
1809
|
# File 'app/models/project.rb', line 1807
def gitlab_project_migration?
import_type == 'gitlab_project_migration'
end
|
#glql_load_on_click_feature_flag_enabled? ⇒ Boolean
3518
3519
3520
|
# File 'app/models/project.rb', line 3518
def glql_load_on_click_feature_flag_enabled?
group&.glql_load_on_click_feature_flag_enabled? || Feature.enabled?(:glql_load_on_click, self, type: :ops)
end
|
#group_group_links ⇒ Object
3553
3554
3555
|
# File 'app/models/project.rb', line 3553
def group_group_links
group&.shared_with_group_links_of_ancestors_and_self || GroupGroupLink.none
end
|
#group_protected_branches ⇒ Object
3267
3268
3269
3270
3271
|
# File 'app/models/project.rb', line 3267
def group_protected_branches
return root_namespace.protected_branches if root_namespace.is_a?(Group)
ProtectedBranch.none
end
|
#group_runners ⇒ Object
2523
2524
2525
|
# File 'app/models/project.rb', line 2523
def group_runners
@group_runners ||= group_runners_enabled? ? Ci::Runner.belonging_to_parent_groups_of_project(self.id) : Ci::Runner.none
end
|
#group_runners_enabled? ⇒ Boolean
3439
3440
3441
3442
3443
|
# File 'app/models/project.rb', line 3439
def group_runners_enabled?
return false unless ci_cd_settings
ci_cd_settings.group_runners_enabled?
end
|
#has_active_hooks?(hooks_scope = :push_hooks) ⇒ Boolean
2221
2222
2223
2224
2225
2226
2227
2228
2229
|
# File 'app/models/project.rb', line 2221
def has_active_hooks?(hooks_scope = :push_hooks)
@has_active_hooks ||= {}
return @has_active_hooks[hooks_scope] if @has_active_hooks.key?(hooks_scope)
@has_active_hooks[hooks_scope] = hooks.hooks_for(hooks_scope).any? ||
SystemHook.hooks_for(hooks_scope).any? ||
Gitlab::FileHook.any?
end
|
#has_active_integrations?(hooks_scope = :push_hooks) ⇒ Boolean
2231
2232
2233
2234
2235
2236
2237
|
# File 'app/models/project.rb', line 2231
def has_active_integrations?(hooks_scope = :push_hooks)
@has_active_integrations ||= {}
return @has_active_integrations[hooks_scope] if @has_active_integrations.key?(hooks_scope)
@has_active_integrations[hooks_scope] = integrations.public_send(hooks_scope).any? end
|
#has_auto_devops_implicitly_disabled? ⇒ Boolean
1525
1526
1527
1528
1529
|
# File 'app/models/project.rb', line 1525
def has_auto_devops_implicitly_disabled?
auto_devops_config = first_auto_devops_config
auto_devops_config[:scope] != :project && !auto_devops_config[:status]
end
|
#has_auto_devops_implicitly_enabled? ⇒ Boolean
1519
1520
1521
1522
1523
|
# File 'app/models/project.rb', line 1519
def has_auto_devops_implicitly_enabled?
auto_devops_config = first_auto_devops_config
auto_devops_config[:scope] != :project && auto_devops_config[:status]
end
|
#has_ci? ⇒ Boolean
2781
2782
2783
|
# File 'app/models/project.rb', line 2781
def has_ci?
has_ci_config_file? || auto_devops_enabled?
end
|
#has_ci_config_file? ⇒ Boolean
2785
2786
2787
2788
2789
|
# File 'app/models/project.rb', line 2785
def has_ci_config_file?
strong_memoize(:has_ci_config_file) do
ci_config_for('HEAD').present?
end
end
|
#has_container_registry_protected_tag_rules?(action:, access_level:) ⇒ Boolean
3685
3686
3687
3688
3689
|
# File 'app/models/project.rb', line 3685
def has_container_registry_protected_tag_rules?(action:, access_level:)
strong_memoize_with(:has_container_registry_protected_tag_rules, action, access_level) do
container_registry_protection_tag_rules.for_actions_and_access([action], access_level).exists?
end
end
|
1585
1586
1587
1588
1589
1590
|
# File 'app/models/project.rb', line 1585
def has_container_registry_tags?
return @images if defined?(@images)
@images = container_repositories.to_a.any?(&:has_tags?) ||
has_root_container_repository_tags?
end
|
#has_pool_repository? ⇒ Boolean
3222
3223
3224
|
# File 'app/models/project.rb', line 3222
def has_pool_repository?
pool_repository.present?
end
|
#has_remote_mirror? ⇒ Boolean
1844
1845
1846
|
# File 'app/models/project.rb', line 1844
def has_remote_mirror?
remote_mirror_available? && remote_mirrors.enabled.exists?
end
|
#has_wiki? ⇒ Boolean
2063
2064
2065
|
# File 'app/models/project.rb', line 2063
def has_wiki?
wiki_enabled? || has_external_wiki?
end
|
#hashed_storage?(feature) ⇒ Boolean
Check if Hashed Storage is enabled for the project with at least informed feature rolled out
3022
3023
3024
3025
3026
|
# File 'app/models/project.rb', line 3022
def hashed_storage?(feature)
raise ArgumentError, _("Invalid feature") unless HASHED_STORAGE_FEATURES.include?(feature)
self.storage_version && self.storage_version >= HASHED_STORAGE_FEATURES[feature]
end
|
#hook_attrs(backward: true) ⇒ Object
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
|
# File 'app/models/project.rb', line 2332
def hook_attrs(backward: true)
attrs = {
id: id,
name: name,
description: description,
web_url: web_url,
avatar_url: avatar_url(only_path: false),
git_ssh_url: ssh_url_to_repo,
git_http_url: http_url_to_repo,
namespace: namespace.name,
visibility_level: visibility_level,
path_with_namespace: full_path,
default_branch: default_branch,
ci_config_path: ci_config_path
}
if backward
attrs.merge!({
homepage: web_url,
url: url_to_repo,
ssh_url: ssh_url_to_repo,
http_url: http_url_to_repo
})
end
attrs
end
|
#human_import_status_name ⇒ Object
1662
1663
1664
|
# File 'app/models/project.rb', line 1662
def human_import_status_name
import_state&.human_status_name || 'none'
end
|
#human_merge_method ⇒ Object
3046
3047
3048
3049
3050
3051
3052
|
# File 'app/models/project.rb', line 3046
def human_merge_method
if merge_method == :ff
'Fast-forward'
else
merge_method.to_s.humanize
end
end
|
#import? ⇒ Boolean
1785
1786
1787
|
# File 'app/models/project.rb', line 1785
def import?
external_import? || forked? || gitlab_project_import? || jira_import? || gitlab_project_migration? || Gitlab::ImportSources.template?(import_type)
end
|
#import_checksums ⇒ Object
1654
1655
1656
|
# File 'app/models/project.rb', line 1654
def import_checksums
import_state&.checksums || {}
end
|
#import_export_shared ⇒ Object
2696
2697
2698
|
# File 'app/models/project.rb', line 2696
def import_export_shared
@import_export_shared ||= Gitlab::ImportExport::Shared.new(self)
end
|
#import_export_upload_by_user(user) ⇒ Object
2761
2762
2763
|
# File 'app/models/project.rb', line 2761
def import_export_upload_by_user(user)
import_export_uploads.find_by(user_id: user.id)
end
|
#import_failed? ⇒ Boolean
1426
1427
1428
|
# File 'app/models/project.rb', line 1426
def import_failed?
!!import_state&.failed?
end
|
#import_finished? ⇒ Boolean
1430
1431
1432
|
# File 'app/models/project.rb', line 1430
def import_finished?
!!import_state&.finished?
end
|
#import_in_progress? ⇒ Boolean
1422
1423
1424
|
# File 'app/models/project.rb', line 1422
def import_in_progress?
!!import_state&.in_progress?
end
|
#import_scheduled? ⇒ Boolean
1414
1415
1416
|
# File 'app/models/project.rb', line 1414
def import_scheduled?
!!import_state&.scheduled?
end
|
#import_started? ⇒ Boolean
1418
1419
1420
|
# File 'app/models/project.rb', line 1418
def import_started?
!!import_state&.started?
end
|
#import_status ⇒ Object
1650
1651
1652
|
# File 'app/models/project.rb', line 1650
def import_status
import_state&.status || 'none'
end
|
#import_url=(value) ⇒ Object
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
|
# File 'app/models/project.rb', line 1741
def import_url=(value)
if Gitlab::UrlSanitizer.valid?(value)
import_url = Gitlab::UrlSanitizer.new(value)
super(import_url.sanitized_url)
credentials = import_url.credentials.to_h.transform_values { |value| CGI.unescape(value.to_s) }
build_or_assign_import_data(credentials: credentials)
else
super(value)
end
end
|
#in_fork_network_of?(other_project) ⇒ Boolean
2405
2406
2407
2408
2409
|
# File 'app/models/project.rb', line 2405
def in_fork_network_of?(other_project)
return false if fork_network.nil? || other_project.fork_network.nil?
fork_network == other_project.fork_network
end
|
#inactive? ⇒ Boolean
3544
3545
3546
3547
|
# File 'app/models/project.rb', line 3544
def inactive?
(statistics || build_statistics).storage_size > ::Gitlab::CurrentSettings.inactive_projects_min_size_mb.megabytes &&
last_activity_at < ::Gitlab::CurrentSettings.inactive_projects_send_warning_email_after_months.months.ago
end
|
#initial_push_to_default_branch_allowed_for_developer? ⇒ Boolean
3287
3288
3289
3290
3291
|
# File 'app/models/project.rb', line 3287
def initial_push_to_default_branch_allowed_for_developer?
branch_protection = Gitlab::Access::DefaultBranchProtection.new(self.namespace.default_branch_protection_settings)
branch_protection.developer_can_push? || branch_protection.developer_can_initial_push?
end
|
#instance_runner_running_jobs_count ⇒ Object
#invalidate_personal_projects_count_of_owner ⇒ Object
1383
1384
1385
1386
1387
1388
|
# File 'app/models/project.rb', line 1383
def invalidate_personal_projects_count_of_owner
return unless personal?
return unless namespace.owner
namespace.owner.invalidate_personal_projects_count
end
|
#issue_exists?(issue_id) ⇒ Boolean
2039
2040
2041
|
# File 'app/models/project.rb', line 2039
def issue_exists?(issue_id)
get_issue(issue_id)
end
|
#issues_enabled? ⇒ Boolean
2465
2466
2467
|
# File 'app/models/project.rb', line 2465
def issues_enabled?
!!project_feature&.issues_enabled?
end
|
#items_for(entity) ⇒ Object
2136
2137
2138
2139
2140
2141
2142
2143
|
# File 'app/models/project.rb', line 2136
def items_for(entity)
case entity
when 'issue' then
issues
when 'merge_request' then
merge_requests
end
end
|
#jenkins_integration_active? ⇒ Boolean
1367
1368
1369
|
# File 'app/models/project.rb', line 1367
def jenkins_integration_active?
!!jenkins_integration&.active?
end
|
#jira_import? ⇒ Boolean
1799
1800
1801
|
# File 'app/models/project.rb', line 1799
def jira_import?
import_type == 'jira' && latest_jira_import.present?
end
|
#jira_import_status ⇒ Object
1658
1659
1660
|
# File 'app/models/project.rb', line 1658
def jira_import_status
latest_jira_import&.status || 'initial'
end
|
#jira_subscription_exists? ⇒ Boolean
3259
3260
3261
|
# File 'app/models/project.rb', line 3259
def jira_subscription_exists?
JiraConnectSubscription.for_project(self).exists?
end
|
#keep_latest_artifact? ⇒ Boolean
3433
3434
3435
3436
3437
|
# File 'app/models/project.rb', line 3433
def keep_latest_artifact?
return false unless ci_cd_settings
ci_cd_settings.keep_latest_artifact?
end
|
#keep_latest_artifacts_available? ⇒ Boolean
3427
3428
3429
3430
3431
|
# File 'app/models/project.rb', line 3427
def keep_latest_artifacts_available?
return false unless ci_cd_settings
ci_cd_settings.keep_latest_artifacts_available?
end
|
#last_activity ⇒ Object
2021
2022
2023
|
# File 'app/models/project.rb', line 2021
def last_activity
last_event
end
|
#latest_jira_import ⇒ Object
3310
3311
3312
|
# File 'app/models/project.rb', line 3310
def latest_jira_import
jira_imports.last
end
|
#latest_pipeline(ref = default_branch, sha = nil, source = nil) ⇒ Object
1635
1636
1637
|
# File 'app/models/project.rb', line 1635
def latest_pipeline(ref = default_branch, sha = nil, source = nil)
latest_pipelines(ref: ref, sha: sha, source: source).take
end
|
#latest_pipelines(ref: default_branch, sha: nil, limit: nil, source: nil) ⇒ Object
1615
1616
1617
1618
1619
1620
1621
|
# File 'app/models/project.rb', line 1615
def latest_pipelines(ref: default_branch, sha: nil, limit: nil, source: nil)
ref = ref.presence || default_branch
sha ||= commit(ref)&.sha
return ci_pipelines.none unless sha
ci_pipelines.newest_first(ref: ref, sha: sha, limit: limit, source: source)
end
|
#latest_successful_build_for_ref(job_name, ref = default_branch) ⇒ Object
ref can’t be HEAD, can only be branch/tag name
1593
1594
1595
1596
1597
1598
1599
1600
|
# File 'app/models/project.rb', line 1593
def latest_successful_build_for_ref(job_name, ref = default_branch)
return unless ref
latest_pipeline = ci_pipelines.latest_successful_for_ref(ref)
return unless latest_pipeline
latest_pipeline.build_with_artifacts_in_self_and_project_descendants(job_name)
end
|
#latest_successful_build_for_ref!(job_name, ref = default_branch) ⇒ Object
1611
1612
1613
|
# File 'app/models/project.rb', line 1611
def latest_successful_build_for_ref!(job_name, ref = default_branch)
latest_successful_build_for_ref(job_name, ref) || raise(ActiveRecord::RecordNotFound, "Couldn't find job #{job_name}")
end
|
#latest_successful_build_for_sha(job_name, sha) ⇒ Object
1602
1603
1604
1605
1606
1607
1608
1609
|
# File 'app/models/project.rb', line 1602
def latest_successful_build_for_sha(job_name, sha)
return unless sha
latest_pipeline = ci_pipelines.latest_successful_for_sha(sha)
return unless latest_pipeline
latest_pipeline.build_with_artifacts_in_self_and_project_descendants(job_name)
end
|
#latest_successful_pipeline_for(ref = nil) ⇒ Object
2437
2438
2439
2440
2441
2442
2443
|
# File 'app/models/project.rb', line 2437
def latest_successful_pipeline_for(ref = nil)
if ref && ref != default_branch
ci_pipelines.latest_successful_for_ref(ref)
else
latest_successful_pipeline_for_default_branch
end
end
|
#latest_successful_pipeline_for_default_branch ⇒ Object
2428
2429
2430
2431
2432
2433
2434
2435
|
# File 'app/models/project.rb', line 2428
def latest_successful_pipeline_for_default_branch
if defined?(@latest_successful_pipeline_for_default_branch)
return @latest_successful_pipeline_for_default_branch
end
@latest_successful_pipeline_for_default_branch =
ci_pipelines.latest_successful_for_ref(default_branch)
end
|
#latest_unscheduled_pipeline(ref = default_branch, sha = nil) ⇒ Object
1631
1632
1633
|
# File 'app/models/project.rb', line 1631
def latest_unscheduled_pipeline(ref = default_branch, sha = nil)
latest_unscheduled_pipelines(ref: ref, sha: sha).take
end
|
#latest_unscheduled_pipelines(ref: default_branch, sha: nil) ⇒ Object
1623
1624
1625
1626
1627
1628
1629
|
# File 'app/models/project.rb', line 1623
def latest_unscheduled_pipelines(ref: default_branch, sha: nil)
ref = ref.presence || default_branch
sha ||= commit(ref)&.sha
return ci_pipelines.none unless sha
ci_pipelines.newest_without_schedules(ref: ref, sha: sha)
end
|
#leave_pool_repository ⇒ Object
3192
3193
3194
3195
3196
3197
3198
3199
|
# File 'app/models/project.rb', line 3192
def leave_pool_repository
return if pool_repository.blank?
pool_repository.unlink_repository(repository, disconnect: !pending_delete?)
update_column(:pool_repository_id, nil)
end
|
#legacy_storage? ⇒ Boolean
rubocop: enable CodeReuse/ServiceClass
3015
3016
3017
|
# File 'app/models/project.rb', line 3015
def legacy_storage?
[nil, 0].include?(self.storage_version)
end
|
#lfs_enabled? ⇒ Boolean
Also known as:
lfs_enabled
1503
1504
1505
1506
1507
|
# File 'app/models/project.rb', line 1503
def lfs_enabled?
return namespace.lfs_enabled? if self[:lfs_enabled].nil?
self[:lfs_enabled] && Gitlab.config.lfs.enabled
end
|
#lfs_file_locks_changed_epoch ⇒ Object
3650
3651
3652
|
# File 'app/models/project.rb', line 3650
def lfs_file_locks_changed_epoch
get_epoch_from(lfs_file_locks_changed_epoch_cache_key)
end
|
#lfs_objects_for_repository_types(*types) ⇒ Object
2257
2258
2259
2260
2261
|
# File 'app/models/project.rb', line 2257
def lfs_objects_for_repository_types(*types)
LfsObject
.joins(:lfs_objects_projects)
.where(lfs_objects_projects: { project: self, repository_type: types })
end
|
#lfs_objects_oids(oids: []) ⇒ Object
2263
2264
2265
|
# File 'app/models/project.rb', line 2263
def lfs_objects_oids(oids: [])
oids(lfs_objects, oids: oids)
end
|
#lfs_objects_oids_from_fork_source(oids: []) ⇒ Object
2267
2268
2269
2270
2271
|
# File 'app/models/project.rb', line 2267
def lfs_objects_oids_from_fork_source(oids: [])
return [] unless forked?
oids(fork_source.lfs_objects, oids: oids)
end
|
#licensed_ai_features_available? ⇒ Boolean
3692
3693
3694
|
# File 'app/models/project.rb', line 3692
def licensed_ai_features_available?
false
end
|
#licensed_feature_available?(_feature) ⇒ Boolean
Overridden in EE::Project
3130
3131
3132
|
# File 'app/models/project.rb', line 3130
def licensed_feature_available?(_feature)
false
end
|
#licensed_features ⇒ Object
3134
3135
3136
|
# File 'app/models/project.rb', line 3134
def licensed_features
[]
end
|
#limited_protected_branches(limit) ⇒ Object
3263
3264
3265
|
# File 'app/models/project.rb', line 3263
def limited_protected_branches(limit)
protected_branches.limit(limit)
end
|
#link_pool_repository ⇒ Object
3215
3216
3217
3218
3219
3220
|
# File 'app/models/project.rb', line 3215
def link_pool_repository
return unless pool_repository
return if pool_repository.shard_name != repository.shard
pool_repository.link_repository(repository)
end
|
#log_import_activity(job_id, type: :import) ⇒ Object
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
|
# File 'app/models/project.rb', line 1691
def log_import_activity(job_id, type: :import)
job_type = type.to_s.capitalize
if job_id
use_primary = ::Gitlab::Database::LoadBalancing::SessionMap.current(load_balancer).use_primary?
Gitlab::AppLogger.info("#{job_type} job scheduled for #{full_path} with job ID #{job_id} (primary: #{use_primary}).")
else
Gitlab::AppLogger.error("#{job_type} job failed to create for #{full_path}.")
end
end
|
#mark_pages_onboarding_complete ⇒ Object
2626
2627
2628
|
# File 'app/models/project.rb', line 2626
def mark_pages_onboarding_complete
ensure_pages_metadatum.update!(onboarding_complete: true)
end
|
#mark_remote_mirrors_for_removal ⇒ Object
1866
1867
1868
|
# File 'app/models/project.rb', line 1866
def mark_remote_mirrors_for_removal
remote_mirrors.each(&:mark_for_delete_if_blank_url)
end
|
#mark_stuck_remote_mirrors_as_failed! ⇒ Object
1858
1859
1860
1861
1862
1863
1864
|
# File 'app/models/project.rb', line 1858
def mark_stuck_remote_mirrors_as_failed!
remote_mirrors.stuck.update_all(
update_status: :failed,
last_error: _('The remote mirror took to long to complete.'),
last_update_at: Time.current
)
end
|
#markdown_placeholders_feature_flag_enabled? ⇒ Boolean
3522
3523
3524
|
# File 'app/models/project.rb', line 3522
def markdown_placeholders_feature_flag_enabled?
group&.markdown_placeholders_feature_flag_enabled? || Feature.enabled?(:markdown_placeholders, self, type: :gitlab_com_derisk)
end
|
#marked_for_deletion_on ⇒ Object
190
|
# File 'app/models/project.rb', line 190
alias_attribute :marked_for_deletion_on, :marked_for_deletion_at
|
#max_attachment_size ⇒ Object
3174
3175
3176
|
# File 'app/models/project.rb', line 3174
def max_attachment_size
Gitlab::CurrentSettings.max_attachment_size.megabytes.to_i
end
|
#member(user) ⇒ Object
2361
2362
2363
2364
2365
2366
2367
|
# File 'app/models/project.rb', line 2361
def member(user)
if project_members.loaded?
project_members.find { |member| member.user_id == user.id }
else
project_members.find_by(user_id: user)
end
end
|
#members_among(users) ⇒ Object
Filters ‘users` to return only authorized users of the project
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
|
# File 'app/models/project.rb', line 2379
def members_among(users)
if users.is_a?(ActiveRecord::Relation) && !users.loaded?
authorized_users.merge(users)
else
return [] if users.empty?
user_ids = authorized_users.where(users: { id: users.map(&:id) }).pluck(:id)
users.select { |user| user_ids.include?(user.id) }
end
end
|
#membership_locked? ⇒ Boolean
2370
2371
2372
|
# File 'app/models/project.rb', line 2370
def membership_locked?
false
end
|
#merge_base_commit(first_commit_id, second_commit_id) ⇒ Object
1639
1640
1641
1642
1643
1644
|
# File 'app/models/project.rb', line 1639
def merge_base_commit(first_commit_id, second_commit_id)
strong_memoize(:"merge_base_commit_#{first_commit_id}_#{second_commit_id}") do
sha = repository.merge_base(first_commit_id, second_commit_id)
commit_by(oid: sha) if sha
end
end
|
#merge_commit_template_or_default ⇒ Object
3478
3479
3480
|
# File 'app/models/project.rb', line 3478
def merge_commit_template_or_default
merge_commit_template.presence || DEFAULT_MERGE_COMMIT_TEMPLATE
end
|
#merge_commit_template_or_default=(value) ⇒ Object
3482
3483
3484
3485
3486
3487
3488
3489
|
# File 'app/models/project.rb', line 3482
def merge_commit_template_or_default=(value)
project_setting.merge_commit_template =
if value.blank? || value.delete("\r") == DEFAULT_MERGE_COMMIT_TEMPLATE
nil
else
value
end
end
|
#merge_method ⇒ Object
3054
3055
3056
3057
3058
3059
3060
3061
3062
|
# File 'app/models/project.rb', line 3054
def merge_method
if self.merge_requests_ff_only_enabled
:ff
elsif self.merge_requests_rebase_enabled
:rebase_merge
else
:merge
end
end
|
#merge_method=(method) ⇒ Object
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
|
# File 'app/models/project.rb', line 3068
def merge_method=(method)
case method.to_s
when "ff"
self.merge_requests_ff_only_enabled = true
self.merge_requests_rebase_enabled = true
when "rebase_merge"
self.merge_requests_ff_only_enabled = false
self.merge_requests_rebase_enabled = true
when "merge"
self.merge_requests_ff_only_enabled = false
self.merge_requests_rebase_enabled = false
end
end
|
#merge_requests_allowing_push_to_user(user) ⇒ Object
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
|
# File 'app/models/project.rb', line 3105
def merge_requests_allowing_push_to_user(user)
return MergeRequest.none unless user
developer_access_exists = user.project_authorizations
.where('access_level >= ? ', Gitlab::Access::DEVELOPER)
.where('project_authorizations.project_id = merge_requests.target_project_id')
.limit(1)
.select(1)
merge_requests_allowing_collaboration.where('EXISTS (?)', developer_access_exists)
end
|
#merge_requests_enabled? ⇒ Boolean
2457
2458
2459
|
# File 'app/models/project.rb', line 2457
def merge_requests_enabled?
!!project_feature&.merge_requests_enabled?
end
|
#merge_trains_enabled? ⇒ Boolean
3646
3647
3648
|
# File 'app/models/project.rb', line 3646
def merge_trains_enabled?
false
end
|
#mr_can_target_upstream? ⇒ Boolean
2982
2983
2984
2985
2986
2987
2988
|
# File 'app/models/project.rb', line 2982
def mr_can_target_upstream?
forked_from_project &&
forked_from_project.merge_requests_enabled? &&
forked_from_project.visibility_level_value <= visibility_level_value
end
|
#multiple_issue_boards_available? ⇒ Boolean
2990
2991
2992
|
# File 'app/models/project.rb', line 2990
def multiple_issue_boards_available?
true
end
|
#new_issuable_address(author, address_type) ⇒ Object
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
|
# File 'app/models/project.rb', line 2002
def new_issuable_address(author, address_type)
return unless Gitlab::Email::IncomingEmail.supports_issue_creation? && author
return unless %w[issue merge_request].include?(address_type)
author.ensure_incoming_email_token!
suffix = address_type.dasherize
Gitlab::Email::IncomingEmail.reply_address("#{full_path_slug}-#{project_id}-#{author.incoming_email_token}-#{suffix}")
end
|
#no_import? ⇒ Boolean
1410
1411
1412
|
# File 'app/models/project.rb', line 1410
def no_import?
!!import_state&.no_import?
end
|
#notify_project_import_complete? ⇒ Boolean
1793
1794
1795
1796
1797
|
# File 'app/models/project.rb', line 1793
def notify_project_import_complete?
return false if import_type.nil? || mirror? || forked?
gitea_import? || github_import? || bitbucket_import? || bitbucket_server_import?
end
|
#on_demand_dast_available? ⇒ Boolean
3636
3637
3638
|
# File 'app/models/project.rb', line 3636
def on_demand_dast_available?
false
end
|
#open_issues_count(current_user = nil) ⇒ Object
rubocop: disable CodeReuse/ServiceClass
#open_merge_requests_count(_current_user = nil) ⇒ Object
rubocop: disable CodeReuse/ServiceClass
2564
2565
2566
2567
2568
2569
2570
|
# File 'app/models/project.rb', line 2564
def open_merge_requests_count(_current_user = nil)
BatchLoader.for(self).batch do |projects, loader|
::Projects::BatchOpenMergeRequestsCountService.new(projects)
.refresh_cache_and_retrieve_data
.each { |project, count| loader.call(project, count) }
end
end
|
#operations_enabled? ⇒ Boolean
2498
2499
2500
|
# File 'app/models/project.rb', line 2498
def operations_enabled?
!!project_feature&.operations_enabled?
end
|
#origin_merge_requests ⇒ Object
2411
2412
2413
|
# File 'app/models/project.rb', line 2411
def origin_merge_requests
merge_requests.where(source_project_id: self.id)
end
|
#override_pipeline_variables_allowed?(access_level, user) ⇒ Boolean
3415
3416
3417
3418
3419
|
# File 'app/models/project.rb', line 3415
def override_pipeline_variables_allowed?(access_level, user)
return false unless ci_cd_settings
ci_cd_settings.override_pipeline_variables_allowed?(access_level, user)
end
|
#owner ⇒ Object
rubocop: enable CodeReuse/ServiceClass
2155
2156
2157
2158
2159
2160
|
# File 'app/models/project.rb', line 2155
def owner
group || namespace.try(:owner)
end
|
#owner_entity ⇒ Object
1341
1342
1343
|
# File 'app/models/project.rb', line 1341
def owner_entity
self
end
|
#owner_entity_name ⇒ Object
1345
1346
1347
|
# File 'app/models/project.rb', line 1345
def owner_entity_name
:project
end
|
#owners ⇒ Object
2168
2169
2170
2171
2172
2173
|
# File 'app/models/project.rb', line 2168
def owners
team.owners
end
|
#packages_cleanup_policy ⇒ Object
1531
1532
1533
|
# File 'app/models/project.rb', line 1531
def packages_cleanup_policy
super || build_packages_cleanup_policy
end
|
#packages_policy_subject ⇒ Object
#pages_access_control_forced_by_ancestor? ⇒ Boolean
2492
2493
2494
2495
2496
|
# File 'app/models/project.rb', line 2492
def pages_access_control_forced_by_ancestor?
return true if ::Gitlab::Pages.access_control_is_forced?
namespace.pages_access_control_forced_by_self_or_ancestor?
end
|
#pages_deployed? ⇒ Boolean
2599
2600
2601
|
# File 'app/models/project.rb', line 2599
def pages_deployed?
active_pages_deployments.exists?
end
|
#pages_domain_present?(domain_url) ⇒ Boolean
3575
3576
3577
|
# File 'app/models/project.rb', line 3575
def pages_domain_present?(domain_url)
pages_url == domain_url || pages_domains.any? { |domain| domain.url == domain_url }
end
|
#pages_enabled? ⇒ Boolean
2469
2470
2471
|
# File 'app/models/project.rb', line 2469
def pages_enabled?
!!project_feature&.pages_enabled?
end
|
#pages_hostname(options = nil) ⇒ Object
3671
3672
3673
|
# File 'app/models/project.rb', line 3671
def pages_hostname(options = nil)
pages_url_builder(options).hostname
end
|
#pages_https_only ⇒ Object
1914
1915
1916
1917
1918
|
# File 'app/models/project.rb', line 1914
def pages_https_only
return false unless Gitlab.config.pages.external_https || Gitlab.config.pages.custom_domain_mode == 'https'
super
end
|
#pages_https_only? ⇒ Boolean
1920
1921
1922
1923
1924
|
# File 'app/models/project.rb', line 1920
def pages_https_only?
return false unless Gitlab.config.pages.external_https || Gitlab.config.pages.custom_domain_mode == 'https'
super
end
|
#pages_show_onboarding? ⇒ Boolean
2603
2604
2605
|
# File 'app/models/project.rb', line 2603
def pages_show_onboarding?
!(pages_metadatum&.onboarding_complete || pages_deployed?)
end
|
#pages_unique_domain_enabled? ⇒ Boolean
2607
2608
2609
|
# File 'app/models/project.rb', line 2607
def pages_unique_domain_enabled?
project_setting.pages_unique_domain_enabled
end
|
#pages_url(options = nil) ⇒ Object
3667
3668
3669
|
# File 'app/models/project.rb', line 3667
def pages_url(options = nil)
pages_url_builder(options).pages_url
end
|
#pages_url_builder(options = nil) ⇒ Object
3679
3680
3681
3682
3683
|
# File 'app/models/project.rb', line 3679
def pages_url_builder(options = nil)
strong_memoize_with(:pages_url_builder, options) do
Gitlab::Pages::UrlBuilder.new(self, options)
end
end
|
#pages_variables ⇒ Object
2851
2852
2853
2854
2855
2856
2857
2858
2859
|
# File 'app/models/project.rb', line 2851
def pages_variables
Gitlab::Ci::Variables::Collection.new.tap do |variables|
break unless pages_enabled?
variables
.append(key: 'CI_PAGES_DOMAIN', value: Gitlab.config.pages.host)
.append(key: 'CI_PAGES_HOSTNAME', value: pages_hostname)
end
end
|
#parent_changed? ⇒ Boolean
2971
2972
2973
|
# File 'app/models/project.rb', line 2971
def parent_changed?
namespace_id_changed?
end
|
#parent_organization_match ⇒ Object
1942
1943
1944
1945
1946
1947
|
# File 'app/models/project.rb', line 1942
def parent_organization_match
return unless parent
return if parent.organization_id == organization_id
errors.add(:organization_id, _("must match the parent organization's ID"))
end
|
#path_availability ⇒ Object
3605
3606
3607
3608
3609
3610
3611
3612
|
# File 'app/models/project.rb', line 3605
def path_availability
base, _, host = path.partition('.')
return unless host == Gitlab.config.pages&.dig('host')
return unless ProjectSetting.where(pages_unique_domain: base).exists?
errors.add(:path, s_('Project|already in use'))
end
|
#personal? ⇒ Boolean
2273
2274
2275
|
# File 'app/models/project.rb', line 2273
def personal?
!group
end
|
#personal_namespace_holder?(user) ⇒ Boolean
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
|
# File 'app/models/project.rb', line 1371
def personal_namespace_holder?(user)
return false unless personal?
return false unless user
namespace.owner == user
end
|
#placeholder_reference_store ⇒ Object
3658
3659
3660
3661
3662
3663
3664
3665
|
# File 'app/models/project.rb', line 3658
def placeholder_reference_store
return unless import_state
::Import::PlaceholderReferences::Store.new(
import_source: import_type,
import_uid: import_state.id
)
end
|
#predefined_ci_server_variables ⇒ Object
rubocop: enable Metrics/AbcSize
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
|
# File 'app/models/project.rb', line 2832
def predefined_ci_server_variables
Gitlab::Ci::Variables::Collection.new
.append(key: 'CI', value: 'true')
.append(key: 'GITLAB_CI', value: 'true')
.append(key: 'CI_SERVER_FQDN', value: Gitlab.config.gitlab.server_fqdn)
.append(key: 'CI_SERVER_URL', value: Gitlab.config.gitlab.url)
.append(key: 'CI_SERVER_HOST', value: Gitlab.config.gitlab.host)
.append(key: 'CI_SERVER_PORT', value: Gitlab.config.gitlab.port.to_s)
.append(key: 'CI_SERVER_PROTOCOL', value: Gitlab.config.gitlab.protocol)
.append(key: 'CI_SERVER_SHELL_SSH_HOST', value: Gitlab.config.gitlab_shell.ssh_host.to_s)
.append(key: 'CI_SERVER_SHELL_SSH_PORT', value: Gitlab.config.gitlab_shell.ssh_port.to_s)
.append(key: 'CI_SERVER_NAME', value: 'GitLab')
.append(key: 'CI_SERVER_VERSION', value: Gitlab::VERSION)
.append(key: 'CI_SERVER_VERSION_MAJOR', value: Gitlab.version_info.major.to_s)
.append(key: 'CI_SERVER_VERSION_MINOR', value: Gitlab.version_info.minor.to_s)
.append(key: 'CI_SERVER_VERSION_PATCH', value: Gitlab.version_info.patch.to_s)
.append(key: 'CI_SERVER_REVISION', value: Gitlab.revision)
end
|
#predefined_project_variables ⇒ Object
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
|
# File 'app/models/project.rb', line 2806
def predefined_project_variables
strong_memoize(:predefined_project_variables) do
Gitlab::Ci::Variables::Collection.new
.append(key: 'GITLAB_FEATURES', value: licensed_features.join(','))
.append(key: 'CI_PROJECT_ID', value: id.to_s)
.append(key: 'CI_PROJECT_NAME', value: path)
.append(key: 'CI_PROJECT_TITLE', value: title)
.append(key: 'CI_PROJECT_DESCRIPTION', value: description)
.append(key: 'CI_PROJECT_TOPICS', value: topic_list.first(20).join(',').downcase)
.append(key: 'CI_PROJECT_PATH', value: full_path)
.append(key: 'CI_PROJECT_PATH_SLUG', value: full_path_slug)
.append(key: 'CI_PROJECT_NAMESPACE', value: namespace.full_path)
.append(key: 'CI_PROJECT_NAMESPACE_SLUG', value: Gitlab::Utils.slugify(namespace.full_path))
.append(key: 'CI_PROJECT_NAMESPACE_ID', value: namespace.id.to_s)
.append(key: 'CI_PROJECT_ROOT_NAMESPACE', value: namespace.root_ancestor.path)
.append(key: 'CI_PROJECT_URL', value: web_url)
.append(key: 'CI_PROJECT_VISIBILITY', value: Gitlab::VisibilityLevel.string_level(visibility_level))
.append(key: 'CI_PROJECT_REPOSITORY_LANGUAGES', value: repository_languages.map(&:name).join(',').downcase)
.append(key: 'CI_PROJECT_CLASSIFICATION_LABEL', value: external_authorization_classification_label)
.append(key: 'CI_DEFAULT_BRANCH', value: default_branch)
.append(key: 'CI_DEFAULT_BRANCH_SLUG', value: Gitlab::Utils.slugify(default_branch.to_s))
.append(key: 'CI_CONFIG_PATH', value: ci_config_path_or_default)
end
end
|
#predefined_variables ⇒ Object
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
|
# File 'app/models/project.rb', line 2791
def predefined_variables
strong_memoize(:predefined_variables) do
Gitlab::Ci::Variables::Collection.new
.concat(predefined_ci_server_variables)
.concat(predefined_project_variables)
.concat(pages_variables)
.concat(container_registry_variables)
.concat(dependency_proxy_variables)
.concat(auto_devops_variables)
.concat(api_variables)
.concat(ci_template_variables)
end
end
|
#preload_protected_branches ⇒ Object
1468
1469
1470
1471
1472
1473
|
# File 'app/models/project.rb', line 1468
def preload_protected_branches
ActiveRecord::Associations::Preloader.new(
records: [all_protected_branches, protected_branches].flatten,
associations: [:push_access_levels, :merge_access_levels]
).call
end
|
#private_pages? ⇒ Boolean
2485
2486
2487
2488
2489
2490
|
# File 'app/models/project.rb', line 2485
def private_pages?
return false unless Gitlab.config.pages.access_control
pages_access_control_forced_by_ancestor? ||
!!project_feature&.private_pages?
end
|
#project_id ⇒ Object
2025
2026
2027
|
# File 'app/models/project.rb', line 2025
def project_id
self.id
end
|
#project_setting ⇒ Object
1390
1391
1392
|
# File 'app/models/project.rb', line 1390
def project_setting
super.presence || build_project_setting
end
|
#protected_for?(ref) ⇒ Boolean
#public_pages? ⇒ Boolean
2481
2482
2483
|
# File 'app/models/project.rb', line 2481
def public_pages?
!private_pages?
end
|
#public_path_for_source_path(path, commit_sha) ⇒ Object
2964
2965
2966
2967
2968
2969
|
# File 'app/models/project.rb', line 2964
def public_path_for_source_path(path, commit_sha)
map = route_map_for(commit_sha)
return unless map
map.public_path_for_source_path(path)
end
|
#readme_url ⇒ Object
1995
1996
1997
1998
1999
2000
|
# File 'app/models/project.rb', line 1995
def readme_url
readme_path = repository.readme_path
if readme_path
Gitlab::Routing.url_helpers.project_blob_url(self, File.join(default_branch, readme_path))
end
end
|
#reconcile_shared_runners_setting! ⇒ Object
1953
1954
1955
1956
1957
|
# File 'app/models/project.rb', line 1953
def reconcile_shared_runners_setting!
if shared_runners_setting_conflicting_with_group?
self.shared_runners_enabled = false
end
end
|
#refresh_lfs_file_locks_changed_epoch ⇒ Object
3654
3655
3656
|
# File 'app/models/project.rb', line 3654
def refresh_lfs_file_locks_changed_epoch
refresh_epoch_cache(lfs_file_locks_changed_epoch_cache_key)
end
|
#refreshing_build_artifacts_size? ⇒ Boolean
3549
3550
3551
|
# File 'app/models/project.rb', line 3549
def refreshing_build_artifacts_size?
build_artifacts_size_refresh&.started?
end
|
#regeneration_in_progress?(user) ⇒ Boolean
2740
2741
2742
|
# File 'app/models/project.rb', line 2740
def regeneration_in_progress?(user)
(export_enqueued?(user) || export_in_progress?(user)) && export_file_exists?(user)
end
|
3339
3340
3341
3342
3343
3344
3345
|
# File 'app/models/project.rb', line 3339
def related_group_ids
ids = invited_group_ids
ids += group.self_and_ancestors_ids if group
ids
end
|
#remote_mirror_available? ⇒ Boolean
1870
1871
1872
1873
|
# File 'app/models/project.rb', line 1870
def remote_mirror_available?
remote_mirror_available_overridden ||
::Gitlab::CurrentSettings.mirror_available
end
|
#remove_export_for_user(user) ⇒ Object
2753
2754
2755
2756
2757
2758
2759
|
# File 'app/models/project.rb', line 2753
def remove_export_for_user(user)
import_export_upload = import_export_upload_by_user(user)
return unless import_export_upload&.export_file_exists?
import_export_upload.remove_export_file!
import_export_upload.save unless import_export_upload.destroyed?
end
|
#remove_exports ⇒ Object
2744
2745
2746
2747
2748
2749
2750
2751
|
# File 'app/models/project.rb', line 2744
def remove_exports
import_export_uploads.each do |import_export_upload|
next unless import_export_upload.export_file_exists?
import_export_upload.remove_export_file!
import_export_upload.save unless import_export_upload.destroyed?
end
end
|
#remove_import_data ⇒ Object
This method is overridden in EE::Project model
1712
1713
1714
|
# File 'app/models/project.rb', line 1712
def remove_import_data
import_data&.destroy
end
|
#remove_private_deploy_keys ⇒ Object
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
|
# File 'app/models/project.rb', line 2611
def remove_private_deploy_keys
exclude_keys_linked_to_other_projects = <<-SQL
NOT EXISTS (
SELECT 1
FROM deploy_keys_projects dkp2
WHERE dkp2.deploy_key_id = deploy_keys_projects.deploy_key_id
AND dkp2.project_id != deploy_keys_projects.project_id
)
SQL
deploy_keys.where(public: false)
.where(exclude_keys_linked_to_other_projects)
.delete_all
end
|
#renamed? ⇒ Boolean
3042
3043
3044
|
# File 'app/models/project.rb', line 3042
def renamed?
persisted? && path_changed?
end
|
#repository ⇒ Object
1550
1551
1552
|
# File 'app/models/project.rb', line 1550
def repository
@repository ||= Gitlab::GlRepository::PROJECT.repository_for(self)
end
|
3614
3615
3616
|
# File 'app/models/project.rb', line 3614
def repository_object_format
project_repository&.object_format
end
|
#reset_cache_and_import_attrs ⇒ Object
1702
1703
1704
1705
1706
1707
1708
1709
|
# File 'app/models/project.rb', line 1702
def reset_cache_and_import_attrs
run_after_commit do
ProjectCacheWorker.perform_async(self.id)
end
import_state.update(last_error: nil)
remove_import_data
end
|
#reset_counters_and_iids ⇒ Object
2649
2650
2651
2652
2653
2654
2655
2656
|
# File 'app/models/project.rb', line 2649
def reset_counters_and_iids
InternalId.flush_records!(project: self)
update_project_counter_caches
end
|
#resource_parent ⇒ Object
1359
1360
1361
|
# File 'app/models/project.rb', line 1359
def resource_parent
self
end
|
#restrict_user_defined_variables? ⇒ Boolean
3409
3410
3411
3412
3413
|
# File 'app/models/project.rb', line 3409
def restrict_user_defined_variables?
return false unless ci_cd_settings
ci_cd_settings.restrict_user_defined_variables?
end
|
#root_group ⇒ Object
3322
3323
3324
3325
3326
|
# File 'app/models/project.rb', line 3322
def root_group
return if personal?
root_namespace
end
|
#root_namespace ⇒ Object
3314
3315
3316
3317
3318
3319
3320
|
# File 'app/models/project.rb', line 3314
def root_namespace
if namespace.has_parent?
namespace.root_ancestor
else
namespace
end
end
|
#route_map_for(commit_sha) ⇒ Object
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
|
# File 'app/models/project.rb', line 2950
def route_map_for(commit_sha)
@route_maps_by_commit ||= Hash.new do |h, sha|
h[sha] = begin
data = repository.route_map_for(sha)
Gitlab::RouteMap.new(data) if data
rescue Gitlab::RouteMap::FormatError
nil
end
end
@route_maps_by_commit[commit_sha]
end
|
#runners_token ⇒ Object
2593
2594
2595
2596
2597
|
# File 'app/models/project.rb', line 2593
def runners_token
return unless namespace.allow_runner_registration_token?
ensure_runners_token!
end
|
#safe_import_url(masked: true) ⇒ String
Returns sanitized import URL.
1736
1737
1738
1739
|
# File 'app/models/project.rb', line 1736
def safe_import_url(masked: true)
url = Gitlab::UrlSanitizer.new(unsafe_import_url)
masked ? url.masked_url : url.sanitized_url
end
|
#saved? ⇒ Boolean
1646
1647
1648
|
# File 'app/models/project.rb', line 1646
def saved?
id && persisted?
end
|
#security_training_available? ⇒ Boolean
3557
3558
3559
|
# File 'app/models/project.rb', line 3557
def security_training_available?
licensed_feature_available?(:security_training)
end
|
#self_and_ancestors_ids ⇒ Object
1487
1488
1489
1490
1491
|
# File 'app/models/project.rb', line 1487
def self_and_ancestors_ids
strong_memoize(:self_and_ancestors_ids) do
ancestors.pluck(:id) + [id]
end
end
|
#self_deletion_in_progress? ⇒ Boolean
3506
3507
3508
|
# File 'app/models/project.rb', line 3506
def self_deletion_in_progress?
pending_delete?
end
|
#self_deletion_in_progress_or_hidden? ⇒ Boolean
3510
3511
3512
|
# File 'app/models/project.rb', line 3510
def self_deletion_in_progress_or_hidden?
self_deletion_in_progress? || hidden?
end
|
#self_or_ancestors_archived? ⇒ Boolean
3034
3035
3036
|
# File 'app/models/project.rb', line 3034
def self_or_ancestors_archived?
self_archived? || namespace.self_or_ancestors_archived?
end
|
#self_or_root_group_ids ⇒ Object
for projects that are part of user namespace, return project.
3329
3330
3331
3332
3333
3334
3335
3336
3337
|
# File 'app/models/project.rb', line 3329
def self_or_root_group_ids
if group
root_group = root_namespace
else
project = self
end
[project&.id, root_group&.id]
end
|
#send_move_instructions(old_path_with_namespace) ⇒ Object
rubocop: disable CodeReuse/ServiceClass
2146
2147
2148
2149
2150
2151
2152
|
# File 'app/models/project.rb', line 2146
def send_move_instructions(old_path_with_namespace)
run_after_commit do
NotificationService.new.project_was_moved(self, old_path_with_namespace)
end
end
|
#set_project_feature_defaults ⇒ Object
Remove along with ProjectFeaturesCompatibility module
1350
1351
1352
1353
1354
1355
1356
1357
|
# File 'app/models/project.rb', line 1350
def set_project_feature_defaults
self.class.project_features_defaults.each do |attr, value|
next unless @init_attributes[:"#{attr}_enabled"].nil? && @init_attributes[:"#{attr}_access_level"].nil?
public_send("#{attr}_enabled=", value) end
end
|
#share_with_group_enabled? ⇒ Boolean
2424
2425
2426
|
# File 'app/models/project.rb', line 2424
def share_with_group_enabled?
!parent.share_with_group_lock?
end
|
#shared_runners ⇒ Object
2515
2516
2517
|
# File 'app/models/project.rb', line 2515
def shared_runners
@shared_runners ||= shared_runners_enabled? ? Ci::Runner.instance_type : Ci::Runner.none
end
|
#shared_runners_available? ⇒ Boolean
2511
2512
2513
|
# File 'app/models/project.rb', line 2511
def shared_runners_available?
shared_runners_enabled?
end
|
#shared_runners_setting_conflicting_with_group? ⇒ Boolean
1949
1950
1951
|
# File 'app/models/project.rb', line 1949
def shared_runners_setting_conflicting_with_group?
shared_runners_enabled && group&.shared_runners_setting == Namespace::SR_DISABLED_AND_UNOVERRIDABLE
end
|
#should_validate_visibility_level? ⇒ Boolean
1893
1894
1895
|
# File 'app/models/project.rb', line 1893
def should_validate_visibility_level?
new_record? || changes.has_key?(:visibility_level)
end
|
#show_default_award_emojis? ⇒ Boolean
1394
1395
1396
|
# File 'app/models/project.rb', line 1394
def show_default_award_emojis?
!!project_setting&.show_default_award_emojis?
end
|
#snippets_enabled? ⇒ Boolean
2477
2478
2479
|
# File 'app/models/project.rb', line 2477
def snippets_enabled?
!!project_feature&.snippets_enabled?
end
|
#snippets_visible?(user = nil) ⇒ Boolean
3170
3171
3172
|
# File 'app/models/project.rb', line 3170
def snippets_visible?(user = nil)
Ability.allowed?(user, :read_snippet, self)
end
|
#squash_commit_template_or_default ⇒ Object
3491
3492
3493
|
# File 'app/models/project.rb', line 3491
def squash_commit_template_or_default
squash_commit_template.presence || DEFAULT_SQUASH_COMMIT_TEMPLATE
end
|
#squash_commit_template_or_default=(value) ⇒ Object
3495
3496
3497
3498
3499
3500
3501
3502
|
# File 'app/models/project.rb', line 3495
def squash_commit_template_or_default=(value)
project_setting.squash_commit_template =
if value.blank? || value.delete("\r") == DEFAULT_SQUASH_COMMIT_TEMPLATE
nil
else
value
end
end
|
#storage ⇒ Object
3157
3158
3159
3160
3161
3162
3163
3164
|
# File 'app/models/project.rb', line 3157
def storage
@storage ||=
if hashed_storage?(:repository)
Storage::Hashed.new(self)
else
Storage::LegacyProject.new(self)
end
end
|
#storage_upgradable? ⇒ Boolean
3166
3167
3168
|
# File 'app/models/project.rb', line 3166
def storage_upgradable?
storage_version != LATEST_STORAGE_VERSION
end
|
#storage_version=(value) ⇒ Object
3093
3094
3095
3096
3097
|
# File 'app/models/project.rb', line 3093
def storage_version=(value)
super
@storage = nil if storage_version_changed?
end
|
#suggested_reviewers_available? ⇒ Boolean
3585
3586
3587
|
# File 'app/models/project.rb', line 3585
def suggested_reviewers_available?
false
end
|
#supports_lock_on_merge? ⇒ Boolean
3601
3602
3603
|
# File 'app/models/project.rb', line 3601
def supports_lock_on_merge?
group&.supports_lock_on_merge? || ::Feature.enabled?(:enforce_locked_labels_on_merge, self, type: :ops)
end
|
#supports_saved_replies? ⇒ Boolean
3641
3642
3643
|
# File 'app/models/project.rb', line 3641
def supports_saved_replies?
false
end
|
#swap_pool_repository! ⇒ Object
After repository is moved from shard to shard, disconnect it from the previous object pool and connect to the new pool
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
|
# File 'app/models/project.rb', line 3202
def swap_pool_repository!
return unless repository_exists?
old_pool_repository = pool_repository
return if old_pool_repository.blank?
return if pool_repository_shard_matches_repository?(old_pool_repository)
new_pool_repository = PoolRepository.by_disk_path_and_shard_name(old_pool_repository.disk_path, repository_storage).take!
update!(pool_repository: new_pool_repository)
old_pool_repository.unlink_repository(repository, disconnect: !pending_delete?)
end
|
#team ⇒ Object
1546
1547
1548
|
# File 'app/models/project.rb', line 1546
def team
@team ||= ProjectTeam.new(self)
end
|
#template_source? ⇒ Boolean
3255
3256
3257
|
# File 'app/models/project.rb', line 3255
def template_source?
false
end
|
#to_human_reference(from = nil) ⇒ Object
1987
1988
1989
1990
1991
1992
1993
|
# File 'app/models/project.rb', line 1987
def to_human_reference(from = nil)
if cross_namespace_reference?(from)
name_with_namespace
elsif cross_project_reference?(from)
name
end
end
|
#to_param ⇒ Object
1959
1960
1961
1962
1963
1964
1965
|
# File 'app/models/project.rb', line 1959
def to_param
if persisted? && errors.include?(:path)
path_was
else
path
end
end
|
#to_reference(from = nil, full: false) ⇒ Object
Produce a valid reference (see Referable#to_reference)
NB: For projects, all references are ‘full’ - i.e. they all include the full_path, rather than just the project name. For this reason, we ignore the value of ‘full:` passed to this method, which is part of the Referable interface.
1973
1974
1975
1976
|
# File 'app/models/project.rb', line 1973
def to_reference(from = nil, full: false)
base = to_reference_base(from, full: true)
"#{base}#{self.class.reference_postfix}"
end
|
#to_reference_base(from = nil, full: false, absolute_path: false) ⇒ Object
‘from` argument can be a Namespace or Project.
1979
1980
1981
1982
1983
1984
1985
|
# File 'app/models/project.rb', line 1979
def to_reference_base(from = nil, full: false, absolute_path: false)
if full || cross_namespace_reference?(from)
absolute_path ? "/#{full_path}" : full_path
elsif cross_project_reference?(from)
path
end
end
|
#toggle_ci_cd_settings!(settings_attribute) ⇒ Object
3138
3139
3140
|
# File 'app/models/project.rb', line 3138
def toggle_ci_cd_settings!(settings_attribute)
ci_cd_settings.toggle!(settings_attribute)
end
|
#track_project_repository ⇒ Object
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
|
# File 'app/models/project.rb', line 2305
def track_project_repository
(project_repository || build_project_repository).tap do |proj_repo|
attributes = { shard_name: repository_storage, disk_path: disk_path }
object_format = repository.object_format
attributes[:object_format] = object_format if object_format.present?
proj_repo.update!(**attributes)
end
cleanup
end
|
#triggered_hooks(hooks_scope, data) ⇒ Object
rubocop: enable CodeReuse/ServiceClass
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
|
# File 'app/models/project.rb', line 2194
def triggered_hooks(hooks_scope, data)
triggered = ::Projects::TriggeredHooks.new(hooks_scope, data)
if hooks_scope == :resource_access_token_hooks &&
data[:interval] != :seven_days &&
!self.extended_prat_expiry_webhooks_execute?
triggered
else
triggered.add_hooks(hooks)
end
end
|
#unsafe_import_url ⇒ String
WARNING - This method returns sensitive userinfo credentials of the import URL. Use ‘#safe_import_url` instead unless it is necessary to include sensitive credentials.
Builds an import URL including userinfo credentials from the ‘import_url` attribute and the encrypted `ProjectImportData#credentials`.
1766
1767
1768
1769
1770
1771
1772
1773
1774
|
# File 'app/models/project.rb', line 1766
def unsafe_import_url
if import_data && import_url.present?
Gitlab::UrlSanitizer.new(import_url, credentials: import_data.credentials).full_url
else
import_url
end
rescue StandardError
import_url
end
|
#update_project_counter_caches ⇒ Object
#update_remote_mirrors ⇒ Object
1852
1853
1854
1855
1856
|
# File 'app/models/project.rb', line 1852
def update_remote_mirrors
return unless remote_mirror_available?
remote_mirrors.enabled.each(&:sync)
end
|
#updating_remote_mirror? ⇒ Boolean
1848
1849
1850
|
# File 'app/models/project.rb', line 1848
def updating_remote_mirror?
remote_mirrors.enabled.started.exists?
end
|
#uploads_sharding_key ⇒ Object
3675
3676
3677
|
# File 'app/models/project.rb', line 3675
def uploads_sharding_key
{ project_id: id }
end
|
#valid_lfs_oids(oids_to_check) ⇒ Object
2253
2254
2255
|
# File 'app/models/project.rb', line 2253
def valid_lfs_oids(oids_to_check)
lfs_objects.where(oid: oids_to_check).pluck(:oid)
end
|
#valid_runners_token?(token) ⇒ Boolean
2545
2546
2547
|
# File 'app/models/project.rb', line 2545
def valid_runners_token?(token)
self.runners_token && ActiveSupport::SecurityUtils.secure_compare(token, self.runners_token)
end
|
#validate_pages_https_only ⇒ Object
1926
1927
1928
1929
1930
1931
1932
|
# File 'app/models/project.rb', line 1926
def validate_pages_https_only
return unless pages_https_only?
unless pages_domains.all?(&:https?)
errors.add(:pages_https_only, _("cannot be enabled unless all domains have TLS certificates"))
end
end
|
#visibility_level_allowed?(level = self.visibility_level) ⇒ Boolean
2589
2590
2591
|
# File 'app/models/project.rb', line 2589
def visibility_level_allowed?(level = self.visibility_level)
visibility_level_allowed_as_fork?(level) && visibility_level_allowed_by_namespace?(level)
end
|
#visibility_level_allowed_as_fork ⇒ Object
1907
1908
1909
1910
1911
1912
|
# File 'app/models/project.rb', line 1907
def visibility_level_allowed_as_fork
return if visibility_level_allowed_as_fork?
level_name = Gitlab::VisibilityLevel.level_name(self.visibility_level).downcase
self.errors.add(:visibility_level, _("%{level_name} is not allowed since the fork source project has lower visibility.") % { level_name: level_name })
end
|
#visibility_level_allowed_as_fork?(level = self.visibility_level) ⇒ Boolean
rubocop: enable CodeReuse/ServiceClass
2573
2574
2575
2576
2577
2578
2579
2580
|
# File 'app/models/project.rb', line 2573
def visibility_level_allowed_as_fork?(level = self.visibility_level)
return true unless forked?
original_project = fork_source
return true unless original_project
level <= original_project.visibility_level
end
|
#visibility_level_allowed_by_namespace ⇒ Object
1897
1898
1899
1900
1901
1902
1903
1904
1905
|
# File 'app/models/project.rb', line 1897
def visibility_level_allowed_by_namespace
return if visibility_level_allowed_by_namespace?
level_name = Gitlab::VisibilityLevel.level_name(self.visibility_level).downcase
namespace_visibility = group ? group.visibility_level : namespace.visibility_level
namespace_level_name = Gitlab::VisibilityLevel.level_name(namespace_visibility).downcase
self.errors.add(:visibility_level, _("%{level_name} is not allowed in a %{namespace_level_name} namespace.") % { level_name: level_name, namespace_level_name: namespace_level_name })
end
|
#visibility_level_allowed_by_namespace?(level = self.visibility_level) ⇒ Boolean
2582
2583
2584
2585
2586
2587
|
# File 'app/models/project.rb', line 2582
def visibility_level_allowed_by_namespace?(level = self.visibility_level)
return true unless group || namespace
return level <= group.visibility_level if group
level <= namespace.visibility_level
end
|
#visibility_level_field ⇒ Object
2390
2391
2392
|
# File 'app/models/project.rb', line 2390
def visibility_level_field
:visibility_level
end
|
#visible_group_links(for_user:) ⇒ Object
3454
3455
3456
3457
3458
3459
3460
3461
3462
|
# File 'app/models/project.rb', line 3454
def visible_group_links(for_user:)
user = for_user
links = project_group_links_with_preload
user.max_member_access_for_group_ids(links.map(&:group_id)) if user && links.any?
DeclarativePolicy.user_scope do
links.select { Ability.allowed?(user, :read_group, _1.group) }
end
end
|
#warn_about_potentially_unwanted_characters? ⇒ Boolean
1402
1403
1404
|
# File 'app/models/project.rb', line 1402
def warn_about_potentially_unwanted_characters?
!!project_setting&.warn_about_potentially_unwanted_characters?
end
|
#wiki_enabled? ⇒ Boolean
2453
2454
2455
|
# File 'app/models/project.rb', line 2453
def wiki_enabled?
!!project_feature&.wiki_enabled?
end
|
#work_item_tasks_on_boards_feature_flag_enabled? ⇒ Boolean
3514
3515
3516
|
# File 'app/models/project.rb', line 3514
def work_item_tasks_on_boards_feature_flag_enabled?
group&.work_item_tasks_on_boards_feature_flag_enabled? || Feature.enabled?(:work_item_tasks_on_boards, type: :wip)
end
|
#work_items_consolidated_list_enabled?(user = nil) ⇒ Boolean
3530
3531
3532
3533
3534
3535
3536
|
# File 'app/models/project.rb', line 3530
def work_items_consolidated_list_enabled?(user = nil)
return true if group&.work_items_consolidated_list_enabled?(user) || Feature.enabled?(:work_item_planning_view, type: :wip)
user.present? && Feature.enabled?(:work_items_consolidated_list_user, user)
end
|