Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-11-22 12:33:18 +00:00
parent f7500ff667
commit d6a7d36ff2
224 changed files with 3202 additions and 1851 deletions

View File

@ -764,6 +764,7 @@ rspec-ee:predictive:trigger single-db-ci-connection:
.rspec-ee-base-gitlab-duo:
extends:
- .rspec-ee-base-pg14
when: manual
variables:
REAL_AI_REQUEST: "true"
AI_GATEWAY_URL: http://ai-gateway:5052
@ -1297,7 +1298,7 @@ rspec-ee system pg16:
stage: test
script:
- !reference [.base-script, script]
- rspec_section rspec_fail_fast "${MATCHING_TESTS_PATH}" "--fail-fast=${RSPEC_FAIL_FAST_THRESHOLD} --tag ~quarantine --tag ~zoekt --tag ~click_house"
- rspec_section rspec_fail_fast "${MATCHING_TESTS_PATH}" "--fail-fast=${RSPEC_FAIL_FAST_THRESHOLD} --tag ~quarantine --tag ~zoekt --tag ~click_house --tag ~real_ai_request"
rspec fail-fast:
extends:

View File

@ -107,7 +107,7 @@ include:
# spec/lib, yet background migration tests are also sitting there,
# and they should run on their own jobs so we don't need to run them
# in unit tests again.
- rspec_section rspec_parallelized_job "--fail-fast=${RSPEC_FAIL_FAST_THRESHOLD} --tag ~quarantine --tag ~level:background_migration --tag ~click_house"
- rspec_section rspec_parallelized_job "--fail-fast=${RSPEC_FAIL_FAST_THRESHOLD} --tag ~quarantine --tag ~level:background_migration --tag ~click_house --tag ~real_ai_request"
after_script:
- source scripts/utils.sh
- log_disk_usage # https://gitlab.com/gitlab-org/gitlab/-/issues/478880
@ -204,7 +204,7 @@ include:
.rspec-base-migration:
script:
- !reference [.base-script, script]
- rspec_section rspec_parallelized_job "--fail-fast=${RSPEC_FAIL_FAST_THRESHOLD} --tag ~quarantine --tag ~zoekt --tag ~click_house"
- rspec_section rspec_parallelized_job "--fail-fast=${RSPEC_FAIL_FAST_THRESHOLD} --tag ~quarantine --tag ~zoekt --tag ~click_house --tag ~real_ai_request"
after_script:
- !reference [.rspec-base, after_script]

View File

@ -67,6 +67,13 @@ Rails/Date:
# See https://gitlab.com/gitlab-org/gitlab/-/issues/502580
- danger/database/Dangerfile
Rails/Pluck:
Exclude:
# See https://gitlab.com/gitlab-org/gitlab/-/issues/502580
- 'tooling/danger/**/*'
# See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/94047#note_1179689274
AutoCorrect: false
RSpec:
Language:
Includes:
@ -363,9 +370,6 @@ Rails/MailerName:
# See for the context on why it's excluded https://gitlab.com/gitlab-org/gitlab/-/issues/239356#note_956419227
- 'app/mailers/notify.rb'
Rails/Pluck:
# See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/94047#note_1179689274
AutoCorrect: false
Rails/RakeEnvironment:
# Context on why it's disabled: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/93419#note_1048223982

View File

@ -945,6 +945,7 @@ Gitlab/BoundedContexts:
- 'app/models/concerns/token_authenticatable_strategies/encrypted.rb'
- 'app/models/concerns/token_authenticatable_strategies/encryption_helper.rb'
- 'app/models/concerns/token_authenticatable_strategies/insecure.rb'
- 'app/models/concerns/token_authenticatable_strategies/routable_token_generator.rb'
- 'app/models/concerns/transactions.rb'
- 'app/models/concerns/transitionable.rb'
- 'app/models/concerns/triggerable_hooks.rb'
@ -3405,7 +3406,6 @@ Gitlab/BoundedContexts:
- 'ee/app/services/personal_access_tokens/groups/update_lifetime_service.rb'
- 'ee/app/services/personal_access_tokens/instance/update_lifetime_service.rb'
- 'ee/app/services/personal_access_tokens/revoke_invalid_tokens.rb'
- 'ee/app/services/personal_access_tokens/rotation_verifier_service.rb'
- 'ee/app/services/phone_verification/telesign_client/base_service.rb'
- 'ee/app/services/phone_verification/telesign_client/risk_score_service.rb'
- 'ee/app/services/phone_verification/telesign_client/send_verification_code_service.rb'

View File

@ -243,7 +243,6 @@ Layout/ClassStructure:
- 'ee/app/services/package_metadata/ingestion/compressed_package/package_ingestion_task.rb'
- 'ee/app/services/path_locks/lock_service.rb'
- 'ee/app/services/path_locks/unlock_service.rb'
- 'ee/app/services/personal_access_tokens/rotation_verifier_service.rb'
- 'ee/app/services/search/zoekt/callback_service.rb'
- 'ee/app/services/search/zoekt/task_serializer_service.rb'
- 'ee/app/services/security/ingestion/tasks/update_vulnerability_uuids.rb'

View File

@ -17,6 +17,7 @@ Layout/LineLength:
- 'app/controllers/concerns/issuable_collections.rb'
- 'app/controllers/concerns/membership_actions.rb'
- 'app/controllers/concerns/notes_actions.rb'
- 'app/controllers/groups/milestones_controller.rb'
- 'app/controllers/groups_controller.rb'
- 'app/controllers/import/base_controller.rb'
- 'app/controllers/import/bitbucket_controller.rb'
@ -791,7 +792,6 @@ Layout/LineLength:
- 'ee/app/services/jira/requests/issues/list_service.rb'
- 'ee/app/services/merge_requests/create_from_vulnerability_data_service.rb'
- 'ee/app/services/merge_trains/refresh_merge_request_service.rb'
- 'ee/app/services/personal_access_tokens/rotation_verifier_service.rb'
- 'ee/app/services/projects/mark_for_deletion_service.rb'
- 'ee/app/services/projects/update_mirror_service.rb'
- 'ee/app/services/security/ingestion/finding_map.rb'
@ -1075,6 +1075,7 @@ Layout/LineLength:
- 'ee/spec/features/groups/saml_providers_spec.rb'
- 'ee/spec/features/groups/scim_token_spec.rb'
- 'ee/spec/features/groups/security/compliance_dashboards_spec.rb'
- 'ee/spec/features/groups/settings/domain_verification_spec.rb'
- 'ee/spec/features/integrations/jira/jira_issues_list_spec.rb'
- 'ee/spec/features/issues/filtered_search/filter_issues_weight_spec.rb'
- 'ee/spec/features/labels_hierarchy_spec.rb'
@ -1096,6 +1097,7 @@ Layout/LineLength:
- 'ee/spec/features/projects/iterations/user_views_iteration_spec.rb'
- 'ee/spec/features/projects/members/member_is_removed_from_project_spec.rb'
- 'ee/spec/features/projects/members/member_leaves_project_spec.rb'
- 'ee/spec/features/projects/mirror_spec.rb'
- 'ee/spec/features/projects/new_project_spec.rb'
- 'ee/spec/features/projects/pipelines/pipeline_spec.rb'
- 'ee/spec/features/projects/quality/test_case_list_spec.rb'
@ -1251,6 +1253,7 @@ Layout/LineLength:
- 'ee/spec/lib/audit/details_spec.rb'
- 'ee/spec/lib/banzai/filter/jira_private_image_link_filter_spec.rb'
- 'ee/spec/lib/banzai/filter/references/epic_reference_filter_spec.rb'
- 'ee/spec/lib/banzai/filter/references/iterations_cadence_reference_filter_spec.rb'
- 'ee/spec/lib/banzai/filter/references/label_reference_filter_spec.rb'
- 'ee/spec/lib/banzai/filter/references/vulnerability_reference_filters_spec.rb'
- 'ee/spec/lib/bulk_imports/projects/pipelines/issues_pipeline_spec.rb'
@ -1387,6 +1390,7 @@ Layout/LineLength:
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_event_streaming_destinations_metric_spec.rb'
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_groups_with_event_streaming_destinations_metric_spec.rb'
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_projects_with_external_status_checks_metric_spec.rb'
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_security_scans_metric_spec.rb'
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_users_associating_group_milestones_to_releases_metric_spec.rb'
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_users_creating_ci_builds_metric_spec.rb'
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/license_metric_spec.rb'
@ -1816,7 +1820,6 @@ Layout/LineLength:
- 'ee/spec/services/merge_trains/create_pipeline_service_spec.rb'
- 'ee/spec/services/merge_trains/refresh_merge_request_service_spec.rb'
- 'ee/spec/services/personal_access_tokens/create_service_audit_log_spec.rb'
- 'ee/spec/services/personal_access_tokens/rotation_verifier_service_spec.rb'
- 'ee/spec/services/projects/alerting/notify_service_spec.rb'
- 'ee/spec/services/projects/cleanup_service_spec.rb'
- 'ee/spec/services/projects/gitlab_projects_import_service_spec.rb'
@ -1891,6 +1894,7 @@ Layout/LineLength:
- 'ee/spec/support/shared_contexts/status_page/status_page_list_objects.rb'
- 'ee/spec/support/shared_examples/controllers/analytics/cycle_analytics/shared_stage_shared_examples.rb'
- 'ee/spec/support/shared_examples/controllers/concerns/description_diff_actions_shared_examples.rb'
- 'ee/spec/support/shared_examples/features/dashboard_saml_reauth_banner_shared_examples.rb'
- 'ee/spec/support/shared_examples/features/epics_filtered_search_shared_examples.rb'
- 'ee/spec/support/shared_examples/features/sidebar_shared_examples.rb'
- 'ee/spec/support/shared_examples/finders/geo/registry_finder_shared_examples.rb'
@ -2065,6 +2069,7 @@ Layout/LineLength:
- 'lib/api/settings.rb'
- 'lib/api/snippet_repository_storage_moves.rb'
- 'lib/api/snippets.rb'
- 'lib/api/submodules.rb'
- 'lib/api/suggestions.rb'
- 'lib/api/tags.rb'
- 'lib/api/templates.rb'
@ -2426,6 +2431,7 @@ Layout/LineLength:
- 'qa/qa/resource/registry_repository.rb'
- 'qa/qa/resource/repository/push.rb'
- 'qa/qa/resource/snippet.rb'
- 'qa/qa/resource/user_runners.rb'
- 'qa/qa/resource/wiki/group_page.rb'
- 'qa/qa/runtime/api/repository_storage_moves.rb'
- 'qa/qa/runtime/env.rb'
@ -2434,6 +2440,7 @@ Layout/LineLength:
- 'qa/qa/scenario/bootable.rb'
- 'qa/qa/service/cluster_provider/gcloud.rb'
- 'qa/qa/service/cluster_provider/k3s.rb'
- 'qa/qa/service/docker_run/gitlab_runner.rb'
- 'qa/qa/service/praefect_manager.rb'
- 'qa/qa/specs/features/api/3_create/merge_request/push_options_labels_spec.rb'
- 'qa/qa/specs/features/api/3_create/merge_request/push_options_mwps_spec.rb'
@ -2515,6 +2522,7 @@ Layout/LineLength:
- 'qa/qa/tools/delete_test_users.rb'
- 'qa/qa/tools/generate_perf_testdata.rb'
- 'qa/qa/tools/initialize_gitlab_auth.rb'
- 'qa/qa/vendor/one_password/cli.rb'
- 'qa/spec/git/repository_spec.rb'
- 'qa/spec/resource/api_fabricator_spec.rb'
- 'qa/spec/runtime/env_spec.rb'
@ -2698,6 +2706,7 @@ Layout/LineLength:
- 'spec/features/groups/milestone_spec.rb'
- 'spec/features/groups/milestones_sorting_spec.rb'
- 'spec/features/groups/packages_spec.rb'
- 'spec/features/groups/participants_autocomplete_spec.rb'
- 'spec/features/groups/settings/access_tokens_spec.rb'
- 'spec/features/groups/settings/repository_spec.rb'
- 'spec/features/groups_spec.rb'
@ -2734,6 +2743,7 @@ Layout/LineLength:
- 'spec/features/merge_request/user_comments_on_diff_spec.rb'
- 'spec/features/merge_request/user_creates_image_diff_notes_spec.rb'
- 'spec/features/merge_request/user_creates_merge_request_spec.rb'
- 'spec/features/merge_request/user_edits_mr_spec.rb'
- 'spec/features/merge_request/user_expands_diff_spec.rb'
- 'spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb'
- 'spec/features/merge_request/user_posts_diff_notes_spec.rb'
@ -3260,6 +3270,8 @@ Layout/LineLength:
- 'spec/lib/gitlab/diff/inline_diff_marker_spec.rb'
- 'spec/lib/gitlab/diff/position_tracer/line_strategy_spec.rb'
- 'spec/lib/gitlab/diff/suggestion_spec.rb'
- 'spec/lib/gitlab/doorkeeper_secret_storing/secret/pbkdf2_sha512_spec.rb'
- 'spec/lib/gitlab/doorkeeper_secret_storing/token/pbkdf2_sha512_spec.rb'
- 'spec/lib/gitlab/email/failure_handler_spec.rb'
- 'spec/lib/gitlab/email/handler/create_issue_handler_spec.rb'
- 'spec/lib/gitlab/email/handler/create_merge_request_handler_spec.rb'
@ -3361,6 +3373,7 @@ Layout/LineLength:
- 'spec/lib/gitlab/legacy_github_import/pull_request_formatter_spec.rb'
- 'spec/lib/gitlab/lfs/client_spec.rb'
- 'spec/lib/gitlab/mail_room/authenticator_spec.rb'
- 'spec/lib/gitlab/merge_requests/message_generator_spec.rb'
- 'spec/lib/gitlab/metrics/background_transaction_spec.rb'
- 'spec/lib/gitlab/metrics/boot_time_tracker_spec.rb'
- 'spec/lib/gitlab/metrics/elasticsearch_rack_middleware_spec.rb'
@ -3406,6 +3419,7 @@ Layout/LineLength:
- 'spec/lib/gitlab/route_map_spec.rb'
- 'spec/lib/gitlab/sanitizers/exif_spec.rb'
- 'spec/lib/gitlab/sanitizers/svg_spec.rb'
- 'spec/lib/gitlab/search/abuse_detection_spec.rb'
- 'spec/lib/gitlab/search/found_blob_spec.rb'
- 'spec/lib/gitlab/search_results_spec.rb'
- 'spec/lib/gitlab/serializer/pagination_spec.rb'
@ -3484,6 +3498,7 @@ Layout/LineLength:
- 'spec/mailers/emails/service_desk_spec.rb'
- 'spec/mailers/notify_spec.rb'
- 'spec/migrations/active_record/schema_spec.rb'
- 'spec/migrations/db/post_migrate/20240319005754_swap_columns_for_upstream_pipeline_id_between_ci_builds_and_ci_pipelines_spec.rb'
- 'spec/models/active_session_spec.rb'
- 'spec/models/alert_management/alert_spec.rb'
- 'spec/models/analytics/cycle_analytics/aggregation_spec.rb'
@ -3835,6 +3850,7 @@ Layout/LineLength:
- 'spec/requests/projects/merge_requests/context_commit_diffs_spec.rb'
- 'spec/requests/projects/merge_requests_discussions_spec.rb'
- 'spec/requests/projects/merge_requests_spec.rb'
- 'spec/requests/projects/releases_controller_spec.rb'
- 'spec/requests/projects/settings/access_tokens_controller_spec.rb'
- 'spec/requests/projects/tags_controller_spec.rb'
- 'spec/requests/projects_controller_spec.rb'
@ -4129,6 +4145,7 @@ Layout/LineLength:
- 'spec/support/helpers/live_debugger.rb'
- 'spec/support/helpers/login_helpers.rb'
- 'spec/support/helpers/merge_request_diff_helpers.rb'
- 'spec/support/helpers/migrations_helpers/vulnerabilities_findings_helper.rb'
- 'spec/support/helpers/prometheus_helpers.rb'
- 'spec/support/helpers/seed_repo.rb'
- 'spec/support/helpers/selection_helper.rb'
@ -4171,6 +4188,7 @@ Layout/LineLength:
- 'spec/support/shared_examples/features/editable_merge_request_shared_examples.rb'
- 'spec/support/shared_examples/features/error_tracking_shared_example.rb'
- 'spec/support/shared_examples/features/manage_applications_shared_examples.rb'
- 'spec/support/shared_examples/features/milestone_editing_shared_examples.rb'
- 'spec/support/shared_examples/features/page_description_shared_examples.rb'
- 'spec/support/shared_examples/features/sidebar/sidebar_milestone_shared_examples.rb'
- 'spec/support/shared_examples/features/wiki/user_views_asciidoc_page_with_includes_shared_examples.rb'

