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)
- 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::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
-
#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_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
-
#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_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_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
-
#continue_indented_text_feature_flag_enabled? ⇒ Boolean
-
#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
-
#enabled_group_deploy_keys ⇒ Object
-
#enforce_auth_checks_on_uploads? ⇒ Boolean
-
#enforced_runner_token_expiration_interval ⇒ Object
-
#enqueue_record_project_target_platforms ⇒ Object
-
#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_integration_feature_flag_enabled? ⇒ 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 ⇒ String
WARNING - This method returns sensitive userinfo credentials of the import URL.
-
#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
-
#job_token_policies_enabled? ⇒ 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
-
#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
-
#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
-
#object_pool_params ⇒ Object
-
#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.
-
#owners ⇒ Object
-
#package_already_taken?(package_name, package_version, package_type:) ⇒ Boolean
-
#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_loaded? ⇒ Boolean
-
#parent_organization_match ⇒ Object
-
#path_availability ⇒ Object
-
#personal? ⇒ Boolean
-
#personal_namespace_holder?(user) ⇒ Boolean
-
#placeholder_reference_store ⇒ Object
-
#predefined_ci_server_variables ⇒ Object
-
#predefined_project_variables ⇒ Object
-
#predefined_variables ⇒ Object
-
#preload_protected_branches ⇒ Object
-
#private_pages? ⇒ Boolean
-
#project_id ⇒ Object
-
#project_setting ⇒ Object
-
#prometheus_integration_active? ⇒ Boolean
-
#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
-
#restrict_user_defined_variables? ⇒ Boolean
-
#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_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.
-
#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_group ⇒ Object
-
#visibility_level_allowed_by_group?(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_status_feature_available? ⇒ Boolean
-
#work_items_alpha_feature_flag_enabled? ⇒ Boolean
-
#work_items_beta_feature_flag_enabled? ⇒ Boolean
-
#work_items_feature_flag_enabled? ⇒ Boolean
extended, request_cache, request_cache_key
extended, extensions, included, method_added, override, prepended, queue_verification, verify!
gitlab_config, gitlab_config_features
#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?, #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_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, #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_project_banner?, #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?, #route_loaded?
#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, declarative_enum, default_select_columns, id_in, id_not_in, iid_in, nullable_column?, pluck_primary_key, primary_key_in, #readable_by?, safe_ensure_unique, safe_find_or_create_by, safe_find_or_create_by!, #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.
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
|
# File 'app/models/project.rb', line 1277
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.
177
178
179
|
# File 'app/models/project.rb', line 177
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.
180
181
182
|
# File 'app/models/project.rb', line 180
def skip_disk_validation
@skip_disk_validation
end
|
#template_name ⇒ Object
Returns the value of attribute template_name.
178
179
180
|
# File 'app/models/project.rb', line 178
def template_name
@template_name
end
|
#topic_list ⇒ Object
3373
3374
3375
|
# File 'app/models/project.rb', line 3373
def topic_list
self.topics.map(&:name)
end
|
Class Method Details
.by_pages_enabled_unique_domain(domain) ⇒ Object
1263
1264
1265
1266
1267
1268
1269
1270
|
# File 'app/models/project.rb', line 1263
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
1211
1212
1213
1214
1215
|
# File 'app/models/project.rb', line 1211
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
1040
1041
1042
1043
1044
1045
1046
1047
1048
|
# File 'app/models/project.rb', line 1040
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
1012
1013
1014
|
# File 'app/models/project.rb', line 1012
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
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
|
# File 'app/models/project.rb', line 1065
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
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
|
# File 'app/models/project.rb', line 1232
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_ids ⇒ Object
1217
1218
1219
|
# File 'app/models/project.rb', line 1217
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))
1225
1226
1227
1228
1229
1230
|
# File 'app/models/project.rb', line 1225
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
1098
1099
1100
1101
1102
1103
1104
1105
1106
|
# File 'app/models/project.rb', line 1098
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
212
213
214
|
# File 'app/models/project.rb', line 212
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.
1198
1199
1200
1201
1202
1203
1204
|
# File 'app/models/project.rb', line 1198
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
1272
1273
1274
|
# File 'app/models/project.rb', line 1272
def project_namespace_for(id:)
find_by(id: id)&.project_namespace
end
|
.projects_user_can(projects, user, action) ⇒ Object
1059
1060
1061
1062
1063
|
# File 'app/models/project.rb', line 1059
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.
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
|
# File 'app/models/project.rb', line 1018
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),
Gitlab::VisibilityLevel.levels_for_user(user)
)
end
end
|
.reference_pattern ⇒ Object
rubocop:enable Metrics/CyclomaticComplexity
.reference_postfix ⇒ Object
1187
1188
1189
|
# File 'app/models/project.rb', line 1187
def reference_postfix
'>'
end
|
.reference_postfix_escaped ⇒ Object
1191
1192
1193
|
# File 'app/models/project.rb', line 1191
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.
1127
1128
1129
1130
1131
1132
1133
1134
1135
|
# File 'app/models/project.rb', line 1127
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
1137
1138
1139
|
# File 'app/models/project.rb', line 1137
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:
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
|
# File 'app/models/project.rb', line 1146
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
1206
1207
1208
1209
|
# File 'app/models/project.rb', line 1206
def trending
joins('INNER JOIN trending_projects ON projects.id = trending_projects.project_id')
.reorder('trending_projects.id ASC')
end
|
.visibility_levels ⇒ Object
.with_api_entity_associations ⇒ Object
990
991
992
|
# File 'app/models/project.rb', line 990
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
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
|
# File 'app/models/project.rb', line 998
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
994
995
996
|
# File 'app/models/project.rb', line 994
def self.with_web_entity_associations
preload(:project_feature, :route, :creator, group: :parent, namespace: [:route, :owner])
end
|
.without_integration(integration) ⇒ Object
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
|
# File 'app/models/project.rb', line 1247
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
1093
1094
1095
1096
|
# File 'app/models/project.rb', line 1093
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
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
|
# File 'app/models/project.rb', line 3148
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
2458
2459
2460
2461
2462
|
# File 'app/models/project.rb', line 2458
def active_runners
strong_memoize(:active_runners) do
all_available_runners.active
end
end
|
#active_webide_pipelines(user:) ⇒ Object
1395
1396
1397
|
# File 'app/models/project.rb', line 1395
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
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
|
# File 'app/models/project.rb', line 2602
def add_export_job(current_user:, after_export_strategy: nil, params: {})
check_project_export_limit!
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
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
|
# File 'app/models/project.rb', line 1605
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
3378
3379
3380
|
# File 'app/models/project.rb', line 3378
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
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
|
# File 'app/models/project.rb', line 2552
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
2318
2319
2320
2321
2322
|
# File 'app/models/project.rb', line 2318
def after_repository_change_head
ProjectCacheWorker.perform_async(self.id, [], %w[commit_count])
super
end
|
#all_available_runners ⇒ Object
2454
2455
2456
|
# File 'app/models/project.rb', line 2454
def all_available_runners
Ci::Runner.from_union([runners, group_runners, available_shared_runners])
end
|
#all_clusters ⇒ Object
2053
2054
2055
2056
2057
2058
|
# File 'app/models/project.rb', line 2053
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
1379
1380
1381
1382
1383
1384
1385
|
# File 'app/models/project.rb', line 1379
def all_pipelines
if builds_enabled?
super
else
super.external
end
end
|
#all_runners ⇒ Object
2450
2451
2452
|
# File 'app/models/project.rb', line 2450
def all_runners
Ci::Runner.from_union([runners, group_runners, shared_runners])
end
|
#allowed_to_share_with_group? ⇒ Boolean
2343
2344
2345
|
# File 'app/models/project.rb', line 2343
def allowed_to_share_with_group?
share_with_group_enabled?
end
|
#allows_multiple_merge_request_assignees? ⇒ Boolean
3559
3560
3561
|
# File 'app/models/project.rb', line 3559
def allows_multiple_merge_request_assignees?
false
end
|
#allows_multiple_merge_request_reviewers? ⇒ Boolean
3564
3565
3566
|
# File 'app/models/project.rb', line 3564
def allows_multiple_merge_request_reviewers?
false
end
|
#analytics_enabled? ⇒ Boolean
2396
2397
2398
|
# File 'app/models/project.rb', line 2396
def analytics_enabled?
!!project_feature&.analytics_enabled?
end
|
#ancestors(hierarchy_order: nil) ⇒ Object
Also known as:
group_and_ancestors
1427
1428
1429
|
# File 'app/models/project.rb', line 1427
def ancestors(hierarchy_order: nil)
group&.self_and_ancestors(hierarchy_order: hierarchy_order) || Group.none
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
1422
1423
1424
1425
|
# File 'app/models/project.rb', line 1422
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
1432
1433
1434
|
# File 'app/models/project.rb', line 1432
def ancestors_upto_ids(...)
ancestors_upto(...).pluck(:id)
end
|
#any_branch_allows_collaboration?(user) ⇒ Boolean
3030
3031
3032
|
# File 'app/models/project.rb', line 3030
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
1764
1765
1766
1767
1768
1769
1770
|
# File 'app/models/project.rb', line 1764
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
3062
3063
3064
|
# File 'app/models/project.rb', line 3062
def any_lfs_file_locks?
lfs_file_locks.any?
end
|
#any_online_runners?(&block) ⇒ Boolean
2464
2465
2466
|
# File 'app/models/project.rb', line 2464
def any_online_runners?(&block)
online_runners_with_tags.any?(&block)
end
|
#archived ⇒ Object
2946
2947
2948
|
# File 'app/models/project.rb', line 2946
def archived
super && !self_deletion_scheduled?
end
|
#auto_cancel_pending_pipelines? ⇒ Boolean
3067
3068
3069
|
# File 'app/models/project.rb', line 3067
def auto_cancel_pending_pipelines?
auto_cancel_pending_pipelines == 'enabled'
end
|
#auto_devops_enabled? ⇒ Boolean
1450
1451
1452
1453
1454
1455
1456
|
# File 'app/models/project.rb', line 1450
def auto_devops_enabled?
if auto_devops&.enabled.nil?
has_auto_devops_implicitly_enabled?
else
auto_devops.enabled?
end
end
|
#auto_devops_variables ⇒ Object
2862
2863
2864
2865
2866
|
# File 'app/models/project.rb', line 2862
def auto_devops_variables
return [] unless auto_devops_enabled?
(auto_devops || build_auto_devops)&.predefined_variables
end
|
#autoclose_referenced_issues ⇒ Object
1407
1408
1409
1410
1411
|
# File 'app/models/project.rb', line 1407
def autoclose_referenced_issues
return true if super.nil?
super
end
|
#available_shared_runners ⇒ Object
2442
2443
2444
|
# File 'app/models/project.rb', line 2442
def available_shared_runners
@available_shared_runners ||= shared_runners_available? ? shared_runners : Ci::Runner.none
end
|
#avatar_in_git ⇒ Object
2040
2041
2042
|
# File 'app/models/project.rb', line 2040
def avatar_in_git
repository.avatar
end
|
#avatar_url(**args) ⇒ Object
2044
2045
2046
|
# File 'app/models/project.rb', line 2044
def avatar_url(**args)
Gitlab::Routing.url_helpers.project_avatar_url(self) if avatar_in_git
end
|
#badges ⇒ Object
3013
3014
3015
3016
3017
|
# File 'app/models/project.rb', line 3013
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
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
|
# File 'app/models/project.rb', line 3221
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
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
|
# File 'app/models/project.rb', line 1593
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
1747
1748
1749
|
# File 'app/models/project.rb', line 1747
def bitbucket_import?
import_type == 'bitbucket'
end
|
#bitbucket_server_import? ⇒ Boolean
1751
1752
1753
|
# File 'app/models/project.rb', line 1751
def bitbucket_server_import?
import_type == 'bitbucket_server'
end
|
#bots ⇒ Object
2297
2298
2299
|
# File 'app/models/project.rb', line 2297
def bots
users.project_bot
end
|
#branch_allows_collaboration?(user, branch_name) ⇒ Boolean
3034
3035
3036
|
# File 'app/models/project.rb', line 3034
def branch_allows_collaboration?(user, branch_name)
fetch_branch_allows_collaboration(user, branch_name)
end
|
#build_commit_note(commit) ⇒ Object
1943
1944
1945
|
# File 'app/models/project.rb', line 1943
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
1704
1705
1706
1707
1708
1709
1710
1711
|
# File 'app/models/project.rb', line 1704
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
2372
2373
2374
|
# File 'app/models/project.rb', line 2372
def builds_enabled?
!!project_feature&.builds_enabled?
end
|
#can_create_custom_domains? ⇒ Boolean
3502
3503
3504
3505
3506
|
# File 'app/models/project.rb', line 3502
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_suggest_reviewers? ⇒ Boolean
3513
3514
3515
|
# File 'app/models/project.rb', line 3513
def can_suggest_reviewers?
false
end
|
#certificate_based_clusters_enabled? ⇒ Boolean
1304
1305
1306
|
# File 'app/models/project.rb', line 1304
def certificate_based_clusters_enabled?
!!namespace&.certificate_based_clusters_enabled?
end
|
#changing_shared_runners_enabled_is_allowed ⇒ Object
1860
1861
1862
1863
1864
1865
1866
|
# File 'app/models/project.rb', line 1860
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
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
|
# File 'app/models/project.rb', line 1803
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
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
|
# File 'app/models/project.rb', line 2213
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
3317
3318
3319
3320
3321
|
# File 'app/models/project.rb', line 3317
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
3285
3286
3287
|
# File 'app/models/project.rb', line 3285
def ci_config_for(sha)
repository.blob_data_at(sha, ci_config_path_or_default)
end
|
#ci_config_path=(value) ⇒ Object
1643
1644
1645
1646
|
# File 'app/models/project.rb', line 1643
def ci_config_path=(value)
super(value&.delete("\0"))
end
|
#ci_config_path_or_default ⇒ Object
3281
3282
3283
|
# File 'app/models/project.rb', line 3281
def ci_config_path_or_default
ci_config_path.presence || Ci::Pipeline::DEFAULT_CONFIG_PATH
end
|
#ci_forward_deployment_enabled? ⇒ Boolean
3305
3306
3307
3308
3309
|
# File 'app/models/project.rb', line 3305
def ci_forward_deployment_enabled?
return false unless ci_cd_settings
ci_cd_settings.forward_deployment_enabled?
end
|
#ci_forward_deployment_rollback_allowed? ⇒ Boolean
3311
3312
3313
3314
3315
|
# File 'app/models/project.rb', line 3311
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
3329
3330
3331
3332
3333
3334
3335
|
# File 'app/models/project.rb', line 3329
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
2036
2037
2038
|
# File 'app/models/project.rb', line 2036
def ci_integration
@ci_integration ||= ci_integrations.reorder(nil).find_by(active: true)
end
|
#ci_integrations ⇒ Object
rubocop: enable CodeReuse/ServiceClass
2032
2033
2034
|
# File 'app/models/project.rb', line 2032
def ci_integrations
integrations.where(category: :ci)
end
|
#ci_outbound_job_token_scope_enabled? ⇒ Boolean
3323
3324
3325
3326
3327
|
# File 'app/models/project.rb', line 3323
def ci_outbound_job_token_scope_enabled?
return false unless ci_cd_settings
ci_cd_settings.job_token_scope_enabled?
end
|
#ci_pipelines ⇒ Object
1387
1388
1389
1390
1391
1392
1393
|
# File 'app/models/project.rb', line 1387
def ci_pipelines
if builds_enabled?
super
else
super.external
end
end
|
#ci_push_repository_for_job_token_allowed? ⇒ Boolean
3349
3350
3351
3352
3353
|
# File 'app/models/project.rb', line 3349
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
2786
2787
2788
2789
2790
|
# File 'app/models/project.rb', line 2786
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!
1503
1504
1505
|
# File 'app/models/project.rb', line 1503
def cleanup
@repository = nil
end
|
#closest_setting(name) ⇒ Object
3160
3161
3162
3163
3164
3165
|
# File 'app/models/project.rb', line 3160
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
2049
2050
2051
|
# File 'app/models/project.rb', line 2049
def code
path
end
|
#commit_notes ⇒ Object
Used by Import/Export to export commit notes
1649
1650
1651
|
# File 'app/models/project.rb', line 1649
def commit_notes
notes.where(noteable_type: "Commit")
end
|
#container_registry_enabled? ⇒ Boolean
Also known as:
container_registry_enabled
2425
2426
2427
|
# File 'app/models/project.rb', line 2425
def container_registry_enabled?
!!project_feature&.container_registry_enabled?
end
|
#container_registry_url ⇒ Object
1509
1510
1511
1512
1513
|
# File 'app/models/project.rb', line 1509
def container_registry_url
if Gitlab.config.registry.enabled
"#{Gitlab.config.registry.host_port}/#{full_path.downcase}"
end
end
|
#container_registry_variables ⇒ Object
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
|
# File 'app/models/project.rb', line 2810
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
#continue_indented_text_feature_flag_enabled? ⇒ Boolean
3467
3468
3469
|
# File 'app/models/project.rb', line 3467
def continue_indented_text_feature_flag_enabled?
group&.continue_indented_text_feature_flag_enabled? || Feature.enabled?(:continue_indented_text, self, type: :wip)
end
|
#create_labels ⇒ Object
rubocop: disable CodeReuse/ServiceClass
2023
2024
2025
2026
2027
2028
2029
|
# File 'app/models/project.rb', line 2023
def create_labels
Label.templates.each do |label|
params = label.attributes.slice(*Label.column_names).except('id', 'template', 'created_at', 'updated_at', 'type')
Labels::FindOrCreateService.new(nil, self, params).execute(skip_authorization: true)
end
end
|
#create_repository(force: false, default_branch: nil, object_format: nil) ⇒ Object
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
|
# File 'app/models/project.rb', line 2242
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
3522
3523
3524
3525
3526
|
# File 'app/models/project.rb', line 3522
def crm_enabled?
return false unless group
group.crm_enabled?
end
|
#crm_group ⇒ Object
3528
3529
3530
3531
3532
|
# File 'app/models/project.rb', line 3528
def crm_group
return unless group
group.crm_group
end
|
#default_branch_or_main ⇒ Object
3275
3276
3277
3278
3279
|
# File 'app/models/project.rb', line 3275
def default_branch_or_main
return default_branch if default_branch
Gitlab::DefaultBranch.value(object: self)
end
|
#default_branch_protected? ⇒ Boolean
3203
3204
3205
3206
3207
|
# File 'app/models/project.rb', line 3203
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
2822
2823
2824
2825
2826
2827
2828
2829
|
# File 'app/models/project.rb', line 2822
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
1973
1974
1975
|
# File 'app/models/project.rb', line 1973
def default_issues_tracker?
!external_issue_tracker
end
|
#default_merge_request_target ⇒ Object
2893
2894
2895
2896
2897
2898
|
# File 'app/models/project.rb', line 2893
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
1399
1400
1401
1402
1403
1404
1405
|
# File 'app/models/project.rb', line 1399
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
3195
3196
3197
|
# File 'app/models/project.rb', line 3195
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
3199
3200
3201
|
# File 'app/models/project.rb', line 3199
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
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
|
# File 'app/models/project.rb', line 2850
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
2086
2087
2088
2089
2090
|
# File 'app/models/project.rb', line 2086
def deprecated_owner
group || namespace.try(:owner)
end
|
#design_management_enabled? ⇒ Boolean
LFS and hashed repository storage are required for using Design Management.
1481
1482
1483
|
# File 'app/models/project.rb', line 1481
def design_management_enabled?
lfs_enabled? && hashed_storage?(:repository)
end
|
#design_repository ⇒ Object
1497
1498
1499
1500
1501
|
# File 'app/models/project.rb', line 1497
def design_repository
strong_memoize(:design_repository) do
find_or_create_design_management_repository.repository
end
end
|
#destroy_deployment_by_id(deployment_id) ⇒ Object
3498
3499
3500
|
# File 'app/models/project.rb', line 3498
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.
2011
2012
2013
|
# File 'app/models/project.rb', line 2011
def disabled_integrations
%w[zentao]
end
|
#drop_visibility_level! ⇒ Object
3167
3168
3169
3170
3171
3172
3173
3174
3175
|
# File 'app/models/project.rb', line 3167
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
1436
1437
1438
1439
|
# File 'app/models/project.rb', line 1436
def emails_disabled?
!emails_enabled?
end
|
#enable_ci ⇒ Object
2430
2431
2432
|
# File 'app/models/project.rb', line 2430
def enable_ci
project_feature.update_attribute(:builds_access_level, ProjectFeature::ENABLED)
end
|
#enabled_group_deploy_keys ⇒ Object
3289
3290
3291
3292
3293
|
# File 'app/models/project.rb', line 3289
def enabled_group_deploy_keys
return GroupDeployKey.none unless group
GroupDeployKey.for_groups(group.self_and_ancestors_ids)
end
|
#enforce_auth_checks_on_uploads? ⇒ Boolean
1343
1344
1345
|
# File 'app/models/project.rb', line 1343
def enforce_auth_checks_on_uploads?
!!project_setting&.enforce_auth_checks_on_uploads?
end
|
#enforced_runner_token_expiration_interval ⇒ Object
3396
3397
3398
3399
3400
3401
3402
3403
3404
|
# File 'app/models/project.rb', line 3396
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_repository ⇒ Object
2338
2339
2340
|
# File 'app/models/project.rb', line 2338
def ensure_repository
create_repository(force: true) unless repository_exists?
end
|
#environments_for_scope(scope) ⇒ Object
3215
3216
3217
3218
3219
|
# File 'app/models/project.rb', line 3215
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
2110
2111
2112
2113
2114
2115
|
# File 'app/models/project.rb', line 2110
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
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
|
# File 'app/models/project.rb', line 2134
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.
2202
2203
2204
2205
2206
2207
2208
2209
2210
|
# File 'app/models/project.rb', line 2202
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
2690
2691
2692
|
# File 'app/models/project.rb', line 2690
def export_archive_exists?(user)
import_export_upload_by_user(user)&.export_archive_exists?
end
|
#export_enqueued?(user) ⇒ Boolean
2649
2650
2651
2652
2653
|
# File 'app/models/project.rb', line 2649
def export_enqueued?(user)
strong_memoize(:export_enqueued) do
::Projects::ExportJobFinder.new(self, user, { status: :queued }).execute.present?
end
end
|
#export_failed?(user) ⇒ Boolean
2655
2656
2657
2658
2659
|
# File 'app/models/project.rb', line 2655
def export_failed?(user)
strong_memoize(:export_failed) do
::Projects::ExportJobFinder.new(self, user, { status: :failed }).execute.present?
end
end
|
#export_file(user) ⇒ Object
2694
2695
2696
|
# File 'app/models/project.rb', line 2694
def export_file(user)
import_export_upload_by_user(user)&.export_file
end
|
#export_file_exists?(user) ⇒ Boolean
2686
2687
2688
|
# File 'app/models/project.rb', line 2686
def export_file_exists?(user)
import_export_upload_by_user(user)&.export_file_exists?
end
|
#export_in_progress?(user) ⇒ Boolean
2643
2644
2645
2646
2647
|
# File 'app/models/project.rb', line 2643
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
2621
2622
2623
2624
2625
|
# File 'app/models/project.rb', line 2621
def export_path
return unless namespace.present? || hashed_storage?(:repository)
import_export_shared.archive_path
end
|
#export_status(user) ⇒ Object
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
|
# File 'app/models/project.rb', line 2627
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
1351
1352
1353
|
# File 'app/models/project.rb', line 1351
def extended_prat_expiry_webhooks_execute?
!!project_setting&.extended_prat_expiry_webhooks_execute?
end
|
#external_authorization_classification_label ⇒ Object
#external_import? ⇒ Boolean
1717
1718
1719
|
# File 'app/models/project.rb', line 1717
def external_import?
import_url.present?
end
|
#external_issue_reference_pattern ⇒ Object
1969
1970
1971
|
# File 'app/models/project.rb', line 1969
def external_issue_reference_pattern
external_issue_tracker.reference_pattern(only_long: issues_enabled?)
end
|
#external_issue_tracker ⇒ Object
1977
1978
1979
1980
1981
1982
1983
|
# File 'app/models/project.rb', line 1977
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
1985
1986
1987
|
# File 'app/models/project.rb', line 1985
def external_references_supported?
external_issue_tracker&.support_cross_reference?
end
|
#external_wiki ⇒ Object
1993
1994
1995
1996
1997
1998
1999
|
# File 'app/models/project.rb', line 1993
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
2368
2369
2370
|
# File 'app/models/project.rb', line 2368
def feature_available?(feature, user = nil)
!!project_feature&.feature_available?(feature, user)
end
|
#feature_flags_client_token ⇒ Object
3295
3296
3297
3298
|
# File 'app/models/project.rb', line 3295
def feature_flags_client_token
instance = operations_feature_flags_client || create_operations_feature_flags_client!
instance.token
end
|
#feature_usage ⇒ Object
2163
2164
2165
|
# File 'app/models/project.rb', line 2163
def feature_usage
super.presence || build_feature_usage
end
|
#ff_merge_must_be_possible? ⇒ Boolean
2996
2997
2998
|
# File 'app/models/project.rb', line 2996
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
1493
1494
1495
|
# File 'app/models/project.rb', line 1493
def find_or_create_design_management_repository
design_management_repository || create_design_management_repository
end
|
#find_or_initialize_integration(name) ⇒ Object
2015
2016
2017
2018
2019
2020
|
# File 'app/models/project.rb', line 2015
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
2001
2002
2003
2004
2005
2006
2007
|
# File 'app/models/project.rb', line 2001
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
1474
1475
1476
1477
1478
|
# File 'app/models/project.rb', line 1474
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
2099
2100
2101
2102
2103
2104
2105
2106
2107
|
# File 'app/models/project.rb', line 2099
def first_owner
obj = owner
if obj.respond_to?(:first_owner)
obj.first_owner
else
obj
end
end
|
#fork_source ⇒ Object
2171
2172
2173
2174
2175
|
# File 'app/models/project.rb', line 2171
def fork_source
return unless forked?
forked_from_project || fork_network&.root_project
end
|
#forked? ⇒ Boolean
2167
2168
2169
|
# File 'app/models/project.rb', line 2167
def forked?
fork_network && fork_network.root_project != self
end
|
#forked_from?(other_project) ⇒ Boolean
2324
2325
2326
|
# File 'app/models/project.rb', line 2324
def forked_from?(other_project)
forked? && forked_from_project == other_project
end
|
#forking_enabled? ⇒ Boolean
2384
2385
2386
|
# File 'app/models/project.rb', line 2384
def forking_enabled?
!!project_feature&.forking_enabled?
end
|
#forks_count ⇒ Object
rubocop: disable CodeReuse/ServiceClass
2922
2923
2924
2925
2926
2927
2928
2929
2930
|
# File 'app/models/project.rb', line 2922
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
2912
2913
2914
|
# File 'app/models/project.rb', line 2912
def full_path_before_last_save
File.join(namespace.full_path, path_before_last_save)
end
|
#full_path_slug ⇒ Object
2698
2699
2700
|
# File 'app/models/project.rb', line 2698
def full_path_slug
Gitlab::Utils.slugify(full_path.to_s)
end
|
#get_issue(issue_id, current_user) ⇒ Object
1955
1956
1957
1958
1959
1960
1961
1962
1963
|
# File 'app/models/project.rb', line 1955
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
3001
3002
3003
3004
3005
|
# File 'app/models/project.rb', line 3001
def git_transfer_in_progress?
GL_REPOSITORY_TYPES.any? do |type|
reference_counter(type: type).value > 0
end
end
|
#gitea_import? ⇒ Boolean
1739
1740
1741
|
# File 'app/models/project.rb', line 1739
def gitea_import?
import_type == 'gitea'
end
|
#github_enterprise_import? ⇒ Boolean
1755
1756
1757
1758
|
# File 'app/models/project.rb', line 1755
def github_enterprise_import?
github_import? &&
URI.parse(safe_import_url).host != URI.parse(Octokit::Default::API_ENDPOINT).host
end
|
#github_import? ⇒ Boolean
1743
1744
1745
|
# File 'app/models/project.rb', line 1743
def github_import?
import_type == 'github'
end
|
#gitlab_deploy_token ⇒ Object
3056
3057
3058
3059
3060
|
# File 'app/models/project.rb', line 3056
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
1731
1732
1733
|
# File 'app/models/project.rb', line 1731
def gitlab_project_import?
import_type == 'gitlab_project'
end
|
#gitlab_project_migration? ⇒ Boolean
1735
1736
1737
|
# File 'app/models/project.rb', line 1735
def gitlab_project_migration?
import_type == 'gitlab_project_migration'
end
|
#glql_integration_feature_flag_enabled? ⇒ Boolean
3459
3460
3461
|
# File 'app/models/project.rb', line 3459
def glql_integration_feature_flag_enabled?
group&.glql_integration_feature_flag_enabled? || Feature.enabled?(:glql_integration, self)
end
|
#glql_load_on_click_feature_flag_enabled? ⇒ Boolean
3463
3464
3465
|
# File 'app/models/project.rb', line 3463
def glql_load_on_click_feature_flag_enabled?
group&.glql_load_on_click_feature_flag_enabled? || Feature.enabled?(:glql_load_on_click, self)
end
|
#group_group_links ⇒ Object
3486
3487
3488
|
# File 'app/models/project.rb', line 3486
def group_group_links
group&.shared_with_group_links_of_ancestors_and_self || GroupGroupLink.none
end
|
#group_protected_branches ⇒ Object
3189
3190
3191
3192
3193
|
# File 'app/models/project.rb', line 3189
def group_protected_branches
return root_namespace.protected_branches if root_namespace.is_a?(Group)
ProtectedBranch.none
end
|
#group_runners ⇒ Object
2446
2447
2448
|
# File 'app/models/project.rb', line 2446
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
3367
3368
3369
3370
3371
|
# File 'app/models/project.rb', line 3367
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
2145
2146
2147
2148
2149
2150
2151
2152
2153
|
# File 'app/models/project.rb', line 2145
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
2155
2156
2157
2158
2159
2160
2161
|
# File 'app/models/project.rb', line 2155
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
1464
1465
1466
1467
1468
|
# File 'app/models/project.rb', line 1464
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
1458
1459
1460
1461
1462
|
# File 'app/models/project.rb', line 1458
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
2702
2703
2704
|
# File 'app/models/project.rb', line 2702
def has_ci?
has_ci_config_file? || auto_devops_enabled?
end
|
#has_ci_config_file? ⇒ Boolean
2706
2707
2708
2709
2710
|
# File 'app/models/project.rb', line 2706
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
3618
3619
3620
3621
3622
|
# File 'app/models/project.rb', line 3618
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
|
1524
1525
1526
1527
1528
1529
|
# File 'app/models/project.rb', line 1524
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
3144
3145
3146
|
# File 'app/models/project.rb', line 3144
def has_pool_repository?
pool_repository.present?
end
|
#has_remote_mirror? ⇒ Boolean
1772
1773
1774
|
# File 'app/models/project.rb', line 1772
def has_remote_mirror?
remote_mirror_available? && remote_mirrors.enabled.exists?
end
|
#has_wiki? ⇒ Boolean
1989
1990
1991
|
# File 'app/models/project.rb', line 1989
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
2940
2941
2942
2943
2944
|
# File 'app/models/project.rb', line 2940
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
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
|
# File 'app/models/project.rb', line 2256
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
1589
1590
1591
|
# File 'app/models/project.rb', line 1589
def human_import_status_name
import_state&.human_status_name || 'none'
end
|
#human_merge_method ⇒ Object
2964
2965
2966
2967
2968
2969
2970
|
# File 'app/models/project.rb', line 2964
def human_merge_method
if merge_method == :ff
'Fast-forward'
else
merge_method.to_s.humanize
end
end
|
#import? ⇒ Boolean
1713
1714
1715
|
# File 'app/models/project.rb', line 1713
def import?
external_import? || forked? || gitlab_project_import? || jira_import? || gitlab_project_migration? || Gitlab::ImportSources.template?(import_type)
end
|
#import_checksums ⇒ Object
1581
1582
1583
|
# File 'app/models/project.rb', line 1581
def import_checksums
import_state&.checksums || {}
end
|
#import_export_shared ⇒ Object
2617
2618
2619
|
# File 'app/models/project.rb', line 2617
def import_export_shared
@import_export_shared ||= Gitlab::ImportExport::Shared.new(self)
end
|
#import_export_upload_by_user(user) ⇒ Object
2682
2683
2684
|
# File 'app/models/project.rb', line 2682
def import_export_upload_by_user(user)
import_export_uploads.find_by(user_id: user.id)
end
|
#import_failed? ⇒ Boolean
1371
1372
1373
|
# File 'app/models/project.rb', line 1371
def import_failed?
!!import_state&.failed?
end
|
#import_finished? ⇒ Boolean
1375
1376
1377
|
# File 'app/models/project.rb', line 1375
def import_finished?
!!import_state&.finished?
end
|
#import_in_progress? ⇒ Boolean
1367
1368
1369
|
# File 'app/models/project.rb', line 1367
def import_in_progress?
!!import_state&.in_progress?
end
|
#import_scheduled? ⇒ Boolean
1359
1360
1361
|
# File 'app/models/project.rb', line 1359
def import_scheduled?
!!import_state&.scheduled?
end
|
#import_started? ⇒ Boolean
1363
1364
1365
|
# File 'app/models/project.rb', line 1363
def import_started?
!!import_state&.started?
end
|
#import_status ⇒ Object
1577
1578
1579
|
# File 'app/models/project.rb', line 1577
def import_status
import_state&.status || 'none'
end
|
#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`.
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
|
# File 'app/models/project.rb', line 1693
def import_url
if import_data && super.present?
import_url = Gitlab::UrlSanitizer.new(super, credentials: import_data.credentials)
import_url.full_url
else
super
end
rescue StandardError
super
end
|
#import_url=(value) ⇒ Object
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
|
# File 'app/models/project.rb', line 1668
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
2328
2329
2330
2331
2332
|
# File 'app/models/project.rb', line 2328
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
3477
3478
3479
3480
|
# File 'app/models/project.rb', line 3477
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
3209
3210
3211
3212
3213
|
# File 'app/models/project.rb', line 3209
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
1328
1329
1330
1331
1332
1333
|
# File 'app/models/project.rb', line 1328
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
1965
1966
1967
|
# File 'app/models/project.rb', line 1965
def issue_exists?(issue_id)
get_issue(issue_id)
end
|
#issues_enabled? ⇒ Boolean
2388
2389
2390
|
# File 'app/models/project.rb', line 2388
def issues_enabled?
!!project_feature&.issues_enabled?
end
|
#items_for(entity) ⇒ Object
2060
2061
2062
2063
2064
2065
2066
2067
|
# File 'app/models/project.rb', line 2060
def items_for(entity)
case entity
when 'issue' then
issues
when 'merge_request' then
merge_requests
end
end
|
#jenkins_integration_active? ⇒ Boolean
1312
1313
1314
|
# File 'app/models/project.rb', line 1312
def jenkins_integration_active?
!!jenkins_integration&.active?
end
|
#jira_import? ⇒ Boolean
1727
1728
1729
|
# File 'app/models/project.rb', line 1727
def jira_import?
import_type == 'jira' && latest_jira_import.present?
end
|
#jira_import_status ⇒ Object
1585
1586
1587
|
# File 'app/models/project.rb', line 1585
def jira_import_status
latest_jira_import&.status || 'initial'
end
|
#jira_subscription_exists? ⇒ Boolean
3181
3182
3183
|
# File 'app/models/project.rb', line 3181
def jira_subscription_exists?
JiraConnectSubscription.for_project(self).exists?
end
|
#job_token_policies_enabled? ⇒ Boolean
3624
3625
3626
|
# File 'app/models/project.rb', line 3624
def job_token_policies_enabled?
namespace.root_ancestor.namespace_settings&.job_token_policies_enabled?
end
|
#keep_latest_artifact? ⇒ Boolean
3361
3362
3363
3364
3365
|
# File 'app/models/project.rb', line 3361
def keep_latest_artifact?
return false unless ci_cd_settings
ci_cd_settings.keep_latest_artifact?
end
|
#keep_latest_artifacts_available? ⇒ Boolean
3355
3356
3357
3358
3359
|
# File 'app/models/project.rb', line 3355
def keep_latest_artifacts_available?
return false unless ci_cd_settings
ci_cd_settings.keep_latest_artifacts_available?
end
|
#last_activity ⇒ Object
1947
1948
1949
|
# File 'app/models/project.rb', line 1947
def last_activity
last_event
end
|
#latest_jira_import ⇒ Object
3232
3233
3234
|
# File 'app/models/project.rb', line 3232
def latest_jira_import
jira_imports.last
end
|
#latest_pipeline(ref = default_branch, sha = nil, source = nil) ⇒ Object
1562
1563
1564
|
# File 'app/models/project.rb', line 1562
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
1554
1555
1556
1557
1558
1559
1560
|
# File 'app/models/project.rb', line 1554
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
1532
1533
1534
1535
1536
1537
1538
1539
|
# File 'app/models/project.rb', line 1532
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
1550
1551
1552
|
# File 'app/models/project.rb', line 1550
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
1541
1542
1543
1544
1545
1546
1547
1548
|
# File 'app/models/project.rb', line 1541
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
2360
2361
2362
2363
2364
2365
2366
|
# File 'app/models/project.rb', line 2360
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
2351
2352
2353
2354
2355
2356
2357
2358
|
# File 'app/models/project.rb', line 2351
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
|
#leave_pool_repository ⇒ Object
3114
3115
3116
3117
3118
3119
3120
3121
|
# File 'app/models/project.rb', line 3114
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
2933
2934
2935
|
# File 'app/models/project.rb', line 2933
def legacy_storage?
[nil, 0].include?(self.storage_version)
end
|
#lfs_enabled? ⇒ Boolean
Also known as:
lfs_enabled
1442
1443
1444
1445
1446
|
# File 'app/models/project.rb', line 1442
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
3583
3584
3585
|
# File 'app/models/project.rb', line 3583
def lfs_file_locks_changed_epoch
get_epoch_from(lfs_file_locks_changed_epoch_cache_key)
end
|
#lfs_objects_for_repository_types(*types) ⇒ Object
2181
2182
2183
2184
2185
|
# File 'app/models/project.rb', line 2181
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
2187
2188
2189
|
# File 'app/models/project.rb', line 2187
def lfs_objects_oids(oids: [])
oids(lfs_objects, oids: oids)
end
|
#lfs_objects_oids_from_fork_source(oids: []) ⇒ Object
2191
2192
2193
2194
2195
|
# File 'app/models/project.rb', line 2191
def lfs_objects_oids_from_fork_source(oids: [])
return [] unless forked?
oids(fork_source.lfs_objects, oids: oids)
end
|
#licensed_ai_features_available? ⇒ Boolean
3630
3631
3632
|
# File 'app/models/project.rb', line 3630
def licensed_ai_features_available?
false
end
|
#licensed_feature_available?(_feature) ⇒ Boolean
Overridden in EE::Project
3044
3045
3046
|
# File 'app/models/project.rb', line 3044
def licensed_feature_available?(_feature)
false
end
|
#licensed_features ⇒ Object
3048
3049
3050
|
# File 'app/models/project.rb', line 3048
def licensed_features
[]
end
|
#limited_protected_branches(limit) ⇒ Object
3185
3186
3187
|
# File 'app/models/project.rb', line 3185
def limited_protected_branches(limit)
protected_branches.limit(limit)
end
|
#link_pool_repository ⇒ Object
3137
3138
3139
3140
3141
3142
|
# File 'app/models/project.rb', line 3137
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
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
|
# File 'app/models/project.rb', line 1618
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
2548
2549
2550
|
# File 'app/models/project.rb', line 2548
def mark_pages_onboarding_complete
ensure_pages_metadatum.update!(onboarding_complete: true)
end
|
#mark_remote_mirrors_for_removal ⇒ Object
1794
1795
1796
|
# File 'app/models/project.rb', line 1794
def mark_remote_mirrors_for_removal
remote_mirrors.each(&:mark_for_delete_if_blank_url)
end
|
#mark_stuck_remote_mirrors_as_failed! ⇒ Object
1786
1787
1788
1789
1790
1791
1792
|
# File 'app/models/project.rb', line 1786
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
|
#marked_for_deletion_on ⇒ Object
187
|
# File 'app/models/project.rb', line 187
alias_attribute :marked_for_deletion_on, :marked_for_deletion_at
|
#max_attachment_size ⇒ Object
3088
3089
3090
|
# File 'app/models/project.rb', line 3088
def max_attachment_size
Gitlab::CurrentSettings.max_attachment_size.megabytes.to_i
end
|
#member(user) ⇒ Object
2285
2286
2287
2288
2289
2290
2291
|
# File 'app/models/project.rb', line 2285
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
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
|
# File 'app/models/project.rb', line 2302
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
2293
2294
2295
|
# File 'app/models/project.rb', line 2293
def membership_locked?
false
end
|
#merge_base_commit(first_commit_id, second_commit_id) ⇒ Object
1566
1567
1568
1569
1570
1571
|
# File 'app/models/project.rb', line 1566
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
3406
3407
3408
|
# File 'app/models/project.rb', line 3406
def merge_commit_template_or_default
merge_commit_template.presence || DEFAULT_MERGE_COMMIT_TEMPLATE
end
|
#merge_commit_template_or_default=(value) ⇒ Object
3410
3411
3412
3413
3414
3415
3416
3417
|
# File 'app/models/project.rb', line 3410
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
2972
2973
2974
2975
2976
2977
2978
2979
2980
|
# File 'app/models/project.rb', line 2972
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
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
|
# File 'app/models/project.rb', line 2982
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
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
|
# File 'app/models/project.rb', line 3019
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
2380
2381
2382
|
# File 'app/models/project.rb', line 2380
def merge_requests_enabled?
!!project_feature&.merge_requests_enabled?
end
|
#merge_trains_enabled? ⇒ Boolean
3579
3580
3581
|
# File 'app/models/project.rb', line 3579
def merge_trains_enabled?
false
end
|
#mr_can_target_upstream? ⇒ Boolean
2900
2901
2902
2903
2904
2905
2906
|
# File 'app/models/project.rb', line 2900
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
2908
2909
2910
|
# File 'app/models/project.rb', line 2908
def multiple_issue_boards_available?
true
end
|
#new_issuable_address(author, address_type) ⇒ Object
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
|
# File 'app/models/project.rb', line 1928
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
1355
1356
1357
|
# File 'app/models/project.rb', line 1355
def no_import?
!!import_state&.no_import?
end
|
#notify_project_import_complete? ⇒ Boolean
1721
1722
1723
1724
1725
|
# File 'app/models/project.rb', line 1721
def notify_project_import_complete?
return false if import_type.nil? || mirror? || forked?
gitea_import? || github_import? || bitbucket_import? || bitbucket_server_import?
end
|
#object_pool_params ⇒ Object
3092
3093
3094
3095
3096
3097
3098
|
# File 'app/models/project.rb', line 3092
def object_pool_params
return {} unless !forked? && git_objects_poolable?
{
pool_repository: pool_repository || create_new_pool_repository
}
end
|
#on_demand_dast_available? ⇒ Boolean
3569
3570
3571
|
# File 'app/models/project.rb', line 3569
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
2487
2488
2489
2490
2491
2492
2493
|
# File 'app/models/project.rb', line 2487
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
2421
2422
2423
|
# File 'app/models/project.rb', line 2421
def operations_enabled?
!!project_feature&.operations_enabled?
end
|
#origin_merge_requests ⇒ Object
2334
2335
2336
|
# File 'app/models/project.rb', line 2334
def origin_merge_requests
merge_requests.where(source_project_id: self.id)
end
|
#override_pipeline_variables_allowed?(access_level, user) ⇒ Boolean
3343
3344
3345
3346
3347
|
# File 'app/models/project.rb', line 3343
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
2079
2080
2081
2082
2083
2084
|
# File 'app/models/project.rb', line 2079
def owner
group || namespace.try(:owner)
end
|
#owners ⇒ Object
2092
2093
2094
2095
2096
2097
|
# File 'app/models/project.rb', line 2092
def owners
team.owners
end
|
#package_already_taken?(package_name, package_version, package_type:) ⇒ Boolean
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
|
# File 'app/models/project.rb', line 3263
def package_already_taken?(package_name, package_version, package_type:)
Packages::Package.with_name(package_name)
.with_version(package_version)
.with_package_type(package_type)
.not_pending_destruction
.for_projects(
root_ancestor.all_projects
.id_not_in(id)
.select(:id)
).exists?
end
|
#packages_cleanup_policy ⇒ Object
1470
1471
1472
|
# File 'app/models/project.rb', line 1470
def packages_cleanup_policy
super || build_packages_cleanup_policy
end
|
#packages_policy_subject ⇒ Object
#pages_access_control_forced_by_ancestor? ⇒ Boolean
2415
2416
2417
2418
2419
|
# File 'app/models/project.rb', line 2415
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
2521
2522
2523
|
# File 'app/models/project.rb', line 2521
def pages_deployed?
active_pages_deployments.exists?
end
|
#pages_domain_present?(domain_url) ⇒ Boolean
3508
3509
3510
|
# File 'app/models/project.rb', line 3508
def pages_domain_present?(domain_url)
pages_url == domain_url || pages_domains.any? { |domain| domain.url == domain_url }
end
|
#pages_enabled? ⇒ Boolean
2392
2393
2394
|
# File 'app/models/project.rb', line 2392
def pages_enabled?
!!project_feature&.pages_enabled?
end
|
#pages_hostname(options = nil) ⇒ Object
3604
3605
3606
|
# File 'app/models/project.rb', line 3604
def pages_hostname(options = nil)
pages_url_builder(options).hostname
end
|
#pages_https_only ⇒ Object
1840
1841
1842
1843
1844
|
# File 'app/models/project.rb', line 1840
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
1846
1847
1848
1849
1850
|
# File 'app/models/project.rb', line 1846
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
2525
2526
2527
|
# File 'app/models/project.rb', line 2525
def pages_show_onboarding?
!(pages_metadatum&.onboarding_complete || pages_deployed?)
end
|
#pages_unique_domain_enabled? ⇒ Boolean
2529
2530
2531
|
# File 'app/models/project.rb', line 2529
def pages_unique_domain_enabled?
project_setting.pages_unique_domain_enabled
end
|
#pages_url(options = nil) ⇒ Object
3600
3601
3602
|
# File 'app/models/project.rb', line 3600
def pages_url(options = nil)
pages_url_builder(options).pages_url
end
|
#pages_url_builder(options = nil) ⇒ Object
3612
3613
3614
3615
3616
|
# File 'app/models/project.rb', line 3612
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
2769
2770
2771
2772
2773
2774
2775
2776
2777
|
# File 'app/models/project.rb', line 2769
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
2889
2890
2891
|
# File 'app/models/project.rb', line 2889
def parent_changed?
namespace_id_changed?
end
|
#parent_loaded? ⇒ Boolean
1300
1301
1302
|
# File 'app/models/project.rb', line 1300
def parent_loaded?
association(:namespace).loaded?
end
|
#parent_organization_match ⇒ Object
1868
1869
1870
1871
1872
1873
|
# File 'app/models/project.rb', line 1868
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
3538
3539
3540
3541
3542
3543
3544
3545
|
# File 'app/models/project.rb', line 3538
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
2197
2198
2199
|
# File 'app/models/project.rb', line 2197
def personal?
!group
end
|
#personal_namespace_holder?(user) ⇒ Boolean
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
|
# File 'app/models/project.rb', line 1316
def personal_namespace_holder?(user)
return false unless personal?
return false unless user
namespace.owner == user
end
|
#placeholder_reference_store ⇒ Object
3591
3592
3593
3594
3595
3596
3597
3598
|
# File 'app/models/project.rb', line 3591
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
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
|
# File 'app/models/project.rb', line 2750
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
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
|
# File 'app/models/project.rb', line 2726
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_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
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
|
# File 'app/models/project.rb', line 2712
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
1413
1414
1415
1416
1417
1418
|
# File 'app/models/project.rb', line 1413
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
2408
2409
2410
2411
2412
2413
|
# File 'app/models/project.rb', line 2408
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
1951
1952
1953
|
# File 'app/models/project.rb', line 1951
def project_id
self.id
end
|
#project_setting ⇒ Object
1335
1336
1337
|
# File 'app/models/project.rb', line 1335
def project_setting
super.presence || build_project_setting
end
|
#prometheus_integration_active? ⇒ Boolean
1308
1309
1310
|
# File 'app/models/project.rb', line 1308
def prometheus_integration_active?
!!prometheus_integration&.active?
end
|
#protected_for?(ref) ⇒ Boolean
#public_pages? ⇒ Boolean
2404
2405
2406
|
# File 'app/models/project.rb', line 2404
def public_pages?
!private_pages?
end
|
#public_path_for_source_path(path, commit_sha) ⇒ Object
2882
2883
2884
2885
2886
2887
|
# File 'app/models/project.rb', line 2882
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
1921
1922
1923
1924
1925
1926
|
# File 'app/models/project.rb', line 1921
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
1879
1880
1881
1882
1883
|
# File 'app/models/project.rb', line 1879
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
3587
3588
3589
|
# File 'app/models/project.rb', line 3587
def refresh_lfs_file_locks_changed_epoch
refresh_epoch_cache(lfs_file_locks_changed_epoch_cache_key)
end
|
#refreshing_build_artifacts_size? ⇒ Boolean
3482
3483
3484
|
# File 'app/models/project.rb', line 3482
def refreshing_build_artifacts_size?
build_artifacts_size_refresh&.started?
end
|
#regeneration_in_progress?(user) ⇒ Boolean
2661
2662
2663
|
# File 'app/models/project.rb', line 2661
def regeneration_in_progress?(user)
(export_enqueued?(user) || export_in_progress?(user)) && export_file_exists?(user)
end
|
3255
3256
3257
3258
3259
3260
3261
|
# File 'app/models/project.rb', line 3255
def related_group_ids
ids = invited_group_ids
ids += group.self_and_ancestors_ids if group
ids
end
|
#remote_mirror_available? ⇒ Boolean
1798
1799
1800
1801
|
# File 'app/models/project.rb', line 1798
def remote_mirror_available?
remote_mirror_available_overridden ||
::Gitlab::CurrentSettings.mirror_available
end
|
#remove_export_for_user(user) ⇒ Object
2674
2675
2676
2677
2678
2679
2680
|
# File 'app/models/project.rb', line 2674
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
2665
2666
2667
2668
2669
2670
2671
2672
|
# File 'app/models/project.rb', line 2665
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
1639
1640
1641
|
# File 'app/models/project.rb', line 1639
def remove_import_data
import_data&.destroy
end
|
#remove_private_deploy_keys ⇒ Object
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
|
# File 'app/models/project.rb', line 2533
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
2960
2961
2962
|
# File 'app/models/project.rb', line 2960
def renamed?
persisted? && path_changed?
end
|
#repository ⇒ Object
1489
1490
1491
|
# File 'app/models/project.rb', line 1489
def repository
@repository ||= Gitlab::GlRepository::PROJECT.repository_for(self)
end
|
3547
3548
3549
|
# File 'app/models/project.rb', line 3547
def repository_object_format
project_repository&.object_format
end
|
#reset_cache_and_import_attrs ⇒ Object
1629
1630
1631
1632
1633
1634
1635
1636
|
# File 'app/models/project.rb', line 1629
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
2571
2572
2573
2574
2575
2576
2577
2578
|
# File 'app/models/project.rb', line 2571
def reset_counters_and_iids
InternalId.flush_records!(project: self)
update_project_counter_caches
end
|
#restrict_user_defined_variables? ⇒ Boolean
3337
3338
3339
3340
3341
|
# File 'app/models/project.rb', line 3337
def restrict_user_defined_variables?
return false unless ci_cd_settings
ci_cd_settings.restrict_user_defined_variables?
end
|
#root_namespace ⇒ Object
3236
3237
3238
3239
3240
3241
3242
|
# File 'app/models/project.rb', line 3236
def root_namespace
if namespace.has_parent?
namespace.root_ancestor
else
namespace
end
end
|
#route_map_for(commit_sha) ⇒ Object
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
|
# File 'app/models/project.rb', line 2868
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
2515
2516
2517
2518
2519
|
# File 'app/models/project.rb', line 2515
def runners_token
return unless namespace.allow_runner_registration_token?
ensure_runners_token!
end
|
#safe_import_url(masked: true) ⇒ String
Returns sanitized import URL.
1663
1664
1665
1666
|
# File 'app/models/project.rb', line 1663
def safe_import_url(masked: true)
url = Gitlab::UrlSanitizer.new(import_url)
masked ? url.masked_url : url.sanitized_url
end
|
#saved? ⇒ Boolean
1573
1574
1575
|
# File 'app/models/project.rb', line 1573
def saved?
id && persisted?
end
|
#security_training_available? ⇒ Boolean
3490
3491
3492
|
# File 'app/models/project.rb', line 3490
def security_training_available?
licensed_feature_available?(:security_training)
end
|
#self_deletion_in_progress? ⇒ Boolean
3434
3435
3436
|
# File 'app/models/project.rb', line 3434
def self_deletion_in_progress?
pending_delete?
end
|
#self_deletion_in_progress_or_hidden? ⇒ Boolean
3438
3439
3440
|
# File 'app/models/project.rb', line 3438
def self_deletion_in_progress_or_hidden?
self_deletion_in_progress? || hidden?
end
|
#self_or_ancestors_archived? ⇒ Boolean
2950
2951
2952
2953
2954
2955
2956
2957
2958
|
# File 'app/models/project.rb', line 2950
def self_or_ancestors_archived?
BatchLoader.for(id).batch(default_value: false) do |project_ids, loader|
Project
.self_or_ancestors_archived
.where(id: project_ids)
.pluck(:id)
.each { |project_id| loader.call(project_id, true) }
end
end
|
#self_or_root_group_ids ⇒ Object
for projects that are part of user namespace, return project.
3245
3246
3247
3248
3249
3250
3251
3252
3253
|
# File 'app/models/project.rb', line 3245
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
2070
2071
2072
2073
2074
2075
2076
|
# File 'app/models/project.rb', line 2070
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
1291
1292
1293
1294
1295
1296
1297
1298
|
# File 'app/models/project.rb', line 1291
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
2347
2348
2349
|
# File 'app/models/project.rb', line 2347
def share_with_group_enabled?
!parent.share_with_group_lock?
end
|
#shared_runners ⇒ Object
2438
2439
2440
|
# File 'app/models/project.rb', line 2438
def shared_runners
@shared_runners ||= shared_runners_enabled? ? Ci::Runner.instance_type : Ci::Runner.none
end
|
#shared_runners_available? ⇒ Boolean
2434
2435
2436
|
# File 'app/models/project.rb', line 2434
def shared_runners_available?
shared_runners_enabled?
end
|
#shared_runners_setting_conflicting_with_group? ⇒ Boolean
1875
1876
1877
|
# File 'app/models/project.rb', line 1875
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
1821
1822
1823
|
# File 'app/models/project.rb', line 1821
def should_validate_visibility_level?
new_record? || changes.has_key?(:visibility_level)
end
|
#show_default_award_emojis? ⇒ Boolean
1339
1340
1341
|
# File 'app/models/project.rb', line 1339
def show_default_award_emojis?
!!project_setting&.show_default_award_emojis?
end
|
#snippets_enabled? ⇒ Boolean
2400
2401
2402
|
# File 'app/models/project.rb', line 2400
def snippets_enabled?
!!project_feature&.snippets_enabled?
end
|
#snippets_visible?(user = nil) ⇒ Boolean
3084
3085
3086
|
# File 'app/models/project.rb', line 3084
def snippets_visible?(user = nil)
Ability.allowed?(user, :read_snippet, self)
end
|
#squash_commit_template_or_default ⇒ Object
3419
3420
3421
|
# File 'app/models/project.rb', line 3419
def squash_commit_template_or_default
squash_commit_template.presence || DEFAULT_SQUASH_COMMIT_TEMPLATE
end
|
#squash_commit_template_or_default=(value) ⇒ Object
3423
3424
3425
3426
3427
3428
3429
3430
|
# File 'app/models/project.rb', line 3423
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
3071
3072
3073
3074
3075
3076
3077
3078
|
# File 'app/models/project.rb', line 3071
def storage
@storage ||=
if hashed_storage?(:repository)
Storage::Hashed.new(self)
else
Storage::LegacyProject.new(self)
end
end
|
#storage_upgradable? ⇒ Boolean
3080
3081
3082
|
# File 'app/models/project.rb', line 3080
def storage_upgradable?
storage_version != LATEST_STORAGE_VERSION
end
|
#storage_version=(value) ⇒ Object
3007
3008
3009
3010
3011
|
# File 'app/models/project.rb', line 3007
def storage_version=(value)
super
@storage = nil if storage_version_changed?
end
|
#suggested_reviewers_available? ⇒ Boolean
3518
3519
3520
|
# File 'app/models/project.rb', line 3518
def suggested_reviewers_available?
false
end
|
#supports_lock_on_merge? ⇒ Boolean
3534
3535
3536
|
# File 'app/models/project.rb', line 3534
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
3574
3575
3576
|
# File 'app/models/project.rb', line 3574
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
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
|
# File 'app/models/project.rb', line 3124
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
1485
1486
1487
|
# File 'app/models/project.rb', line 1485
def team
@team ||= ProjectTeam.new(self)
end
|
#template_source? ⇒ Boolean
3177
3178
3179
|
# File 'app/models/project.rb', line 3177
def template_source?
false
end
|
#to_human_reference(from = nil) ⇒ Object
1913
1914
1915
1916
1917
1918
1919
|
# File 'app/models/project.rb', line 1913
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
1885
1886
1887
1888
1889
1890
1891
|
# File 'app/models/project.rb', line 1885
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.
1899
1900
1901
1902
|
# File 'app/models/project.rb', line 1899
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.
1905
1906
1907
1908
1909
1910
1911
|
# File 'app/models/project.rb', line 1905
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
3052
3053
3054
|
# File 'app/models/project.rb', line 3052
def toggle_ci_cd_settings!(settings_attribute)
ci_cd_settings.toggle!(settings_attribute)
end
|
#track_project_repository ⇒ Object
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
|
# File 'app/models/project.rb', line 2229
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
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
|
# File 'app/models/project.rb', line 2118
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
|
#update_project_counter_caches ⇒ Object
#update_remote_mirrors ⇒ Object
1780
1781
1782
1783
1784
|
# File 'app/models/project.rb', line 1780
def update_remote_mirrors
return unless remote_mirror_available?
remote_mirrors.enabled.each(&:sync)
end
|
#updating_remote_mirror? ⇒ Boolean
1776
1777
1778
|
# File 'app/models/project.rb', line 1776
def updating_remote_mirror?
remote_mirrors.enabled.started.exists?
end
|
#uploads_sharding_key ⇒ Object
3608
3609
3610
|
# File 'app/models/project.rb', line 3608
def uploads_sharding_key
{ project_id: id }
end
|
#valid_lfs_oids(oids_to_check) ⇒ Object
2177
2178
2179
|
# File 'app/models/project.rb', line 2177
def valid_lfs_oids(oids_to_check)
lfs_objects.where(oid: oids_to_check).pluck(:oid)
end
|
#valid_runners_token?(token) ⇒ Boolean
2468
2469
2470
|
# File 'app/models/project.rb', line 2468
def valid_runners_token?(token)
self.runners_token && ActiveSupport::SecurityUtils.secure_compare(token, self.runners_token)
end
|
#validate_pages_https_only ⇒ Object
1852
1853
1854
1855
1856
1857
1858
|
# File 'app/models/project.rb', line 1852
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
2511
2512
2513
|
# File 'app/models/project.rb', line 2511
def visibility_level_allowed?(level = self.visibility_level)
visibility_level_allowed_as_fork?(level) && visibility_level_allowed_by_group?(level)
end
|
#visibility_level_allowed_as_fork ⇒ Object
1833
1834
1835
1836
1837
1838
|
# File 'app/models/project.rb', line 1833
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
2496
2497
2498
2499
2500
2501
2502
2503
|
# File 'app/models/project.rb', line 2496
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_group ⇒ Object
1825
1826
1827
1828
1829
1830
1831
|
# File 'app/models/project.rb', line 1825
def visibility_level_allowed_by_group
return if visibility_level_allowed_by_group?
level_name = Gitlab::VisibilityLevel.level_name(self.visibility_level).downcase
group_level_name = Gitlab::VisibilityLevel.level_name(self.group.visibility_level).downcase
self.errors.add(:visibility_level, _("%{level_name} is not allowed in a %{group_level_name} group.") % { level_name: level_name, group_level_name: group_level_name })
end
|
#visibility_level_allowed_by_group?(level = self.visibility_level) ⇒ Boolean
2505
2506
2507
2508
2509
|
# File 'app/models/project.rb', line 2505
def visibility_level_allowed_by_group?(level = self.visibility_level)
return true unless group
level <= group.visibility_level
end
|
#visibility_level_field ⇒ Object
2313
2314
2315
|
# File 'app/models/project.rb', line 2313
def visibility_level_field
:visibility_level
end
|
#visible_group_links(for_user:) ⇒ Object
3382
3383
3384
3385
3386
3387
3388
3389
3390
|
# File 'app/models/project.rb', line 3382
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
1347
1348
1349
|
# File 'app/models/project.rb', line 1347
def warn_about_potentially_unwanted_characters?
!!project_setting&.warn_about_potentially_unwanted_characters?
end
|
#wiki_enabled? ⇒ Boolean
2376
2377
2378
|
# File 'app/models/project.rb', line 2376
def wiki_enabled?
!!project_feature&.wiki_enabled?
end
|
#work_item_status_feature_available? ⇒ Boolean
3454
3455
3456
3457
|
# File 'app/models/project.rb', line 3454
def work_item_status_feature_available?
(group&.work_item_status_feature_available? || Feature.enabled?(:work_item_status_feature_flag, type: :wip)) &&
licensed_feature_available?(:work_item_status)
end
|
#work_items_alpha_feature_flag_enabled? ⇒ Boolean
3450
3451
3452
|
# File 'app/models/project.rb', line 3450
def work_items_alpha_feature_flag_enabled?
group&.work_items_alpha_feature_flag_enabled? || Feature.enabled?(:work_items_alpha)
end
|
#work_items_beta_feature_flag_enabled? ⇒ Boolean
3446
3447
3448
|
# File 'app/models/project.rb', line 3446
def work_items_beta_feature_flag_enabled?
group&.work_items_beta_feature_flag_enabled? || Feature.enabled?(:work_items_beta, type: :beta)
end
|
#work_items_feature_flag_enabled? ⇒ Boolean
3442
3443
3444
|
# File 'app/models/project.rb', line 3442
def work_items_feature_flag_enabled?
group&.work_items_feature_flag_enabled? || Feature.enabled?(:work_items, self)
end
|