diff --git a/.gitlab/ci/release-environments/main.gitlab-ci.yml b/.gitlab/ci/release-environments/main.gitlab-ci.yml index 664b3ec2c48..8ff0f160565 100644 --- a/.gitlab/ci/release-environments/main.gitlab-ci.yml +++ b/.gitlab/ci/release-environments/main.gitlab-ci.yml @@ -55,9 +55,9 @@ release-environments-qa: stage: qa extends: - .qa-base - timeout: 4h + timeout: 3h variables: - QA_SCENARIO: "Test::Instance::Any" + QA_SCENARIO: "Test::Instance::Smoke" RELEASE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_SHA}" GITLAB_QA_OPTS: --address "https://gitlab.${ENVIRONMENT}.release.gke.gitlab.net" GITLAB_INITIAL_ROOT_PASSWORD: "${RELEASE_ENVIRONMENTS_ROOT_PASSWORD}" diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 12c5d5162ce..59a17b629e6 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -50,6 +50,7 @@ class Projects::IssuesController < Projects::ApplicationController push_frontend_feature_flag(:issues_list_drawer, project) push_frontend_feature_flag(:linked_work_items, project) push_frontend_feature_flag(:display_work_item_epic_issue_sidebar, project) + push_frontend_feature_flag(:notifications_todos_buttons, current_user) end before_action only: [:index, :show] do @@ -69,7 +70,6 @@ class Projects::IssuesController < Projects::ApplicationController push_frontend_feature_flag(:epic_widget_edit_confirmation, project) push_frontend_feature_flag(:display_work_item_epic_issue_sidebar, project) push_force_frontend_feature_flag(:linked_work_items, project.linked_work_items_feature_flag_enabled?) - push_frontend_feature_flag(:notifications_todos_buttons, current_user) push_frontend_feature_flag(:mention_autocomplete_backend_filtering, project) end diff --git a/app/presenters/projects/security/configuration_presenter.rb b/app/presenters/projects/security/configuration_presenter.rb index 8fab1bb5735..64127c9ac3e 100644 --- a/app/presenters/projects/security/configuration_presenter.rb +++ b/app/presenters/projects/security/configuration_presenter.rb @@ -24,7 +24,8 @@ module Projects auto_fix_user_path: auto_fix_user_path, security_training_enabled: project.security_training_available?, continuous_vulnerability_scans_enabled: continuous_vulnerability_scans_enabled, - container_scanning_for_registry_enabled: container_scanning_for_registry_enabled + container_scanning_for_registry_enabled: container_scanning_for_registry_enabled, + pre_receive_secret_detection_enabled: pre_receive_secret_detection_enabled } end @@ -98,6 +99,7 @@ module Projects def continuous_vulnerability_scans_enabled; end def container_scanning_for_registry_enabled; end + def pre_receive_secret_detection_enabled; end end end end diff --git a/app/validators/json_schemas/member_role_permissions.json b/app/validators/json_schemas/member_role_permissions.json new file mode 100644 index 00000000000..9d14329c367 --- /dev/null +++ b/app/validators/json_schemas/member_role_permissions.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Permissions on custom roles", + "type": "object", + "additionalProperties": false, + "properties": { + "admin_cicd_variables": { + "type": "boolean" + }, + "admin_group_member": { + "type": "boolean" + }, + "admin_merge_request": { + "type": "boolean" + }, + "admin_terraform_state": { + "type": "boolean" + }, + "admin_vulnerability": { + "type": "boolean" + }, + "archive_project": { + "type": "boolean" + }, + "manage_group_access_tokens": { + "type": "boolean" + }, + "manage_project_access_tokens": { + "type": "boolean" + }, + "read_code": { + "type": "boolean" + }, + "read_dependency": { + "type": "boolean" + }, + "read_vulnerability": { + "type": "boolean" + }, + "remove_group": { + "type": "boolean" + }, + "remove_project": { + "type": "boolean" + } + } +} diff --git a/config/feature_flags/ops/code_suggestions_tokens_api.yml b/config/feature_flags/ops/ai_duo_code_suggestions_switch.yml similarity index 83% rename from config/feature_flags/ops/code_suggestions_tokens_api.yml rename to config/feature_flags/ops/ai_duo_code_suggestions_switch.yml index 2de8afc0428..87f42f233e0 100644 --- a/config/feature_flags/ops/code_suggestions_tokens_api.yml +++ b/config/feature_flags/ops/ai_duo_code_suggestions_switch.yml @@ -1,5 +1,5 @@ --- -name: code_suggestions_tokens_api +name: ai_duo_code_suggestions_switch introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/120892 rollout_issue_url: milestone: '16.1' diff --git a/db/docs/alert_management_alerts.yml b/db/docs/alert_management_alerts.yml index 4e3f4151165..b38813f48c9 100644 --- a/db/docs/alert_management_alerts.yml +++ b/db/docs/alert_management_alerts.yml @@ -7,4 +7,12 @@ feature_categories: description: Persists incoming alert data including its payload introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29864 milestone: '13.0' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +sharding_key: + project_id: projects diff --git a/db/docs/alert_management_http_integrations.yml b/db/docs/alert_management_http_integrations.yml index 4eb824f74ec..6352d9b0ed8 100644 --- a/db/docs/alert_management_http_integrations.yml +++ b/db/docs/alert_management_http_integrations.yml @@ -7,4 +7,12 @@ feature_categories: description: Persists settings for alert HTTP integrations introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/43634 milestone: '13.5' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +sharding_key: + project_id: projects diff --git a/db/docs/customer_relations_contacts.yml b/db/docs/customer_relations_contacts.yml index dcb7e3184dd..17d59f9e38c 100644 --- a/db/docs/customer_relations_contacts.yml +++ b/db/docs/customer_relations_contacts.yml @@ -4,7 +4,16 @@ classes: - CustomerRelations::Contact feature_categories: - service_desk -description: Contacts, against which time can be spent by users on issues using the CRM functionality +description: Contacts, against which time can be spent by users on issues using the + CRM functionality introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67985 milestone: '14.3' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +sharding_key: + group_id: namespaces diff --git a/db/docs/group_crm_settings.yml b/db/docs/group_crm_settings.yml index 3165cdffb02..d9c81e4418b 100644 --- a/db/docs/group_crm_settings.yml +++ b/db/docs/group_crm_settings.yml @@ -8,3 +8,5 @@ description: Group-level settings for CRM-related features introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76983 milestone: '14.7' gitlab_schema: gitlab_main_cell +sharding_key: + group_id: namespaces diff --git a/db/docs/incident_management_escalation_policies.yml b/db/docs/incident_management_escalation_policies.yml index 74f58525767..df7a5771779 100644 --- a/db/docs/incident_management_escalation_policies.yml +++ b/db/docs/incident_management_escalation_policies.yml @@ -7,4 +7,12 @@ feature_categories: description: Persists information about escalation policies in a project introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60685 milestone: '13.12' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +sharding_key: + project_id: projects diff --git a/db/docs/incident_management_oncall_schedules.yml b/db/docs/incident_management_oncall_schedules.yml index b2ddd795b30..7cd95658376 100644 --- a/db/docs/incident_management_oncall_schedules.yml +++ b/db/docs/incident_management_oncall_schedules.yml @@ -8,4 +8,12 @@ feature_categories: description: Persists on-call schedules for incident management in a project introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/47407 milestone: '13.7' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +sharding_key: + project_id: projects diff --git a/db/docs/incident_management_timeline_event_tags.yml b/db/docs/incident_management_timeline_event_tags.yml index 9243616d26a..8b2354bfda7 100644 --- a/db/docs/incident_management_timeline_event_tags.yml +++ b/db/docs/incident_management_timeline_event_tags.yml @@ -8,3 +8,5 @@ description: Persists tags for timeline events in a project. introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/100271 milestone: '15.6' gitlab_schema: gitlab_main_cell +sharding_key: + project_id: projects diff --git a/db/docs/incident_management_timeline_events.yml b/db/docs/incident_management_timeline_events.yml index 428d25d71cb..876112b01f1 100644 --- a/db/docs/incident_management_timeline_events.yml +++ b/db/docs/incident_management_timeline_events.yml @@ -7,4 +7,12 @@ feature_categories: description: Persists timeline events for an incident introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74530 milestone: '14.6' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +sharding_key: + project_id: projects diff --git a/db/docs/project_alerting_settings.yml b/db/docs/project_alerting_settings.yml index 629ba0ba834..25a853153aa 100644 --- a/db/docs/project_alerting_settings.yml +++ b/db/docs/project_alerting_settings.yml @@ -7,4 +7,12 @@ feature_categories: description: Persists project-level tokens for manual Prometheus installations introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/9334 milestone: '11.8' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +sharding_key: + project_id: projects diff --git a/db/docs/project_incident_management_settings.yml b/db/docs/project_incident_management_settings.yml index 2e9812e9bf0..4511e61951d 100644 --- a/db/docs/project_incident_management_settings.yml +++ b/db/docs/project_incident_management_settings.yml @@ -7,4 +7,12 @@ feature_categories: description: Persists project settings for incident management introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/9744 milestone: '11.9' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +sharding_key: + project_id: projects diff --git a/db/docs/prometheus_alerts.yml b/db/docs/prometheus_alerts.yml index cfab6c1c094..15f189d0ac4 100644 --- a/db/docs/prometheus_alerts.yml +++ b/db/docs/prometheus_alerts.yml @@ -7,4 +7,12 @@ feature_categories: description: Persists information about prometheus alerts from an environment introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6590 milestone: '11.2' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +sharding_key: + project_id: projects diff --git a/db/docs/service_desk_custom_email_credentials.yml b/db/docs/service_desk_custom_email_credentials.yml index fdfdce8fc21..7f3260e2179 100644 --- a/db/docs/service_desk_custom_email_credentials.yml +++ b/db/docs/service_desk_custom_email_credentials.yml @@ -4,8 +4,15 @@ classes: - ServiceDesk::CustomEmailCredential feature_categories: - service_desk -description: Holds all the credentials for custom email - addresses for Service Desk +description: Holds all the credentials for custom email addresses for Service Desk introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/114917 milestone: '15.11' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +sharding_key: + project_id: projects diff --git a/db/docs/service_desk_custom_email_verifications.yml b/db/docs/service_desk_custom_email_verifications.yml index cec5db374d9..c47b840e352 100644 --- a/db/docs/service_desk_custom_email_verifications.yml +++ b/db/docs/service_desk_custom_email_verifications.yml @@ -8,4 +8,12 @@ description: Holds the verification state and additional information for custom addresses for Service Desk introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/112938 milestone: '15.10' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +sharding_key: + project_id: projects diff --git a/db/docs/service_desk_settings.yml b/db/docs/service_desk_settings.yml index 90c304c480c..7d1cc640771 100644 --- a/db/docs/service_desk_settings.yml +++ b/db/docs/service_desk_settings.yml @@ -7,4 +7,12 @@ feature_categories: description: Settings related to Service Desk such as templates to use for email notifications introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/19515 milestone: '12.6' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +sharding_key: + project_id: projects diff --git a/db/docs/status_page_settings.yml b/db/docs/status_page_settings.yml index 0e948b6da5c..c7fca009b2d 100644 --- a/db/docs/status_page_settings.yml +++ b/db/docs/status_page_settings.yml @@ -7,4 +7,12 @@ feature_categories: description: Project settings related to Status Page introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25863 milestone: '12.9' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +sharding_key: + project_id: projects diff --git a/db/docs/zoom_meetings.yml b/db/docs/zoom_meetings.yml index 95bb98bf896..37624efc42d 100644 --- a/db/docs/zoom_meetings.yml +++ b/db/docs/zoom_meetings.yml @@ -7,4 +7,12 @@ feature_categories: description: Persists Zoom meetings, its associations and its metadata introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17890 milestone: '12.5' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +sharding_key: + project_id: projects diff --git a/db/migrate/20240228141630_add_permissions_to_member_roles.rb b/db/migrate/20240228141630_add_permissions_to_member_roles.rb new file mode 100644 index 00000000000..477504af07a --- /dev/null +++ b/db/migrate/20240228141630_add_permissions_to_member_roles.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddPermissionsToMemberRoles < Gitlab::Database::Migration[2.2] + milestone '16.11' + + def change + add_column :member_roles, :permissions, :jsonb, null: false, default: {} + end +end diff --git a/db/migrate/20240228142222_copy_permissions_on_member_roles.rb b/db/migrate/20240228142222_copy_permissions_on_member_roles.rb new file mode 100644 index 00000000000..5553ffab36c --- /dev/null +++ b/db/migrate/20240228142222_copy_permissions_on_member_roles.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +class CopyPermissionsOnMemberRoles < Gitlab::Database::Migration[2.2] + include Gitlab::Database::SchemaHelpers + + milestone '16.11' + disable_ddl_transaction! + + FUNCTION_NAME = 'copy_member_roles_permissions' + TRIGGER_NAME = 'trigger_copy_member_roles_permissions' + + def up + execute(<<~SQL) + CREATE OR REPLACE FUNCTION #{FUNCTION_NAME}() + RETURNS trigger + LANGUAGE plpgsql + AS $$ + BEGIN + -- when permissions have not changed + IF (current_query() !~ '\ypermissions\y') THEN + NEW.permissions = to_jsonb (( + SELECT + perm_cols + FROM ( + SELECT + NEW.admin_cicd_variables, + NEW.admin_group_member, + NEW.admin_merge_request, + NEW.admin_terraform_state, + NEW.admin_vulnerability, + NEW.archive_project, + NEW.manage_group_access_tokens, + NEW.manage_project_access_tokens, + NEW.read_code, + NEW.read_dependency, + NEW.read_vulnerability, + NEW.remove_group, + NEW.remove_project) perm_cols)); + -- when permissions have changed + ELSE + NEW.admin_cicd_variables = COALESCE((NEW.permissions->'admin_cicd_variables')::BOOLEAN, FALSE); + NEW.admin_group_member = COALESCE((NEW.permissions->'admin_group_member')::BOOLEAN, FALSE); + NEW.admin_merge_request = COALESCE((NEW.permissions->'admin_merge_request')::BOOLEAN, FALSE); + NEW.admin_terraform_state = COALESCE((NEW.permissions->'admin_terraform_state')::BOOLEAN, FALSE); + NEW.admin_vulnerability = COALESCE((NEW.permissions->'admin_vulnerability')::BOOLEAN, FALSE); + NEW.archive_project = COALESCE((NEW.permissions->'archive_project')::BOOLEAN, FALSE); + NEW.manage_group_access_tokens = COALESCE((NEW.permissions->'manage_group_access_tokens')::BOOLEAN, FALSE); + NEW.manage_project_access_tokens = COALESCE((NEW.permissions->'manage_project_access_tokens')::BOOLEAN, FALSE); + NEW.read_code = COALESCE((NEW.permissions->'read_code')::BOOLEAN, FALSE); + NEW.read_dependency = COALESCE((NEW.permissions->'read_dependency')::BOOLEAN, FALSE); + NEW.read_vulnerability = COALESCE((NEW.permissions->'read_vulnerability')::BOOLEAN, FALSE); + NEW.remove_group = COALESCE((NEW.permissions->'remove_group')::BOOLEAN, FALSE); + NEW.remove_project = COALESCE((NEW.permissions->'remove_project')::BOOLEAN, FALSE); + END IF; + RETURN NEW; + END; + $$ + SQL + + execute(<<~SQL) + CREATE OR REPLACE TRIGGER #{TRIGGER_NAME} + BEFORE INSERT OR UPDATE ON member_roles + FOR EACH ROW + EXECUTE FUNCTION #{FUNCTION_NAME}(); + SQL + end + + def down + drop_trigger(:member_roles, TRIGGER_NAME) + drop_function(FUNCTION_NAME) + end +end diff --git a/db/migrate/20240228144013_migrate_custom_permissions.rb b/db/migrate/20240228144013_migrate_custom_permissions.rb new file mode 100644 index 00000000000..25254efa3ec --- /dev/null +++ b/db/migrate/20240228144013_migrate_custom_permissions.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +class MigrateCustomPermissions < Gitlab::Database::Migration[2.2] + milestone '16.11' + restrict_gitlab_migration gitlab_schema: :gitlab_main + disable_ddl_transaction! + + PERMISSION_COLUMNS = %w[ + admin_cicd_variables + admin_group_member + admin_merge_request + admin_terraform_state + admin_vulnerability + archive_project + manage_group_access_tokens + manage_project_access_tokens + read_code + read_dependency + read_vulnerability + remove_group + remove_project + ].join(', ') + + def up + update_value = Arel.sql("(SELECT to_jsonb ((SELECT perm_cols FROM (SELECT #{PERMISSION_COLUMNS}) perm_cols)))") + update_column_in_batches(:member_roles, :permissions, update_value) + end + + def down + update_column_in_batches(:member_roles, :permissions, '{}') + end +end diff --git a/db/migrate/20240325150539_add_pre_receive_secret_detection_enabled_to_project_security_settings.rb b/db/migrate/20240325150539_add_pre_receive_secret_detection_enabled_to_project_security_settings.rb new file mode 100644 index 00000000000..d08717e4d49 --- /dev/null +++ b/db/migrate/20240325150539_add_pre_receive_secret_detection_enabled_to_project_security_settings.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class AddPreReceiveSecretDetectionEnabledToProjectSecuritySettings < Gitlab::Database::Migration[2.2] + milestone '16.11' + + enable_lock_retries! + TABLE_NAME = :project_security_settings + COLUMN_NAME = :pre_receive_secret_detection_enabled + + def up + add_column TABLE_NAME, COLUMN_NAME, :boolean, null: false, + default: false + end + + def down + remove_column TABLE_NAME, COLUMN_NAME + end +end diff --git a/db/post_migrate/20240321123441_remove_copy_permissions_on_member_roles.rb b/db/post_migrate/20240321123441_remove_copy_permissions_on_member_roles.rb new file mode 100644 index 00000000000..f37896c2b45 --- /dev/null +++ b/db/post_migrate/20240321123441_remove_copy_permissions_on_member_roles.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +class RemoveCopyPermissionsOnMemberRoles < Gitlab::Database::Migration[2.2] + include Gitlab::Database::SchemaHelpers + + milestone '16.11' + disable_ddl_transaction! + + FUNCTION_NAME = 'copy_member_roles_permissions' + TRIGGER_NAME = 'trigger_copy_member_roles_permissions' + + def up + drop_trigger(:member_roles, TRIGGER_NAME) + drop_function(FUNCTION_NAME) + end + + def down + execute(<<~SQL) + CREATE OR REPLACE FUNCTION #{FUNCTION_NAME}() + RETURNS trigger + LANGUAGE plpgsql + AS $$ + BEGIN + -- when permissions have not changed + IF (current_query() !~ '\ypermissions\y') THEN + NEW.permissions = to_jsonb (( + SELECT + perm_cols + FROM ( + SELECT + NEW.admin_cicd_variables, + NEW.admin_group_member, + NEW.admin_merge_request, + NEW.admin_terraform_state, + NEW.admin_vulnerability, + NEW.archive_project, + NEW.manage_group_access_tokens, + NEW.manage_project_access_tokens, + NEW.read_code, + NEW.read_dependency, + NEW.read_vulnerability, + NEW.remove_group, + NEW.remove_project) perm_cols)); + -- when permissions have changed + ELSE + NEW.admin_cicd_variables = COALESCE((NEW.permissions->'admin_cicd_variables')::BOOLEAN, FALSE); + NEW.admin_group_member = COALESCE((NEW.permissions->'admin_group_member')::BOOLEAN, FALSE); + NEW.admin_merge_request = COALESCE((NEW.permissions->'admin_merge_request')::BOOLEAN, FALSE); + NEW.admin_terraform_state = COALESCE((NEW.permissions->'admin_terraform_state')::BOOLEAN, FALSE); + NEW.admin_vulnerability = COALESCE((NEW.permissions->'admin_vulnerability')::BOOLEAN, FALSE); + NEW.archive_project = COALESCE((NEW.permissions->'archive_project')::BOOLEAN, FALSE); + NEW.manage_group_access_tokens = COALESCE((NEW.permissions->'manage_group_access_tokens')::BOOLEAN, FALSE); + NEW.manage_project_access_tokens = COALESCE((NEW.permissions->'manage_project_access_tokens')::BOOLEAN, FALSE); + NEW.read_code = COALESCE((NEW.permissions->'read_code')::BOOLEAN, FALSE); + NEW.read_dependency = COALESCE((NEW.permissions->'read_dependency')::BOOLEAN, FALSE); + NEW.read_vulnerability = COALESCE((NEW.permissions->'read_vulnerability')::BOOLEAN, FALSE); + NEW.remove_group = COALESCE((NEW.permissions->'remove_group')::BOOLEAN, FALSE); + NEW.remove_project = COALESCE((NEW.permissions->'remove_project')::BOOLEAN, FALSE); + END IF; + RETURN NEW; + END; + $$ + SQL + + execute(<<~SQL) + CREATE OR REPLACE TRIGGER #{TRIGGER_NAME} + BEFORE INSERT OR UPDATE ON member_roles + FOR EACH ROW + EXECUTE FUNCTION #{FUNCTION_NAME}(); + SQL + end +end diff --git a/db/schema_migrations/20240228141630 b/db/schema_migrations/20240228141630 new file mode 100644 index 00000000000..e1c86420d70 --- /dev/null +++ b/db/schema_migrations/20240228141630 @@ -0,0 +1 @@ +e87e345f4f1c23d7da6139d650f2495d19f29861bc4687a500004cb16d66ff1c \ No newline at end of file diff --git a/db/schema_migrations/20240228142222 b/db/schema_migrations/20240228142222 new file mode 100644 index 00000000000..6afbc966878 --- /dev/null +++ b/db/schema_migrations/20240228142222 @@ -0,0 +1 @@ +b62e7414bc855cffc756356a4d737a7180ef059d5247b46af06ad004a40ed052 \ No newline at end of file diff --git a/db/schema_migrations/20240228144013 b/db/schema_migrations/20240228144013 new file mode 100644 index 00000000000..6c09b03c998 --- /dev/null +++ b/db/schema_migrations/20240228144013 @@ -0,0 +1 @@ +e288768e45871e930fa0ecd6fb2ebeec2ac8ab838ce3957a2f73c398bfd7a619 \ No newline at end of file diff --git a/db/schema_migrations/20240321123441 b/db/schema_migrations/20240321123441 new file mode 100644 index 00000000000..04941d0bfba --- /dev/null +++ b/db/schema_migrations/20240321123441 @@ -0,0 +1 @@ +9440a6ae18916cd700585f419d6bc22e0a44f4eeeef3402f0522bd26dce79be9 \ No newline at end of file diff --git a/db/schema_migrations/20240325150539 b/db/schema_migrations/20240325150539 new file mode 100644 index 00000000000..881b21526b6 --- /dev/null +++ b/db/schema_migrations/20240325150539 @@ -0,0 +1 @@ +c7f58b9a72200dcbf1895ee1d9d0f75eca278211cadd1c325565f253c250c224 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 0e41ff00a9f..42f6d32da4d 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -10794,6 +10794,7 @@ CREATE TABLE member_roles ( admin_cicd_variables boolean DEFAULT false NOT NULL, remove_group boolean DEFAULT false NOT NULL, occupies_seat boolean DEFAULT false NOT NULL, + permissions jsonb DEFAULT '{}'::jsonb NOT NULL, CONSTRAINT check_4364846f58 CHECK ((char_length(description) <= 255)), CONSTRAINT check_9907916995 CHECK ((char_length(name) <= 255)) ); @@ -14346,7 +14347,8 @@ CREATE TABLE project_security_settings ( auto_fix_dependency_scanning boolean DEFAULT true NOT NULL, auto_fix_sast boolean DEFAULT true NOT NULL, continuous_vulnerability_scans_enabled boolean DEFAULT false NOT NULL, - container_scanning_for_registry_enabled boolean DEFAULT false NOT NULL + container_scanning_for_registry_enabled boolean DEFAULT false NOT NULL, + pre_receive_secret_detection_enabled boolean DEFAULT false NOT NULL ); CREATE SEQUENCE project_security_settings_project_id_seq diff --git a/doc/api/integrations.md b/doc/api/integrations.md index e8a1a26d5f5..bbf2637544f 100644 --- a/doc/api/integrations.md +++ b/doc/api/integrations.md @@ -1769,7 +1769,7 @@ Parameters: | --------- | ---- | -------- | ----------- | | `token` | string | true | The Telegram bot token (for example, `123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11`). | | `room` | string | true | Unique identifier for the target chat or the username of the target channel (in the format `@channelusername`). | -| `thread` | integer | false | Unique identifier for the target message thread (topic in a forum supergroup). | +| `thread` | integer | false | Unique identifier for the target message thread (topic in a forum supergroup). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/441097) in GitLab 16.11. | | `notify_only_broken_pipelines` | boolean | false | Send notifications for broken pipelines. | | `branches_to_be_notified` | string | false | Branches to send notifications for ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/134361) in GitLab 16.5). Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `push_events` | boolean | true | Enable notifications for push events. | diff --git a/doc/api/openapi/openapi.yaml b/doc/api/openapi/openapi.yaml index 4235f377da6..08af0fc7a13 100644 --- a/doc/api/openapi/openapi.yaml +++ b/doc/api/openapi/openapi.yaml @@ -19,7 +19,7 @@ info: name: CC BY-SA 4.0 url: 'https://gitlab.com/gitlab-org/gitlab/-/blob/master/LICENSE' servers: -- url: https://www.gitlab.com/api/ +- url: https://www.gitlab.com/api/v4 security: - ApiKeyAuth: [] tags: @@ -176,7 +176,7 @@ tags: - name: unleash_api description: Operations related to Unleash API paths: - /api/v4/groups/{id}/badges/{badge_id}: + /groups/{id}/badges/{badge_id}: get: tags: - badges @@ -271,7 +271,7 @@ paths: 204: description: Removes a badge from the group. content: {} - /api/v4/groups/{id}/badges: + /groups/{id}/badges: get: tags: - badges @@ -353,7 +353,7 @@ paths: application/json: schema: $ref: '#/components/schemas/API_Entities_Badge' - /api/v4/groups/{id}/badges/render: + /groups/{id}/badges/render: get: tags: - badges @@ -387,7 +387,7 @@ paths: application/json: schema: $ref: '#/components/schemas/API_Entities_BasicBadgeDetails' - /api/v4/groups/{id}/access_requests/{user_id}: + /groups/{id}/access_requests/{user_id}: delete: tags: - access_requests @@ -413,7 +413,7 @@ paths: 204: description: Denies an access request for the given user. content: {} - /api/v4/groups/{id}/access_requests/{user_id}/approve: + /groups/{id}/access_requests/{user_id}/approve: put: tags: - access_requests @@ -461,7 +461,7 @@ paths: state: active created_at: 2012-10-22T14:13:35Z access_level: 20 - /api/v4/groups/{id}/access_requests: + /groups/{id}/access_requests: get: tags: - access_requests @@ -526,7 +526,7 @@ paths: state: active created_at: 2012-10-22T14:13:35Z access_level: 20 - /api/v4/projects/{id}/repository/merged_branches: + /projects/{id}/repository/merged_branches: delete: tags: - branches @@ -546,7 +546,7 @@ paths: 404: description: 404 Project Not Found content: {} - /api/v4/projects/{id}/repository/branches/{branch}: + /projects/{id}/repository/branches/{branch}: get: tags: - branches @@ -625,7 +625,7 @@ paths: 404: description: Not Found content: {} - /api/v4/projects/{id}/repository/branches: + /projects/{id}/repository/branches: get: tags: - branches @@ -722,7 +722,7 @@ paths: 400: description: Failed to create branch content: {} - /api/v4/projects/{id}/repository/branches/{branch}/unprotect: + /projects/{id}/repository/branches/{branch}/unprotect: put: tags: - branches @@ -751,7 +751,7 @@ paths: 404: description: 404 Project Not Found content: {} - /api/v4/projects/{id}/repository/branches/{branch}/protect: + /projects/{id}/repository/branches/{branch}/protect: put: tags: - branches @@ -791,7 +791,7 @@ paths: 404: description: 404 Branch Not Found content: {} - /api/v4/projects/{id}/badges/{badge_id}: + /projects/{id}/badges/{badge_id}: get: tags: - badges @@ -886,7 +886,7 @@ paths: 204: description: Removes a badge from the project. content: {} - /api/v4/projects/{id}/badges: + /projects/{id}/badges: get: tags: - badges @@ -969,7 +969,7 @@ paths: application/json: schema: $ref: '#/components/schemas/API_Entities_Badge' - /api/v4/projects/{id}/badges/render: + /projects/{id}/badges/render: get: tags: - badges @@ -1003,7 +1003,7 @@ paths: application/json: schema: $ref: '#/components/schemas/API_Entities_BasicBadgeDetails' - /api/v4/projects/{id}/access_requests/{user_id}: + /projects/{id}/access_requests/{user_id}: delete: tags: - access_requests @@ -1029,7 +1029,7 @@ paths: 204: description: Denies an access request for the given user. content: {} - /api/v4/projects/{id}/access_requests/{user_id}/approve: + /projects/{id}/access_requests/{user_id}/approve: put: tags: - access_requests @@ -1077,7 +1077,7 @@ paths: state: active created_at: 2012-10-22T14:13:35Z access_level: 20 - /api/v4/projects/{id}/access_requests: + /projects/{id}/access_requests: get: tags: - access_requests @@ -1142,7 +1142,7 @@ paths: state: active created_at: 2012-10-22T14:13:35Z access_level: 20 - /api/v4/projects/{id}/alert_management_alerts/{alert_iid}/metric_images/{metric_image_id}: + /projects/{id}/alert_management_alerts/{alert_iid}/metric_images/{metric_image_id}: put: tags: - alert_management @@ -1232,7 +1232,7 @@ paths: 422: description: Unprocessable entity content: {} - /api/v4/projects/{id}/alert_management_alerts/{alert_iid}/metric_images: + /projects/{id}/alert_management_alerts/{alert_iid}/metric_images: get: tags: - alert_management @@ -1311,7 +1311,7 @@ paths: 403: description: Forbidden content: {} - /api/v4/projects/{id}/alert_management_alerts/{alert_iid}/metric_images/authorize: + /projects/{id}/alert_management_alerts/{alert_iid}/metric_images/authorize: post: tags: - alert_management @@ -1338,7 +1338,7 @@ paths: 403: description: Forbidden content: {} - /api/v4/admin/batched_background_migrations/{id}: + /admin/batched_background_migrations/{id}: get: tags: - batched_background_migrations @@ -1380,7 +1380,7 @@ paths: 404: description: 404 Not found content: {} - /api/v4/admin/batched_background_migrations: + /admin/batched_background_migrations: get: tags: - batched_background_migrations @@ -1414,7 +1414,7 @@ paths: 403: description: 403 Forbidden content: {} - /api/v4/admin/batched_background_migrations/{id}/resume: + /admin/batched_background_migrations/{id}/resume: put: tags: - batched_background_migrations @@ -1462,7 +1462,7 @@ paths: 422: description: You can resume only `paused` batched background migrations. content: {} - /api/v4/admin/batched_background_migrations/{id}/pause: + /admin/batched_background_migrations/{id}/pause: put: tags: - batched_background_migrations @@ -1510,7 +1510,7 @@ paths: 422: description: You can pause only `active` batched background migrations. content: {} - /api/v4/admin/ci/variables/{key}: + /admin/ci/variables/{key}: get: tags: - ci_variables @@ -1601,7 +1601,7 @@ paths: 404: description: Instance Variable Not Found content: {} - /api/v4/admin/ci/variables: + /admin/ci/variables: get: tags: - ci_variables @@ -1675,7 +1675,7 @@ paths: 400: description: 400 Bad Request content: {} - /api/v4/admin/databases/{database_name}/dictionary/tables/{table_name}: + /admin/databases/{database_name}/dictionary/tables/{table_name}: get: tags: - admin @@ -1713,7 +1713,7 @@ paths: 404: description: 404 Not found content: {} - /api/v4/admin/clusters/{cluster_id}: + /admin/clusters/{cluster_id}: get: tags: - clusters @@ -1845,7 +1845,7 @@ paths: 404: description: Not found content: {} - /api/v4/admin/clusters/add: + /admin/clusters/add: post: tags: - clusters @@ -1928,7 +1928,7 @@ paths: 404: description: Not found content: {} - /api/v4/admin/clusters: + /admin/clusters: get: tags: - clusters @@ -1948,7 +1948,7 @@ paths: 403: description: Forbidden content: {} - /api/v4/admin/migrations/{timestamp}/mark: + /admin/migrations/{timestamp}/mark: post: tags: - migrations @@ -1993,7 +1993,7 @@ paths: 422: description: You can mark only pending migrations content: {} - /api/v4/applications/{id}: + /applications/{id}: delete: tags: - applications @@ -2012,7 +2012,7 @@ paths: 204: description: Delete an application content: {} - /api/v4/applications: + /applications: get: tags: - applications @@ -2068,7 +2068,7 @@ paths: application/json: schema: $ref: '#/components/schemas/API_Entities_ApplicationWithSecret' - /api/v4/avatar: + /avatar: get: tags: - avatar @@ -2094,7 +2094,7 @@ paths: application/json: schema: $ref: '#/components/schemas/API_Entities_Avatar' - /api/v4/broadcast_messages/{id}: + /broadcast_messages/{id}: get: tags: - broadcast_messages @@ -2204,7 +2204,7 @@ paths: application/json: schema: $ref: '#/components/schemas/API_Entities_BroadcastMessage' - /api/v4/broadcast_messages: + /broadcast_messages: get: tags: - broadcast_messages @@ -2295,7 +2295,7 @@ paths: application/json: schema: $ref: '#/components/schemas/API_Entities_BroadcastMessage' - /api/v4/bulk_imports/{import_id}/entities/{entity_id}: + /bulk_imports/{import_id}/entities/{entity_id}: get: tags: - bulk_imports @@ -2333,7 +2333,7 @@ paths: 503: description: Service unavailable content: {} - /api/v4/bulk_imports/{import_id}/entities: + /bulk_imports/{import_id}/entities: get: tags: - bulk_imports @@ -2391,7 +2391,7 @@ paths: 503: description: Service unavailable content: {} - /api/v4/bulk_imports/{import_id}: + /bulk_imports/{import_id}: get: tags: - bulk_imports @@ -2422,7 +2422,7 @@ paths: 503: description: Service unavailable content: {} - /api/v4/bulk_imports/entities: + /bulk_imports/entities: get: tags: - bulk_imports @@ -2483,7 +2483,7 @@ paths: 503: description: Service unavailable content: {} - /api/v4/bulk_imports: + /bulk_imports: get: tags: - bulk_imports @@ -2624,7 +2624,7 @@ paths: 503: description: Service unavailable content: {} - /api/v4/application/appearance: + /application/appearance: get: tags: - application @@ -2707,7 +2707,7 @@ paths: application/json: schema: $ref: '#/components/schemas/API_Entities_Appearance' - /api/v4/application/plan_limits: + /application/plan_limits: get: tags: - plan_limits @@ -2869,7 +2869,7 @@ paths: 403: description: Forbidden content: {} - /api/v4/metadata: + /metadata: get: tags: - metadata @@ -2886,7 +2886,7 @@ paths: 401: description: Unauthorized content: {} - /api/v4/version: + /version: get: tags: - metadata @@ -2904,7 +2904,7 @@ paths: 401: description: Unauthorized content: {} - /api/v4/projects/{id}/jobs: + /projects/{id}/jobs: get: tags: - jobs @@ -2934,7 +2934,7 @@ paths: type: array items: $ref: '#/components/schemas/API_Entities_Job' - /api/v4/projects/{id}/jobs/{job_id}: + /projects/{id}/jobs/{job_id}: get: tags: - jobs @@ -2960,7 +2960,7 @@ paths: application/json: schema: $ref: '#/components/schemas/API_Entities_Job' - /api/v4/projects/{id}/jobs/{job_id}/play: + /projects/{id}/jobs/{job_id}/play: post: tags: - jobs diff --git a/doc/architecture/blueprints/runner_tokens/index.md b/doc/architecture/blueprints/runner_tokens/index.md index ac83559d3df..e52295eca90 100644 --- a/doc/architecture/blueprints/runner_tokens/index.md +++ b/doc/architecture/blueprints/runner_tokens/index.md @@ -421,8 +421,9 @@ scope. | GitLab Rails app | `%16.0` | Adapt `register_{group|project}_runner` permissions to take [application setting](https://gitlab.com/gitlab-org/gitlab/-/issues/386712) in consideration. | | GitLab Rails app | `%16.1` | Make [`POST /api/v4/runners` endpoint](../../../api/runners.md#create-an-instance-runner) permanently return `HTTP 410 Gone` if either `allow_runner_registration_token` setting disables registration tokens.
A future v5 version of the API should return `HTTP 404 Not Found`. | | GitLab Rails app | `%16.1` | Add runner group metadata to the runner list. | -| GitLab Rails app | | Add UI to allow disabling use of registration tokens in top-level group settings. | -| GitLab Rails app | | Hide legacy UI showing registration with a registration token, if it disabled on in top-level group settings or by admins. | +| GitLab Rails app | `%16.11` | Add UI to allow disabling use of registration tokens in top-level group settings. | +| GitLab Rails app | `%16.11` | Add UI to allow disabling use of registration tokens in admin panel. | +| GitLab Rails app | `%16.11` | Hide legacy UI showing registration with a registration token, if it disabled on in top-level group settings or by admins. | @@ -432,7 +433,6 @@ scope. |------------------|----------:|---------| | GitLab Rails app | `%17.0` | Disable registration tokens for all groups by running database migration (only on GitLab.com) | | GitLab Rails app | `%17.0` | Disable registration tokens on the instance level by running database migration (except GitLab.com) | -| GitLab Rails app | `%17.0` | Disable registration tokens on the instance level for GitLab.com | | GitLab Rails app | `%16.3` | Implement new `:create_runner` PPGAT scope so that we don't require a full `api` scope. | | GitLab Rails app | | Document gotchas when [automatically rotating runner tokens](../../../ci/runners/configure_runners.md#automatically-rotate-runner-authentication-tokens) with multiple machines. | diff --git a/doc/ci/pipelines/cicd_minutes.md b/doc/ci/pipelines/cicd_minutes.md index c5cb1f50e71..1eaed7c8b97 100644 --- a/doc/ci/pipelines/cicd_minutes.md +++ b/doc/ci/pipelines/cicd_minutes.md @@ -147,14 +147,14 @@ DETAILS: **Tier:** Free, Premium, Ultimate **Offering:** GitLab.com -If you're using GitLab SaaS, you can purchase additional packs of compute minutes. +If you're using GitLab.com, you can purchase additional packs of compute minutes. These additional compute minutes: - Are used only after the monthly quota included in your subscription runs out. - Are carried over to the next month, if any remain at the end of the month. - Are valid for 12 months from date of purchase or until all compute minutes are consumed, whichever comes first. Expiry of compute minutes is not enforced. -For example, with a GitLab SaaS Premium license: +For example, with a GitLab.com Premium license: - You have `10,000` monthly compute minutes. - You purchase an additional `5,000` compute minutes. @@ -207,7 +207,7 @@ To purchase additional compute minutes for your personal namespace: 1. Select **Edit profile**. 1. On the left sidebar, select **Usage Quotas**. 1. Select **Buy additional compute minutes**. GitLab redirects you to the Customers Portal. -1. Locate the subscription card that's linked to your personal namespace on GitLab SaaS, select **Buy more compute minutes**, +1. Locate the subscription card that's linked to your personal namespace on GitLab.com, select **Buy more compute minutes**, and complete the details of the transaction. After your payment is processed, the additional compute minutes are added to your personal @@ -279,11 +279,11 @@ For this reduced cost factor: GitLab administrators can add a namespace to the reduced cost factor [with a flag](../../administration/feature_flags.md) named `ci_minimal_cost_factor_for_gitlab_namespaces`. -### Additional costs on GitLab SaaS +### GitLab-hosted runner costs -GitLab SaaS runners have different cost factors, depending on the runner type (Linux, Windows, macOS) and the virtual machine configuration. +GitLab-hosted runners have different cost factors, depending on the runner type (Linux, Windows, macOS) and the virtual machine configuration. -| GitLab SaaS runner type | Machine Size | Cost factor | +| GitLab-hosted runner type | Machine Size | Cost factor | |:-----------------------------|:-----------------------|:------------| | Linux OS amd64 | `small` | 1 | | Linux OS amd64 | `medium` | 2 | @@ -291,8 +291,8 @@ GitLab SaaS runners have different cost factors, depending on the runner type (L | Linux OS amd64 | `xlarge` | 6 | | Linux OS amd64 | `2xlarge` | 12 | | Linux OS amd64 + GPU-enabled | `medium`, GPU standard | 7 | -| macOS M1 | `medium` | 6 (**Status:** Beta) | -| Windows Server | - | 1 (**Status:** Beta) | +| macOS M1 | `medium` | 6 (**Status:** Beta) | +| Windows Server | - | 1 (**Status:** Beta) | ### Monthly reset of compute usage @@ -336,9 +336,9 @@ The grace period for running jobs is `1,000` compute minutes. Jobs on project runners are not affected by the compute quota. -### GitLab SaaS usage notifications +### GitLab.com usage notifications -On GitLab SaaS an in-app banner is displayed and an email notification sent to the namespace owners when: +On GitLab.com an in-app banner is displayed and an email notification sent to the namespace owners when: - The remaining compute minutes is below 30% of the quota. - The remaining compute minutes is below 5% of the quota. diff --git a/doc/ci/runners/hosted_runners/linux.md b/doc/ci/runners/hosted_runners/linux.md index b8a55593850..e32363fa897 100644 --- a/doc/ci/runners/hosted_runners/linux.md +++ b/doc/ci/runners/hosted_runners/linux.md @@ -32,7 +32,7 @@ For Free, Premium, and Ultimate plan customers, jobs on these instances consume The `small` machine type is set as default. If no [tag](../../yaml/index.md#tags) keyword in your `.gitlab-ci.yml` file is specified, the jobs will run on this default runner. -There are [different rates of compute minutes consumption](../../pipelines/cicd_minutes.md#additional-costs-on-gitlab-saas), based on the type of machine that is used. +There are [different rates of compute minutes consumption](../../pipelines/cicd_minutes.md#gitlab-hosted-runner-costs), based on the type of machine that is used. All hosted runners on Linux currently run on [`n2d-standard`](https://cloud.google.com/compute/docs/general-purpose-machines#n2d_machines) general-purpose compute from GCP. diff --git a/doc/ci/runners/index.md b/doc/ci/runners/index.md index c0a32105706..f730a7a1eea 100644 --- a/doc/ci/runners/index.md +++ b/doc/ci/runners/index.md @@ -23,7 +23,7 @@ Your jobs can run on: - [Hosted runners on Windows](saas/windows_saas_runner.md) ([Beta](../../policy/experiment-beta-support.md#beta)) - [Hosted runners on macOS](saas/macos_saas_runner.md) ([Beta](../../policy/experiment-beta-support.md#beta)) -For more information about the cost factor applied to the machine type based on size, see [cost factor](../../ci/pipelines/cicd_minutes.md#cost-factor). +For more information about the cost factor applied to the machine type based on size, see [cost factor](../../ci/pipelines/cicd_minutes.md#gitlab-hosted-runner-costs). The number of minutes you can use on these runners depends on the [maximum number of units of compute](../pipelines/cicd_minutes.md) in your [subscription plan](https://about.gitlab.com/pricing/). diff --git a/doc/development/code_suggestions/index.md b/doc/development/code_suggestions/index.md index cb91db93c38..5b477545b93 100644 --- a/doc/development/code_suggestions/index.md +++ b/doc/development/code_suggestions/index.md @@ -30,10 +30,10 @@ This should enable everyone to see locally any change in an IDE being sent to th 1. You will see completion request URLs being fetched that match the Git remote URL for your GDK. 1. Main Application (GDK): 1. Install the [GitLab Development Kit](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/index.md#one-line-installation). - 1. Enable Feature Flag ```code_suggestions_tokens_api```: + 1. Enable Feature Flag ```ai_duo_code_suggestions_switch```: 1. In your terminal, go to your `gitlab-development-kit` > `gitlab` directory. 1. Run `gdk rails console` or `bundle exec rails c` to start a Rails console. - 1. [Enable the Feature Flag](../../administration/feature_flags.md#enable-or-disable-the-feature) for the code suggestions tokens API by calling `Feature.enable(:code_suggestions_tokens_api)` from the console. + 1. [Enable the Feature Flag](../../administration/feature_flags.md#enable-or-disable-the-feature) for the code suggestions tokens API by calling `Feature.enable(:ai_duo_code_suggestions_switch)` from the console. 1. Set the AI Gateway URL environmental variable by running `export AI_GATEWAY_URL=http://localhost:5052`. 1. Run your GDK server with `gdk start` if it's not already running. 1. [Setup AI Gateway](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist): diff --git a/doc/development/permissions/custom_roles.md b/doc/development/permissions/custom_roles.md index 9c8a8691c0b..a487e436097 100644 --- a/doc/development/permissions/custom_roles.md +++ b/doc/development/permissions/custom_roles.md @@ -193,9 +193,9 @@ security dashboard. | `requirements` | no | The list of custom permissions this ability is dependent on. For instance `admin_vulnerability` is dependent on `read_vulnerability`. If none, then enter `[]` | | `available_from_access_level` | no | The access level from which this ability is available, if applicable. See the section on [understanding logic for individual abilities](#understanding-logic-for-individual-abilities) for help on determining the base access level for an ability. | -#### Step 2: Create a migration file +#### Step 2: Create a spec file and update validation schema -- Run `bundle exec rails generate gitlab:custom_roles:code --ability ` which will generate a migration file to add the ability as a boolean column to the `member_roles` table. +- Run `bundle exec rails generate gitlab:custom_roles:code --ability ` which will update the permissions validation schema file and create an empty spec file. #### Step 3: Update policies diff --git a/doc/user/ai_features.md b/doc/user/ai_features.md index 93e5edb6979..94d32e66675 100644 --- a/doc/user/ai_features.md +++ b/doc/user/ai_features.md @@ -60,12 +60,12 @@ For other features: ### Disable GitLab Duo features -> - [Settings to disable AI features were introduced](https://gitlab.com/groups/gitlab-org/-/epics/12404) in GitLab 16.10. - DETAILS: **Tier:** Premium, Ultimate **Offering:** GitLab.com, Self-managed, GitLab Dedicated +> - [Settings to disable AI features introduced](https://gitlab.com/groups/gitlab-org/-/epics/12404) in GitLab 16.10. + You can disable GitLab Duo AI features for a group, project, or instance. When it's disabled, any attempt to use GitLab Duo features on the group, project, or instance is blocked and an error is displayed. GitLab Duo features are also blocked for resources in the group or project, like epics, diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md index f588e33f4cb..c243cedf796 100644 --- a/doc/user/application_security/dependency_scanning/index.md +++ b/doc/user/application_security/dependency_scanning/index.md @@ -413,7 +413,7 @@ The following package managers use lockfiles that GitLab analyzers are capable o yarn - v1, v24, v34 + versions 1, 2, 3, 44 1.x, 2.x, @@ -453,10 +453,10 @@ The following package managers use lockfiles that GitLab analyzers are capable o
  • - Support for Yarn v2 and v3 was introduced in GitLab 15.11. However, this feature is also available to versions of GitLab 15.0 and later. + Support for Yarn version 4 was introduced in GitLab 16.11.

    - The following features are not supported for Yarn v2 or v3: + The following features are not supported for Yarn Berry:

    • diff --git a/doc/user/application_security/policies/scan-execution-policies.md b/doc/user/application_security/policies/scan-execution-policies.md index 394fe8a2310..4296a8cd414 100644 --- a/doc/user/application_security/policies/scan-execution-policies.md +++ b/doc/user/application_security/policies/scan-execution-policies.md @@ -258,6 +258,74 @@ Note the following: - If the CI/CD variables suffixed `_DISABLED_ANALYZERS` were declared in a policy, their values were ignored, regardless of where they were defined: policy, group, or project. +## Security policy scopes + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/135398) in GitLab 16.7 [with a flag](../../../administration/feature_flags.md) named `security_policies_policy_scope`. Enabled by default. +> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/443594) in GitLab 16.11. Feature flag `security_policies_policy_scope` removed. + +Security policy enforcement depends first on establishing a link between the group, subgroup, or +project on which you want to enforce policies, and the security policy project that contains the +policies. For example, if you are linking policies to a group, a group owner must create the link to +the security policy project. Then, all policies in the security policy project are inherited by all +projects in the group. + +You can refine a security policy's scope to: + +- _Include_ only projects containing a compliance framework label. +- _Include_ or _exclude_ selected projects from enforcement. + +### Policy scope schema + +| Field | Type | Required | Possible values | Description | +|-------|------|----------|-----------------|-------------| +| `policy_scope` | `object` | false | `compliance_frameworks`, `projects` | Scopes the policy based on compliance framework labels or projects you define. | + +#### `policy_scope` scope type + +| Field | Type | Possible values | Description | +|-------|------|-----------------|-------------| +| `compliance_frameworks` | `array` | | List of IDs of the compliance frameworks in scope of enforcement, in an array of objects with key `id`. | +| `projects` | `object` | `including`, `excluding` | Use `excluding:` or `including:` then list the IDs of the projects you wish to include or exclude, in an array of objects with key `id`. | + +#### Example `policy.yml` with security policy scopes + +```yaml +--- +scan_execution_policy: +- name: Enforce DAST in every release pipeline + description: This policy enforces pipeline configuration to have a job with DAST scan for release branches + enabled: true + rules: + - type: pipeline + branches: + - release/* + actions: + - scan: dast + scanner_profile: Scanner Profile A + site_profile: Site Profile B + policy_scope: + compliance_frameworks: + - id: 2 + - id: 11 +- name: Enforce Secret Detection and Container Scanning in every default branch pipeline + description: This policy enforces pipeline configuration to have a job with Secret Detection and Container Scanning scans for the default branch + enabled: true + rules: + - type: pipeline + branches: + - main + actions: + - scan: secret_detection + - scan: sast + variables: + SAST_EXCLUDED_ANALYZERS: brakeman + policy_scope: + projects: + excluding: + - id: 24 + - id: 27 +``` + ## Example security policies project You can use this example in a `.gitlab/security-policies/policy.yml` file stored in a @@ -438,81 +506,3 @@ scan_execution_policy: ``` In this example a `test job` is injected into the `test` stage of the pipeline, printing `Hello World`. - -### Security policy scopes - -Prerequisites: - -- To enable the pipeline execution policy action feature, a group owner or administrator must enable - the experimental feature: - - 1. On the left sidebar, select **Search or go to** and find your group. - 1. Select **Settings > General**. - 1. Expand **Permissions and group features**. - 1. Select the **Security Policy Scopes** checkbox. - 1. Optional. Select **Enforce for all subgroups**. - - If the setting is not enforced for all subgroups, subgroup owners can manage the setting per subgroup. - -Security policy enforcement depends first on establishing a link between the group, subgroup, or -project on which you want to enforce policies, and the security policy project that contains the -policies. For example, if you are linking policies to a group, a group owner must create the link to -the security policy project. Then, all policies in the security policy project are inherited by all -projects in the group. - -You can refine a security policy's scope to: - -- _Include_ only projects containing a compliance framework label. -- _Include_ or _exclude_ selected projects from enforcement. - -#### Policy scope schema - -| Field | Type | Required | Possible values | Description | -|-------|------|----------|-----------------|-------------| -| `policy_scope` | `object` | false | `compliance_frameworks`, `projects` | Scopes the policy based on compliance framework labels or projects you define. | - -#### `policy_scope` scope type - -| Field | Type | Possible values | Description | -|-------|------|-----------------|-------------| -| `compliance_frameworks` | `array` | | List of IDs of the compliance frameworks in scope of enforcement, in an array of objects with key `id`. | -| `projects` | `object` | `including`, `excluding` | Use `excluding:` or `including:` then list the IDs of the projects you wish to include or exclude, in an array of objects with key `id`. | - -#### Example `policy.yml` with security policy scopes - -```yaml ---- -scan_execution_policy: -- name: Enforce DAST in every release pipeline - description: This policy enforces pipeline configuration to have a job with DAST scan for release branches - enabled: true - rules: - - type: pipeline - branches: - - release/* - actions: - - scan: dast - scanner_profile: Scanner Profile A - site_profile: Site Profile B - policy_scope: - compliance_frameworks: - - id: 2 - - id: 11 -- name: Enforce Secret Detection and Container Scanning in every default branch pipeline - description: This policy enforces pipeline configuration to have a job with Secret Detection and Container Scanning scans for the default branch - enabled: true - rules: - - type: pipeline - branches: - - main - actions: - - scan: secret_detection - - scan: sast - variables: - SAST_EXCLUDED_ANALYZERS: brakeman - policy_scope: - projects: - excluding: - - id: 24 - - id: 27 -``` diff --git a/doc/user/gitlab_com/index.md b/doc/user/gitlab_com/index.md index d265eb69d60..86018a041b7 100644 --- a/doc/user/gitlab_com/index.md +++ b/doc/user/gitlab_com/index.md @@ -384,6 +384,7 @@ The following table describes the rate limits for GitLab.com: | **Alert integration endpoint** requests (for a given **project**) | **3600** requests per hour | | **[Pull mirroring](../project/repository/mirror/pull.md)** intervals | **5** minutes | | **API Requests** (from a given **user**) to `/api/v4/users/:id` | **300** requests per **10 minutes** | +| GitLab package cloud requests for a given IP address ([introduced](https://gitlab.com/gitlab-com/gl-infra/production-engineering/-/issues/24083) in GitLab 16.11) | 3,000 requests per minute | More details are available on the rate limits for [protected paths](#protected-paths-throttle) and diff --git a/doc/user/project/integrations/telegram.md b/doc/user/project/integrations/telegram.md index 141e15f7842..099ee09aeb3 100644 --- a/doc/user/project/integrations/telegram.md +++ b/doc/user/project/integrations/telegram.md @@ -40,6 +40,8 @@ To configure the bot in Telegram: ## Set up the Telegram integration in GitLab +> - **Message thread ID** [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/441097) in GitLab 16.11. + After you invite the bot to a Telegram channel, you can configure GitLab to send notifications: 1. To enable the integration: diff --git a/lib/gitlab/content_security_policy/config_loader.rb b/lib/gitlab/content_security_policy/config_loader.rb index f7c9d95c53c..6bd266ecb8f 100644 --- a/lib/gitlab/content_security_policy/config_loader.rb +++ b/lib/gitlab/content_security_policy/config_loader.rb @@ -48,7 +48,7 @@ module Gitlab 'media_src' => "'self' data: blob: http: https:", 'script_src' => ContentSecurityPolicy::Directives.script_src, 'style_src' => ContentSecurityPolicy::Directives.style_src, - 'worker_src' => "#{Gitlab::Utils.append_path(Gitlab.config.gitlab.url, 'assets/')} blob: data:", + 'worker_src' => ContentSecurityPolicy::Directives.worker_src, 'object_src' => "'none'", 'report_uri' => nil } diff --git a/lib/gitlab/content_security_policy/directives.rb b/lib/gitlab/content_security_policy/directives.rb index 09500ec623d..bd2799eda24 100644 --- a/lib/gitlab/content_security_policy/directives.rb +++ b/lib/gitlab/content_security_policy/directives.rb @@ -22,6 +22,10 @@ module Gitlab def self.style_src "'self' 'unsafe-inline'" end + + def self.worker_src + "'self' #{Gitlab::Utils.append_path(Gitlab.config.gitlab.url, 'assets/')} blob: data:" + end end end end diff --git a/spec/lib/gitlab/content_security_policy/config_loader_spec.rb b/spec/lib/gitlab/content_security_policy/config_loader_spec.rb index 9e2f3bda14c..30f10e3b34d 100644 --- a/spec/lib/gitlab/content_security_policy/config_loader_spec.rb +++ b/spec/lib/gitlab/content_security_policy/config_loader_spec.rb @@ -108,6 +108,12 @@ RSpec.describe Gitlab::ContentSecurityPolicy::ConfigLoader, feature_category: :s end end + describe 'the worker-src directive' do + it 'can be loaded from local origins' do + expect(worker_src).to eq("'self' http://localhost/assets/ blob: data:") + end + end + describe 'Webpack dev server websocket connections' do let(:webpack_dev_server_host) { 'webpack-dev-server.com' } let(:webpack_dev_server_port) { '9999' } @@ -319,7 +325,7 @@ RSpec.describe Gitlab::ContentSecurityPolicy::ConfigLoader, feature_category: :s expect(script_src).to eq(::Gitlab::ContentSecurityPolicy::Directives.script_src) expect(style_src).to eq(::Gitlab::ContentSecurityPolicy::Directives.style_src) expect(font_src).to eq("'self'") - expect(worker_src).to eq("http://localhost/assets/ blob: data:") + expect(worker_src).to eq(::Gitlab::ContentSecurityPolicy::Directives.worker_src) expect(frame_src).to eq(::Gitlab::ContentSecurityPolicy::Directives.frame_src) end end diff --git a/spec/migrations/migrate_custom_permissions_spec.rb b/spec/migrations/migrate_custom_permissions_spec.rb new file mode 100644 index 00000000000..442ff053830 --- /dev/null +++ b/spec/migrations/migrate_custom_permissions_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe MigrateCustomPermissions, feature_category: :permissions do + let(:member_roles) { table(:member_roles) } + let!(:member_role_a) { member_roles.create!(name: 'a', base_access_level: 10, read_code: true) } + let!(:member_role_b) { member_roles.create!(name: 'b', base_access_level: 10, archive_project: true) } + let(:boolean_permissions_where) { { read_code: true } } + let(:jsonb_permissions_where) { "member_roles.permissions @> ('{\"read_code\":true}')::jsonb" } + + it 'correctly migrates up and down' do + disable_migrations_output do + reversible_migration do |migration| + migration.before -> { + expect(member_roles.where(boolean_permissions_where).pluck(:id)).to contain_exactly(member_role_a.id) + } + + migration.after -> { + expect(member_roles.where(jsonb_permissions_where).pluck(:id)).to contain_exactly(member_role_a.id) + } + end + end + end +end diff --git a/spec/models/project_export_job_spec.rb b/spec/models/project_export_job_spec.rb index 565a2e88ee7..79fe4af2288 100644 --- a/spec/models/project_export_job_spec.rb +++ b/spec/models/project_export_job_spec.rb @@ -54,4 +54,55 @@ RSpec.describe ProjectExportJob, feature_category: :importers, type: :model do end end end + + describe 'status transitions' do + let(:queued) { ProjectExportJob::STATUS[:queued] } + let(:started) { ProjectExportJob::STATUS[:started] } + let(:failed) { ProjectExportJob::STATUS[:failed] } + let(:finished) { ProjectExportJob::STATUS[:finished] } + + context 'when a new ProjectExportJob is created' do + let(:project_export_job) { create(:project_export_job) } + + it 'is initialized in the queued state' do + expect(project_export_job).to be_queued + end + end + + context 'when the ProjectExportJob is in queued state' do + let(:project_export_job) { create(:project_export_job) } + + it 'can transition to started state' do + expect { project_export_job.start }.to change { project_export_job.status }.from(queued).to(started) + end + + it 'can transition to failed state' do + expect { project_export_job.fail_op }.to change { project_export_job.status }.from(queued).to(failed) + end + + it 'cannnot transition to finished state' do + expect { project_export_job.finish }.not_to change { project_export_job.status } + end + end + + context 'when the ProjectExportJob is in started state' do + let(:project_export_job) { create(:project_export_job, status: started) } + + it 'can transition to finished state' do + expect { project_export_job.finish }.to change { project_export_job.status }.from(started).to(finished) + end + + it 'can transition to failed state' do + expect { project_export_job.fail_op }.to change { project_export_job.status }.from(started).to(failed) + end + end + + context 'when the ProjectExportJob is in finished state' do + let(:project_export_job) { create(:project_export_job, status: finished) } + + it 'does not transition further' do + expect { project_export_job.fail_op }.not_to change { project_export_job.status } + end + end + end end