diff options
Diffstat (limited to 'app/services/projects')
10 files changed, 146 insertions, 29 deletions
diff --git a/app/services/projects/apple_target_platform_detector_service.rb b/app/services/projects/apple_target_platform_detector_service.rb new file mode 100644 index 00000000000..ec4c16a1416 --- /dev/null +++ b/app/services/projects/apple_target_platform_detector_service.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +module Projects + # Service class to detect target platforms of a project made for the Apple + # Ecosystem. + # + # This service searches project.pbxproj and *.xcconfig files (contains build + # settings) for the string "SDKROOT = <SDK_name>" where SDK_name can be + # 'iphoneos', 'macosx', 'appletvos' or 'watchos'. Currently, the service is + # intentionally limited (for performance reasons) to detect if a project + # targets iOS. + # + # Ref: https://developer.apple.com/documentation/xcode/build-settings-reference/ + # + # Example usage: + # > AppleTargetPlatformDetectorService.new(a_project).execute + # => [] + # > AppleTargetPlatformDetectorService.new(an_ios_project).execute + # => [:ios] + # > AppleTargetPlatformDetectorService.new(multiplatform_project).execute + # => [:ios, :osx, :tvos, :watchos] + class AppleTargetPlatformDetectorService < BaseService + BUILD_CONFIG_FILENAMES = %w(project.pbxproj *.xcconfig).freeze + + # For the current iteration, we only want to detect when the project targets + # iOS. In the future, we can use the same logic to detect projects that + # target OSX, TvOS, and WatchOS platforms with SDK names 'macosx', 'appletvos', + # and 'watchos', respectively. + PLATFORM_SDK_NAMES = { ios: 'iphoneos' }.freeze + + def execute + detect_platforms + end + + private + + def file_finder + @file_finder ||= ::Gitlab::FileFinder.new(project, project.default_branch) + end + + def detect_platforms + # Return array of SDK names for which "SDKROOT = <sdk_name>" setting + # definition can be found in either project.pbxproj or *.xcconfig files. + PLATFORM_SDK_NAMES.select do |_, sdk| + config_files_containing_sdk_setting(sdk).present? + end.keys + end + + # Return array of project.pbxproj and/or *.xcconfig files + # (Gitlab::Search::FoundBlob) that contain the setting definition string + # "SDKROOT = <sdk_name>" + def config_files_containing_sdk_setting(sdk) + BUILD_CONFIG_FILENAMES.map do |filename| + file_finder.find("SDKROOT = #{sdk} filename:#{filename}") + end.flatten + end + end +end diff --git a/app/services/projects/container_repository/third_party/delete_tags_service.rb b/app/services/projects/container_repository/third_party/delete_tags_service.rb index 4184c676fc3..942df177bea 100644 --- a/app/services/projects/container_repository/third_party/delete_tags_service.rb +++ b/app/services/projects/container_repository/third_party/delete_tags_service.rb @@ -33,7 +33,7 @@ module Projects if deleted_tags.any? && @container_repository.delete_tag_by_digest(deleted_tags.each_value.first) success(deleted: deleted_tags.keys) else - error('could not delete tags') + error("could not delete tags: #{@tag_names.join(', ')}".truncate(1000)) end end diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb index 252e1d76bef..3e26c8c35b2 100644 --- a/app/services/projects/create_service.rb +++ b/app/services/projects/create_service.rb @@ -105,7 +105,8 @@ module Projects end @project.track_project_repository - @project.create_project_setting unless @project.project_setting + + create_project_settings yield if block_given? @@ -122,6 +123,14 @@ module Projects create_sast_commit if @initialize_with_sast end + def create_project_settings + if Feature.enabled?(:create_project_settings, default_enabled: :yaml) + @project.project_setting.save if @project.project_setting.changed? + else + @project.create_project_setting unless @project.project_setting + end + end + # Add an authorization for the current user authorizations inline # (so they can access the project immediately after this request # completes), and any other affected users in the background @@ -243,7 +252,7 @@ module Projects def import_schedule if @project.errors.empty? - @project.import_state.schedule if @project.import? && !@project.bare_repository_import? + @project.import_state.schedule if @project.import? && !@project.bare_repository_import? && !@project.gitlab_project_migration? else fail(error: @project.errors.full_messages.join(', ')) end diff --git a/app/services/projects/deploy_tokens/create_service.rb b/app/services/projects/deploy_tokens/create_service.rb index 2486544b150..c44a7686c04 100644 --- a/app/services/projects/deploy_tokens/create_service.rb +++ b/app/services/projects/deploy_tokens/create_service.rb @@ -6,7 +6,7 @@ module Projects include DeployTokenMethods def execute - deploy_token = create_deploy_token_for(@project, params) + deploy_token = create_deploy_token_for(@project, current_user, params) create_deploy_token_payload_for(deploy_token) end diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb index b91b7f34d42..72492b6f5a5 100644 --- a/app/services/projects/import_export/export_service.rb +++ b/app/services/projects/import_export/export_service.rb @@ -23,6 +23,13 @@ module Projects cleanup end + def exporters + [ + version_saver, avatar_saver, project_tree_saver, uploads_saver, + repo_saver, wiki_repo_saver, lfs_saver, snippets_repo_saver, design_repo_saver + ] + end + protected def extra_attributes_for_measurement @@ -59,30 +66,23 @@ module Projects end def save_export_archive - Gitlab::ImportExport::Saver.save(exportable: project, shared: shared) - end - - def exporters - [ - version_saver, avatar_saver, project_tree_saver, uploads_saver, - repo_saver, wiki_repo_saver, lfs_saver, snippets_repo_saver, design_repo_saver - ] + @export_saver ||= Gitlab::ImportExport::Saver.save(exportable: project, shared: shared) end def version_saver - Gitlab::ImportExport::VersionSaver.new(shared: shared) + @version_saver ||= Gitlab::ImportExport::VersionSaver.new(shared: shared) end def avatar_saver - Gitlab::ImportExport::AvatarSaver.new(project: project, shared: shared) + @avatar_saver ||= Gitlab::ImportExport::AvatarSaver.new(project: project, shared: shared) end def project_tree_saver - tree_saver_class.new(project: project, - current_user: current_user, - shared: shared, - params: params, - logger: logger) + @project_tree_saver ||= tree_saver_class.new(project: project, + current_user: current_user, + shared: shared, + params: params, + logger: logger) end def tree_saver_class @@ -90,27 +90,31 @@ module Projects end def uploads_saver - Gitlab::ImportExport::UploadsSaver.new(project: project, shared: shared) + @uploads_saver ||= Gitlab::ImportExport::UploadsSaver.new(project: project, shared: shared) end def repo_saver - Gitlab::ImportExport::RepoSaver.new(exportable: project, shared: shared) + @repo_saver ||= Gitlab::ImportExport::RepoSaver.new(exportable: project, shared: shared) end def wiki_repo_saver - Gitlab::ImportExport::WikiRepoSaver.new(exportable: project, shared: shared) + @wiki_repo_saver ||= Gitlab::ImportExport::WikiRepoSaver.new(exportable: project, shared: shared) end def lfs_saver - Gitlab::ImportExport::LfsSaver.new(project: project, shared: shared) + @lfs_saver ||= Gitlab::ImportExport::LfsSaver.new(project: project, shared: shared) end def snippets_repo_saver - Gitlab::ImportExport::SnippetsRepoSaver.new(current_user: current_user, project: project, shared: shared) + @snippets_repo_saver ||= Gitlab::ImportExport::SnippetsRepoSaver.new( + current_user: current_user, + project: project, + shared: shared + ) end def design_repo_saver - Gitlab::ImportExport::DesignRepoSaver.new(exportable: project, shared: shared) + @design_repo_saver ||= Gitlab::ImportExport::DesignRepoSaver.new(exportable: project, shared: shared) end def cleanup diff --git a/app/services/projects/operations/update_service.rb b/app/services/projects/operations/update_service.rb index ef74f3e6e7a..b66435d013b 100644 --- a/app/services/projects/operations/update_service.rb +++ b/app/services/projects/operations/update_service.rb @@ -112,8 +112,9 @@ module Projects integration = project.find_or_initialize_integration(::Integrations::Prometheus.to_param) integration.assign_attributes(attrs) + attrs = integration.to_integration_hash.except('created_at', 'updated_at') - { prometheus_integration_attributes: integration.attributes.except(*%w[id project_id created_at updated_at]) } + { prometheus_integration_attributes: attrs } end def incident_management_setting_params diff --git a/app/services/projects/participants_service.rb b/app/services/projects/participants_service.rb index 152590fffff..c7a34afffb3 100644 --- a/app/services/projects/participants_service.rb +++ b/app/services/projects/participants_service.rb @@ -39,6 +39,7 @@ module Projects GroupMember .active_without_invites_and_requests .with_source_id(visible_groups.self_and_ancestors.pluck_primary_key) + .select(*GroupMember.cached_column_list) end def visible_groups @@ -52,11 +53,12 @@ module Projects end def project_members_through_ancestral_groups - project.group.present? ? project.group.members_with_parents : Member.none + members = project.group.present? ? project.group.members_with_parents : Member.none + members.select(*GroupMember.cached_column_list) end def individual_project_members - project.project_members + project.project_members.select(*GroupMember.cached_column_list) end def project_owner? diff --git a/app/services/projects/record_target_platforms_service.rb b/app/services/projects/record_target_platforms_service.rb new file mode 100644 index 00000000000..224e16f53b3 --- /dev/null +++ b/app/services/projects/record_target_platforms_service.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Projects + class RecordTargetPlatformsService < BaseService + include Gitlab::Utils::StrongMemoize + + def execute + record_target_platforms + end + + private + + def target_platforms + strong_memoize(:target_platforms) do + AppleTargetPlatformDetectorService.new(project).execute + end + end + + def record_target_platforms + return unless target_platforms.present? + + setting = ::ProjectSetting.find_or_initialize_by(project: project) # rubocop:disable CodeReuse/ActiveRecord + setting.target_platforms = target_platforms + setting.save + + setting.target_platforms + end + end +end diff --git a/app/services/projects/refresh_build_artifacts_size_statistics_service.rb b/app/services/projects/refresh_build_artifacts_size_statistics_service.rb index 794c042ea39..1f86e5f4ba9 100644 --- a/app/services/projects/refresh_build_artifacts_size_statistics_service.rb +++ b/app/services/projects/refresh_build_artifacts_size_statistics_service.rb @@ -12,7 +12,7 @@ module Projects if batch.any? # We are doing the sum in ruby because the query takes too long when done in SQL - total_artifacts_size = batch.sum(&:size) + total_artifacts_size = batch.sum { |artifact| artifact.size.to_i } Projects::BuildArtifactsSizeRefresh.transaction do # Mark the refresh ready for another worker to pick up and process the next batch diff --git a/app/services/projects/transfer_service.rb b/app/services/projects/transfer_service.rb index 51c0989ee55..2ad5c303be2 100644 --- a/app/services/projects/transfer_service.rb +++ b/app/services/projects/transfer_service.rb @@ -121,6 +121,7 @@ module Projects # Overridden in EE def post_update_hooks(project) move_pages(project) + ensure_personal_project_owner_membership(project) end # Overridden in EE @@ -152,6 +153,19 @@ module Projects project.track_project_repository end + def ensure_personal_project_owner_membership(project) + # In case of personal projects, we want to make sure that + # a membership record with `OWNER` access level exists for the owner of the namespace. + return unless project.personal? + + namespace_owner = project.namespace.owner + existing_membership_record = project.member(namespace_owner) + + return if existing_membership_record.present? && existing_membership_record.access_level == Gitlab::Access::OWNER + + project.add_owner(namespace_owner) + end + def refresh_permissions # This ensures we only schedule 1 job for every user that has access to # the namespaces. |