View File

@ -1,56 +1,5 @@
---
# Cop supports --autocorrect.
Lint/RedundantCopDisableDirective:
# Offense count: 62
# Temporarily disabled due to too many offenses
# Temporarily disabled
Enabled: false
Exclude:
- 'app/controllers/groups/milestones_controller.rb'
- 'app/models/concerns/integrations/base/integration.rb'
- 'app/models/work_items/type.rb'
- 'app/policies/issue_policy.rb'
- 'app/services/ci/runners/set_runner_associated_projects_service.rb'
- 'app/services/work_items/data_sync/clone_service.rb'
- 'app/services/work_items/data_sync/move_service.rb'
- 'db/migrate/20241021082113_create_partitioned_ci_runners.rb'
- 'db/migrate/20241024204816_create_partitioned_ci_runner_managers.rb'
- 'db/post_migrate/20241021163518_drop_user_canonical_emails_table.rb'
- 'ee/app/controllers/ee/projects/settings/ci_cd_controller.rb'
- 'ee/app/models/ee/audit_events/project_audit_event.rb'
- 'ee/app/services/search/zoekt/routing_service.rb'
- 'ee/app/services/vulnerabilities/statistics/adjustment_service.rb'
- 'ee/db/geo/migrate/20210504143244_add_verification_to_merge_request_diff_registry.rb'
- 'ee/spec/features/groups/settings/domain_verification_spec.rb'
- 'ee/spec/features/projects/mirror_spec.rb'
- 'ee/spec/lib/banzai/filter/references/iterations_cadence_reference_filter_spec.rb'
- 'ee/spec/lib/gitlab/elastic/client_spec.rb'
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_secure_pipelines_metric_spec.rb'
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_security_scans_metric_spec.rb'
- 'ee/spec/support/shared_examples/features/dashboard_saml_reauth_banner_shared_examples.rb'
- 'ee/spec/views/admin/users/show.html.haml_spec.rb'
- 'lib/api/submodules.rb'
- 'lib/gitlab/popen/runner.rb'
- 'qa/qa/resource/user_runners.rb'
- 'qa/qa/service/docker_run/gitlab_runner.rb'
- 'qa/qa/vendor/one_password/cli.rb'
- 'spec/components/previews/pajamas/banner_component_preview.rb'
- 'spec/features/groups/participants_autocomplete_spec.rb'
- 'spec/features/merge_request/user_edits_mr_spec.rb'
- 'spec/lib/gitlab/doorkeeper_secret_storing/secret/pbkdf2_sha512_spec.rb'
- 'spec/lib/gitlab/doorkeeper_secret_storing/token/pbkdf2_sha512_spec.rb'
- 'spec/lib/gitlab/merge_requests/message_generator_spec.rb'
- 'spec/lib/gitlab/search/abuse_detection_spec.rb'
- 'spec/migrations/db/post_migrate/20240319005754_swap_columns_for_upstream_pipeline_id_between_ci_builds_and_ci_pipelines_spec.rb'
- 'spec/models/concerns/encrypted_user_password_spec.rb'
- 'spec/requests/api/alert_management_alerts_spec.rb'
- 'spec/requests/projects/releases_controller_spec.rb'
- 'spec/scripts/setup/tests-metadata_spec.rb'
- 'spec/services/ci/create_pipeline_service/logger_spec.rb'
- 'spec/services/packages/pypi/create_package_service_spec.rb'
- 'spec/services/pages_domains/create_acme_order_service_spec.rb'
- 'spec/support/helpers/migrations_helpers/vulnerabilities_findings_helper.rb'
- 'spec/support/helpers/wait_for_requests.rb'
- 'spec/support/shared_examples/features/milestone_editing_shared_examples.rb'
- 'spec/support/shared_examples/models/concerns/protected_ref_access_shared_examples.rb'
- 'tooling/danger/sidekiq_queues.rb'
- 'tooling/danger/stable_branch.rb'

View File

@ -705,7 +705,6 @@ RSpec/ContextWording:
- 'ee/spec/services/milestones/update_service_spec.rb'
- 'ee/spec/services/package_metadata/ingestion/ingestion_service_spec.rb'
- 'ee/spec/services/personal_access_tokens/revoke_invalid_tokens_spec.rb'
- 'ee/spec/services/personal_access_tokens/rotation_verifier_service_spec.rb'
- 'ee/spec/services/projects/alerting/notify_service_spec.rb'
- 'ee/spec/services/projects/create_from_template_service_spec.rb'
- 'ee/spec/services/projects/destroy_service_spec.rb'

View File

@ -198,7 +198,6 @@ RSpec/ExampleWithoutDescription:
- 'ee/spec/services/package_metadata/compressed_package_data_object_spec.rb'
- 'ee/spec/services/package_metadata/data_object_fabricator_spec.rb'
- 'ee/spec/services/package_metadata/data_objects/cve_enrichment_spec.rb'
- 'ee/spec/services/personal_access_tokens/rotation_verifier_service_spec.rb'
- 'ee/spec/services/sbom/ingestion/occurrence_map_spec.rb'
- 'ee/spec/services/security/scan_result_policies/sync_findings_to_approval_rules_service_spec.rb'
- 'ee/spec/services/security/scan_result_policies/update_approvals_service_spec.rb'

View File

@ -1 +1 @@
9d2ddd160b10e94d8ff252071373d278bfaf4208
9fd3ef87a54f73b17bf775d30b2153e8b242cf1c

View File

