summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab/CODEOWNERS139
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--app/helpers/ci/pipeline_editor_helper.rb2
-rw-r--r--app/helpers/projects_helper.rb3
-rw-r--r--app/helpers/search_helper.rb8
-rw-r--r--app/models/concerns/project_features_compatibility.rb4
-rw-r--r--app/models/project.rb2
-rw-r--r--app/models/project_feature.rb1
-rw-r--r--app/policies/project_policy.rb12
-rw-r--r--data/removals/15_0/removal_manage_repository_push_audit_event.yml (renamed from data/removals/15_0/removal_manage_ repository_push_audit_event.yml)0
-rw-r--r--lib/gitlab/import_export/project/import_export.yml2
-rw-r--r--qa/qa/specs/features/api/3_create/gitaly/changing_repository_storage_spec.rb22
-rw-r--r--rubocop/cop/gitlab/feature_available_usage.rb1
-rw-r--r--spec/factories/projects.rb1
-rw-r--r--spec/helpers/ci/pipeline_editor_helper_spec.rb4
-rw-r--r--spec/helpers/projects_helper_spec.rb3
-rw-r--r--spec/helpers/search_helper_spec.rb13
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml1
-rw-r--r--spec/models/concerns/project_features_compatibility_spec.rb2
-rw-r--r--spec/models/project_spec.rb1
-rw-r--r--spec/policies/project_policy_spec.rb125
-rw-r--r--spec/tooling/lib/tooling/find_codeowners_spec.rb43
-rw-r--r--tooling/config/CODEOWNERS.yml21
-rw-r--r--tooling/lib/tooling/find_codeowners.rb92
24 files changed, 430 insertions, 74 deletions
diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS
index b7cc60d2f68..d82821205da 100644
--- a/.gitlab/CODEOWNERS
+++ b/.gitlab/CODEOWNERS
@@ -1057,3 +1057,142 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/lib/system_check/incoming_email/imap_authentication_check.rb @gitlab-org/manage/authentication-and-authorization/approvers
/lib/tasks/gitlab/password.rake @gitlab-org/manage/authentication-and-authorization/approvers
/lib/tasks/tokens.rake @gitlab-org/manage/authentication-and-authorization/approvers
+
+[Compliance]
+/ee/app/services/audit_events/build_service.rb @gitlab-org/manage/compliance
+/ee/spec/services/audit_events/custom_audit_event_service_spec.rb @gitlab-org/manage/compliance
+/app/models/audit_event.rb @gitlab-org/manage/compliance
+/app/services/audit_event_service.rb @gitlab-org/manage/compliance
+/app/services/concerns/audit_event_save_type.rb @gitlab-org/manage/compliance
+/app/views/profiles/audit_log.html.haml @gitlab-org/manage/compliance
+/config/feature_flags/development/custom_headers_streaming_audit_events_ui.yml @gitlab-org/manage/compliance
+/data/deprecations/14-3-repository-push-audit-events.yml @gitlab-org/manage/compliance
+/data/removals/15_0/removal_manage_repository_push_audit_event.yml @gitlab-org/manage/compliance
+/db/docs/audit_events.yml @gitlab-org/manage/compliance
+/db/docs/audit_events_external_audit_event_destinations.yml @gitlab-org/manage/compliance
+/db/docs/audit_events_streaming_headers.yml @gitlab-org/manage/compliance
+/db/migrate/20210819185500_create_external_audit_event_destinations_table.rb @gitlab-org/manage/compliance
+/db/migrate/20220524141800_create_audit_events_streaming_headers.rb @gitlab-org/manage/compliance
+/db/post_migrate/20210331105335_drop_non_partitioned_audit_events.rb @gitlab-org/manage/compliance
+/db/post_migrate/20220119094503_populate_audit_event_streaming_verification_token.rb @gitlab-org/manage/compliance
+/doc/administration/audit_event_streaming.md @gitlab-org/manage/compliance
+/doc/administration/audit_events.md @gitlab-org/manage/compliance
+/doc/administration/audit_reports.md @gitlab-org/manage/compliance
+/doc/administration/auditor_users.md @gitlab-org/manage/compliance
+/doc/api/audit_events.md @gitlab-org/manage/compliance
+/doc/api/graphql/audit_report.md @gitlab-org/manage/compliance
+/ee/app/assets/javascripts/audit_events/components/audit_events_app.vue @gitlab-org/manage/compliance
+/ee/app/assets/javascripts/audit_events/components/audit_events_export_button.vue @gitlab-org/manage/compliance
+/ee/app/assets/javascripts/audit_events/components/audit_events_filter.vue @gitlab-org/manage/compliance
+/ee/app/assets/javascripts/audit_events/components/audit_events_log.vue @gitlab-org/manage/compliance
+/ee/app/assets/javascripts/audit_events/components/audit_events_stream.vue @gitlab-org/manage/compliance
+/ee/app/assets/javascripts/audit_events/components/audit_events_table.vue @gitlab-org/manage/compliance
+/ee/app/assets/javascripts/audit_events/components/tokens/shared/ @gitlab-org/manage/compliance
+/ee/app/assets/javascripts/audit_events/init_audit_events.js @gitlab-org/manage/compliance
+/ee/app/controllers/admin/audit_log_reports_controller.rb @gitlab-org/manage/compliance
+/ee/app/controllers/admin/audit_logs_controller.rb @gitlab-org/manage/compliance
+/ee/app/controllers/concerns/audit_events/audit_events_params.rb @gitlab-org/manage/compliance
+/ee/app/controllers/groups/audit_events_controller.rb @gitlab-org/manage/compliance
+/ee/app/controllers/projects/audit_events_controller.rb @gitlab-org/manage/compliance
+/ee/app/finders/audit_event_finder.rb @gitlab-org/manage/compliance
+/ee/app/graphql/types/audit_events/external_audit_event_destination_type.rb @gitlab-org/manage/compliance
+/ee/app/helpers/audit_events_helper.rb @gitlab-org/manage/compliance
+/ee/app/helpers/auditor_user_helper.rb @gitlab-org/manage/compliance
+/ee/app/models/audit_events/external_audit_event_destination.rb @gitlab-org/manage/compliance
+/ee/app/models/concerns/auditable.rb @gitlab-org/manage/compliance
+/ee/app/models/ee/audit_event.rb @gitlab-org/manage/compliance
+/ee/app/policies/audit_events/external_audit_event_destination_policy.rb @gitlab-org/manage/compliance
+/ee/app/presenters/audit_event_presenter.rb @gitlab-org/manage/compliance
+/ee/app/serializers/audit_event_entity.rb @gitlab-org/manage/compliance
+/ee/app/serializers/audit_event_serializer.rb @gitlab-org/manage/compliance
+/ee/app/services/ci/audit_variable_change_service.rb @gitlab-org/manage/compliance
+/ee/app/services/ee/audit_event_service.rb @gitlab-org/manage/compliance
+/ee/app/views/admin/users/_auditor_access_level_radio.html.haml @gitlab-org/manage/compliance
+/ee/app/views/admin/users/_auditor_user_badge.html.haml @gitlab-org/manage/compliance
+/ee/app/views/shared/icons/_icon_audit_events_purple.svg @gitlab-org/manage/compliance
+/ee/app/views/shared/promotions/_promote_audit_events.html.haml @gitlab-org/manage/compliance
+/ee/app/workers/audit_events/audit_event_streaming_worker.rb @gitlab-org/manage/compliance
+/ee/config/events/1652263097_groups__audit_events__index_click_streams_tab.yml @gitlab-org/manage/compliance
+/ee/config/events/202108302307_admin_audit_logs_index_click_date_range_button.yml @gitlab-org/manage/compliance
+/ee/config/events/202108302307_groups__audit_events_controller_search_audit_event.yml @gitlab-org/manage/compliance
+/ee/config/events/202108302307_profiles_controller_search_audit_event.yml @gitlab-org/manage/compliance
+/ee/config/events/202108302307_projects__audit_events_controller_search_audit_event.yml @gitlab-org/manage/compliance
+/ee/config/events/202111041910_admin__audit_logs_controller_search_audit_event.yml @gitlab-org/manage/compliance
+/ee/config/feature_flags/development/audit_event_streaming_git_operations.yml @gitlab-org/manage/compliance
+/ee/config/feature_flags/development/audit_log_group_level.yml @gitlab-org/manage/compliance
+/ee/config/metrics/counts_28d/20210216183930_g_compliance_audit_events_monthly.yml @gitlab-org/manage/compliance
+/ee/config/metrics/counts_28d/20210216183934_i_compliance_audit_events_monthly.yml @gitlab-org/manage/compliance
+/ee/config/metrics/counts_28d/20210216183942_a_compliance_audit_events_api_monthly.yml @gitlab-org/manage/compliance
+/ee/config/metrics/counts_28d/20211130085433_g_manage_compliance_audit_event_destinations.yml @gitlab-org/manage/compliance
+/ee/config/metrics/counts_7d/20210216183906_g_compliance_audit_events.yml @gitlab-org/manage/compliance
+/ee/config/metrics/counts_7d/20210216183908_i_compliance_audit_events.yml @gitlab-org/manage/compliance
+/ee/config/metrics/counts_7d/20210216183912_a_compliance_audit_events_api.yml @gitlab-org/manage/compliance
+/ee/config/metrics/counts_7d/20210216183928_g_compliance_audit_events_weekly.yml @gitlab-org/manage/compliance
+/ee/config/metrics/counts_7d/20210216183932_i_compliance_audit_events_weekly.yml @gitlab-org/manage/compliance
+/ee/config/metrics/counts_7d/20210216183940_a_compliance_audit_events_api_weekly.yml @gitlab-org/manage/compliance
+/ee/config/metrics/counts_all/20211130085433_g_manage_compliance_audit_event_destinations.yml @gitlab-org/manage/compliance
+/ee/lib/api/audit_events.rb @gitlab-org/manage/compliance
+/ee/lib/audit/external_status_check_changes_auditor.rb @gitlab-org/manage/compliance
+/ee/lib/audit/group_merge_request_approval_setting_changes_auditor.rb @gitlab-org/manage/compliance
+/ee/lib/audit/group_push_rules_changes_auditor.rb @gitlab-org/manage/compliance
+/ee/lib/ee/api/entities/audit_event.rb @gitlab-org/manage/compliance
+/ee/lib/ee/audit/ @gitlab-org/manage/compliance
+/ee/lib/gitlab/audit/auditor.rb @gitlab-org/manage/compliance
+/ee/spec/controllers/admin/audit_log_reports_controller_spec.rb @gitlab-org/manage/compliance
+/ee/spec/controllers/admin/audit_logs_controller_spec.rb @gitlab-org/manage/compliance
+/ee/spec/controllers/groups/audit_events_controller_spec.rb @gitlab-org/manage/compliance
+/ee/spec/controllers/projects/audit_events_controller_spec.rb @gitlab-org/manage/compliance
+/ee/spec/factories/audit_events/external_audit_event_destinations.rb @gitlab-org/manage/compliance
+/ee/spec/features/admin/admin_audit_logs_spec.rb @gitlab-org/manage/compliance
+/ee/spec/features/groups/audit_events_spec.rb @gitlab-org/manage/compliance
+/ee/spec/features/projects/audit_events_spec.rb @gitlab-org/manage/compliance
+/ee/spec/finders/audit_event_finder_spec.rb @gitlab-org/manage/compliance
+/ee/spec/fixtures/api/schemas/public_api/v4/audit_event.json @gitlab-org/manage/compliance
+/ee/spec/fixtures/api/schemas/public_api/v4/audit_events.json @gitlab-org/manage/compliance
+/ee/spec/frontend/audit_events/components/__snapshots__/ @gitlab-org/manage/compliance
+/ee/spec/frontend/audit_events/components/audit_events_app_spec.js @gitlab-org/manage/compliance
+/ee/spec/frontend/audit_events/components/audit_events_export_button_spec.js @gitlab-org/manage/compliance
+/ee/spec/frontend/audit_events/components/audit_events_filter_spec.js @gitlab-org/manage/compliance
+/ee/spec/frontend/audit_events/components/audit_events_logs_spec.js @gitlab-org/manage/compliance
+/ee/spec/frontend/audit_events/components/audit_events_stream_spec.js @gitlab-org/manage/compliance
+/ee/spec/frontend/audit_events/components/audit_events_table_spec.js @gitlab-org/manage/compliance
+/ee/spec/frontend/audit_events/components/tokens/shared/ @gitlab-org/manage/compliance
+/ee/spec/graphql/types/audit_events/exterrnal_audit_event_destination_type_spec.rb @gitlab-org/manage/compliance
+/ee/spec/helpers/audit_events_helper_spec.rb @gitlab-org/manage/compliance
+/ee/spec/lib/audit/external_status_check_changes_auditor_spec.rb @gitlab-org/manage/compliance
+/ee/spec/lib/audit/group_merge_request_approval_setting_changes_auditor_spec.rb @gitlab-org/manage/compliance
+/ee/spec/lib/audit/group_push_rules_changes_auditor_spec.rb @gitlab-org/manage/compliance
+/ee/spec/lib/ee/audit/ @gitlab-org/manage/compliance
+/ee/spec/lib/gitlab/audit/auditor_spec.rb @gitlab-org/manage/compliance
+/ee/spec/models/audit_events/external_audit_event_destination_spec.rb @gitlab-org/manage/compliance
+/ee/spec/models/concerns/auditable_spec.rb @gitlab-org/manage/compliance
+/ee/spec/models/ee/audit_event_spec.rb @gitlab-org/manage/compliance
+/ee/spec/presenters/audit_event_presenter_spec.rb @gitlab-org/manage/compliance
+/ee/spec/requests/admin/audit_events_spec.rb @gitlab-org/manage/compliance
+/ee/spec/requests/api/audit_events_spec.rb @gitlab-org/manage/compliance
+/ee/spec/requests/api/graphql/group/external_audit_event_destinations_spec.rb @gitlab-org/manage/compliance
+/ee/spec/requests/groups/audit_events_spec.rb @gitlab-org/manage/compliance
+/ee/spec/requests/projects/audit_events_spec.rb @gitlab-org/manage/compliance
+/ee/spec/serializers/audit_event_entity_spec.rb @gitlab-org/manage/compliance
+/ee/spec/serializers/audit_event_serializer_spec.rb @gitlab-org/manage/compliance
+/ee/spec/services/audit_event_service_spec.rb @gitlab-org/manage/compliance
+/ee/spec/support/shared_contexts/audit_event_not_licensed_shared_context.rb @gitlab-org/manage/compliance
+/ee/spec/support/shared_contexts/audit_event_queue_shared_context.rb @gitlab-org/manage/compliance
+/ee/spec/support/shared_examples/audit/ @gitlab-org/manage/compliance
+/ee/spec/support/shared_examples/features/audit_events_filter_shared_examples.rb @gitlab-org/manage/compliance
+/ee/spec/support/shared_examples/services/audit_event_logging_shared_examples.rb @gitlab-org/manage/compliance
+/ee/spec/workers/audit_events/audit_event_streaming_worker_spec.rb @gitlab-org/manage/compliance
+/lib/gitlab/audit_json_logger.rb @gitlab-org/manage/compliance
+/qa/qa/ee/page/admin/monitoring/ @gitlab-org/manage/compliance
+/qa/qa/specs/features/ee/browser_ui/1_manage/group/group_audit_logs_1_spec.rb @gitlab-org/manage/compliance
+/qa/qa/specs/features/ee/browser_ui/1_manage/group/group_audit_logs_2_spec.rb @gitlab-org/manage/compliance
+/qa/qa/specs/features/ee/browser_ui/1_manage/instance/ @gitlab-org/manage/compliance
+/qa/qa/specs/features/ee/browser_ui/1_manage/project/project_audit_logs_spec.rb @gitlab-org/manage/compliance
+/spec/factories/audit_events.rb @gitlab-org/manage/compliance
+/spec/migrations/populate_audit_event_streaming_verification_token_spec.rb @gitlab-org/manage/compliance
+/spec/models/audit_event_spec.rb @gitlab-org/manage/compliance
+/spec/services/audit_event_service_spec.rb @gitlab-org/manage/compliance
+/spec/services/concerns/audit_event_save_type_spec.rb @gitlab-org/manage/compliance
+/spec/support/shared_examples/sends_git_audit_streaming_event_shared_examples.rb @gitlab-org/manage/compliance
+/spec/views/profiles/audit_log.html.haml_spec.rb @gitlab-org/manage/compliance
+/vendor/project_templates/hipaa_audit_protocol.tar.gz @gitlab-org/manage/compliance
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index fa0e10c647e..d89e6180f1a 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-445024454b60b661cc7bc7782c9e9367517f42e2
+157e6b6ad8fd7aa0ebdd43727f00b81f34b100a1
diff --git a/app/helpers/ci/pipeline_editor_helper.rb b/app/helpers/ci/pipeline_editor_helper.rb
index d044a93213a..48eb7b4c41a 100644
--- a/app/helpers/ci/pipeline_editor_helper.rb
+++ b/app/helpers/ci/pipeline_editor_helper.rb
@@ -33,7 +33,7 @@ module Ci
"project-full-path" => project.full_path,
"project-namespace" => project.namespace.full_path,
"runner-help-page-path" => help_page_path('ci/runners/index'),
- "simulate-pipeline-help-page-path" => help_page_path('ci/lint', anchor: 'simulate-a-pipeline'),
+ "simulate-pipeline-help-page-path" => help_page_path('ci/pipeline_editor/index', anchor: 'simulate-a-cicd-pipeline'),
"total-branches" => total_branches,
"validate-tab-illustration-path" => image_path('illustrations/project-run-CICD-pipelines-sm.svg'),
"yml-help-page-path" => help_page_path('ci/yaml/index')
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index c52cadeaec2..75622e7430c 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -639,7 +639,8 @@ module ProjectsHelper
warnAboutPotentiallyUnwantedCharacters: project.warn_about_potentially_unwanted_characters?,
enforceAuthChecksOnUploads: project.enforce_auth_checks_on_uploads?,
securityAndComplianceAccessLevel: project.security_and_compliance_access_level,
- containerRegistryAccessLevel: feature.container_registry_access_level
+ containerRegistryAccessLevel: feature.container_registry_access_level,
+ environmentsAccessLevel: feature.environments_access_level
}
end
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index 6e2e0a86446..dc53be330fe 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -22,14 +22,14 @@ module SearchHelper
resource_results(term)
when :generic
[
- generic_results(term),
- recent_items_autocomplete(term)
+ recent_items_autocomplete(term),
+ generic_results(term)
]
else
[
- generic_results(term),
+ recent_items_autocomplete(term),
resource_results(term),
- recent_items_autocomplete(term)
+ generic_results(term)
]
end
diff --git a/app/models/concerns/project_features_compatibility.rb b/app/models/concerns/project_features_compatibility.rb
index 900e8f7d39b..65b1cf023ec 100644
--- a/app/models/concerns/project_features_compatibility.rb
+++ b/app/models/concerns/project_features_compatibility.rb
@@ -94,6 +94,10 @@ module ProjectFeaturesCompatibility
write_feature_attribute_string(:container_registry_access_level, value)
end
+ def environments_access_level=(value)
+ write_feature_attribute_string(:environments_access_level, value)
+ end
+
# TODO: Remove this method after we drop support for project create/edit APIs to set the
# container_registry_enabled attribute. They can instead set the container_registry_access_level
# attribute.
diff --git a/app/models/project.rb b/app/models/project.rb
index 8e59a3599dd..cfa726ede41 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -446,7 +446,7 @@ class Project < ApplicationRecord
:repository_access_level, :package_registry_access_level, :pages_access_level,
:metrics_dashboard_access_level, :analytics_access_level,
:operations_access_level, :security_and_compliance_access_level,
- :container_registry_access_level,
+ :container_registry_access_level, :environments_access_level,
to: :project_feature, allow_nil: true
delegate :show_default_award_emojis, :show_default_award_emojis=,
diff --git a/app/models/project_feature.rb b/app/models/project_feature.rb
index 0a30e125c83..30d871a2756 100644
--- a/app/models/project_feature.rb
+++ b/app/models/project_feature.rb
@@ -21,6 +21,7 @@ class ProjectFeature < ApplicationRecord
security_and_compliance
container_registry
package_registry
+ environments
].freeze
EXPORTABLE_FEATURES = (FEATURES - [:security_and_compliance, :pages]).freeze
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index 9d121715d2c..a36aa5721f2 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -209,6 +209,7 @@ class ProjectPolicy < BasePolicy
analytics
operations
security_and_compliance
+ environments
]
features.each do |f|
@@ -366,7 +367,11 @@ class ProjectPolicy < BasePolicy
prevent(:metrics_dashboard)
end
- rule { operations_disabled }.policy do
+ condition(:split_operations_visibility_permissions) do
+ ::Feature.enabled?(:split_operations_visibility_permissions, @subject)
+ end
+
+ rule { ~split_operations_visibility_permissions & operations_disabled }.policy do
prevent(*create_read_update_admin_destroy(:feature_flag))
prevent(*create_read_update_admin_destroy(:environment))
prevent(*create_read_update_admin_destroy(:sentry_issue))
@@ -379,6 +384,11 @@ class ProjectPolicy < BasePolicy
prevent(:read_prometheus)
end
+ rule { split_operations_visibility_permissions & environments_disabled }.policy do
+ prevent(*create_read_update_admin_destroy(:environment))
+ prevent(*create_read_update_admin_destroy(:deployment))
+ end
+
rule { can?(:metrics_dashboard) }.policy do
enable :read_prometheus
enable :read_deployment
diff --git a/data/removals/15_0/removal_manage_ repository_push_audit_event.yml b/data/removals/15_0/removal_manage_repository_push_audit_event.yml
index 474a5c41a95..474a5c41a95 100644
--- a/data/removals/15_0/removal_manage_ repository_push_audit_event.yml
+++ b/data/removals/15_0/removal_manage_repository_push_audit_event.yml
diff --git a/lib/gitlab/import_export/project/import_export.yml b/lib/gitlab/import_export/project/import_export.yml
index 50ff6146174..1fdc374aa39 100644
--- a/lib/gitlab/import_export/project/import_export.yml
+++ b/lib/gitlab/import_export/project/import_export.yml
@@ -284,6 +284,7 @@ included_attributes:
- :security_and_compliance_access_level
- :container_registry_access_level
- :package_registry_access_level
+ - :environments_access_level
prometheus_metrics:
- :created_at
- :updated_at
@@ -686,6 +687,7 @@ included_attributes:
- :security_and_compliance_access_level
- :container_registry_access_level
- :package_registry_access_level
+ - :environments_access_level
- :allow_merge_on_skipped_pipeline
- :auto_devops_deploy_strategy
- :auto_devops_enabled
diff --git a/qa/qa/specs/features/api/3_create/gitaly/changing_repository_storage_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/changing_repository_storage_spec.rb
index cd1b7730fa9..5ee6dfdb8d8 100644
--- a/qa/qa/specs/features/api/3_create/gitaly/changing_repository_storage_spec.rb
+++ b/qa/qa/specs/features/api/3_create/gitaly/changing_repository_storage_spec.rb
@@ -67,6 +67,28 @@ module QA
it_behaves_like 'repository storage move'
end
+
+ # Note: This test doesn't have the :orchestrated tag because it runs in the Test::Integration::Praefect
+ # scenario with other tests that aren't considered orchestrated.
+ # It also runs on staging using nfs-file07 as non-cluster storage and nfs-file22 as cluster/praefect storage
+ context 'when moving from Gitaly Cluster to Gitaly', :requires_praefect, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/369204' do
+ let(:source_storage) { { type: :praefect, name: QA::Runtime::Env.praefect_repository_storage } }
+ let(:destination_storage) { { type: :gitaly, name: QA::Runtime::Env.non_cluster_repository_storage } }
+ let(:project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.name = 'repo-storage-move'
+ project.initialize_with_readme = true
+ project.repository_storage = source_storage[:name]
+ project.api_client = Runtime::API::Client.as_admin
+ end
+ end
+
+ before do
+ praefect_manager.gitlab = 'gitlab-gitaly-cluster'
+ end
+
+ it_behaves_like 'repository storage move'
+ end
end
end
end
diff --git a/rubocop/cop/gitlab/feature_available_usage.rb b/rubocop/cop/gitlab/feature_available_usage.rb
index b50bdd8ca43..fafe6c35b5f 100644
--- a/rubocop/cop/gitlab/feature_available_usage.rb
+++ b/rubocop/cop/gitlab/feature_available_usage.rb
@@ -23,6 +23,7 @@ module RuboCop
operations
security_and_compliance
container_registry
+ environments
].freeze
EE_FEATURES = %i[requirements].freeze
ALL_FEATURES = (FEATURES + EE_FEATURES).freeze
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb
index 5c8f5d1a603..107fa28a639 100644
--- a/spec/factories/projects.rb
+++ b/spec/factories/projects.rb
@@ -37,6 +37,7 @@ FactoryBot.define do
operations_access_level { ProjectFeature::ENABLED }
container_registry_access_level { ProjectFeature::ENABLED }
security_and_compliance_access_level { ProjectFeature::PRIVATE }
+ environments_access_level { ProjectFeature::ENABLED }
# we can't assign the delegated `#ci_cd_settings` attributes directly, as the
# `#ci_cd_settings` relation needs to be created first
diff --git a/spec/helpers/ci/pipeline_editor_helper_spec.rb b/spec/helpers/ci/pipeline_editor_helper_spec.rb
index bc9e47a4ca1..5d3837171d0 100644
--- a/spec/helpers/ci/pipeline_editor_helper_spec.rb
+++ b/spec/helpers/ci/pipeline_editor_helper_spec.rb
@@ -63,7 +63,7 @@ RSpec.describe Ci::PipelineEditorHelper do
"project-full-path" => project.full_path,
"project-namespace" => project.namespace.full_path,
"runner-help-page-path" => help_page_path('ci/runners/index'),
- "simulate-pipeline-help-page-path" => help_page_path('ci/lint', anchor: 'simulate-a-pipeline'),
+ "simulate-pipeline-help-page-path" => help_page_path('ci/pipeline_editor/index', anchor: 'simulate-a-cicd-pipeline'),
"total-branches" => project.repository.branches.length,
"validate-tab-illustration-path" => 'illustrations/validate.svg',
"yml-help-page-path" => help_page_path('ci/yaml/index')
@@ -94,7 +94,7 @@ RSpec.describe Ci::PipelineEditorHelper do
"project-full-path" => project.full_path,
"project-namespace" => project.namespace.full_path,
"runner-help-page-path" => help_page_path('ci/runners/index'),
- "simulate-pipeline-help-page-path" => help_page_path('ci/lint', anchor: 'simulate-a-pipeline'),
+ "simulate-pipeline-help-page-path" => help_page_path('ci/pipeline_editor/index', anchor: 'simulate-a-cicd-pipeline'),
"total-branches" => 0,
"validate-tab-illustration-path" => 'illustrations/validate.svg',
"yml-help-page-path" => help_page_path('ci/yaml/index')
diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb
index b443ebff552..200e93f8dff 100644
--- a/spec/helpers/projects_helper_spec.rb
+++ b/spec/helpers/projects_helper_spec.rb
@@ -966,7 +966,8 @@ RSpec.describe ProjectsHelper do
operationsAccessLevel: project.project_feature.operations_access_level,
showDefaultAwardEmojis: project.show_default_award_emojis?,
securityAndComplianceAccessLevel: project.security_and_compliance_access_level,
- containerRegistryAccessLevel: project.project_feature.container_registry_access_level
+ containerRegistryAccessLevel: project.project_feature.container_registry_access_level,
+ environmentsAccessLevel: project.project_feature.environments_access_level
)
end
diff --git a/spec/helpers/search_helper_spec.rb b/spec/helpers/search_helper_spec.rb
index 1ead1fc9b8b..513e2865ee3 100644
--- a/spec/helpers/search_helper_spec.rb
+++ b/spec/helpers/search_helper_spec.rb
@@ -74,19 +74,21 @@ RSpec.describe SearchHelper do
expect(result.keys).to match_array(%i[category id value label url avatar_url])
end
- it 'includes the users recently viewed issues', :aggregate_failures do
+ it 'includes the users recently viewed issues and project with correct order', :aggregate_failures do
recent_issues = instance_double(::Gitlab::Search::RecentIssues)
expect(::Gitlab::Search::RecentIssues).to receive(:new).with(user: user).and_return(recent_issues)
project1 = create(:project, :with_avatar, namespace: user.namespace)
project2 = create(:project, namespace: user.namespace)
issue1 = create(:issue, title: 'issue 1', project: project1)
issue2 = create(:issue, title: 'issue 2', project: project2)
+ project = create(:project, title: 'the search term')
+ project.add_developer(user)
expect(recent_issues).to receive(:search).with('the search term').and_return(Issue.id_in_ordered([issue1.id, issue2.id]))
results = search_autocomplete_opts("the search term")
- expect(results.count).to eq(2)
+ expect(results.count).to eq(3)
expect(results[0]).to include({
category: 'Recent issues',
@@ -103,6 +105,13 @@ RSpec.describe SearchHelper do
url: Gitlab::Routing.url_helpers.project_issue_path(issue2.project, issue2),
avatar_url: '' # This project didn't have an avatar so set this to ''
})
+
+ expect(results[2]).to include({
+ category: 'Projects',
+ id: project.id,
+ label: project.full_name,
+ url: Gitlab::Routing.url_helpers.project_path(project)
+ })
end
it 'includes the users recently viewed issues with the exact same name', :aggregate_failures do
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index bd60bb53d49..3ff830b825b 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -584,6 +584,7 @@ ProjectFeature:
- security_and_compliance_access_level
- container_registry_access_level
- package_registry_access_level
+- environments_access_level
- created_at
- updated_at
ProtectedBranch::MergeAccessLevel:
diff --git a/spec/models/concerns/project_features_compatibility_spec.rb b/spec/models/concerns/project_features_compatibility_spec.rb
index f2dc8464e86..6730b7a02f3 100644
--- a/spec/models/concerns/project_features_compatibility_spec.rb
+++ b/spec/models/concerns/project_features_compatibility_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe ProjectFeaturesCompatibility do
let(:project) { create(:project) }
let(:features_enabled) { %w(issues wiki builds merge_requests snippets security_and_compliance) }
- let(:features) { features_enabled + %w(repository pages operations container_registry package_registry) }
+ let(:features) { features_enabled + %w(repository pages operations container_registry package_registry environments) }
# We had issues_enabled, snippets_enabled, builds_enabled, merge_requests_enabled and issues_enabled fields on projects table
# All those fields got moved to a new table called project_feature and are now integers instead of booleans
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index b434b2c0332..fb6fc01ed88 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -831,6 +831,7 @@ RSpec.describe Project, factory_default: :keep do
it { is_expected.to delegate_method(:last_pipeline).to(:commit).allow_nil }
it { is_expected.to delegate_method(:container_registry_enabled?).to(:project_feature) }
it { is_expected.to delegate_method(:container_registry_access_level).to(:project_feature) }
+ it { is_expected.to delegate_method(:environments_access_level).to(:project_feature) }
describe 'read project settings' do
%i(
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index c041c72a0be..01a0a96be30 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -1930,6 +1930,10 @@ RSpec.describe ProjectPolicy do
describe 'operations feature' do
using RSpec::Parameterized::TableSyntax
+ before do
+ stub_feature_flags(split_operations_visibility_permissions: false)
+ end
+
let(:guest_operations_permissions) { [:read_environment, :read_deployment] }
let(:developer_operations_permissions) do
@@ -2002,38 +2006,95 @@ RSpec.describe ProjectPolicy do
end
end
- def project_subject(project_type)
- case project_type
- when :public
- public_project
- when :internal
- internal_project
+ def permissions_abilities(role)
+ case role
+ when :maintainer
+ maintainer_operations_permissions
+ when :developer
+ developer_operations_permissions
else
- private_project
+ guest_operations_permissions
end
end
+ end
+ end
- def user_subject(role)
- case role
- when :maintainer
- maintainer
- when :developer
- developer
- when :guest
- guest
- when :anonymous
- anonymous
+ describe 'environments feature' do
+ using RSpec::Parameterized::TableSyntax
+
+ let(:guest_environments_permissions) { [:read_environment, :read_deployment] }
+
+ let(:developer_environments_permissions) do
+ guest_environments_permissions + [
+ :create_environment, :create_deployment, :update_environment, :update_deployment, :destroy_environment
+ ]
+ end
+
+ let(:maintainer_environments_permissions) do
+ developer_environments_permissions + [:admin_environment, :admin_deployment]
+ end
+
+ where(:project_visibility, :access_level, :role, :allowed) do
+ :public | ProjectFeature::ENABLED | :maintainer | true
+ :public | ProjectFeature::ENABLED | :developer | true
+ :public | ProjectFeature::ENABLED | :guest | true
+ :public | ProjectFeature::ENABLED | :anonymous | true
+ :public | ProjectFeature::PRIVATE | :maintainer | true
+ :public | ProjectFeature::PRIVATE | :developer | true
+ :public | ProjectFeature::PRIVATE | :guest | true
+ :public | ProjectFeature::PRIVATE | :anonymous | false
+ :public | ProjectFeature::DISABLED | :maintainer | false
+ :public | ProjectFeature::DISABLED | :developer | false
+ :public | ProjectFeature::DISABLED | :guest | false
+ :public | ProjectFeature::DISABLED | :anonymous | false
+ :internal | ProjectFeature::ENABLED | :maintainer | true
+ :internal | ProjectFeature::ENABLED | :developer | true
+ :internal | ProjectFeature::ENABLED | :guest | true
+ :internal | ProjectFeature::ENABLED | :anonymous | false
+ :internal | ProjectFeature::PRIVATE | :maintainer | true
+ :internal | ProjectFeature::PRIVATE | :developer | true
+ :internal | ProjectFeature::PRIVATE | :guest | true
+ :internal | ProjectFeature::PRIVATE | :anonymous | false
+ :internal | ProjectFeature::DISABLED | :maintainer | false
+ :internal | ProjectFeature::DISABLED | :developer | false
+ :internal | ProjectFeature::DISABLED | :guest | false
+ :internal | ProjectFeature::DISABLED | :anonymous | false
+ :private | ProjectFeature::ENABLED | :maintainer | true
+ :private | ProjectFeature::ENABLED | :developer | true
+ :private | ProjectFeature::ENABLED | :guest | false
+ :private | ProjectFeature::ENABLED | :anonymous | false
+ :private | ProjectFeature::PRIVATE | :maintainer | true
+ :private | ProjectFeature::PRIVATE | :developer | true
+ :private | ProjectFeature::PRIVATE | :guest | false
+ :private | ProjectFeature::PRIVATE | :anonymous | false
+ :private | ProjectFeature::DISABLED | :maintainer | false
+ :private | ProjectFeature::DISABLED | :developer | false
+ :private | ProjectFeature::DISABLED | :guest | false
+ :private | ProjectFeature::DISABLED | :anonymous | false
+ end
+
+ with_them do
+ let(:current_user) { user_subject(role) }
+ let(:project) { project_subject(project_visibility) }
+
+ it 'allows/disallows the abilities based on the environments feature access level' do
+ project.project_feature.update!(environments_access_level: access_level)
+
+ if allowed
+ expect_allowed(*permissions_abilities(role))
+ else
+ expect_disallowed(*permissions_abilities(role))
end
end
def permissions_abilities(role)
case role
when :maintainer
- maintainer_operations_permissions
+ maintainer_environments_permissions
when :developer
- developer_operations_permissions
+ developer_environments_permissions
else
- guest_operations_permissions
+ guest_environments_permissions
end
end
end
@@ -2481,4 +2542,28 @@ RSpec.describe ProjectPolicy do
end
end
end
+
+ def project_subject(project_type)
+ case project_type
+ when :public
+ public_project
+ when :internal
+ internal_project
+ else
+ private_project
+ end
+ end
+
+ def user_subject(role)
+ case role
+ when :maintainer
+ maintainer
+ when :developer
+ developer
+ when :guest
+ guest
+ when :anonymous
+ anonymous
+ end
+ end
end
diff --git a/spec/tooling/lib/tooling/find_codeowners_spec.rb b/spec/tooling/lib/tooling/find_codeowners_spec.rb
index 10c2a076847..5f6f83ab2c7 100644
--- a/spec/tooling/lib/tooling/find_codeowners_spec.rb
+++ b/spec/tooling/lib/tooling/find_codeowners_spec.rb
@@ -11,6 +11,7 @@ RSpec.describe Tooling::FindCodeowners do
allow(subject).to receive(:load_config).and_return(
'[Section name]': {
'@group': {
+ entries: %w[whatever entries],
allow: {
keywords: %w[dir0 file],
patterns: ['/%{keyword}/**/*', '/%{keyword}']
@@ -31,8 +32,11 @@ RSpec.describe Tooling::FindCodeowners do
end
end.to output(<<~CODEOWNERS).to_stdout
[Section name]
+ whatever @group
+ entries @group
/dir0/dir1/ @group
/file @group
+
CODEOWNERS
end
end
@@ -57,21 +61,33 @@ RSpec.describe Tooling::FindCodeowners do
patterns: ['%{keyword}']
}
}
+ },
+ '[Compliance]': {
+ '@gitlab-org/manage/compliance': {
+ entries: %w[
+ /ee/app/services/audit_events/build_service.rb
+ ],
+ allow: {
+ patterns: %w[
+ /ee/app/services/audit_events/*
+ ]
+ }
+ }
}
}
)
end
it 'expands the allow and deny list with keywords and patterns' do
- subject.load_definitions.each do |section, group_defintions|
- group_defintions.each do |group, definitions|
- expect(definitions[:allow]).to be_an(Array)
- expect(definitions[:deny]).to be_an(Array)
- end
+ group_defintions = subject.load_definitions[:'[Authentication and Authorization]']
+
+ group_defintions.each do |group, definitions|
+ expect(definitions[:allow]).to be_an(Array)
+ expect(definitions[:deny]).to be_an(Array)
end
end
- it 'expands the auth group' do
+ it 'expands the patterns for the auth group' do
auth = subject.load_definitions.dig(
:'[Authentication and Authorization]',
:'@gitlab-org/manage/authentication-and-authorization')
@@ -95,6 +111,21 @@ RSpec.describe Tooling::FindCodeowners do
]
)
end
+
+ it 'retains the array and expands the patterns for the compliance group' do
+ compliance = subject.load_definitions.dig(
+ :'[Compliance]',
+ :'@gitlab-org/manage/compliance')
+
+ expect(compliance).to eq(
+ entries: %w[
+ /ee/app/services/audit_events/build_service.rb
+ ],
+ allow: %w[
+ /ee/app/services/audit_events/*
+ ]
+ )
+ end
end
describe '#load_config' do
diff --git a/tooling/config/CODEOWNERS.yml b/tooling/config/CODEOWNERS.yml
index 18f3abfc97b..9a3a7e8e5be 100644
--- a/tooling/config/CODEOWNERS.yml
+++ b/tooling/config/CODEOWNERS.yml
@@ -55,3 +55,24 @@
- '/lib/gitlab/conan_token.rb'
patterns:
- '%{keyword}'
+
+'[Compliance]':
+ '@gitlab-org/manage/compliance':
+ entries:
+ - '/ee/app/services/audit_events/build_service.rb'
+ - '/ee/spec/services/audit_events/custom_audit_event_service_spec.rb'
+ allow:
+ keywords:
+ - audit
+ patterns:
+ - '**%{keyword}**'
+ deny:
+ keywords:
+ - '*.png'
+ - '*bundler-audit*'
+ - '/ee/app/services/audit_events/*'
+ - '/ee/spec/services/audit_events/*'
+ - '/ee/spec/services/ci/*'
+ - '/ee/spec/services/personal_access_tokens/*'
+ patterns:
+ - '%{keyword}'
diff --git a/tooling/lib/tooling/find_codeowners.rb b/tooling/lib/tooling/find_codeowners.rb
index 3b50b33d85c..6a90f86eecc 100644
--- a/tooling/lib/tooling/find_codeowners.rb
+++ b/tooling/lib/tooling/find_codeowners.rb
@@ -9,37 +9,10 @@ module Tooling
puts section
group_defintions.each do |group, list|
- matched_files = git_ls_files.each_line.select do |line|
- list[:allow].find do |pattern|
- path = "/#{line.chomp}"
+ print_entries(group, list[:entries]) if list[:entries]
+ print_expanded_entries(group, list) if list[:allow]
- path_matches?(pattern, path) &&
- list[:deny].none? { |pattern| path_matches?(pattern, path) }
- end
- end
-
- consolidated = consolidate_paths(matched_files)
- consolidated_again = consolidate_paths(consolidated)
-
- # Consider the directory structure is a tree structure:
- # https://en.wikipedia.org/wiki/Tree_(data_structure)
- # After we consolidated the leaf entries, it could be possible that
- # we can consolidate further for the new leaves. Repeat this
- # process until we see no improvements.
- while consolidated_again.size < consolidated.size
- consolidated = consolidated_again
- consolidated_again = consolidate_paths(consolidated)
- end
-
- consolidated.each do |line|
- path = line.chomp
-
- if File.directory?(path)
- puts "/#{path}/ #{group}"
- else
- puts "/#{path} #{group}"
- end
- end
+ puts
end
end
end
@@ -50,10 +23,20 @@ module Tooling
result.each do |section, group_defintions|
group_defintions.each do |group, definitions|
definitions.transform_values! do |rules|
- rules[:keywords].flat_map do |keyword|
- rules[:patterns].map do |pattern|
- pattern % { keyword: keyword }
+ case rules
+ when Hash
+ case rules[:keywords]
+ when Array
+ rules[:keywords].flat_map do |keyword|
+ rules[:patterns].map do |pattern|
+ pattern % { keyword: keyword }
+ end
+ end
+ else
+ rules[:patterns]
end
+ when Array
+ rules
end
end
end
@@ -118,6 +101,49 @@ module Tooling
private
+ def print_entries(group, entries)
+ entries.each do |entry|
+ puts "#{entry} #{group}"
+ end
+ end
+
+ def print_expanded_entries(group, list)
+ matched_files = git_ls_files.each_line.select do |line|
+ list[:allow].find do |pattern|
+ path = "/#{line.chomp}"
+
+ path_matches?(pattern, path) &&
+ (
+ list[:deny].nil? ||
+ list[:deny].none? { |pattern| path_matches?(pattern, path) }
+ )
+ end
+ end
+
+ consolidated = consolidate_paths(matched_files)
+ consolidated_again = consolidate_paths(consolidated)
+
+ # Consider the directory structure is a tree structure:
+ # https://en.wikipedia.org/wiki/Tree_(data_structure)
+ # After we consolidated the leaf entries, it could be possible that
+ # we can consolidate further for the new leaves. Repeat this
+ # process until we see no improvements.
+ while consolidated_again.size < consolidated.size
+ consolidated = consolidated_again
+ consolidated_again = consolidate_paths(consolidated)
+ end
+
+ consolidated.each do |line|
+ path = line.chomp
+
+ if File.directory?(path)
+ puts "/#{path}/ #{group}"
+ else
+ puts "/#{path} #{group}"
+ end
+ end
+ end
+
def find_dir_maxdepth_1(dir)
`find #{dir} -maxdepth 1`
end