@ -4,6 +4,7 @@ import { __, s__ } from '~/locale';
export const ACCESS_LEVEL_NO_ACCESS_INTEGER = 0;
export const ACCESS_LEVEL_MINIMAL_ACCESS_INTEGER = 5;
export const ACCESS_LEVEL_GUEST_INTEGER = 10;
export const ACCESS_LEVEL_PLANNER_INTEGER = 15;
export const ACCESS_LEVEL_REPORTER_INTEGER = 20;
export const ACCESS_LEVEL_DEVELOPER_INTEGER = 30;
export const ACCESS_LEVEL_MAINTAINER_INTEGER = 40;
@ -14,6 +15,7 @@ export const ACCESS_LEVEL_ADMIN_INTEGER = 60;
export const ACCESS_LEVEL_NO_ACCESS_STRING = 'NO_ACCESS';
export const ACCESS_LEVEL_MINIMAL_ACCESS_STRING = 'MINIMAL_ACCESS';
export const ACCESS_LEVEL_GUEST_STRING = 'GUEST';
export const ACCESS_LEVEL_PLANNER_STRING = 'PLANNER';
export const ACCESS_LEVEL_REPORTER_STRING = 'REPORTER';
export const ACCESS_LEVEL_DEVELOPER_STRING = 'DEVELOPER';
export const ACCESS_LEVEL_MAINTAINER_STRING = 'MAINTAINER';
@ -23,6 +25,7 @@ export const ACCESS_LEVELS_INTEGER_TO_STRING = {
[ACCESS_LEVEL_NO_ACCESS_INTEGER]: ACCESS_LEVEL_NO_ACCESS_STRING,
[ACCESS_LEVEL_MINIMAL_ACCESS_INTEGER]: ACCESS_LEVEL_MINIMAL_ACCESS_STRING,
[ACCESS_LEVEL_GUEST_INTEGER]: ACCESS_LEVEL_GUEST_STRING,
[ACCESS_LEVEL_PLANNER_INTEGER]: ACCESS_LEVEL_PLANNER_STRING,
[ACCESS_LEVEL_REPORTER_INTEGER]: ACCESS_LEVEL_REPORTER_STRING,
[ACCESS_LEVEL_DEVELOPER_INTEGER]: ACCESS_LEVEL_DEVELOPER_STRING,
[ACCESS_LEVEL_MAINTAINER_INTEGER]: ACCESS_LEVEL_MAINTAINER_STRING,
@ -32,6 +35,7 @@ export const ACCESS_LEVELS_INTEGER_TO_STRING = {
const ACCESS_LEVEL_NO_ACCESS = __('No access');
const ACCESS_LEVEL_MINIMAL_ACCESS = __('Minimal Access');
const ACCESS_LEVEL_GUEST = __('Guest');
const ACCESS_LEVEL_PLANNER = __('Planner');
const ACCESS_LEVEL_REPORTER = __('Reporter');
const ACCESS_LEVEL_DEVELOPER = __('Developer');
const ACCESS_LEVEL_MAINTAINER = __('Maintainer');
@ -56,6 +60,16 @@ export const BASE_ROLES = [
'MemberRole|The Guest role is for users who need visibility into a project or group but should not have the ability to make changes, such as external stakeholders.',
),
},
{
value: 'PLANNER',
text: ACCESS_LEVEL_PLANNER,
accessLevel: ACCESS_LEVEL_PLANNER_INTEGER,
memberRoleId: null,
occupiesSeat: true,
description: s__(
'MemberRole|The Planner role is suitable for team members who need to manage projects and track work items but do not need to contribute code, such as project managers and scrum masters.',
),
},
{
value: 'REPORTER',
text: ACCESS_LEVEL_REPORTER,

View File

@ -45,6 +45,10 @@ export default {
urlParams.search = this.searchTerm.length > 0 ? this.searchTerm : null;
if (urlParams.search) {
urlParams.state = 'all';
}
const newUrl = mergeUrlParams(urlParams, this.projectBranchesFilteredPath);
visitUrl(newUrl);
},

View File

@ -1,3 +1,8 @@
import initTodosApp from '~/todos';
import Todos from './todos';
new Todos(); // eslint-disable-line no-new
if (gon.features.todosVueApplication) {
initTodosApp();
} else {
new Todos(); // eslint-disable-line no-new
}

View File

@ -1,3 +0,0 @@
import initTodosApp from '~/todos';
initTodosApp();

View File

@ -11,16 +11,12 @@ import {
} from '@gitlab/ui';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import { getHTTPProtocol } from '~/lib/utils/url_utility';
import { __, s__, sprintf } from '~/locale';
import { __, sprintf } from '~/locale';
export default {
i18n: {
steps: {
step1: s__('WikiClone|Step 1: Clone repository'),
step2: s__('WikiClone|Step 2: Install and start Gollum'),
step2Directory: s__('WikiClone|Go to directory'),
step2Install: s__('WikiClone|Install Gollum'),
step2Start: s__('WikiClone|Start Gollum and edit locally'),
step1: __('Clone repository'),
},
cloneWithSsh: __('Clone with SSH'),
copyToClipboard: __('Copy to clipboard'),
@ -62,15 +58,6 @@ export default {
cloneHttpUrlDisplay() {
return `git clone ${this.cloneHttpUrl}`; // eslint-disable-line @gitlab/require-i18n-strings
},
directoryCommand() {
return `cd ${this.wikiPath}`; // eslint-disable-line @gitlab/require-i18n-strings
},
installCommand() {
return 'gem install gollum'; // eslint-disable-line @gitlab/require-i18n-strings
},
gollumCommand() {
return 'gollum';
},
listItem() {
return {
text: __('Clone repository'),
@ -156,65 +143,6 @@ export default {
</gl-form-input-group>
</gl-form-group>
</div>
<div class="gl-mt-6">
<h3 class="gl-heading-4">
{{ $options.i18n.steps.step2 }}
</h3>
<gl-form-group :label="$options.i18n.steps.step2Directory" label-for="go-to-directory">
<gl-form-input-group
id="go-to-directory"
:value="directoryCommand"
:label="$options.i18n.steps.step2Directory"
input-class="!gl-font-monospace"
readonly
select-on-click
>
<template #append>
<clipboard-button
:text="directoryCommand"
:title="$options.i18n.copyToClipboard"
data-clipboard-target="#go-to-directory"
/>
</template>
</gl-form-input-group>
</gl-form-group>
<gl-form-group :label="$options.i18n.steps.step2Install" label-for="install-gollum">
<gl-form-input-group
id="install-gollum"
:value="installCommand"
:label="$options.i18n.steps.step2Install"
input-class="!gl-font-monospace"
readonly
select-on-click
>
<template #append>
<clipboard-button
:text="installCommand"
:title="$options.i18n.copyToClipboard"
data-clipboard-target="#install-gollum"
/>
</template>
</gl-form-input-group>
</gl-form-group>
<gl-form-group :label="$options.i18n.steps.step2Start" label-for="run-gollum">
<gl-form-input-group
id="run-gollum"
:value="gollumCommand"
:label="$options.i18n.steps.step2Start"
input-class="!gl-font-monospace"
readonly
select-on-click
>
<template #append>
<clipboard-button
:text="gollumCommand"
:title="$options.i18n.copyToClipboard"
data-clipboard-target="#run-gollum"
/>
</template>
</gl-form-input-group>
</gl-form-group>
</div>
</gl-modal>
</div>
</template>

View File

@ -3,7 +3,7 @@ import CustomizableDashboard from './customizable_dashboard.vue';
export default {
component: CustomizableDashboard,
title: '~/vue_shared/components/customizable_dashboard',
title: 'vue_shared/components/customizable_dashboard',
};
const Template = (args, { argTypes }) => ({

View File

@ -4,7 +4,7 @@ import PanelsBase from './panels_base.vue';
export default {
component: PanelsBase,
title: '~/vue_shared/components/panels_base',
title: 'vue_shared/components/panels_base',
};
const Template = (args, { argTypes }) => ({

View File

@ -34,14 +34,6 @@
text-align: center;
}
.no-btn {
border: 0;
background: none;
outline: none;
width: 100%;
text-align: left;
}
.environment-child-row {
padding-left: 20px;
}
@ -90,43 +82,6 @@
}
}
.metric-area {
opacity: 0.25;
}
.rect-text-metric {
fill: var(--white, $white);
stroke-width: 1;
stroke: var(--gray-600, $gray-600);
}
.rect-axis-text {
fill: var(--white, $white);
}
.selected-metric-line {
stroke: var(--gray-900, $gray-900);
stroke-width: 1;
}
.deployment-line {
stroke: var(--white, $white);
stroke-width: 1;
}
.divider-line {
stroke-width: 1;
stroke: var(--gray-600, $gray-600);
}
.environments-actions {
.external-url,
.monitoring-url,
.terminal-button {
width: 38px;
}
}
/**
* Deploy boards
*/
@ -170,10 +125,6 @@
margin-left: 10px;
}
&.deploy-board-error-message {
justify-content: center;
}
.deploy-board-empty-state-text {
order: 2;
flex-wrap: wrap;

View File

@ -126,15 +126,9 @@
overflow: visible;
}
div:has(> .diff-file-is-active) {
box-shadow: 0 0 0 1px var(--gl-focus-ring-outer-color);
border-radius: #{$border-radius + $gl-spacing-scale-1};
padding: $gl-spacing-scale-1;
.diff-file-is-active {
margin-bottom: 0;
}
.diff-file-is-active {
outline: 1px solid var(--gl-focus-ring-outer-color);
outline-offset: 2px;
}
}

View File

@ -191,7 +191,6 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
allowed_to_push: [:access_level]
}
] },
:can_create_organization,
:lets_encrypt_notification_email,
:lets_encrypt_terms_of_service_accepted,
:domain_denylist_file,

View File

@ -13,17 +13,26 @@ class Dashboard::TodosController < Dashboard::ApplicationController
urgency :low
def index
@sort = pagination_params[:sort]
@todos = @todos.page(pagination_params[:page])
@todos = @todos.with_entity_associations
push_frontend_feature_flag(:todos_vue_application, current_user)
return if redirect_out_of_range(@todos, todos_page_count(@todos))
# When removing the `todos_vue_application`, also drop the #vue method below
if Feature.enabled?(:todos_vue_application, current_user)
render :vue
else
@sort = pagination_params[:sort]
@todos = @todos.page(pagination_params[:page])
@todos = @todos.with_entity_associations
@allowed_todos = ::Todos::AllowedTargetFilterService.new(@todos, current_user).execute
return if redirect_out_of_range(@todos, todos_page_count(@todos))
@allowed_todos = ::Todos::AllowedTargetFilterService.new(@todos, current_user).execute
end
end
# To be removed along with the `todos_vue_application` feature flag.
# Also make sure to remove the corresponding route in `config/routes/dashboard.rb`.
def vue
redirect_to(dashboard_todos_path, status: :found) unless Feature.enabled?(:todos_vue_application, current_user)
redirect_to(dashboard_todos_path, status: :found)
end
def destroy

View File

@ -70,7 +70,7 @@ class Groups::MilestonesController < Groups::ApplicationController
render json: {
errors: [
format(
_("Someone edited this %{model_name} at the same time you did. Please refresh your browser and make sure your changes will not unintentionally remove theirs."), # rubocop:disable Layout/LineLength
_("Someone edited this %{model_name} at the same time you did. Please refresh your browser and make sure your changes will not unintentionally remove theirs."),
model_name: _('milestone')
)
]

View File

@ -52,8 +52,7 @@ class RootController < Dashboard::ProjectsController
when 'groups'
redirect_to(dashboard_groups_path)
when 'todos'
redirect_to(Feature.enabled?(:todos_vue_application,
current_user) ? vue_dashboard_todos_path : dashboard_todos_path)
redirect_to(dashboard_todos_path)
when 'issues'
redirect_to(issues_dashboard_path(assignee_username: current_user.username))
when 'merge_requests'

View File

@ -2,7 +2,7 @@
module Issues
class ConfidentialityFilter < Issuables::BaseFilter
CONFIDENTIAL_ACCESS_LEVEL = Gitlab::Access::REPORTER
CONFIDENTIAL_ACCESS_LEVEL = Gitlab::Access::PLANNER
def initialize(current_user:, parent:, assignee_filter:, related_groups: nil, **kwargs)
@current_user = current_user

View File

@ -35,6 +35,10 @@ module Resolvers
required: false,
description: 'Filter projects by programming language name (case insensitive). For example: "css" or "ruby".'
before_connection_authorization do |projects, current_user|
::Preloaders::UserMaxAccessLevelInProjectsPreloader.new(projects, current_user).execute
end
def resolve_with_lookahead(**args)
validate_args!(args)

View File

@ -10,6 +10,7 @@ module Types
end
value 'GUEST', value: Gitlab::Access::GUEST, description: descriptions[Gitlab::Access::GUEST]
value 'PLANNER', value: Gitlab::Access::PLANNER, description: descriptions[Gitlab::Access::PLANNER]
value 'REPORTER', value: Gitlab::Access::REPORTER, description: descriptions[Gitlab::Access::REPORTER]
value 'DEVELOPER', value: Gitlab::Access::DEVELOPER, description: descriptions[Gitlab::Access::DEVELOPER]
value 'MAINTAINER', value: Gitlab::Access::MAINTAINER, description: descriptions[Gitlab::Access::MAINTAINER]

View File

@ -16,7 +16,7 @@ module Types
Types::WorkItems::ClosingMergeRequestType.connection_type,
null: true,
description: 'Merge requests that will close the work item when merged.'
field :related_branches, # rubocop:disable GraphQL/ExtractType -- no need to extract to related
field :related_branches,
Types::WorkItems::RelatedBranchType.connection_type,
calls_gitaly: true,
description: 'Branches that have referred to the work item, but do not have an associated merge request.',

View File

@ -502,6 +502,7 @@ module ApplicationSettingsHelper
:pipeline_limit_per_project_user_sha,
:invitation_flow_enforcement,
:can_create_group,
:can_create_organization,
:bulk_import_concurrent_pipeline_batch_limit,
:concurrent_relation_batch_export_limit,
:bulk_import_enabled,

View File

@ -771,6 +771,7 @@ module ProjectsHelper
Gitlab::Access::NO_ACCESS => _('No access'),
Gitlab::Access::MINIMAL_ACCESS => _("Minimal Access"),
Gitlab::Access::GUEST => _('Guest'),
Gitlab::Access::PLANNER => _('Planner'),
Gitlab::Access::REPORTER => _('Reporter'),
Gitlab::Access::DEVELOPER => _('Developer'),
Gitlab::Access::MAINTAINER => _('Maintainer'),

View File

@ -98,11 +98,7 @@ module SidebarsHelper
issues_dashboard_path: issues_dashboard_path(assignee_username: user.username),
merge_request_dashboard_path: user.merge_request_dashboard_enabled? ? merge_requests_dashboard_path : nil,
todos_dashboard_path: if Feature.enabled?(:todos_vue_application, user)
vue_dashboard_todos_path
else
dashboard_todos_path
end,
todos_dashboard_path: dashboard_todos_path,
create_new_menu_groups: create_new_menu_groups(group: group, project: project),
merge_request_menu: create_merge_request_menu(user),

View File

@ -122,8 +122,14 @@ module Ci
project = options&.dig(:trigger, :project)
next unless project
scoped_variables.to_runner_variables.then do |all_variables|
::ExpandVariables.expand(project, all_variables)
if ci_optimize_memory_for_variables_enabled?
scoped_variables.to_hash_variables.then do |all_variables|
::ExpandVariables.expand(project, all_variables)
end
else
scoped_variables.to_runner_variables.then do |all_variables|
::ExpandVariables.expand(project, all_variables)
end
end
end
end
@ -223,8 +229,14 @@ module Ci
branch = options&.dig(:trigger, :branch)
return unless branch
scoped_variables.to_runner_variables.then do |all_variables|
::ExpandVariables.expand(branch, all_variables)
if ci_optimize_memory_for_variables_enabled?
scoped_variables.to_hash_variables.then do |all_variables|
::ExpandVariables.expand(branch, all_variables)
end
else
scoped_variables.to_runner_variables.then do |all_variables|
::ExpandVariables.expand(branch, all_variables)
end
end
end
@ -339,6 +351,11 @@ module Ci
}
}
end
def ci_optimize_memory_for_variables_enabled?
::Feature.enabled?(:ci_optimize_memory_for_variables, project)
end
strong_memoize_attr :ci_optimize_memory_for_variables_enabled?
end
end

View File

@ -692,7 +692,7 @@ module Integrations
def api_field_names
fields # rubocop:disable Style/NumberedParameters -- existing code moved as is
.reject { _1[:type] == :password || _1[:name] == 'webhook' || (_1.key?(:if) && _1[:if] != true) } # rubocop:disable Style/NumberedParameters -- existing code moved as is
.reject { _1[:type] == :password || _1[:name] == 'webhook' || (_1.key?(:if) && _1[:if] != true) }
.pluck(:name) # rubocop:disable Database/AvoidUsingPluckWithoutLimit -- existing code moved as is
end

View File

@ -2,14 +2,10 @@
module TokenAuthenticatableStrategies
class Base
RANDOM_BYTES_LENGTH = 16
TRUE_PROC = ->(_) { true }
attr_reader :klass, :token_field, :expires_at_field, :options
def self.random_bytes
SecureRandom.random_bytes(RANDOM_BYTES_LENGTH)
end
def initialize(klass, token_field, options)
@klass = klass
@token_field = token_field
@ -94,6 +90,8 @@ module TokenAuthenticatableStrategies
private
# If a `format_with_prefix` option is provided, it applies and returns the formatted token.
# Otherwise, default implementation returns the token as-is
def prefix_for(token_owner_record)
case prefix_option = options[:format_with_prefix]
when nil
@ -105,18 +103,9 @@ module TokenAuthenticatableStrategies
end
end
# If a `format_with_prefix` option is provided, it applies and returns the formatted token.
# Otherwise, default implementation returns the token as-is
def format_token(token_owner_record, token)
prefix = prefix_for(token_owner_record)
prefix ? "#{prefix}#{token}" : token
end
def write_new_token(token_owner_record)
new_token = generate_available_token(token_owner_record)
formatted_token = format_token(token_owner_record, new_token)
set_token(token_owner_record, formatted_token)
set_token(token_owner_record, new_token)
if expirable?
token_owner_record[@expires_at_field] = @options[:expires_at].to_proc.call(token_owner_record)
@ -135,33 +124,30 @@ module TokenAuthenticatableStrategies
end
def generate_token(token_owner_record)
if @options[:token_generator]
@options[:token_generator].call
if token_generator_proc
"#{prefix_for(token_owner_record)}#{token_generator_proc.call}"
# TODO: Make all tokens routable by default: https://gitlab.com/gitlab-org/gitlab/-/issues/500016
elsif generate_routable_token?(token_owner_record)
generate_routable_payload(@options[:routable_token], token_owner_record)
RoutableTokenGenerator.new(
token_owner_record,
routing_payload: options.dig(:routable_token, :payload),
prefix: prefix_for(token_owner_record)
).generate_token
else
Devise.friendly_token
"#{prefix_for(token_owner_record)}#{Devise.friendly_token}"
end
end
def generate_routable_token?(token_owner_record)
@options[:routable_token] && token_owner_record.respond_to?(:user) && Feature.enabled?(:routable_token, token_owner_record.user)
@options.dig(:routable_token, :payload) && routing_condition_proc.call(token_owner_record)
end
def default_routing_payload_hash
{
c: Settings.cell[:id]&.to_s(36),
r: self.class.random_bytes
}
def token_generator_proc
@options[:token_generator]
end
def generate_routable_payload(routable_parts, token_owner_record)
payload_hash = default_routing_payload_hash.merge(
routable_parts.transform_values { |generator| generator.call(token_owner_record) }
).compact_blank
Base64.urlsafe_encode64(payload_hash.sort.map { |k, v| "#{k}:#{v}" }.join("\n"), padding: false)
def routing_condition_proc
@options.dig(:routable_token, :if) || TRUE_PROC
end
def relation(unscoped)

View File

@ -0,0 +1,112 @@
# frozen_string_literal: true
module TokenAuthenticatableStrategies
class RoutableTokenGenerator
RANDOM_BYTES_LENGTH = 16
BASE64_PAYLOAD_LENGTH_HOLDER_BYTES = 2
CRC_BYTES = 7
VALID_ROUTING_KEYS = %i[c g o p u].freeze
REQUIRED_ROUTING_KEYS = %i[o].freeze
MAXIMUM_SIZE_OF_ROUTING_PAYLOAD = 159
DEFAULT_ROUTING_PAYLOAD_HASH =
{
c: ->(_) { Settings.cell[:id] }
}.freeze
PayloadTooLarge = Class.new(RuntimeError)
MissingRequiredRoutingKeys = Class.new(ArgumentError)
InvalidRoutingKeys = Class.new(ArgumentError)
def self.random_bytes(length)
SecureRandom.random_bytes(length)
end
attr_reader :token_owner_record, :routing_payload, :prefix
def initialize(token_owner_record, routing_payload:, prefix: '')
@token_owner_record = token_owner_record
@routing_payload = routing_payload
@prefix = prefix
validate_routing_keys!
end
def generate_token
routing_hash
.then { |routing_hash| build_payload(routing_hash) }
.then { |payload| check_payload_size!(payload) }
.then { |payload| encode_payload(payload, self.class.random_bytes(RANDOM_BYTES_LENGTH)) }
.then { |encoded_payload| append_crc(encoded_payload) }
end
private
def validate_routing_keys!
check_required_routing_keys!
check_invalid_routing_keys!
end
def routing_hash
routing_payload
.merge(DEFAULT_ROUTING_PAYLOAD_HASH)
.transform_values { |generator| format_value(generator.call(token_owner_record)) }
.compact_blank
.sort
end
def build_payload(routing_hash)
routing_hash.map { |k, v| "#{k}:#{v}" }.join("\n")
end
def format_value(value)
value.is_a?(Integer) ? value.to_s(36) : value
end
def encode_payload(payload, random_bytes)
encodable_payload = "#{payload}#{random_bytes}#{[random_bytes.size].pack('C')}"
base64_payload = Base64.urlsafe_encode64(encodable_payload, padding: false)
base64_payload_length = base64_payload.size.to_s(36).rjust(BASE64_PAYLOAD_LENGTH_HOLDER_BYTES, '0')
"#{prefix}#{base64_payload}.#{base64_payload_length}"
end
def append_crc(encoded_payload)
crc = Zlib.crc32(encoded_payload).to_s(36).rjust(CRC_BYTES, '0')
"#{encoded_payload}#{crc}"
end
def check_required_routing_keys!
missing_keys = REQUIRED_ROUTING_KEYS - routing_payload.keys
return if missing_keys.empty?
raise MissingRequiredRoutingKeys, missing_keys_error_message(missing_keys)
end
def check_invalid_routing_keys!
invalid_keys = routing_payload.keys - VALID_ROUTING_KEYS
return if invalid_keys.empty?
raise InvalidRoutingKeys, invalid_keys_error_message(invalid_keys)
end
def check_payload_size!(payload)
return payload if payload.size <= MAXIMUM_SIZE_OF_ROUTING_PAYLOAD
raise PayloadTooLarge, payload_size_error_message(payload.size)
end
def missing_keys_error_message(missing_keys)
"Missing required routing keys: #{missing_keys.map(&:inspect).join(', ')}. " \
"Required routing keys are: #{REQUIRED_ROUTING_KEYS.map(&:inspect).join(', ')}."
end
def invalid_keys_error_message(invalid_keys)
"Invalid routing keys: #{invalid_keys.map(&:inspect).join(', ')}. " \
"Valid routing keys are: #{VALID_ROUTING_KEYS.map(&:inspect).join(', ')}."
end
def payload_size_error_message(size)
"Routing payload is too big: #{size}. " \
"Maximum size is #{MAXIMUM_SIZE_OF_ROUTING_PAYLOAD}."
end
end
end

View File

@ -553,6 +553,10 @@ class Group < Namespace
add_member(user, :guest, current_user: current_user)
end
def add_planner(user, current_user = nil)
add_member(user, :planner, current_user: current_user)
end
def add_reporter(user, current_user = nil)
add_member(user, :reporter, current_user: current_user)
end

View File

@ -835,7 +835,7 @@ class Issue < ApplicationRecord
elsif project.personal? && project.team.owner?(user)
true
elsif confidential? && !assignee_or_author?(user)
project.member?(user, Gitlab::Access::REPORTER)
project.member?(user, Gitlab::Access::PLANNER)
elsif project.public? || (project.internal? && !user.external?)
project.feature_available?(:issues, user)
else
@ -848,7 +848,7 @@ class Issue < ApplicationRecord
return false unless namespace.is_a?(::Group)
if confidential? && !assignee_or_author?(user)
namespace.member?(user, Gitlab::Access::REPORTER)
namespace.member?(user, Gitlab::Access::PLANNER)
else
namespace.member?(user)
end

View File

@ -189,6 +189,7 @@ class Member < ApplicationRecord
scope :has_access, -> { active.where('access_level > 0') }
scope :guests, -> { active.where(access_level: GUEST) }
scope :planners, -> { active.where(access_level: PLANNER) }
scope :reporters, -> { active.where(access_level: REPORTER) }
scope :developers, -> { active.where(access_level: DEVELOPER) }
scope :maintainers, -> { active.where(access_level: MAINTAINER) }

View File

@ -538,7 +538,7 @@ class Project < ApplicationRecord
with_options to: :team do
delegate :members, prefix: true
delegate :add_member, :add_members, :member?
delegate :add_guest, :add_reporter, :add_developer, :add_maintainer, :add_owner, :add_role
delegate :add_guest, :add_planner, :add_reporter, :add_developer, :add_maintainer, :add_owner, :add_role
delegate :has_user?
end

View File

@ -11,6 +11,10 @@ class ProjectTeam
add_member(user, :guest, current_user: current_user)
end
def add_planner(user, current_user: nil)
add_member(user, :planner, current_user: current_user)
end
def add_reporter(user, current_user: nil)
add_member(user, :reporter, current_user: current_user)
end
@ -89,6 +93,10 @@ class ProjectTeam
@guests ||= fetch_members(Gitlab::Access::GUEST)
end
def planners
@planners ||= fetch_members(Gitlab::Access::PLANNER)
end
def reporters
@reporters ||= fetch_members(Gitlab::Access::REPORTER)
end
@ -152,6 +160,10 @@ class ProjectTeam
max_member_access(user.id) == Gitlab::Access::GUEST
end
def planner?(user)
max_member_access(user.id) == Gitlab::Access::PLANNER
end
def reporter?(user)
max_member_access(user.id) == Gitlab::Access::REPORTER
end

View File

@ -7,6 +7,7 @@ module System
ALLOWED_TARGET_ACCESS_LEVELS = [
Gitlab::Access::GUEST,
Gitlab::Access::PLANNER,
Gitlab::Access::REPORTER,
Gitlab::Access::DEVELOPER,
Gitlab::Access::MAINTAINER,

View File

@ -1424,7 +1424,7 @@ class User < ApplicationRecord
#
# This logic is duplicated from `Ability#project_abilities` into a SQL form.
def projects_where_can_admin_issues
authorized_projects(Gitlab::Access::REPORTER).non_archived.with_issues_enabled
authorized_projects(Gitlab::Access::PLANNER).non_archived.with_issues_enabled
end
# rubocop: disable CodeReuse/ServiceClass

View File

@ -41,7 +41,7 @@ module WorkItems
issue: { name: TYPE_NAMES[:issue], icon_name: 'issue-type-issue', enum_value: 0, id: 1 },
incident: { name: TYPE_NAMES[:incident], icon_name: 'issue-type-incident', enum_value: 1, id: 2 },
test_case: { name: TYPE_NAMES[:test_case], icon_name: 'issue-type-test-case', enum_value: 2, id: 3 }, ## EE-only
requirement: { name: TYPE_NAMES[:requirement], icon_name: 'issue-type-requirements', enum_value: 3, id: 4 }, ## EE-only # rubocop:disable Layout/LineLength -- Only comment exceeds length
requirement: { name: TYPE_NAMES[:requirement], icon_name: 'issue-type-requirements', enum_value: 3, id: 4 }, ## EE
task: { name: TYPE_NAMES[:task], icon_name: 'issue-type-task', enum_value: 4, id: 5 },
objective: { name: TYPE_NAMES[:objective], icon_name: 'issue-type-objective', enum_value: 5, id: 6 }, ## EE-only
key_result: { name: TYPE_NAMES[:key_result], icon_name: 'issue-type-keyresult', enum_value: 6, id: 7 }, ## EE-only

View File

@ -16,11 +16,11 @@ class BoardPolicy < BasePolicy
enable :read_issue
end
condition(:reporter_of_group_projects) do
condition(:planner_of_group_projects) do
next unless @user
group_projects_for(user: @user, group: @subject.resource_parent)
.visible_to_user_and_access_level(@user, ::Gitlab::Access::REPORTER)
.visible_to_user_and_access_level(@user, ::Gitlab::Access::PLANNER)
.exists?
end
@ -28,7 +28,7 @@ class BoardPolicy < BasePolicy
enable :create_non_backlog_issues
end
rule { is_group_board & reporter_of_group_projects }.policy do
rule { is_group_board & planner_of_group_projects }.policy do
enable :create_non_backlog_issues
end

View File

@ -13,6 +13,8 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
condition(:has_access) { access_level != GroupMember::NO_ACCESS }
condition(:guest) { access_level >= GroupMember::GUEST }
# This is not a linear condition (some policies available for planner might not be available for higher access levels)
condition(:planner) { access_level == GroupMember::PLANNER }
condition(:developer) { access_level >= GroupMember::DEVELOPER }
condition(:owner) { access_level >= GroupMember::OWNER }
condition(:maintainer) { access_level >= GroupMember::MAINTAINER }
@ -135,6 +137,21 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
enable :award_emoji
end
rule { planner }.policy do
enable :planner_access
enable :guest_access
enable :admin_label
enable :admin_milestone
enable :admin_issue_board
enable :admin_issue_board_list
enable :admin_issue
enable :update_issue
enable :destroy_issue
enable :read_confidential_issues
enable :read_crm_organization
enable :read_crm_contact
end
rule { admin | organization_owner }.policy do
enable :read_group
end
@ -403,7 +420,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
rule { can?(:admin_group) | can?(:admin_runner) }.enable :admin_group_or_admin_runner
# Should be matched with ProjectPolicy#read_internal_note
rule { admin | reporter }.enable :read_internal_note
rule { admin | reporter | planner }.enable :read_internal_note
rule { can?(:remove_group) }.enable :view_edit_page

View File

@ -12,6 +12,11 @@ class IssuablePolicy < BasePolicy
@user && @subject.assignee_or_author?(@user)
end
desc "User has planner or reporter access"
condition(:planner_or_reporter_access) do
can?(:reporter_access) || can?(:planner_access)
end
condition(:is_author) { @subject&.author == @user }
condition(:is_incident) { @subject.incident_type_issue? }
@ -53,7 +58,7 @@ class IssuablePolicy < BasePolicy
enable :admin_incident_management_timeline_event
end
rule { can?(:reporter_access) }.policy do
rule { planner_or_reporter_access }.policy do
enable :create_timelog
end

View File

@ -13,10 +13,12 @@ class IssuePolicy < IssuablePolicy
false
end
# rubocop:disable Cop/UserAdmin -- specifically check the admin attribute
desc "User can read confidential issues"
condition(:can_read_confidential) do
@user && (@user.admin? || can?(:reporter_access) || assignee_or_author?) # rubocop:disable Cop/UserAdmin
@user && (@user.admin? || planner_or_reporter_access? || assignee_or_author?)
end
# rubocop:enable Cop/UserAdmin
desc "Project belongs to a group, crm is enabled and user can read contacts in source group"
condition(:can_read_crm_contacts, scope: :subject) do
@ -45,13 +47,11 @@ class IssuePolicy < IssuablePolicy
end
end
# rubocop:disable Gitlab/FeatureFlagWithoutActor -- this is a on/off toggle
# group level issues license for now is equivalent to epics license. We'll have to migrate epics license to
# work items context once epics are fully migrated to work items.
condition(:group_level_issues_license_available) do
epics_license_available?
end
# rubocop:enable Gitlab/FeatureFlagWithoutActor
rule { group_issue & can?(:read_group) }.policy do
enable :create_note
@ -145,7 +145,7 @@ class IssuePolicy < IssuablePolicy
enable :set_issue_crm_contacts
end
rule { can?(:reporter_access) }.policy do
rule { planner_or_reporter_access }.policy do
enable :mark_note_as_internal
end

View File

@ -44,7 +44,7 @@ class MergeRequestPolicy < IssuablePolicy
enable :set_merge_request_metadata
end
rule { can?(:reporter_access) }.policy do
rule { planner_or_reporter_access }.policy do
enable :mark_note_as_internal
end

View File

@ -19,6 +19,10 @@ module Namespaces
enable :reopen_issue
end
rule { can?(:planner_access) }.policy do
enable :reopen_issue
end
rule { can?(:guest_access) }.policy do
enable :read_work_item
enable :read_issue

View File

@ -15,6 +15,10 @@ class ProjectPolicy < BasePolicy
desc "User has guest access"
condition(:guest) { team_member? }
# This is not a linear condition (some policies available for planner might not be available for higher access levels)
desc "User has planner access"
condition(:planner) { team_access_level == Gitlab::Access::PLANNER }
desc "User has reporter access"
condition(:reporter) { team_access_level >= Gitlab::Access::REPORTER }
@ -311,6 +315,11 @@ class ProjectPolicy < BasePolicy
Feature.enabled?(:hide_projects_of_banned_users) && @subject.created_and_owned_by_banned_user?
end
desc "User has either planner or reporter access"
condition(:planner_or_reporter_access) do
can?(:reporter_access) || can?(:planner_access)
end
# `:read_project` may be prevented in EE, but `:read_project_for_iids` should
# not.
rule { guest | admin | organization_owner }.enable :read_project_for_iids
@ -320,6 +329,7 @@ class ProjectPolicy < BasePolicy
rule { can?(:read_all_resources) }.enable :read_confidential_issues
rule { guest }.enable :guest_access
rule { planner }.enable :planner_access
rule { reporter }.enable :reporter_access
rule { developer }.enable :developer_access
rule { maintainer }.enable :maintainer_access
@ -329,6 +339,7 @@ class ProjectPolicy < BasePolicy
rule { can?(:owner_access) }.policy do
enable :guest_access
enable :planner_access
enable :reporter_access
enable :developer_access
enable :maintainer_access
@ -379,6 +390,29 @@ class ProjectPolicy < BasePolicy
enable :read_upload
end
rule { can?(:planner_access) }.policy do
enable :guest_access
enable :admin_issue_board
enable :admin_issue_board_list
enable :update_issue
enable :reopen_issue
enable :admin_issue
enable :destroy_issue
enable :read_confidential_issues
enable :create_design
enable :update_design
enable :move_design
enable :destroy_design
enable :admin_label
enable :admin_milestone
enable :download_wiki_code
enable :create_wiki
enable :admin_wiki
enable :read_merge_request
enable :download_code
enable :export_work_items
end
rule { can?(:reporter_access) & can?(:create_issue) }.enable :create_incident
rule { can?(:reporter_access) & can?(:read_environment) }.enable :read_freeze_period
@ -503,8 +537,8 @@ class ProjectPolicy < BasePolicy
rule { owner | admin | organization_owner | guest | group_member | group_requester }.prevent :request_access
rule { ~request_access_enabled }.prevent :request_access
rule { can?(:developer_access) & can?(:create_issue) }.enable :import_issues
rule { can?(:reporter_access) & can?(:create_work_item) }.enable :import_work_items
rule { (can?(:planner_access) | can?(:developer_access)) & can?(:create_issue) }.enable :import_issues
rule { planner_or_reporter_access & can?(:create_work_item) }.enable :import_work_items
rule { can?(:developer_access) }.policy do
enable :create_package
@ -747,6 +781,7 @@ class ProjectPolicy < BasePolicy
# If this project is public or internal we want to prevent all aside from a few public policies
rule { public_or_internal & ~project_allowed_for_job_token_by_scope }.policy do
prevent :guest_access
prevent :planner_access
prevent :public_access
prevent :reporter_access
prevent :developer_access
@ -854,6 +889,7 @@ class ProjectPolicy < BasePolicy
# `:read_project_for_iids` is not prevented by this condition, as it is
# used for cross-project reference checks.
prevent :guest_access
prevent :planner_access
prevent :public_access
prevent :public_user_access
prevent :reporter_access
@ -1013,7 +1049,7 @@ class ProjectPolicy < BasePolicy
end
# Should be matched with GroupPolicy#read_internal_note
rule { admin | can?(:reporter_access) }.enable :read_internal_note
rule { admin | planner_or_reporter_access }.enable :read_internal_note
rule { can?(:developer_access) & namespace_catalog_available }.policy do
enable :read_namespace_catalog
@ -1117,7 +1153,7 @@ class ProjectPolicy < BasePolicy
return -1 if @user.nil?
return -1 unless user_is_user?
lookup_access_level!
@team_access_level ||= lookup_access_level!
end
def lookup_access_level!

View File

@ -30,7 +30,7 @@ module Ci
response = ServiceResponse.success
runner.transaction do
current_project_ids = runner.project_ids # rubocop:disable CodeReuse/ActiveRecord -- reasonable use
current_project_ids = runner.project_ids
response = associate_new_projects(new_project_ids, current_project_ids)
response = disassociate_old_projects(new_project_ids, current_project_ids) if response.success?

View File

@ -37,12 +37,14 @@ module Groups
end
def public_only?
!user_is_at_least_reporter?
# Although PLANNER is not a linear access level, it can be considered so for the purpose of issues visibility
# because the same permissions apply to all levels higher than Gitlab::Access::PLANNER
!user_is_at_least_planner?
end
def user_is_at_least_reporter?
strong_memoize(:user_is_at_least_reporter) do
group.member?(user, Gitlab::Access::REPORTER)
def user_is_at_least_planner?
strong_memoize(:user_is_at_least_planner) do
group.member?(user, Gitlab::Access::PLANNER)
end
end

View File

@ -21,12 +21,12 @@ module Projects
end
def public_only?
!user_is_at_least_reporter?
!user_is_at_least_planner?
end
def user_is_at_least_reporter?
strong_memoize(:user_is_at_least_reporter) do
@project.member?(@user, Gitlab::Access::REPORTER)
def user_is_at_least_planner?
strong_memoize(:user_is_at_least_planner) do
@project.member?(@user, Gitlab::Access::PLANNER)
end
end
@ -57,7 +57,7 @@ module Projects
end
end
# We only show issues count including confidential for reporters, who are allowed to view confidential issues.
# We only show issues count including confidential for planners, who are allowed to view confidential issues.
# This will still show a discrepancy on issues number but should be less than before.
# Check https://gitlab.com/gitlab-org/gitlab-foss/issues/38418 description.

View File

@ -3,7 +3,7 @@
module Todos
module Destroy
# Service class for deleting todos that belongs to confidential issues.
# It deletes todos for users that are not at least reporters, issue author or assignee.
# It deletes todos for users that are not at least planners, issue author or assignee.
#
# Accepts issue_id or project_id as argument.
# When issue_id is passed it deletes matching todos for one confidential issue.

View File

@ -19,8 +19,10 @@ module Todos
def execute
return unless entity && user
# if at least reporter, all entities including confidential issues can be accessed
return if user_has_reporter_access?
# If at least planner, all entities including confidential issues can be accessed. Although PLANNER is not a
# linear access level, it can be considered so for the purpose of issuables visibility because the same
# permissions apply to all levels higher than Gitlab::Access::PLANNER
return if user_has_planner_access?
remove_confidential_resource_todos
remove_group_todos
@ -52,7 +54,7 @@ module Todos
Todo
.for_type(Issue.name)
.for_internal_notes
.for_project(non_authorized_reporter_projects) # Only Reporter+ can read internal notes
.for_project(non_authorized_planner_projects) # Only Planner+ can read internal notes
.for_user(user)
.delete_all
end
@ -65,9 +67,9 @@ module Todos
.for_user(user)
.delete_all
# MRs require reporter access, so remove those todos that are not authorized
# MRs require planner access, so remove those todos that are not authorized
Todo
.for_project(non_authorized_reporter_projects)
.for_project(non_authorized_planner_projects)
.for_type(MergeRequest.name)
.for_user(user)
.delete_all
@ -87,30 +89,30 @@ module Todos
when Project
{ id: entity.id }
when Namespace
{ namespace_id: non_authorized_reporter_groups }
{ namespace_id: non_authorized_planner_groups }
end
Project.where(condition) # rubocop: disable CodeReuse/ActiveRecord
end
def authorized_reporter_projects
user.authorized_projects(Gitlab::Access::REPORTER).select(:id)
def authorized_planner_projects
user.authorized_projects(Gitlab::Access::PLANNER).select(:id)
end
def authorized_guest_projects
user.authorized_projects(Gitlab::Access::GUEST).select(:id)
end
def non_authorized_reporter_projects
projects.id_not_in(authorized_reporter_projects)
def non_authorized_planner_projects
projects.id_not_in(authorized_planner_projects)
end
def non_authorized_guest_projects
projects.id_not_in(authorized_guest_projects)
end
def authorized_reporter_groups
GroupsFinder.new(user, min_access_level: Gitlab::Access::REPORTER).execute.select(:id)
def authorized_planner_groups
GroupsFinder.new(user, min_access_level: Gitlab::Access::PLANNER).execute.select(:id)
end
# rubocop: disable CodeReuse/ActiveRecord
@ -124,15 +126,15 @@ module Todos
end
# rubocop: enable CodeReuse/ActiveRecord
def non_authorized_reporter_groups
def non_authorized_planner_groups
entity.self_and_descendants.select(:id)
.id_not_in(authorized_reporter_groups)
.id_not_in(authorized_planner_groups)
end
def user_has_reporter_access?
def user_has_planner_access?
return unless entity.is_a?(Namespace)
entity.member?(User.find(user.id), Gitlab::Access::REPORTER)
entity.member?(User.find(user.id), Gitlab::Access::PLANNER)
end
def confidential_issues
@ -141,7 +143,7 @@ module Todos
Issue
.in_projects(projects)
.confidential_only
.not_in_projects(authorized_reporter_projects)
.not_in_projects(authorized_planner_projects)
.not_authored_by(user)
.id_not_in(assigned_ids)
end

View File

@ -41,7 +41,7 @@ module WorkItems
return error(error_message, :unprocessable_entity)
end
if target_namespace.pending_delete? # rubocop:disable Style/GuardClause -- does not read right with other checks above
if target_namespace.pending_delete?
error_message = s_('CloneWorkItem|Cannot clone work item to target namespace as it is pending deletion.')
return error(error_message, :unprocessable_entity)

View File

@ -39,7 +39,7 @@ module WorkItems
return error(error_message, :unprocessable_entity)
end
if target_namespace.pending_delete? # rubocop:disable Style/GuardClause -- does not read right with other checks above
if target_namespace.pending_delete?
error_message = s_('MoveWorkItem|Cannot move work item to target namespace as it is pending deletion.')
return error(error_message, :unprocessable_entity)

View File

@ -10,13 +10,13 @@
.top-area
= gl_tabs_nav({ class: 'gl-grow gl-border-b-0' }) do
= gl_tab_link_to s_('Branches|Overview'), project_branches_path(@project), { item_active: @mode == 'overview', title: s_('Branches|Show overview of the branches') }
= gl_tab_link_to s_('Branches|Active'), project_branches_filtered_path(@project, state: 'active'), { title: s_('Branches|Show active branches') }
= gl_tab_link_to s_('Branches|Stale'), project_branches_filtered_path(@project, state: 'stale'), { title: s_('Branches|Show stale branches') }
= gl_tab_link_to s_('Branches|Active'), project_branches_filtered_path(@project, state: 'active'), { item_active: @mode == 'active', title: s_('Branches|Show active branches') }
= gl_tab_link_to s_('Branches|Stale'), project_branches_filtered_path(@project, state: 'stale'), { item_active: @mode == 'stale', title: s_('Branches|Show stale branches') }
= gl_tab_link_to s_('Branches|All'), project_branches_filtered_path(@project, state: 'all'), { item_active: %w[overview active stale].exclude?(@mode), title: s_('Branches|Show all branches') }
.nav-controls
#js-branches-sort-dropdown{ data: {
project_branches_filtered_path: project_branches_path(@project, state: 'all'),
project_branches_filtered_path: project_branches_path(@project, state: @mode),
sort_options: branches_sort_options_hash.to_json,
show_dropdown: @mode == 'overview' ? 'false' : 'true',
sorted_by: @sort }

View File

@ -6,29 +6,6 @@
.wiki-page-header.has-sidebar-toggle.gl-flex-col.gl-py-5
%h1.gl-heading-1{ class: '!gl-mt-0' }= s_('WikiClone|Clone Wiki repository')
%h2.gl-heading-3{ class: '!gl-mb-0' }= s_('WikiClone|Step 1: Clone repository')
%h5= s_("WikiClone|Clone repository")
= wiki_sidebar_toggle_button
= render "shared/clone_panel", container: @wiki
.wiki-git-access.gl-mt-3
%h2.gl-heading-3= s_('WikiClone|Step 2: Install and start Gollum')
%h5.gl-mt-2= s_("WikiClone|Go to directory")
%pre.dark
:preserve
cd #{h @wiki.path}
%h5= s_("WikiClone|Install Gollum")
%pre.dark
:preserve
gem install gollum
%h5.gl-mt-2= s_("WikiClone|Start Gollum and edit locally")
%pre.dark
:preserve
gollum
= render 'shared/wikis/sidebar'

View File

@ -1,9 +1,9 @@
---
name: routable_token
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/486946
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/169581
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/499537
milestone: '17.6'
group: group::tenant scale
type: gitlab_com_derisk
name: ci_optimize_memory_for_variables
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/499707
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/173126
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/502800
milestone: '17.7'
group: group::pipeline authoring
type: beta
default_enabled: false

View File

@ -0,0 +1,47 @@
- name: Use self-hosted model for GitLab Duo Chat
description: |
You can now host your own supported large language models (LLMs) and configure them to enable self-hosted GitLab Duo Chat. This feature is in beta and available with an Ultimate and Duo Enterprise subscription on GitLab self-managed. With self-hosted models, you can use models hosted either on-premise or in a private cloud to enable GitLab Duo Chat or Code Suggestions (introduced as a beta feature in GitLab 17.5). For Code Suggestions, we currently support open-source Mistral models on vLLM or AWS Bedrock, Claude 3.5 Sonnet on AWS Bedrock, and OpenAI models on Azure OpenAI. For Chat, we currently support open-source Mistral models on vLLM or AWS Bedrock, and Claude 3.5 Sonnet on AWS Bedrock. By enabling self-hosted models, you can leverage the power of generative AI while maintaining complete data sovereignty and privacy.
stage: ai-powered
self-managed: true
gitlab-com: false
available_in: [Ultimate]
documentation_link: https://docs.gitlab.com/ee/administration/self_hosted_models/
image_url: https://about.gitlab.com/images/17_6/self-hosted-models-ui-17.6.png
published_at: 2024-11-21
release: 17.6
- name: Vulnerability report grouping
description: |
Users require the ability to view vulnerabilities in groups. This will help security analysts optimize their triage tasks by utilizing bulk actions. In addition users can see how many vulnerabilities match their group; i.e. how many OWASP Top 10 vulnerabilities are there?
stage: security_risk_management
self-managed: true
gitlab-com: true
available_in: [Ultimate]
documentation_link: https://docs.gitlab.com/ee/user/application_security/vulnerability_report/#group-vulnerabilities
image_url: https://about.gitlab.com/images/17_6/vulnerability_report_grouping.png
published_at: 2024-11-21
release: 17.6
- name: Display release notes on deployment details page
description: |
Have you ever wondered what might be included in a deployment youve been asked to approve? In past versions, you could create a release with a detailed description about its content and instructions for testing, but the related environment-specific deployment did not show this data. We are happy to share that GitLab now displays the release notes under the related deployment details page.
stage: deploy
self-managed: true
gitlab-com: true
available_in: [Free, Premium, Ultimate]
documentation_link: https://docs.gitlab.com/ee/ci/environments/deployment_approvals.html#view-blocked-deployments
image_url: https://about.gitlab.com/images/17_6/deploy-automatically-show-release-notes.png
published_at: 2024-11-21
release: 17.6
- name: Enhanced merge request reviewer assignments
description: |
Now, when assigning reviewers, the sidebar creates a connection between the approval requirements for your merge request and reviewers. View each approval rule, then select from approvers who can satisfy that approval rule and move the merge request forward for you. If you use optional CODEOWNER sections those rules are also shown in the sidebar to help you identify appropriate subject matter experts for your changes.
stage: create
self-managed: true
gitlab-com: true
available_in: [Free, Premium, Ultimate]
documentation_link: https://docs.gitlab.com/ee/user/project/merge_requests/reviews/#request-a-review
image_url: https://about.gitlab.com/images/17_6/create-enhanced-reviewer-assignment.png
published_at: 2024-11-21
release: 17.6

View File

@ -0,0 +1,10 @@
---
view_name: postgres_table_sizes
classes:
- Gitlab::Database::PostgresTableSize
feature_categories:
- database
description: SQL view to get information about postgres table sizes
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/173113
milestone: '17.7'
gitlab_schema: gitlab_shared

View File

@ -35,7 +35,6 @@ class CreatePartitionedCiRunners < Gitlab::Database::Migration[2.2]
def create_partitioned_table(name)
options = 'PARTITION BY LIST (runner_type)'
# rubocop: disable Migration/EnsureFactoryForTable -- we'll reuse the ci_runners factory once migrated
create_table name, primary_key: PARTITIONED_TABLE_PK, options: options do |t|
t.bigint :id, null: false
t.bigint :creator_id
@ -88,6 +87,5 @@ class CreatePartitionedCiRunners < Gitlab::Database::Migration[2.2]
t.index %i[token_expires_at id], name: "idx_#{name}_on_token_expires_at_desc_and_id_desc",
order: { token_expires_at: :desc, runner_type: :asc, id: :desc }
end
# rubocop: enable Migration/EnsureFactoryForTable
end
end

View File

@ -28,7 +28,6 @@ class CreatePartitionedCiRunnerManagers < Gitlab::Database::Migration[2.2]
def create_partitioned_table(name)
options = 'PARTITION BY LIST (runner_type)'
# rubocop: disable Migration/EnsureFactoryForTable -- we'll reuse the ci_runner_machines factory once migrated
create_table name, primary_key: PARTITIONED_TABLE_PK, options: options do |t|
t.bigint :id, null: false
t.bigint :runner_id, null: false
@ -59,6 +58,5 @@ class CreatePartitionedCiRunnerManagers < Gitlab::Database::Migration[2.2]
name: "index_#{name}_on_patch_version"
t.index :version, name: "index_#{name}_on_version"
end
# rubocop: enable Migration/EnsureFactoryForTable
end
end

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
class AddPostgresTableSizesView < Gitlab::Database::Migration[2.2]
milestone '17.7'
def up
execute(<<~SQL)
CREATE OR REPLACE VIEW postgres_table_sizes AS
SELECT
schemaname || '.' || relname as identifier,
schemaname as schema_name,
relname as table_name,
pg_size_pretty(pg_total_relation_size(quote_ident(schemaname) || '.' || quote_ident(relname))) as total_size,
pg_size_pretty(pg_relation_size(quote_ident(schemaname) || '.' || quote_ident(relname))) as table_size,
pg_size_pretty(pg_total_relation_size(quote_ident(schemaname) || '.' || quote_ident(relname)) -
pg_relation_size(quote_ident(schemaname) || '.' || quote_ident(relname))) as index_size,
pg_total_relation_size(quote_ident(schemaname) || '.' || quote_ident(relname)) as size_in_bytes
FROM pg_stat_user_tables
WHERE pg_total_relation_size(quote_ident(schemaname) || '.' || quote_ident(relname)) IS NOT NULL
ORDER BY pg_total_relation_size(quote_ident(schemaname) || '.' || quote_ident(relname)) DESC;
SQL
end
def down
execute(<<~SQL)
DROP VIEW postgres_table_sizes
SQL
end
end

View File

@ -12,7 +12,7 @@ class DropUserCanonicalEmailsTable < Gitlab::Database::Migration[2.2]
create_table :user_canonical_emails do |t|
t.timestamps_with_timezone
t.references :user, index: false, null: false, foreign_key: { on_delete: :cascade }
t.string :canonical_email, null: false, index: true # rubocop:disable Migration/AddLimitToStringColumns -- limit ignored in original migration
t.string :canonical_email, null: false, index: true
end
add_index :user_canonical_emails, [:user_id, :canonical_email], unique: true

View File

@ -0,0 +1 @@
0bff9c7868fd9cbc139610f9f4a39e7ccc54b059ea1cec5d17fbf67725f83121

View File

@ -17459,6 +17459,18 @@ CREATE VIEW postgres_sequences AS
LEFT JOIN pg_attribute ON (((dep_pg_class.oid = pg_attribute.attrelid) AND (pg_depend.refobjsubid = pg_attribute.attnum))))
WHERE (seq_pg_class.relkind = 'S'::"char");
CREATE VIEW postgres_table_sizes AS
SELECT (((pg_stat_user_tables.schemaname)::text || '.'::text) || (pg_stat_user_tables.relname)::text) AS identifier,
pg_stat_user_tables.schemaname AS schema_name,
pg_stat_user_tables.relname AS table_name,
pg_size_pretty(pg_total_relation_size((((quote_ident((pg_stat_user_tables.schemaname)::text) || '.'::text) || quote_ident((pg_stat_user_tables.relname)::text)))::regclass)) AS total_size,
pg_size_pretty(pg_relation_size((((quote_ident((pg_stat_user_tables.schemaname)::text) || '.'::text) || quote_ident((pg_stat_user_tables.relname)::text)))::regclass)) AS table_size,
pg_size_pretty((pg_total_relation_size((((quote_ident((pg_stat_user_tables.schemaname)::text) || '.'::text) || quote_ident((pg_stat_user_tables.relname)::text)))::regclass) - pg_relation_size((((quote_ident((pg_stat_user_tables.schemaname)::text) || '.'::text) || quote_ident((pg_stat_user_tables.relname)::text)))::regclass))) AS index_size,
pg_total_relation_size((((quote_ident((pg_stat_user_tables.schemaname)::text) || '.'::text) || quote_ident((pg_stat_user_tables.relname)::text)))::regclass) AS size_in_bytes
FROM pg_stat_user_tables
WHERE (pg_total_relation_size((((quote_ident((pg_stat_user_tables.schemaname)::text) || '.'::text) || quote_ident((pg_stat_user_tables.relname)::text)))::regclass) IS NOT NULL)
ORDER BY (pg_total_relation_size((((quote_ident((pg_stat_user_tables.schemaname)::text) || '.'::text) || quote_ident((pg_stat_user_tables.relname)::text)))::regclass)) DESC;
CREATE TABLE programming_languages (
id bigint NOT NULL,
name character varying NOT NULL,

View File

@ -23,12 +23,12 @@ and the following external authentication and authorization providers:
NOTE:
UltraAuth has removed their software which supports OmniAuth integration. We have therefore removed all references to UltraAuth integration.
## SaaS vs self-managed comparison
## GitLab.com compared to self-managed
The external authentication and authorization providers may support the following capabilities.
For more information, see the links shown on this page for each external provider.
| Capability | SaaS | Self-managed |
| Capability | GitLab.com | Self-managed |
|-------------------------------------------------|-----------------------------------------|------------------------------------|
| **User Provisioning** | SCIM<br>SAML <sup>1</sup> | LDAP <sup>1</sup><br>SAML <sup>1</sup><br>[OmniAuth Providers](../../integration/omniauth.md#supported-providers) <sup>1</sup><br>SCIM |
| **User Detail Updating** (not group management) | Not Available | LDAP Sync |

View File

@ -1,5 +1,5 @@
---
stage: Govern
stage: Software Supply Chain Security
group: Anti-Abuse
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

View File

@ -1,5 +1,5 @@
---
stage: Govern
stage: Software Supply Chain Security
group: Anti-Abuse
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

View File

@ -1,5 +1,5 @@
---
stage: Govern
stage: Software Supply Chain Security
group: Anti-Abuse
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

View File

@ -1,5 +1,5 @@
---
stage: Govern
stage: Software Supply Chain Security
group: Anti-Abuse
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

View File

@ -245,13 +245,10 @@ When you require expiration dates for new access tokens:
DETAILS:
**Tier:** Premium, Ultimate
**Offering:** Self-managed
**Offering:** Self-managed, GitLab Dedicated
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/163726) in GitLab 17.5 [with a feature flag](../feature_flags.md) named `allow_top_level_group_owners_to_create_service_accounts` for GitLab self-managed. Disabled by default.
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125835) in GitLab 17.6. Feature flag `allow_top_level_group_owners_to_create_service_accounts` removed.
FLAG:
On GitLab self-managed, by default this feature is not available. To make it available, an administrator can [enable the feature flag](../feature_flags.md) named `allow_top_level_group_owners_to_create_service_accounts`. On GitLab.com, this feature is available.
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/172502) in GitLab 17.6. Feature flag `allow_top_level_group_owners_to_create_service_accounts` removed.
By default, in GitLab self-managed, top-level group Owners can not create service accounts. GitLab administrators can allow top-level group Owners to create service accounts.

View File

@ -18,6 +18,7 @@ following levels are recognized:
- No access (`0`)
- Minimal access (`5`)
- Guest (`10`)
- Planner (`15`)
- Reporter (`20`)
- Developer (`30`)
- Maintainer (`40`)

View File

@ -127,6 +127,7 @@ The `target_access_levels` are defined in the `Gitlab::Access` module. The
following levels are valid:
- Guest (`10`)
- Planner (`15`)
- Reporter (`20`)
- Developer (`30`)
- Maintainer (`40`)
@ -198,6 +199,7 @@ The `target_access_levels` are defined in the `Gitlab::Access` module. The
following levels are valid:
- Guest (`10`)
- Planner (`15`)
- Reporter (`20`)
- Developer (`30`)
- Maintainer (`40`)

View File

@ -39234,6 +39234,7 @@ Access level of a group or project member.
| <a id="memberaccesslevelmaintainer"></a>`MAINTAINER` | The Maintainer role is primarily used for managing code reviews, approvals, and administrative settings for projects. This role can also manage project memberships. |
| <a id="memberaccesslevelminimal_access"></a>`MINIMAL_ACCESS` | The Minimal Access role is for users who need the least amount of access into groups and projects. You can assign this role as a default, before giving a user another role with more permissions. |
| <a id="memberaccesslevelowner"></a>`OWNER` | The Owner role is normally assigned to the individual or team responsible for managing and maintaining the group or creating the project. This role has the highest level of administrative control, and can manage all aspects of the group or project, including managing other Owners. |
| <a id="memberaccesslevelplanner"></a>`PLANNER` | The Planner role is suitable for team members who need to manage projects and track work items but do not need to contribute code. |
| <a id="memberaccesslevelreporter"></a>`REPORTER` | The Reporter role is suitable for team members who need to stay informed about a project or group but do not actively contribute code. |
### `MemberAccessLevelName`
@ -39246,6 +39247,7 @@ Name of access levels of a group or project member.
| <a id="memberaccesslevelnameguest"></a>`GUEST` | Guest access. |
| <a id="memberaccesslevelnamemaintainer"></a>`MAINTAINER` | Maintainer access. |
| <a id="memberaccesslevelnameowner"></a>`OWNER` | Owner access. |
| <a id="memberaccesslevelnameplanner"></a>`PLANNER` | Planner access. |
| <a id="memberaccesslevelnamereporter"></a>`REPORTER` | Reporter access. |
### `MemberApprovalStatusType`

View File

@ -116,7 +116,7 @@ POST /groups/:id/access_tokens
| `id` | integer or string | yes | ID or [URL-encoded path of the group](rest/index.md#namespaced-paths) |
| `name` | String | yes | Name of the group access token |
| `scopes` | `Array[String]` | yes | [List of scopes](../user/group/settings/group_access_tokens.md#scopes-for-a-group-access-token) |
| `access_level` | Integer | no | Access level. Valid values are `10` (Guest), `20` (Reporter), `30` (Developer), `40` (Maintainer), and `50` (Owner). |
| `access_level` | Integer | no | Access level. Valid values are `10` (Guest), `15` (Planner), `20` (Reporter), `30` (Developer), `40` (Maintainer), and `50` (Owner). |
| `expires_at` | Date | yes | Expiration date of the access token in ISO format (`YYYY-MM-DD`). The date cannot be set later than the [maximum allowable lifetime of an access token](../user/profile/personal_access_tokens.md#access-token-expiration). |
```shell

View File

@ -21,6 +21,7 @@ levels are defined in the `Gitlab::Access` module. Currently, these levels are v
- No access (`0`)
- Minimal access (`5`)
- Guest (`10`)
- Planner (`15`)
- Reporter (`20`)
- Developer (`30`)
- Maintainer (`40`)

View File

@ -100,7 +100,7 @@ Supported attributes:
|:----------|:--------|:---------|:-------------------------------------|
| `name` | string | yes | The name of the member role. |
| `description` | string | no | The description of the member role. |
| `base_access_level` | integer | yes | Base access level for configured role. Valid values are `10` (Guest), `20` (Reporter), `30` (Developer), `40` (Maintainer), or `50` (Owner).|
| `base_access_level` | integer | yes | Base access level for configured role. Valid values are `10` (Guest), `15` (Planner), `20` (Reporter), `30` (Developer), `40` (Maintainer), or `50` (Owner).|
| `admin_cicd_variables` | boolean | no | Permission to create, read, update, and delete CI/CD variables. |
| `admin_compliance_framework` | boolean | no | Permission to administer compliance frameworks. |
| `admin_group_member` | boolean | no | Permission to add, remove and assign members in a group. |

View File

@ -18,6 +18,7 @@ in the `Gitlab::Access` module as `access_level`.
- No access (`0`)
- Minimal access (`5`)
- Guest (`10`)
- Planner (`15`)
- Reporter (`20`)
- Developer (`30`)
- Maintainer (`40`)

View File

@ -123,8 +123,9 @@ Parameters:
## Delete project milestone
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/343889) the minimum user role from Developer to Reporter in GitLab 15.0.
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/169256) the minimum user role from Reporter to Planner in GitLab 17.7.
Only for users with at least the Reporter role for the project.
Only for users with at least the Planner role for the project.
```plaintext
DELETE /projects/:id/milestones/:milestone_id
@ -170,8 +171,9 @@ Parameters:
## Promote project milestone to a group milestone
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/343889) the minimum user role from Developer to Reporter in GitLab 15.0.
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/169256) the minimum user role from Reporter to Planner in GitLab 17.7.
Only for users with at least the Reporter role for the group.
Only for users with at least the Planner role for the group.
```plaintext
POST /projects/:id/milestones/:milestone_id/promote

View File

@ -122,7 +122,7 @@ POST projects/:id/access_tokens
| `id` | integer or string | yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-paths) |
| `name` | string | yes | Name of the project access token |
| `scopes` | `Array[String]` | yes | [List of scopes](../user/project/settings/project_access_tokens.md#scopes-for-a-project-access-token) |
| `access_level` | integer | no | Access level. Valid values are `10` (Guest), `20` (Reporter), `30` (Developer), `40` (Maintainer), and `50` (Owner). Defaults to `40`. |
| `access_level` | integer | no | Access level. Valid values are `10` (Guest), `15` (Planner), `20` (Reporter), `30` (Developer), `40` (Maintainer), and `50` (Owner). Defaults to `40`. |
| `expires_at` | date | yes | Expiration date of the access token in ISO format (`YYYY-MM-DD`). The date cannot be set later than the [maximum allowable lifetime of an access token](../user/profile/personal_access_tokens.md#access-token-expiration). |
```shell

View File

@ -30,9 +30,11 @@ For more information, see [Product Stage Direction - Plan](https://about.gitlab.
## Create a test case
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/169256) the minimum user role from Reporter to Planner in GitLab 17.7.
Prerequisites:
- You must have at least the Reporter role.
- You must have at least the Planner role.
To create a test case in a GitLab project:
@ -51,7 +53,7 @@ Prerequisites:
- Non-confidential test case in a public project: You don't have to be a member of the project.
- Non-confidential test case in a private project: You must have at least the Guest role for the project.
- Confidential test case (regardless of project visibility): You must have at least the Reporter role for the project.
- Confidential test case (regardless of project visibility): You must have at least the Planner role for the project.
To view a test case:
@ -63,11 +65,13 @@ To view a test case:
## Edit a test case
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/169256) the minimum user role from Reporter to Planner in GitLab 17.7.
You can edit a test case's title and description.
Prerequisites:
- You must have at least the Reporter role.
- You must have at least the Planner role.
- Users demoted to the Guest role can continue to edit the test cases they created
when they were in the higher role.
@ -81,12 +85,13 @@ To edit a test case:
## Make a test case confidential
> - Introduced for [new](https://gitlab.com/gitlab-org/gitlab/-/issues/422121) and [existing](https://gitlab.com/gitlab-org/gitlab/-/issues/422120) test cases in GitLab 16.5.
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/169256) the minimum user role from Reporter to Planner in GitLab 17.7.
If you're working on a test case that contains private information, you can make it confidential.
Prerequisites:
- You must have at least the Reporter role.
- You must have at least the Planner role.
To make a test case confidential:
@ -98,11 +103,13 @@ or editing an existing one.
## Archive a test case
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/169256) the minimum user role from Reporter to Planner in GitLab 17.7.
When you want to stop using a test case, you can archive it. You can [reopen an archived test case](#reopen-an-archived-test-case) later.
Prerequisites:
- You must have at least the Reporter role.
- You must have at least the Planner role.
To archive a test case, on the test case's page, select **Archive test case**.
@ -114,11 +121,13 @@ To view archived test cases:
## Reopen an archived test case
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/169256) the minimum user role from Reporter to Planner in GitLab 17.7.
If you decide to start using an archived test case again, you can reopen it.
Prerequisites:
- You must have at least the Reporter role.
- You must have at least the Planner role.
To reopen an archived test case:

View File

@ -1320,6 +1320,7 @@ When writing alt text:
- Try to avoid repeating text you've already used in the topic.
- Do not use inline styling like bold, italics, or backticks.
Screen readers read `**text**` as `star star text star star`.
- Use an empty alt text tag (`alt=""`) instead of omitting the tag altogether when the image does not add any unique information to the page. For example, when the image is decorative or is already fully described in the body text or caption. An empty alt tag tells assistive technologies that you have omitted the text intentionally, while a missing alt tag is ambiguous.
#### Automatic screenshot generator

View File

@ -31,12 +31,13 @@ You can read more about enabling browser-specific keyboard navigation on [a11ypr
## Quick checklist
- [Text](#text-inputs-with-accessible-names),
[select](#select-inputs-with-accessible-names),
[checkbox](#checkbox-inputs-with-accessible-names),
[radio](#radio-inputs-with-accessible-names),
- [Text](https://design.gitlab.com/components/text-input#accessibility),
[textarea](https://design.gitlab.com/components/textarea#accessibility),
[select](https://design.gitlab.com/components/select#accessibility),
[checkbox](https://design.gitlab.com/components/checkbox#accessibility),
[radio](https://design.gitlab.com/components/radio-button#accessibility),
[file](#file-inputs-with-accessible-names),
and [toggle](#gltoggle-components-with-accessible-names) inputs have accessible names.
and [toggle](https://design.gitlab.com/components/toggle#accessibility) inputs have accessible names.
- [Buttons](#buttons-and-links-with-descriptive-accessible-names),
[links](#buttons-and-links-with-descriptive-accessible-names),
and [images](#images-with-accessible-names) have descriptive accessible names.
@ -45,7 +46,7 @@ You can read more about enabling browser-specific keyboard navigation on [a11ypr
- [Clickable icons](#icons-that-are-clickable) are buttons, that is, `<gl-button icon="close" />` is used and not `<gl-icon />`.
- Icon-only buttons have an `aria-label`.
- Interactive elements can be [accessed with the Tab key](#support-keyboard-only-use) and have a visible focus state.
- Elements with [tooltips](#tooltips) are focusable using the Tab key.
- Elements with [tooltips](https://design.gitlab.com/components/tooltip#accessibility) are focusable using the Tab key.
- Are any `role`, `tabindex` or `aria-*` attributes unnecessary?
- Can any `div` or `span` elements be replaced with a more semantic [HTML element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element) like `p`, `button`, or `time`?
@ -85,151 +86,6 @@ Note that [when using `GlFormGroup`](https://bootstrap-vue.org/docs/components/f
- Passing only a `label` prop renders a `fieldset` with a `legend` containing the `label` value.
- Passing both a `label` and a `label-for` prop renders a `label` that points to the form input with the same `label-for` ID.
#### Text inputs with accessible names
When using `GlFormGroup`, the `label` prop alone does not give the input an accessible name.
The `label-for` prop must also be provided to give the input an accessible name.
Text input examples:
```html
<!-- Input with label -->
<gl-form-group :label="__('Issue title')" label-for="issue-title">
<gl-form-input id="issue-title" v-model="title" />
</gl-form-group>
<!-- Input with hidden label -->
<gl-form-group :label="__('Issue title')" label-for="issue-title" label-sr-only>
<gl-form-input id="issue-title" v-model="title" />
</gl-form-group>
```
`textarea` examples:
```html
<!-- textarea with label -->
<gl-form-group :label="__('Issue description')" label-for="issue-description">
<gl-form-textarea id="issue-description" v-model="description" />
</gl-form-group>
<!-- textarea with hidden label -->
<gl-form-group :label="__('Issue description')" label-for="issue-description" label-sr-only>
<gl-form-textarea id="issue-description" v-model="description" />
</gl-form-group>
```
Alternatively, you can use a plain `label` element:
```html
<!-- Input with label using `label` -->
<label for="issue-title">{{ __('Issue title') }}</label>
<gl-form-input id="issue-title" v-model="title" />
<!-- Input with hidden label using `label` -->
<label for="issue-title" class="gl-sr-only">{{ __('Issue title') }}</label>
<gl-form-input id="issue-title" v-model="title" />
```
#### Select inputs with accessible names
Select input examples:
```html
<!-- Select input with label -->
<gl-form-group :label="__('Issue status')" label-for="issue-status">
<gl-form-select id="issue-status" v-model="status" :options="options" />
</gl-form-group>
<!-- Select input with hidden label -->
<gl-form-group :label="__('Issue status')" label-for="issue-status" label-sr-only>
<gl-form-select id="issue-status" v-model="status" :options="options" />
</gl-form-group>
```
#### Checkbox inputs with accessible names
Single checkbox:
```html
<!-- Single checkbox with label -->
<gl-form-checkbox v-model="status" value="task-complete">
{{ __('Task complete') }}
</gl-form-checkbox>
<!-- Single checkbox with hidden label -->
<gl-form-checkbox v-model="status" value="task-complete">
<span class="gl-sr-only">{{ __('Task complete') }}</span>
</gl-form-checkbox>
```
Multiple checkboxes:
```html
<!-- Multiple labeled checkboxes grouped within a fieldset -->
<gl-form-group :label="__('Task list')">
<gl-form-checkbox value="task-1">{{ __('Task 1') }}</gl-form-checkbox>
<gl-form-checkbox value="task-2">{{ __('Task 2') }}</gl-form-checkbox>
</gl-form-group>
<!-- Or -->
<gl-form-group :label="__('Task list')">
<gl-form-checkbox-group v-model="selected" :options="options" />
</gl-form-group>
<!-- Multiple labeled checkboxes grouped within a fieldset with hidden legend -->
<gl-form-group :label="__('Task list')" label-sr-only>
<gl-form-checkbox value="task-1">{{ __('Task 1') }}</gl-form-checkbox>
<gl-form-checkbox value="task-2">{{ __('Task 2') }}</gl-form-checkbox>
</gl-form-group>
<!-- Or -->
<gl-form-group :label="__('Task list')" label-sr-only>
<gl-form-checkbox-group v-model="selected" :options="options" />
</gl-form-group>
```
#### Radio inputs with accessible names
Single radio input:
```html
<!-- Single radio with a label -->
<gl-form-radio v-model="status" value="opened">
{{ __('Opened') }}
</gl-form-radio>
<!-- Single radio with a hidden label -->
<gl-form-radio v-model="status" value="opened">
<span class="gl-sr-only">{{ __('Opened') }}</span>
</gl-form-radio>
```
Multiple radio inputs:
```html
<!-- Multiple labeled radio inputs grouped within a fieldset -->
<gl-form-group :label="__('Issue status')">
<gl-form-radio value="opened">{{ __('Opened') }}</gl-form-radio>
<gl-form-radio value="closed">{{ __('Closed') }}</gl-form-radio>
</gl-form-group>
<!-- Or -->
<gl-form-group :label="__('Issue status')">
<gl-form-radio-group v-model="selected" :options="options" />
</gl-form-group>
<!-- Multiple labeled radio inputs grouped within a fieldset with hidden legend -->
<gl-form-group :label="__('Issue status')" label-sr-only>
<gl-form-radio value="opened">{{ __('Opened') }}</gl-form-radio>
<gl-form-radio value="closed">{{ __('Closed') }}</gl-form-radio>
</gl-form-group>
<!-- Or -->
<gl-form-group :label="__('Issue status')" label-sr-only>
<gl-form-radio-group v-model="selected" :options="options" />
</gl-form-group>
```
#### File inputs with accessible names
File input examples:
@ -244,27 +100,6 @@ File input examples:
<input id="attach-file" type="file" />
```
#### GlToggle components with accessible names
`GlToggle` examples:
```html
<!-- GlToggle with label -->
<gl-toggle v-model="notifications" :label="__('Notifications')" />
<!-- GlToggle with hidden label -->
<gl-toggle v-model="notifications" :label="__('Notifications')" label-position="hidden" />
```
#### GlFormCombobox components with accessible names
`GlFormCombobox` example:
```html
<!-- GlFormCombobox with label -->
<gl-form-combobox :label-text="__('Key')" :token-list="$options.tokenList" />
```
#### Images with accessible names
Image examples:
@ -295,14 +130,6 @@ Buttons and links should have accessible names that are descriptive enough to be
<gl-link :href="url">{{ __("GitLab's accessibility page") }}</gl-link>
```
#### Links styled like buttons
Links can be styled like buttons using `GlButton`.
```html
<gl-button :href="url">{{ __('Link styled as a button') }}</gl-button>
```
## Role
In general, avoid using `role`.
@ -355,7 +182,7 @@ Use interactive elements instead of `div` and `span` tags.
For example:
- If the element should be clickable, use a `button` (`GlButton`).
- If the element should be text editable, use an [`input` or `textarea`](#text-inputs-with-accessible-names).
- If the element should be text editable, use an [`input`](https://design.gitlab.com/components/text-input#accessibility) or [`textarea`](https://design.gitlab.com/components/textarea#accessibility).
Once the markup is semantically complete, use CSS to update it to its desired visual state.
@ -451,28 +278,6 @@ Icons that are clickable are semantically buttons, so they should be rendered as
<gl-button icon="close" category="tertiary" :aria-label="__('Close')" @click="handleClick" />
```
## Tooltips
When adding tooltips, we must ensure that the element with the tooltip can receive focus so keyboard users can see the tooltip.
If the element is a static one, such as an icon, we can enclose it in a button, which already is
focusable, so we don't have to add `tabindex=0` to the icon.
The following code snippet is a good example of an icon with a tooltip.
- It is automatically focusable, as it is a button.
- It is given an accessible name with `aria-label`, as it is a button with no text.
```html
<button
v-gl-tooltip
class="gl-border-0 gl-bg-transparent gl-p-0 gl-leading-0"
:title="tooltipText"
:aria-label="__('Warning')"
>
<gl-icon name="warning" />
</button>
```
## Hiding elements
Use the following table to hide elements from users, when appropriate.

View File

@ -1,5 +1,5 @@
---
stage: Govern
stage: Software Supply Chain Security
group: Anti-Abuse
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
---

View File

@ -89,17 +89,15 @@ sequenceDiagram
- `elapsed` - Amount of time which passed since Service Ping report process started and moment of error occurrence
- `message` - Error message
<pre>
<code>
{
"uuid"=>"02333324-1cd7-4c3b-a45b-a4993f05fb1d",
"hostname"=>"127.0.0.1",
"version"=>"14.7.0-pre",
"elapsed"=>0.006946,
"message"=>'PG::UndefinedColumn: ERROR: column \"non_existent_attribute\" does not exist\nLINE 1: SELECT COUNT(non_existent_attribute) FROM \"issues\" /*applica...'
}
</code>
</pre>
```ruby
{
"uuid"=>"02333324-1cd7-4c3b-a45b-a4993f05fb1d",
"hostname"=>"127.0.0.1",
"version"=>"14.7.0-pre",
"elapsed"=>0.006946,
"message"=>'PG::UndefinedColumn: ERROR: column \"non_existent_attribute\" does not exist\nLINE 1: SELECT COUNT(non_existent_attribute) FROM \"issues\" /*applica...'
}
```
1. Finally, the timing metadata information that is used for diagnostic purposes is submitted to the Versions application. It consists of a list of metric identifiers and the time it took to calculate the metrics:

View File

@ -1,5 +1,5 @@
---
stage: Govern
stage: Software Supply Chain Security
group: Anti-Abuse
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
---

View File

@ -1,5 +1,5 @@
---
stage: Govern
stage: Software Supply Chain Security
group: Anti-Abuse
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
---

View File

@ -1,5 +1,5 @@
---
stage: Govern
stage: Software Supply Chain Security
group: Anti-Abuse
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
---

View File

@ -1,5 +1,5 @@
---
stage: Govern
stage: Software Supply Chain Security
group: Anti-Abuse
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
---

View File

@ -1,5 +1,5 @@
---
stage: Govern
stage: Software Supply Chain Security
group: Anti-Abuse
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
---

View File

@ -1,5 +1,5 @@
---
stage: Govern
stage: Software Supply Chain Security
group: Anti-Abuse
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
---

View File

@ -1,5 +1,5 @@
---
stage: Govern
stage: Software Supply Chain Security
group: Anti-Abuse
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

View File

@ -1,5 +1,5 @@
---
stage: Govern
stage: Software Supply Chain Security
group: Anti-Abuse
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

View File

@ -1,5 +1,5 @@
---
stage: Govern
stage: Software Supply Chain Security
group: Anti-Abuse
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

View File

@ -1,5 +1,5 @@
---
stage: Govern
stage: Software Supply Chain Security
group: Anti-Abuse
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

View File

@ -1,5 +1,5 @@
---
stage: Govern
stage: Software Supply Chain Security
group: Anti-Abuse
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

View File

@ -4,123 +4,123 @@ group: Distribution
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Convert Community Edition to Enterprise Edition
# Convert a Linux package CE instance to EE
DETAILS:
**Tier:** Free, Premium, Ultimate
**Offering:** Self-managed
To convert an existing GitLab Community Edition (CE) server installed using the Linux
packages to GitLab [Enterprise Edition](https://about.gitlab.com/pricing/) (EE), you install the EE
package on top of CE.
You can convert an existing Linux package instance from Community Edition (CE) to Enterprise Edition (EE).
To convert the instance, you install the EE Linux package on top of the CE instance.
Converting from the same version of CE to EE is not explicitly necessary, and any standard upgrade
(for example, CE 12.0 to EE 12.1) should work. However, in the following steps we assume that
you are upgrading the same version (for example, CE 12.1 to EE 12.1), which is **recommended**.
You don't need the same version of CE to EE. For example, CE 17.0 to EE 17.1 should work. However, upgrading the same
version (for example, CE 17.1 to EE 17.1) is **recommended**.
WARNING:
When updating to EE from CE, avoid reverting back to CE if you plan to go to EE again in the
future. Reverting back to CE can cause
[database issues](package_troubleshooting.md#500-error-when-accessing-project--settings--repository)
that may require Support intervention.
After you convert from EE from CE, don't revert back to CE if you plan to go to EE again. Reverting back to CE can cause
[database issues](package_troubleshooting.md#500-error-when-accessing-project--settings--repository) that may require
Support intervention.
The steps can be summed up to:
## Convert from CE to EE
To convert a Linux package CE instance to EE:
1. Make a [GitLab backup](../../administration/backup_restore/backup_gitlab.md).
1. Find the installed GitLab version:
**For Debian/Ubuntu**
::Tabs
:::TabTitle Debian/Ubuntu
```shell
sudo apt-cache policy gitlab-ce | grep Installed
```
The output should be similar to: `Installed: 13.0.4-ce.0`. In that case,
the equivalent Enterprise Edition version is: `13.0.4-ee.0`. Write this
value down.
Note down the returned version.
**For CentOS/RHEL**
:::TabTitle CentOS/RHEL
```shell
sudo rpm -q gitlab-ce
```
The output should be similar to: `gitlab-ce-13.0.4-ce.0.el8.x86_64`. In that
case, the equivalent Enterprise Edition version is:
`gitlab-ee-13.0.4-ee.0.el8.x86_64`. Write this value down.
Note down the returned version.
1. Add the `gitlab-ee` [Apt or Yum repository](https://packages.gitlab.com/gitlab/gitlab-ee/install):
::EndTabs
**For Debian/Ubuntu**
1. Add the `gitlab-ee` [Apt or Yum repository](https://packages.gitlab.com/gitlab/gitlab-ee/install). These commands
find your OS version and automatically set up the repository. If you are not comfortable installing the repository
through a piped script, you can first [check the script's contents](https://packages.gitlab.com/gitlab/gitlab-ee/install).
::Tabs
:::TabTitle Debian/Ubuntu
```shell
curl --silent "https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh" | sudo bash
```
**For CentOS/RHEL**
:::TabTitle CentOS/RHEL
```shell
curl --silent "https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.rpm.sh" | sudo bash
```
The above command finds your OS version and automatically set up the
repository. If you are not comfortable installing the repository through a
piped script, you can first
[check its contents](https://packages.gitlab.com/gitlab/gitlab-ee/install).
::EndTabs
NOTE:
If you want to use `dpkg`/`rpm` instead of `apt-get`/`yum`, go through the first
step to find the current GitLab version, then follow
[Upgrade using a manually downloaded package](index.md#by-using-a-downloaded-package),
and then [add your license](../../administration/license.md).
To use `dpkg` or `rpm` instead of using `apt-get` or `yum` follow
[Upgrade using a manually downloaded package](index.md#by-using-a-downloaded-package).
1. Install the `gitlab-ee` package. The install automatically
uninstalls the `gitlab-ce` package on your GitLab server. `reconfigure`
Omnibus right after the `gitlab-ee` package is installed. **Make sure that you
install the exact same GitLab version**:
1. Install the `gitlab-ee` Linux package. The install automatically uninstalls the `gitlab-ce` package on your GitLab.
**For Debian/Ubuntu**
::Tabs
:::TabTitle Debian/Ubuntu
```shell
## Make sure the repositories are up-to-date
sudo apt-get update
## Install the package using the version you wrote down from step 1
sudo apt-get install gitlab-ee=13.0.4-ee.0
sudo apt-get install gitlab-ee=17.1.0-ee.0
## Reconfigure GitLab
sudo gitlab-ctl reconfigure
```
**For CentOS/RHEL**
:::TabTitle CentOS/RHEL
```shell
## Install the package using the version you wrote down from step 1
sudo yum install gitlab-ee-13.0.4-ee.0.el8.x86_64
sudo yum install gitlab-ee-17.1.0-ee.0.el9.x86_64
## Reconfigure GitLab
sudo gitlab-ctl reconfigure
```
1. Now activate GitLab Enterprise Edition by [adding your license](../../administration/license.md).
::EndTabs
1. After you confirm that GitLab is working as expected, you may remove the old
Community Edition repository:
1. [Add your license](../../administration/license.md) to activate Enterprise Edition.
1. Confirm that GitLab is working as expected, then you can remove the old Community Edition repository:
**For Debian/Ubuntu**
::Tabs
:::TabTitle Debian/Ubuntu
```shell
sudo rm /etc/apt/sources.list.d/gitlab_gitlab-ce.list
```
**For CentOS/RHEL**
:::TabTitle CentOS/RHEL
```shell
sudo rm /etc/yum.repos.d/gitlab_gitlab-ce.repo
```
1. Optional. [Set up the Elasticsearch integration](../../integration/advanced_search/elasticsearch.md) to enable [advanced search](../../user/search/advanced_search.md).
::EndTabs
1. Optional. [Set up the Elasticsearch integration](../../integration/advanced_search/elasticsearch.md) to enable
[advanced search](../../user/search/advanced_search.md).
That's it! You can now use GitLab Enterprise Edition! To upgrade to a newer
version, follow [Upgrading Linux package instances](index.md).

View File

@ -242,6 +242,21 @@ You can [define project or group variables in the UI](../../../ci/variables/inde
To prevent a regular pipeline from triggering, users can push a commit to a protected branch with `[skip ci]` in the commit message. However, jobs defined with a pipeline execution policy are always triggered, as the policy ignores the `[skip ci]` directive. This prevents developers from skipping the execution of jobs defined in the policy, which ensures that critical security and compliance checks are always performed.
## Interaction with scan execution policies
When you use pipeline execution policies with the `override_ci` strategy, be aware that this can affect the behavior of [scan execution policies](scan_execution_policies.md):
- The scan execution policy may be overridden if both pipeline execution policies and scan execution policies are configured for a project, and the pipeline execution policy uses the `override_ci` strategy.
This is because the `override_ci` strategy removes all CI/CD configuration that is defined on the project level, including policies.
To ensure that both pipeline execution policies and scan execution policies are applied:
- Consider using a different strategy for pipeline execution policies, such as `inject_ci`.
- If you must use `override_ci`, include the scanner templates that you require in your pipeline execution policy to maintain the desired security scans.
Support for improvements in the integration between these policy types is proposed in [issue 504434](https://gitlab.com/gitlab-org/gitlab/-/issues/504434).
## Examples
These examples demonstrate what you can achieve with pipeline execution policies.

Some files were not shown because too many files have changed in this diff Show More