diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS index fcd0b1a215c..b671cafa536 100644 --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -1289,7 +1289,6 @@ lib/gitlab/checks/** /app/views/projects/pipeline_schedules/ /app/views/projects/pipelines/ /app/views/projects/triggers/ -/app/workers/build_hooks_worker.rb /app/workers/build_queue_worker.rb /app/workers/build_success_worker.rb /app/workers/ci_platform_metrics_update_cron_worker.rb diff --git a/.gitlab/ci/qa-common/main.gitlab-ci.yml b/.gitlab/ci/qa-common/main.gitlab-ci.yml index 159dd7842b0..764f7646e55 100644 --- a/.gitlab/ci/qa-common/main.gitlab-ci.yml +++ b/.gitlab/ci/qa-common/main.gitlab-ci.yml @@ -15,7 +15,7 @@ include: gitlab_auth_token_variable_name: "PROJECT_TOKEN_FOR_CI_SCRIPTS_API_USAGE" allure_job_name: "${QA_RUN_TYPE}" - project: gitlab-org/quality/pipeline-common - ref: 8.4.0 + ref: 8.4.3 file: - /ci/base.gitlab-ci.yml - /ci/knapsack-report.yml diff --git a/.rubocop_todo/gitlab/namespaced_class.yml b/.rubocop_todo/gitlab/namespaced_class.yml index 9c42715dde7..e102827f4f0 100644 --- a/.rubocop_todo/gitlab/namespaced_class.yml +++ b/.rubocop_todo/gitlab/namespaced_class.yml @@ -712,7 +712,6 @@ Gitlab/NamespacedClass: - 'app/workers/authorized_projects_worker.rb' - 'app/workers/auto_merge_process_worker.rb' - 'app/workers/background_migration_worker.rb' - - 'app/workers/build_hooks_worker.rb' - 'app/workers/build_queue_worker.rb' - 'app/workers/build_success_worker.rb' - 'app/workers/bulk_import_worker.rb' diff --git a/.rubocop_todo/lint/redundant_cop_disable_directive.yml b/.rubocop_todo/lint/redundant_cop_disable_directive.yml index 5555a3b6743..abba53fe393 100644 --- a/.rubocop_todo/lint/redundant_cop_disable_directive.yml +++ b/.rubocop_todo/lint/redundant_cop_disable_directive.yml @@ -59,7 +59,6 @@ Lint/RedundantCopDisableDirective: - 'app/services/web_hook_service.rb' - 'app/uploaders/object_storage/cdn/google_ip_cache.rb' - 'app/workers/authorized_project_update/user_refresh_over_user_range_worker.rb' - - 'app/workers/build_hooks_worker.rb' - 'app/workers/bulk_imports/entity_worker.rb' - 'app/workers/ci/track_failed_build_worker.rb' - 'app/workers/container_registry/migration/enqueuer_worker.rb' diff --git a/.rubocop_todo/rspec/any_instance_of.yml b/.rubocop_todo/rspec/any_instance_of.yml index 0516664422d..7283728ad24 100644 --- a/.rubocop_todo/rspec/any_instance_of.yml +++ b/.rubocop_todo/rspec/any_instance_of.yml @@ -332,7 +332,6 @@ RSpec/AnyInstanceOf: - 'spec/uploaders/records_uploads_spec.rb' - 'spec/uploaders/workers/object_storage/migrate_uploads_worker_spec.rb' - 'spec/views/layouts/_head.html.haml_spec.rb' - - 'spec/workers/build_hooks_worker_spec.rb' - 'spec/workers/ci/build_schedule_worker_spec.rb' - 'spec/workers/ci/daily_build_group_report_results_worker_spec.rb' - 'spec/workers/clusters/cleanup/project_namespace_worker_spec.rb' diff --git a/.rubocop_todo/style/inline_disable_annotation.yml b/.rubocop_todo/style/inline_disable_annotation.yml index 5e49a3a90ad..f5796df2b97 100644 --- a/.rubocop_todo/style/inline_disable_annotation.yml +++ b/.rubocop_todo/style/inline_disable_annotation.yml @@ -791,7 +791,6 @@ Style/InlineDisableAnnotation: - 'app/workers/background_migration/ci_database_worker.rb' - 'app/workers/background_migration_worker.rb' - 'app/workers/batched_git_ref_updates/cleanup_scheduler_worker.rb' - - 'app/workers/build_hooks_worker.rb' - 'app/workers/build_queue_worker.rb' - 'app/workers/build_success_worker.rb' - 'app/workers/bulk_imports/finish_batched_pipeline_worker.rb' diff --git a/.rubocop_todo/style/redundant_self.yml b/.rubocop_todo/style/redundant_self.yml index 8c23290babe..183d679c43f 100644 --- a/.rubocop_todo/style/redundant_self.yml +++ b/.rubocop_todo/style/redundant_self.yml @@ -151,7 +151,6 @@ Style/RedundantSelf: - 'app/uploaders/gitlab_uploader.rb' - 'app/uploaders/object_storage.rb' - 'app/workers/background_migration/single_database_worker.rb' - - 'app/workers/build_hooks_worker.rb' - 'app/workers/concerns/application_worker.rb' - 'app/workers/concerns/limited_capacity/worker.rb' - 'app/workers/concerns/project_start_import.rb' diff --git a/CHANGELOG.md b/CHANGELOG.md index 08922805c8b..bfe0d2e488e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,26 @@ documentation](doc/development/changelog.md) for instructions on adding your own entry. +## 16.9.1 (2024-02-20) + +### Fixed (2 changes) + +- [Fix Duo Chat CORS issue by updating web-ide package](gitlab-org/security/gitlab@6c4fccdd4d33fd40550197699a990a0d07a65137) +- [Fix deny_all_requests_except_allowed of AddressableUrlValidator](gitlab-org/security/gitlab@18ff795a3b9fdd54705c1a8898ad15b5dd84e2f0) + +### Security (10 changes) + +- [Add a limit to CodeOwners reference extractor regex](gitlab-org/security/gitlab@b090b503c47300d708d7e51192a486467fdecefd) ([merge request](gitlab-org/security/gitlab!3894)) +- [Ensure LDAP user cannot sign in with password](gitlab-org/security/gitlab@1c2de5ef077c5710e213b668373557c01ff8ba26) ([merge request](gitlab-org/security/gitlab!3891)) +- [Ensure LDAP users cannot reset local password to bypass LDAP](gitlab-org/security/gitlab@07621ad26d2db3656c99b332e697a6b0857f6e07) ([merge request](gitlab-org/security/gitlab!3879)) +- [Disallow assigning higher role than current user](gitlab-org/security/gitlab@c9d8ffebe020dfdc1435e073516a098a8d188ff0) ([merge request](gitlab-org/security/gitlab!3889)) +- [Check project read access in Environment and Operations dashboard](gitlab-org/security/gitlab@83fdac099562fa4aebcc43e400b0da2026c730a6) ([merge request](gitlab-org/security/gitlab!3873)) +- [Fix Stored-XSS in user's profile page: Change markup used for pronouns](gitlab-org/security/gitlab@0fafb29660c08e72b87bd79d792da802c566b650) ([merge request](gitlab-org/security/gitlab!3882)) +- [Invalidate markdown cache to clear up stored XSS](gitlab-org/security/gitlab@3411c25e77642fddc3619bf24ee956d4ba4d99b2) ([merge request](gitlab-org/security/gitlab!3884)) +- [Disallow users to modify deploy key title](gitlab-org/security/gitlab@46ffceb9c94b6f4ba207ddf035ae67e8de413d57) ([merge request](gitlab-org/security/gitlab!3876)) +- [Adds authorization for analytics settings](gitlab-org/security/gitlab@01e2c82cb79b6b4a9f6cf3428890149d023aacfb) ([merge request](gitlab-org/security/gitlab!3877)) +- [Use merge_head_diff for codeowners when merge request is mergeable](gitlab-org/security/gitlab@eafc00662cb6e604b35278a5f59c25d418ef00c9) ([merge request](gitlab-org/security/gitlab!3878)) + ## 16.9.0 (2024-02-14) ### Added (145 changes) @@ -739,6 +759,30 @@ entry. - [Add remediation badge to vulnerability report](gitlab-org/gitlab@e6236197509eae1bb27edf8fb2c63ccf769c2642) ([merge request](gitlab-org/gitlab!142455)) +## 16.8.3 (2024-02-20) + +### Added (1 change) + +- [Allow creation of group-level custom-roles on self-managed instances](gitlab-org/security/gitlab@72eeb80a95e7190b5a6a9a4b113dd88d3f66bdd4) **GitLab Enterprise Edition** + +### Fixed (3 changes) + +- [Avoid mutating OpenSSL::PKey::EC keys](gitlab-org/security/gitlab@f562d0d13834ec09123d49019265a1202d8c2cc2) +- [Fix X509::Signature#x509_issuer not working with OpenSSL 3](gitlab-org/security/gitlab@7ad0ea9d286e003814032275cd1bcc487b7ecac7) +- [Fix urlblocker validate calls with more options](gitlab-org/security/gitlab@04111c2e90b8e40668ccb74a4f64c3a2853bc3c0) + +### Security (9 changes) + +- [Add a limit to CodeOwners reference extractor regex](gitlab-org/security/gitlab@55d0ba98eaa460f86b6d750d91d1eb21a0759836) ([merge request](gitlab-org/security/gitlab!3860)) +- [Ensure LDAP user cannot sign in with password](gitlab-org/security/gitlab@085b95fd9ec3ad3a4fa3aab7136ce29ae3dac507) ([merge request](gitlab-org/security/gitlab!3892)) +- [Ensure LDAP users cannot reset local password to bypass LDAP](gitlab-org/security/gitlab@746702abea2a7703f75885f4a52df4d4ec2f8a41) ([merge request](gitlab-org/security/gitlab!3880)) +- [Disallow assigning higher role than current user](gitlab-org/security/gitlab@d018ba8f447e0ae98f4ee74011d1aa4dcaab7432) ([merge request](gitlab-org/security/gitlab!3851)) +- [Check project read access in Environments and Operations dashboard](gitlab-org/security/gitlab@d7c1e953fb21c2aa793156eb035cd170072cffca) ([merge request](gitlab-org/security/gitlab!3872)) +- [Invalidate markdown cache to clear up stored XSS](gitlab-org/security/gitlab@d3dfc38783578bfecc3dfaa26546867b9f63694a) ([merge request](gitlab-org/security/gitlab!3885)) +- [Disallow users to modify deploy key title](gitlab-org/security/gitlab@6bc3fca49ec264873100509683490b91c136b29e) ([merge request](gitlab-org/security/gitlab!3866)) +- [Adds authorization for analytics settings](gitlab-org/security/gitlab@01a31cdf0d9879f048cdff21fcb20f368307ed11) ([merge request](gitlab-org/security/gitlab!3850)) +- [Use merge_head_diff for codeowners when merge request is mergeable](gitlab-org/security/gitlab@6da2d42bfb260dcb387f2ea692df06c6054afd45) ([merge request](gitlab-org/security/gitlab!3868)) + ## 16.8.2 (2024-02-07) ### Fixed (3 changes) @@ -1256,6 +1300,25 @@ entry. - [Bump the finalize_after date of backfill migration](gitlab-org/gitlab@770ab7faa2048bfeb8bddd506e6f37fe18bb4d06) ([merge request](gitlab-org/gitlab!140109)) - [Remove code_suggestions_completion_api feature](gitlab-org/gitlab@988e2f57f9635ed9cc3896b15965b608fce54756) ([merge request](gitlab-org/gitlab!138174)) **GitLab Enterprise Edition** +## 16.7.6 (2024-02-20) + +### Fixed (2 changes) + +- [Avoid mutating OpenSSL::PKey::EC keys](gitlab-org/security/gitlab@3d15d7efb953ff7abe9837caa99dd9be776c1a58) +- [Fix X509::Signature#x509_issuer not working with OpenSSL 3](gitlab-org/security/gitlab@e1fb88e53d6a699f3b26db233ec275fc6dbaeeb9) + +### Security (9 changes) + +- [Add a limit to CodeOwners reference extractor regex](gitlab-org/security/gitlab@df77f98beec6c91605b697a84dabcabe12a9aa8e) ([merge request](gitlab-org/security/gitlab!3861)) +- [Ensure LDAP user cannot sign in with password](gitlab-org/security/gitlab@a711d3d91d2c66b97fef6987107838b68f471b68) ([merge request](gitlab-org/security/gitlab!3893)) +- [Ensure LDAP users cannot reset local password to bypass LDAP](gitlab-org/security/gitlab@4c0cb71664cc31f93a3adbc71aa2339c8ce8ee20) ([merge request](gitlab-org/security/gitlab!3881)) +- [Disallow assigning higher role than current user](gitlab-org/security/gitlab@9699f280e711fd75e8c02e6849efbc09e6162b59) ([merge request](gitlab-org/security/gitlab!3852)) +- [Check project read access in Environments and Operations dashboard](gitlab-org/security/gitlab@0a6b7ffd36aafd377065e61e6806734e9fcf449c) ([merge request](gitlab-org/security/gitlab!3871)) +- [Invalidate markdown cache to clear up stored XSS](gitlab-org/security/gitlab@d17f1b2b42c5d0872392e0c26f244e4ae55f4c2c) ([merge request](gitlab-org/security/gitlab!3886)) +- [Disallow users to modify deploy key title](gitlab-org/security/gitlab@b581173dbe86002261584a16a13360e2e6497274) ([merge request](gitlab-org/security/gitlab!3865)) +- [Adds authorization for analytics settings](gitlab-org/security/gitlab@b4eec07d6a987d1ae508ba7aacc66f39ec2dd30d) ([merge request](gitlab-org/security/gitlab!3857)) +- [Use merge_head_diff for codeowners when merge request is mergeable](gitlab-org/security/gitlab@52e8d1a80ae99ac8c68b1df3581c1817e6fb7d49) ([merge request](gitlab-org/security/gitlab!3869)) + ## 16.7.5 (2024-02-07) ### Fixed (1 change) diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js index 25bc6f3ff3d..c51bef92e18 100644 --- a/app/assets/javascripts/merge_request_tabs.js +++ b/app/assets/javascripts/merge_request_tabs.js @@ -171,11 +171,11 @@ function toggleLoader(state) { $('.mr-loading-status .loading').toggleClass('hide', !state); } -function getActionFromHref(href) { - let action = new URL(href).pathname.match(/\/(commits|diffs|pipelines).*$/); +export function getActionFromHref(pathName) { + let action = pathName.match(/\/(\d+)\/(commits|diffs|pipelines).*$/); if (action) { - action = action[0].replace(/(^\/|\.html)/g, ''); + action = action.at(-1).replace(/(^\/|\.html)/g, ''); } else { action = 'show'; } @@ -239,7 +239,7 @@ export default class MergeRequestTabs { $('.merge-request-tabs a[data-toggle="tabvue"]').on('click', this.clickTab); window.addEventListener('popstate', (event) => { if (event?.state?.skipScrolling) return; - const action = getActionFromHref(location.href); + const action = getActionFromHref(window.location.pathname); this.tabShown(action, location.href); this.eventHub.$emit('MergeRequestTabChange', action); diff --git a/app/assets/stylesheets/page_bundles/settings.scss b/app/assets/stylesheets/page_bundles/settings.scss index f8a5f28170a..cf029b1b883 100644 --- a/app/assets/stylesheets/page_bundles/settings.scss +++ b/app/assets/stylesheets/page_bundles/settings.scss @@ -120,6 +120,14 @@ margin-top: 0; } + .instance-runners-info { + .gl-alert-body { + p:last-child { + margin-bottom: 0; + } + } + } + .form-check .form-text.text-muted { margin-bottom: $grid-size; } diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb index d1ca16bd8fb..48ce6479f07 100644 --- a/app/controllers/passwords_controller.rb +++ b/app/controllers/passwords_controller.rb @@ -60,11 +60,7 @@ class PasswordsController < Devise::PasswordsController end def check_password_authentication_available - if resource - return if resource.allow_password_authentication? - elsif Gitlab::CurrentSettings.password_authentication_enabled? - return - end + return if Gitlab::CurrentSettings.password_authentication_enabled? redirect_to after_sending_reset_password_instructions_path_for(resource_name), alert: _("Password authentication is unavailable.") diff --git a/app/controllers/projects/deploy_keys_controller.rb b/app/controllers/projects/deploy_keys_controller.rb index 66ce501f9f0..4be0fb2a6f8 100644 --- a/app/controllers/projects/deploy_keys_controller.rb +++ b/app/controllers/projects/deploy_keys_controller.rb @@ -117,7 +117,7 @@ class Projects::DeployKeysController < Projects::ApplicationController def update_params permitted_params = [deploy_keys_projects_attributes: [:can_push]] - permitted_params << :title if can?(current_user, :update_deploy_key, deploy_key) + permitted_params << :title if can?(current_user, :update_deploy_key_title, deploy_key) key_update_params = params.require(:deploy_key).permit(*permitted_params) key_update_params.dig(:deploy_keys_projects_attributes, '0')&.merge!(id: deploy_keys_project.id) diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index a8a09bd6ac6..1fc60da2a5b 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -26,8 +26,10 @@ class SessionsController < Devise::SessionsController prepend_before_action :check_captcha, only: [:create] prepend_before_action :store_redirect_uri, only: [:new] prepend_before_action :require_no_authentication_without_flash, only: [:new, :create] - prepend_before_action :check_forbidden_password_based_login, if: -> { action_name == 'create' && password_based_login? } - prepend_before_action :ensure_password_authentication_enabled!, if: -> { action_name == 'create' && password_based_login? } + prepend_before_action :ensure_user_allowed_to_password_authenticate, + if: -> { action_name == 'create' && password_based_login? } + prepend_before_action :ensure_password_authentication_enabled!, + if: -> { action_name == 'create' && password_based_login? } before_action :auto_sign_in_with_provider, only: [:new] before_action :init_preferred_language, only: :new before_action :store_unauthenticated_sessions, only: [:new] @@ -317,11 +319,11 @@ class SessionsController < Devise::SessionsController @invite_email = ActionController::Base.helpers.sanitize(params[:invite_email]) end - def check_forbidden_password_based_login - if find_user&.password_based_login_forbidden? - flash[:alert] = _('You are not allowed to log in using password') - redirect_to new_user_session_path - end + def ensure_user_allowed_to_password_authenticate + return unless find_user + return if find_user.allow_password_authentication_for_web? && !find_user.password_based_login_forbidden? + + redirect_to new_user_session_path, alert: I18n.t('devise.failure.invalid') end end diff --git a/app/graphql/types/ci/pipeline_type.rb b/app/graphql/types/ci/pipeline_type.rb index c84864dcb9f..709be718295 100644 --- a/app/graphql/types/ci/pipeline_type.rb +++ b/app/graphql/types/ci/pipeline_type.rb @@ -202,6 +202,8 @@ module Types field :yaml_errors, GraphQL::Types::Boolean, method: :yaml_errors?, null: false, description: "If the pipeline has YAML errors." + field :yaml_error_messages, GraphQL::Types::String, method: :yaml_errors, null: true, description: "The pipeline YAML errors." + field :trigger, GraphQL::Types::Boolean, method: :trigger?, null: false, description: "If the pipeline was created by a Trigger request." def commit diff --git a/app/models/concerns/recoverable_by_any_email.rb b/app/models/concerns/recoverable_by_any_email.rb index 7bd908597c9..05d5e2f89a0 100644 --- a/app/models/concerns/recoverable_by_any_email.rb +++ b/app/models/concerns/recoverable_by_any_email.rb @@ -14,6 +14,7 @@ module RecoverableByAnyEmail return super unless email recoverable = email.user + return recoverable.password_auth_unavailable_error! unless recoverable.allow_password_authentication_for_web? recoverable.send_reset_password_instructions(to: email.email) recoverable @@ -28,6 +29,11 @@ module RecoverableByAnyEmail token end + def password_auth_unavailable_error! + errors.add(:password, :unavailable, message: _('Password authentication is unavailable.')) + self + end + protected def send_reset_password_instructions_notification(token, opts = {}) diff --git a/app/models/member.rb b/app/models/member.rb index e6bf5c7788a..1aef1fe21b6 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -540,6 +540,10 @@ class Member < ApplicationRecord end end + def prevent_role_assignement?(_current_user, _params) + false + end + private # TODO: https://gitlab.com/groups/gitlab-org/-/epics/7054 diff --git a/app/models/namespaces/traversal/linear.rb b/app/models/namespaces/traversal/linear.rb index 0b408220911..8529f4a2b25 100644 --- a/app/models/namespaces/traversal/linear.rb +++ b/app/models/namespaces/traversal/linear.rb @@ -261,7 +261,17 @@ module Namespaces skope = self.class if top - skope = skope.where("traversal_ids @> ('{?}')", top.id) + if ::Feature.enabled?(:optimize_top_bound_lineage_search, self) + lower = top.traversal_ids + upper = lower.dup + upper[-1] = upper[-1].next + + skope = skope + .where("traversal_ids >= ('{?}')", lower) + .where("traversal_ids < ('{?}')", upper) + else + skope = skope.where("traversal_ids @> ('{?}')", top.id) + end end if bottom diff --git a/app/policies/deploy_key_policy.rb b/app/policies/deploy_key_policy.rb index ccf1bda26bb..54bb0d4b571 100644 --- a/app/policies/deploy_key_policy.rb +++ b/app/policies/deploy_key_policy.rb @@ -5,6 +5,11 @@ class DeployKeyPolicy < BasePolicy condition(:private_deploy_key) { @subject.private? } condition(:public_deploy_key) { @subject.public? } condition(:has_deploy_key) { @user.project_deploy_keys.any? { |pdk| pdk.id.eql?(@subject.id) } } + condition(:orphaned_deploy_key) { @subject.orphaned? } + condition(:is_maintainer_of_deploy_key_project) do + # Note: 'almost_orphaned' deploy key has only one project record and we can check it as 'first' + @subject.almost_orphaned? && can?(:maintainer_access, @subject.deploy_keys_projects.first) + end rule { anonymous }.prevent_all rule { public_deploy_key | admin | has_deploy_key }.policy do @@ -13,4 +18,7 @@ class DeployKeyPolicy < BasePolicy rule { admin | (private_deploy_key & has_deploy_key) }.policy do enable :update_deploy_key end + rule { can?(:update_deploy_key) & (admin | orphaned_deploy_key | is_maintainer_of_deploy_key_project) }.policy do + enable :update_deploy_key_title + end end diff --git a/app/views/projects/runners/_group_runners.html.haml b/app/views/projects/runners/_group_runners.html.haml index a79b73f6f61..44a8742166a 100644 --- a/app/views/projects/runners/_group_runners.html.haml +++ b/app/views/projects/runners/_group_runners.html.haml @@ -3,23 +3,28 @@ %h4 = _('Group runners') -.bs-callout.bs-callout-warning - = _('These runners are shared across projects in this group.') - %br - %br - = _('Group runners can be managed with the %{link}.').html_safe % { link: link } - += render Pajamas::AlertComponent.new(variant: :warning, + dismissible: false, + show_icon: false, + alert_options: { class: 'gl-mb-5' }) do |c| + - c.with_body do + = _('These runners are shared across projects in this group.') + %br + %br + = _('Group runners can be managed with the %{link}.').html_safe % { link: link } - if @project.group - %br - %br - - if @project.group_runners_enabled? - = link_button_to toggle_group_runners_project_runners_path(@project), method: :post do - = _('Disable group runners') - - else - = link_button_to toggle_group_runners_project_runners_path(@project), method: :post, variant: :confirm, category: :secondary do - = _('Enable group runners') -   - = _('for this project') + - c.with_actions do + %br + %br + %div + - if @project.group_runners_enabled? + = link_button_to toggle_group_runners_project_runners_path(@project), method: :post do + = _('Disable group runners') + - else + = link_button_to toggle_group_runners_project_runners_path(@project), method: :post, variant: :confirm, category: :secondary do + = _('Enable group runners') +   + = _('for this project') - if !@project.group = _('This project does not belong to a group and cannot make use of group runners.') diff --git a/app/views/projects/runners/_project_runners.html.haml b/app/views/projects/runners/_project_runners.html.haml index 0f2f0c3f21c..a5a83fe0309 100644 --- a/app/views/projects/runners/_project_runners.html.haml +++ b/app/views/projects/runners/_project_runners.html.haml @@ -1,17 +1,17 @@ %h4 = s_('Runners|Project runners') -.bs-callout.help-callout - %p= s_('Runners|These runners are assigned to this project.') - - if can?(current_user, :create_runner, @project) - = render Pajamas::ButtonComponent.new(href: new_project_runner_path(@project), variant: :confirm) do - = s_('Runners|New project runner') - .gl-display-inline - #js-project-runner-registration-dropdown{ data: { registration_token: @project.runners_token, project_id: @project.id } } - - else - = _('Please contact an admin to create runners.') - = link_to _('Learn more.'), help_page_path('administration/settings/continuous_integration', anchor: 'restrict-runner-registration-by-all-users-in-an-instance'), target: '_blank', rel: 'noopener noreferrer' - += render Pajamas::AlertComponent.new(dismissible: false, show_icon: false, alert_options: { class: 'gl-mb-5' }) do |c| + - c.with_body do + %p= s_('Runners|These runners are assigned to this project.') + - if can?(current_user, :create_runner, @project) + = render Pajamas::ButtonComponent.new(href: new_project_runner_path(@project), variant: :confirm) do + = s_('Runners|New project runner') + .gl-display-inline + #js-project-runner-registration-dropdown{ data: { registration_token: @project.runners_token, project_id: @project.id } } + - else + = _('Please contact an admin to create runners.') + = link_to _('Learn more.'), help_page_path('administration/settings/continuous_integration', anchor: 'restrict-runner-registration-by-all-users-in-an-instance'), target: '_blank', rel: 'noopener noreferrer' %hr - if @project_runners.any? diff --git a/app/views/shared/deploy_keys/_form.html.haml b/app/views/shared/deploy_keys/_form.html.haml index f36de252c01..304f4dbe204 100644 --- a/app/views/shared/deploy_keys/_form.html.haml +++ b/app/views/shared/deploy_keys/_form.html.haml @@ -6,7 +6,7 @@ .form-group = form.label :title - = form.text_field :title, class: 'form-control gl-form-input', data: { testid: 'deploy-key-title-field' }, readonly: ('readonly' unless can?(current_user, :update_deploy_key, deploy_key)) + = form.text_field :title, class: 'form-control gl-form-input', data: { testid: 'deploy-key-title-field' }, readonly: ('readonly' unless can?(current_user, :update_deploy_key_title, deploy_key)) - if deploy_key.new_record? .form-group @@ -39,4 +39,4 @@ = form.fields_for :deploy_keys_projects, deploy_keys_project do |deploy_keys_project_form| .form-group = deploy_keys_project_form.gitlab_ui_checkbox_component :can_push, _('Grant write permissions to this key'), - help_text: _('Allow this key to push to this repository') + help_text: _('Allow this key to push to this repository') diff --git a/app/views/shared/runners/_shared_runners_description.html.haml b/app/views/shared/runners/_shared_runners_description.html.haml index 59876a9ead4..3878879f37f 100644 --- a/app/views/shared/runners/_shared_runners_description.html.haml +++ b/app/views/shared/runners/_shared_runners_description.html.haml @@ -3,7 +3,10 @@ %h4 = s_('Runners|Instance runners') -.bs-callout{ data: { testid: 'shared-runners-description' } } - %p= s_('Runners|%{link_start}These runners%{link_end} are available to all groups and projects.').html_safe % { link_start: shared_link_start, link_end: ''.html_safe } - - if Gitlab::CurrentSettings.shared_runners_text.present? - = markdown(Gitlab::CurrentSettings.current_application_settings.shared_runners_text) += render Pajamas::AlertComponent.new(dismissible: false, + show_icon: false, + alert_options: { class: 'instance-runners-info gl-mb-5', data: { testid: 'shared-runners-description' } }) do |c| + - c.with_body do + %p= s_('Runners|%{link_start}These runners%{link_end} are available to all groups and projects.').html_safe % { link_start: shared_link_start, link_end: ''.html_safe } + - if Gitlab::CurrentSettings.shared_runners_text.present? + = markdown(Gitlab::CurrentSettings.current_application_settings.shared_runners_text) diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index b3b98323b8b..e084f96eb64 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -110,11 +110,15 @@ %h2.gl-font-base.gl-mb-2.gl-mt-4= s_('UserProfile|About') .gl-display-flex.gl-gap-2.gl-flex-direction-column - if @user.pronouns.present? || @user.pronunciation.present? - %div + .gl-mb-2 - if @user.pronunciation.present? - %div= sprintf(s_("UserProfile|Pronounced as: %{div_start}%{pronunciation}%{div_end}"), { pronunciation: @user.pronunciation, div_start: '
', div_end: '
' }).html_safe + %p.gl-m-0 + = s_("UserProfile|Pronounced as:") + %span.gl-font-sm.gl-text-secondary.gl-display-inline-flex= @user.pronunciation - if @user.pronouns.present? - %div= sprintf(s_("UserProfile|Pronouns: %{div_start}%{pronouns}%{div_end}"), { pronouns: @user.pronouns, div_start: '
', div_end: '
' }).html_safe + %p.gl-m-0 + = s_("UserProfile|Pronouns:") + %span.gl-font-sm.gl-text-secondary.gl-display-inline-flex= @user.pronouns - if @user.bio.present? %p.profile-user-bio.gl-mb-0 = @user.bio diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index 87a0ed15024..58dc282ebbc 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -2145,15 +2145,6 @@ :weight: 3 :idempotent: false :tags: [] -- :name: pipeline_hooks:build_hooks - :worker_name: BuildHooksWorker - :feature_category: :continuous_integration - :has_external_dependencies: false - :urgency: :high - :resource_boundary: :unknown - :weight: 2 - :idempotent: false - :tags: [] - :name: pipeline_hooks:pipeline_hooks :worker_name: PipelineHooksWorker :feature_category: :continuous_integration diff --git a/app/workers/build_hooks_worker.rb b/app/workers/build_hooks_worker.rb deleted file mode 100644 index 2c62aed72d6..00000000000 --- a/app/workers/build_hooks_worker.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -class BuildHooksWorker # rubocop:disable Scalability/IdempotentWorker - include ApplicationWorker - - sidekiq_options retry: 3 - include PipelineQueue - - queue_namespace :pipeline_hooks - feature_category :continuous_integration - urgency :high - data_consistency :delayed - - # rubocop: disable CodeReuse/ActiveRecord - def perform(build_id) - build = Ci::Build.find_by_id(build_id) - - build.execute_hooks if build - end - # rubocop: enable CodeReuse/ActiveRecord - - def self.perform_async(build) - Gitlab::AppLogger.info( - message: "Enqueuing hooks for Build #{build.id}: #{build.status}", - class: self.name, - build_id: build.id, - pipeline_id: build.pipeline_id, - project_id: build.project_id, - build_status: build.status) - - super(build.id) - end -end diff --git a/config/feature_flags/gitlab_com_derisk/optimize_top_bound_lineage_search.yml b/config/feature_flags/gitlab_com_derisk/optimize_top_bound_lineage_search.yml new file mode 100644 index 00000000000..f99e8e868ae --- /dev/null +++ b/config/feature_flags/gitlab_com_derisk/optimize_top_bound_lineage_search.yml @@ -0,0 +1,9 @@ +--- +name: optimize_top_bound_lineage_search +feature_issue_url: +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/144835 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/442634 +milestone: '16.10' +group: group::threat insights +type: gitlab_com_derisk +default_enabled: false diff --git a/config/metrics/counts_28d/20210216181152_projects_jira_dvcs_cloud_active.yml b/config/metrics/counts_28d/20210216181152_projects_jira_dvcs_cloud_active.yml index 650e84cca79..86c05df3083 100644 --- a/config/metrics/counts_28d/20210216181152_projects_jira_dvcs_cloud_active.yml +++ b/config/metrics/counts_28d/20210216181152_projects_jira_dvcs_cloud_active.yml @@ -5,7 +5,7 @@ description: Distinct count of creator_id from projects with an active Jira Clou DVCS integration. product_section: dev product_stage: manage -product_group: integration +product_group: import_and_integrate value_type: number status: removed time_frame: 28d diff --git a/config/metrics/counts_28d/20210216181154_projects_jira_dvcs_server_active.yml b/config/metrics/counts_28d/20210216181154_projects_jira_dvcs_server_active.yml index d0d730381a6..34bcee9905b 100644 --- a/config/metrics/counts_28d/20210216181154_projects_jira_dvcs_server_active.yml +++ b/config/metrics/counts_28d/20210216181154_projects_jira_dvcs_server_active.yml @@ -5,7 +5,7 @@ description: Distinct count of creator_id from projects with an active Jira Serv DVCS integration. product_section: dev product_stage: manage -product_group: integration +product_group: import_and_integrate value_type: number status: active time_frame: 28d diff --git a/config/metrics/counts_all/20210216181128_projects_jira_dvcs_cloud_active.yml b/config/metrics/counts_all/20210216181128_projects_jira_dvcs_cloud_active.yml index 7b89554c2b2..2fb27416694 100644 --- a/config/metrics/counts_all/20210216181128_projects_jira_dvcs_cloud_active.yml +++ b/config/metrics/counts_all/20210216181128_projects_jira_dvcs_cloud_active.yml @@ -5,7 +5,7 @@ description: Distinct count of creator_id from projects with an active Jira Clou DVCS integration. product_section: dev product_stage: manage -product_group: integration +product_group: import_and_integrate value_type: number status: removed time_frame: all diff --git a/config/metrics/counts_all/20210216181130_projects_jira_dvcs_server_active.yml b/config/metrics/counts_all/20210216181130_projects_jira_dvcs_server_active.yml index b3f8b6ac307..bbf8cbb367b 100644 --- a/config/metrics/counts_all/20210216181130_projects_jira_dvcs_server_active.yml +++ b/config/metrics/counts_all/20210216181130_projects_jira_dvcs_server_active.yml @@ -5,7 +5,7 @@ description: Distinct count of creator_id from projects with an active Jira Serv DVCS integration. product_section: dev product_stage: manage -product_group: integration +product_group: import_and_integrate value_type: number status: active time_frame: all diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml index 5751fb57976..a2465a123a5 100644 --- a/config/sidekiq_queues.yml +++ b/config/sidekiq_queues.yml @@ -189,12 +189,12 @@ - 1 - - compliance_management_chain_of_custody_report - 1 -- - compliance_management_framework_export_mailer - - 1 - - compliance_management_merge_requests_compliance_violations - 1 - - compliance_management_pending_status_check - 1 +- - compliance_management_project_framework_export_mailer + - 1 - - compliance_management_standards_adherence_export_mailer - 1 - - compliance_management_standards_gitlab_at_least_two_approvals diff --git a/db/docs/packages_conan_file_metadata.yml b/db/docs/packages_conan_file_metadata.yml index 9d8888d73eb..7f1b7886e6e 100644 --- a/db/docs/packages_conan_file_metadata.yml +++ b/db/docs/packages_conan_file_metadata.yml @@ -7,4 +7,20 @@ feature_categories: description: Conan package file metadata introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16418 milestone: '12.5' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +desired_sharding_key: + project_id: + references: projects + backfill_via: + parent: + foreign_key: package_file_id + table: packages_package_files + sharding_key: project_id + belongs_to: package_file + awaiting_backfill_on_parent: true diff --git a/db/docs/packages_debian_file_metadata.yml b/db/docs/packages_debian_file_metadata.yml index f24ddd0efbf..cb6ecd1aac7 100644 --- a/db/docs/packages_debian_file_metadata.yml +++ b/db/docs/packages_debian_file_metadata.yml @@ -7,4 +7,20 @@ feature_categories: description: Debian package file metadata introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49692 milestone: '13.8' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +desired_sharding_key: + project_id: + references: projects + backfill_via: + parent: + foreign_key: package_file_id + table: packages_package_files + sharding_key: project_id + belongs_to: package_file + awaiting_backfill_on_parent: true diff --git a/db/docs/packages_debian_project_component_files.yml b/db/docs/packages_debian_project_component_files.yml index a90860ba8b9..7e6fa9e442f 100644 --- a/db/docs/packages_debian_project_component_files.yml +++ b/db/docs/packages_debian_project_component_files.yml @@ -7,4 +7,20 @@ feature_categories: description: Debian project-level component files introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52885 milestone: '13.9' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +desired_sharding_key: + project_id: + references: projects + backfill_via: + parent: + foreign_key: component_id + table: packages_debian_project_components + sharding_key: project_id + belongs_to: component + awaiting_backfill_on_parent: true diff --git a/db/docs/packages_helm_file_metadata.yml b/db/docs/packages_helm_file_metadata.yml index dbd39544482..0b423f30028 100644 --- a/db/docs/packages_helm_file_metadata.yml +++ b/db/docs/packages_helm_file_metadata.yml @@ -7,4 +7,20 @@ feature_categories: description: Helm package file metadata introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57017 milestone: '13.12' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +desired_sharding_key: + project_id: + references: projects + backfill_via: + parent: + foreign_key: package_file_id + table: packages_package_files + sharding_key: project_id + belongs_to: package_file + awaiting_backfill_on_parent: true diff --git a/db/docs/packages_nuget_dependency_link_metadata.yml b/db/docs/packages_nuget_dependency_link_metadata.yml index 7d93e6aaf77..3c9f815d600 100644 --- a/db/docs/packages_nuget_dependency_link_metadata.yml +++ b/db/docs/packages_nuget_dependency_link_metadata.yml @@ -7,4 +7,20 @@ feature_categories: description: Join table between nuget target frameworks and packages_dependency_links introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30618 milestone: '13.0' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +desired_sharding_key: + project_id: + references: projects + backfill_via: + parent: + foreign_key: dependency_link_id + table: packages_dependency_links + sharding_key: project_id + belongs_to: dependency_link + awaiting_backfill_on_parent: true diff --git a/db/docs/packages_package_file_build_infos.yml b/db/docs/packages_package_file_build_infos.yml index 2477117add9..7a25b5a4ef5 100644 --- a/db/docs/packages_package_file_build_infos.yml +++ b/db/docs/packages_package_file_build_infos.yml @@ -7,4 +7,20 @@ feature_categories: description: Join table relating packages_package_files and ci_pipelines introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44348 milestone: '13.6' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +desired_sharding_key: + project_id: + references: projects + backfill_via: + parent: + foreign_key: package_file_id + table: packages_package_files + sharding_key: project_id + belongs_to: package_file + awaiting_backfill_on_parent: true diff --git a/db/migrate/20240216133415_rename_type_column_of_group_external_streaming_destination.rb b/db/migrate/20240216133415_rename_type_column_of_group_external_streaming_destination.rb new file mode 100644 index 00000000000..a178384ff5d --- /dev/null +++ b/db/migrate/20240216133415_rename_type_column_of_group_external_streaming_destination.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class RenameTypeColumnOfGroupExternalStreamingDestination < Gitlab::Database::Migration[2.2] + milestone '16.10' + + def change + rename_column :audit_events_group_external_streaming_destinations, :type, :category + end +end diff --git a/db/migrate/20240216133523_rename_type_column_of_instance_external_streaming_destination.rb b/db/migrate/20240216133523_rename_type_column_of_instance_external_streaming_destination.rb new file mode 100644 index 00000000000..2d464c22a88 --- /dev/null +++ b/db/migrate/20240216133523_rename_type_column_of_instance_external_streaming_destination.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class RenameTypeColumnOfInstanceExternalStreamingDestination < Gitlab::Database::Migration[2.2] + milestone '16.10' + + def change + rename_column :audit_events_instance_external_streaming_destinations, :type, :category + end +end diff --git a/db/migrate/20240221100732_remove_build_hooks_worker.rb b/db/migrate/20240221100732_remove_build_hooks_worker.rb new file mode 100644 index 00000000000..1f7a945ae76 --- /dev/null +++ b/db/migrate/20240221100732_remove_build_hooks_worker.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class RemoveBuildHooksWorker < Gitlab::Database::Migration[2.2] + milestone '16.10' + disable_ddl_transaction! + + DEPRECATED_JOB_CLASSES = %w[ + BuildHooksWorker + ] + + def up + sidekiq_remove_jobs(job_klasses: DEPRECATED_JOB_CLASSES) + end + + def down + # This migration removes any instances of deprecated workers and cannot be undone. + end +end diff --git a/db/schema_migrations/20240216133415 b/db/schema_migrations/20240216133415 new file mode 100644 index 00000000000..f3590e0c11b --- /dev/null +++ b/db/schema_migrations/20240216133415 @@ -0,0 +1 @@ +2f0111d20042ca30b154bc409b0e9437d598c20e32a4ce00bc9babc659798152 \ No newline at end of file diff --git a/db/schema_migrations/20240216133523 b/db/schema_migrations/20240216133523 new file mode 100644 index 00000000000..9b250c793cb --- /dev/null +++ b/db/schema_migrations/20240216133523 @@ -0,0 +1 @@ +adf1ba23379a6be9f5ab0b7af1c24fed51d5739152e518fb5cfe0f84e504c544 \ No newline at end of file diff --git a/db/schema_migrations/20240221100732 b/db/schema_migrations/20240221100732 new file mode 100644 index 00000000000..63068d66bae --- /dev/null +++ b/db/schema_migrations/20240221100732 @@ -0,0 +1 @@ +6677d9a0a9b8255855fcb0e14cce4d0dd22e2c7284d1a00cd3ffecf42a6b20f3 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index fd9b1838fb9..9153190f76c 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -4618,7 +4618,7 @@ CREATE TABLE audit_events_group_external_streaming_destinations ( created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, group_id bigint NOT NULL, - type smallint NOT NULL, + category smallint NOT NULL, name text NOT NULL, config jsonb NOT NULL, encrypted_secret_token bytea NOT NULL, @@ -4694,7 +4694,7 @@ CREATE TABLE audit_events_instance_external_streaming_destinations ( id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, - type smallint NOT NULL, + category smallint NOT NULL, name text NOT NULL, config jsonb NOT NULL, encrypted_secret_token bytea NOT NULL, diff --git a/doc/administration/dedicated/create_instance.md b/doc/administration/dedicated/create_instance.md index 67b88186c18..6e0a0721341 100644 --- a/doc/administration/dedicated/create_instance.md +++ b/doc/administration/dedicated/create_instance.md @@ -23,6 +23,7 @@ provide the following information to your account team: - Email addresses of the users who are responsible to complete the onboarding and create your GitLab Dedicated instance. - Whether you want to [bring your own encryption keys (BYOK)](#encrypted-data-at-rest-byok). If so, GitLab provides an AWS account ID, which is necessary to enable BYOK. +- Whether you want to use Geo migration for inbound migration of your Dedicated instance. If you've been granted access to Switchboard, you will receive an email invitation with temporary credentials to sign in. diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 83a672f659f..f82b3505b28 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -24724,6 +24724,7 @@ Returns [`UserMergeRequestInteraction`](#usermergerequestinteraction). | `usesNeeds` | [`Boolean`](#boolean) | Indicates if the pipeline has jobs with `needs` dependencies. | | `warningMessages` | [`[PipelineMessage!]`](#pipelinemessage) | Pipeline warning messages. | | `warnings` | [`Boolean!`](#boolean) | Indicates if a pipeline has warnings. | +| `yamlErrorMessages` | [`String`](#string) | The pipeline YAML errors. | | `yamlErrors` | [`Boolean!`](#boolean) | If the pipeline has YAML errors. | #### Fields with arguments diff --git a/doc/api/integrations.md b/doc/api/integrations.md index 6d8847ab53b..7177b028b8a 100644 --- a/doc/api/integrations.md +++ b/doc/api/integrations.md @@ -712,9 +712,6 @@ FLAG: On self-managed GitLab, by default this feature is available. To hide the feature, ask an administrator to [disable the feature flag](../administration/feature_flags.md) named `git_guardian_integration`. On GitLab.com, this feature is not available. -WARNING: -Pushes can be delayed or can time out. With the GitGuardian integration, pushes are sent to a third-party, and GitLab has no control over the connection with GitGuardian or the GitGuardian process. - [GitGuardian](https://www.gitguardian.com/) is a cybersecurity service that detects sensitive data such as API keys and passwords in source code repositories. It scans Git repositories, alerts on policy violations, and helps organizations @@ -722,6 +719,16 @@ fix security issues before hackers can exploit them. You can configure GitLab to reject commits based on GitGuardian policies. +### Known issues + +- Pushes can be delayed or can time out. With the GitGuardian integration, pushes are sent to a third-party, and GitLab has no control over the connection with GitGuardian or the GitGuardian process. +- Due to a [GitGuardian API limitation](https://api.gitguardian.com/docs#operation/multiple_scan), the integration ignores files over the size of 1 MB. They are not scanned. +- If a pushed file has a name over 256 characters long the push won't go through. + For more information, see [GitGuardian API documentation](https://api.gitguardian.com/docs#operation/multiple_scan) . + +Troubleshooting steps on [the integration page](../user/project/integrations/git_guardian.md#troubleshooting) +show how to mitigate some of these problems. + ### Set up GitGuardian Set up the GitGuardian integration for a project. diff --git a/doc/api/merge_request_approvals.md b/doc/api/merge_request_approvals.md index af472a1166d..1e107b6b5c2 100644 --- a/doc/api/merge_request_approvals.md +++ b/doc/api/merge_request_approvals.md @@ -103,6 +103,80 @@ Example response: } ``` +### Update group-level approval rules + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/440639) in GitLab 16.10. + +Group admins can update group level approval rules using the following endpoint: + +```shell +PUT /groups/:id/approval_rules/:approval_rule_id +``` + +Supported attributes: + +| Attribute | Type | Required | Description | +|----------------------|-------------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------| +| `approval_rule_id`. | integer | Yes | The ID of the approval rule. | +| `id` | integer or string | Yes | The ID or [URL-encoded path of a group](rest/index.md#namespaced-path-encoding). | +| `approvals_required` | string | No | The number of required approvals for this rule. | +| `group_ids` | integer | No | The IDs of users as approvers. | +| `name` | string | No | The name of the approval rule. | +| `rule_type` | array | No | The type of rule. `any_approver` is a pre-configured default rule with `approvals_required` at `0`. Other rules are `regular` and `report_approver`. | +| `user_ids` | array | No | The IDs of groups as approvers. | + +Example request: + +```shell +curl --request PUT --header "PRIVATE-TOKEN: " \ + --url "https://gitlab.example.com/api/v4/groups/29/approval_rules/5?name=security2&approvals_required=1" +``` + +Example response: + +```json +{ + "id": 5, + "name": "security2", + "rule_type": "any_approver", + "eligible_approvers": [], + "approvals_required": 1, + "users": [], + "groups": [], + "contains_hidden_groups": false, + "protected_branches": [ + { + "id": 5, + "name": "master", + "push_access_levels": [ + { + "id": 5, + "access_level": 40, + "access_level_description": "Maintainers", + "deploy_key_id": null, + "user_id": null, + "group_id": null + } + ], + "merge_access_levels": [ + { + "id": 5, + "access_level": 40, + "access_level_description": "Maintainers", + "user_id": null, + "group_id": null + } + ], + "allow_force_push": false, + "unprotect_access_levels": [], + "code_owner_approval_required": false, + "inherited": false + } + ], + "applies_to_all_protected_branches": true +} +``` + ## Project-level MR approvals ### Get Configuration diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md index 51508c8ea37..df1ffbae620 100644 --- a/doc/api/merge_requests.md +++ b/doc/api/merge_requests.md @@ -1149,7 +1149,7 @@ following response attributes: | `new_file` | boolean | Indicates if the file has just been added. | | `renamed_file` | boolean | Indicates if the file has been renamed. | | `deleted_file` | boolean | Indicates if the file has been removed. | -| `generated_file` | boolean | Indicates if the file is marked as generated. | +| `generated_file` | boolean | Indicates if the file is [marked as generated](../user/project/merge_requests/changes.md#collapse-generated-files). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/141576) in GitLab 16.9. | Example request: diff --git a/doc/architecture/blueprints/cells/infrastructure/deployments.md b/doc/architecture/blueprints/cells/infrastructure/deployments.md index 9776ff4af70..53f6e5e6323 100644 --- a/doc/architecture/blueprints/cells/infrastructure/deployments.md +++ b/doc/architecture/blueprints/cells/infrastructure/deployments.md @@ -12,15 +12,15 @@ Disclaimer: This blueprint requires more cross-functional alignment - **Confiden # Application Deployment with a Cellular Architecture -This blueprint describes a deployment strategy that can support the new scaling dimension intruduced by the Cell Architecture. +This blueprint describes a deployment strategy that can support the new scaling dimension introduced by the Cell Architecture. -The complexity of this transition will demand participation from many team in the Platforms section to take ownership of the features necessary to reach the production grade rating on this architecture. +The complexity of this transition will require many teams in the Platforms section to participate by taking ownership of the features necessary to reach the production grade rating on this architecture. ## Introduction ### Preamble -From an high level perspective, a Cell Cluster is a system made of only 3 items: +From a high level perspective, a Cell Cluster is a system made of only 3 items: 1. **Router** - An HA routing system deployed independently from the GitLab application. 1. **Primary Cell** - The GitLab installation that is the leader for all the cluster wide data and services. This will be the legacy GitLab.com deployment. @@ -55,12 +55,12 @@ It is important to note that even if a Secondary Cell supports GitLab Geo out of - Deployment - The GitLab application and its components being installed into infrastructure - `auto-deploy` version - The active version that creates a package viable for deployment -- ring - A logical partition of the cell cluster. In order to deploy to the next ring a package must be validated inside the current ring +- ring - A logical partition of the cell cluster. In order to deploy to the next ring a package must be validated inside the current ring. - `perimeter` - the ring marking the "definition of done" for Release Managers, a package validated inside the perimeter is allowed to rollout in the rest of the fleet - `graduated` version - The version deemed safe to deploy to cells outside of the perimeter -- `.com` - refers to our old existing or currently running infrastructure +- `.com` - Our old existing or currently running infrastructure - Primary Cell - The GitLab installation that is the leader for all the cluster wide data and services. Initially this will be the legacy GitLab.com deployment. This implicitly includes .com as our legacy infrastructure. -- Secondary Cell(s) - GitLab installation(s) authoritative for a limited number of Organizations. Cell(s) are deployed using GitLab Dedicated tools. +- Secondary Cell(s) - GitLab installation(s) authoritative for a limited number of Organizations. Deployed using GitLab Dedicated tools. ### Ring deployment @@ -123,7 +123,7 @@ In the image above we are showing a possible ring layout with a cluster made of The general rule is that: -1. The deployment process progresses from Ring 0 to the outer rings +1. The deployment process progresses from Ring 0 to the outer rings. 1. Rings are a collection of Cells sharing the same risk factor associated to a deployment. 1. Deployments can get halted at any stage and the package will not reach the outer rings. 1. We define the "perimeter" ring that marks the "definition of done" for the Release Managers. diff --git a/doc/architecture/blueprints/cells/infrastructure/index.md b/doc/architecture/blueprints/cells/infrastructure/index.md index 55233096020..34bb85effb7 100644 --- a/doc/architecture/blueprints/cells/infrastructure/index.md +++ b/doc/architecture/blueprints/cells/infrastructure/index.md @@ -17,34 +17,34 @@ status: proposed ## Philosophy -- **Cell local by default**: All services should be cell local, and not global unless there are documented and good reasons why they aren't. - If we keep things cell local communication between the cell and service stays internal, the service has to run at a smaller scale, and the blast radius is much smaller. - Example, Gitaly and GitLab Registry are cell local. +- **Cell-local by default**: All services should be cell-local, and not global, unless there are documented and good reasons why they aren't cell-local. + If we keep things cell-local, communication between the cell and service stays internal, the service has to run at a smaller scale, and the blast radius is much smaller. + Example, Gitaly and GitLab Registry are cell-local. - **homogeneous environments**: For now, every GitLab cell should look the same. Bootstrapping and provisioning should be done in an automated way. - For the first iteration all Cells is the same size, there are benefits of running different sizes but this adds complexity, and scope. + For the first iteration all Cells are the same size, there are benefits of running different sizes but this adds complexity and scope. - **Fresh start, but not so much**: Brand new GitLab instances are created, so it's tempting to redo everything. We have to balance the existing infrastructure, dedicated tooling, and time. - **All operations get rolled out the same**: Configuration changes, Feature Flags, Deployments, and operational tasks ideally go through the same process of rolling out a change. Having 1 way of doing things can bring efficiencies and a single source of truth for automation. - **Centralize Tooling**: We have a lot of tooling to manage GitLab.com and separate tooling for GitLab Dedicated, - which creates silos, duplication of effort and less portability. - We have to provision multiple Cells for GitLab.com we need new tooling, GitLab Dedicated built tooling just for this reason. - We should try use this tooling as much as possible, if there are things we don't agree with we should try [disagree, commit, and disagree](https://handbook.gitlab.com/handbook/values/#disagree-commit-and-disagree) to improve a single tool. + which creates silos, duplication of effort, and less portability. + We have to provision multiple Cells for GitLab.com, we need new tooling, GitLab Dedicated built tooling just for this reason. + We should try to use this tooling as much as possible, if there are things we don't agree with we should try [disagree, commit, and disagree](https://handbook.gitlab.com/handbook/values/#disagree-commit-and-disagree) to improve a single tool. It is ok to start with tooling that has shortcomings, an iterative approach leads to _one_ mature product instead of two. ## Glossary/[Ubiquitous Language](https://martinfowler.com/bliki/UbiquitousLanguage.html) -- `Provision`: When we create a new Cell. Example; We _provisioned_ Cell 5, which is a brand new Cell. -- `Deploy`: When we change the running code inside of an existing Cell. Example; We _deployed_ the new auto-deploy version on GitLab.com. +- `Provision`: When we create a new Cell. Example: We _provisioned_ Cell 5, which is a brand new Cell. +- `Deploy`: When we change the running code inside of an existing Cell. Example: We _deployed_ the new auto-deploy version on GitLab.com. - [Blueprint](deployments.md) -- `Configuration change`: When we change any configuration on the application or infrastructure. Example; We did a _configuration change_ on labels added to VMs. +- `Configuration change`: When we change any configuration on the application or infrastructure. Example: We did a _configuration change_ on labels added to VMs. - `Cell`: A single unit, and instance of GitLab. Not used to refer to Dedicated, where an instance of GitLab is called a Tenant. -- `Cluster`: A collection of Cells, and the existing GitLab.com infrastructure. Example; We need to change the version of Registry in the Cluster. +- `Cluster`: A collection of Cells, and the existing GitLab.com infrastructure. Example: We need to change the version of Registry in the Cluster. - `Fleet`: The collection of all SaaS environments, both single-tenant and multi-tenant, that collectively form our production environments. This includes existing GitLab.com infrastructure, Cells, and Dedicated. ## Architecture -Below is the Cell architecture you can find the current GitLab.com architecture (pre-Cells) in +Below is the Cell architecture. You can find the current GitLab.com architecture (pre-Cells) in . ```plantuml @startuml @@ -208,8 +208,8 @@ frame "Google Cloud Platform" <> { The infrastructure is multifaceted and all teams have a role in setting up the cell infrastructure. -The `Confidence` column is to get a sense of how confident we are with the specific domain and it's path forward for Cells. -When we have a blueprint merged ideally the confidence should move to 👍 because we have a blueprint that provides direction to that domain. +The `Confidence` column refers to how confident we are with the specific domain and its path forward for Cells. +When we have a blueprint merged ideally the confidence should move to 👍 because we have a blueprint that provides direction to that domain. | Domain | Owner | Blueprint | Confidence | |----------------------------------|-----------------------------------|--------------------------------------|------------| @@ -262,7 +262,7 @@ component "Configuration Management" ## Stakeholders We have several teams partaking in the operations of Cell. -The first distinction is between teams implementing and maintaining the tools and teams using those tools. +The first distinction is between teams implementing and maintaining the tools, and teams using those tools. | Areas | Features | Owners | |---------------------------------------------------|-----------------------------------------------------------|---------------------------------| @@ -270,7 +270,7 @@ The first distinction is between teams implementing and maintaining the tools an | | Integration with Release Managers' workflows | team::Delivery-Deployments | | | Deployment mechanics using `Instrumentor` and `AMP` | team::Foundations | | | Cell application reference architectures and overlays | team::Ops | -| | Cell bootstrapping, tooling and supporting infrastructure | team::Ops | +| | Cell bootstrapping, tooling, and supporting infrastructure | team::Ops | | | Cell deprovisioning | team::Ops | | Control Plane for cluster state** | | | | | Investigate GitOps model | team::Delivery-Deployments | @@ -295,12 +295,12 @@ The first distinction is between teams implementing and maintaining the tools an | | Load Balancing and networking | team::Foundations | | | Rate Limiting | team::Foundations | -> \* These items may require contributions from various stakeholders in SaaS Platforms and Core Platform. This work should be heavily collaborated on as to help ensure appropriate alignment to meet the needs of the owning team and customer teams. +> \* These items may require contributions from various stakeholders in SaaS Platforms and Core Platform. Stakeholders should closely collaborate on this work to ensure appropriate alignment to meet the needs of the owning team and customer teams. > -> \*\* These items are for consideration after Cell 2.0 iteration . +> \*\* These items are for consideration after the Cell 2.0 iteration. The users of those features are the Release Managers, the Engineer On Call, and the Team:Ops. -The following list define the tasks those groups can perform in the cell cluster: +The following list defines the tasks those groups can perform in the cell cluster: 1. Release Managers - Command deployments inside the perimeter diff --git a/doc/architecture/blueprints/cells/rejected/deployment-architecture.md b/doc/architecture/blueprints/cells/rejected/deployment-architecture.md index dd18382bd56..aefe43ed63b 100644 --- a/doc/architecture/blueprints/cells/rejected/deployment-architecture.md +++ b/doc/architecture/blueprints/cells/rejected/deployment-architecture.md @@ -17,7 +17,7 @@ of GitLab.com and contrasts it with the expected Cells architecture. The diagram represents simplified GitLab.com deployment components before the introduction of a Cells architecture. -This diagram intentionally misses some services that are not relevant for the architecture overview (Cloudflare, Consul, PgBouncers, ...). +This diagram intentionally omits some services that are not relevant for the architecture overview (Cloudflare, Consul, PgBouncers, ...). Those services are considered to be Cell-local, with the exception of Cloudflare. The component blocks are: @@ -25,16 +25,16 @@ The component blocks are: - Separate components that can be deployed independently. - Components that are independent from other components and offer a wide range of version compatibility. -The application layer services are: +The application layer services: -- Strongly interconnected and require to run the same version of the application. +- Are strongly interconnected and require to run the same version of the application. Read more in [!131657](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/131657#note_1563513431). - Each service is run across many nodes and scaled horizontally to provide sufficient throughput. - Services that interact with other services using an API (REST, gRPC), Redis or DB. -The dependent services are: +The dependent services: -- Updated infrequently and selectively. +- Are updated infrequently and selectively. - Might use cloud managed services. - Each service is clustered and might be run across different availability zones to provide high availability. - Object storage is also accessible directly to users if a pre-signed URL is provided. @@ -43,7 +43,7 @@ The dependent services are: -The purpose of **Development Cells** is to model a production-like architecture for the purpose of testing and validating the changes introduced. +The purpose of **Development Cells** is to model a production-like architecture to test and validate the changes introduced. This could be achieved with testing Cells on top of the [Reference Architectures](../../../../administration/reference_architectures/index.md). Read more in [#425197](https://gitlab.com/gitlab-org/gitlab/-/issues/425197). @@ -63,9 +63,9 @@ The differences compared to [Development Cells](#2-development-cells---adapting- - A Cluster-wide Data Provider is introduced by Cells. - The Cluster-wide Data Provider is deployed with Cell 1 to be able to access cluster-wide data directly. -- The cluster-wide database is isolated from the main PostgreSQL database. +- The Cluster-wide database is isolated from the main PostgreSQL database. - A Cluster-wide Data Provider is responsible for storing and sharing user data, - user sessions (currently stored in Redis sessions cluster), routing information + user sessions (currently stored in Redis sessions cluster), routing information, and cluster-wide settings across all Cells. - Access to the cluster-wide database is done asynchronously: - Read access always uses a database replica. @@ -129,7 +129,7 @@ As per the architecture, the above services are required to be run cluster-wide: As per the architecture, the above services are required to be run Cell-local: - The consumer data held by the Cell-local services needs to be migratable to another Cell. -- The compute generated by the service is substational and is strongly desired to reduce impact of [single Cell failure](../goals.md#high-resilience-to-a-single-cell-failure). +- The compute generated by the service is substatial, and it is strongly desired to reduce impact of [single Cell failure](../goals.md#high-resilience-to-a-single-cell-failure). - It is complex to run the service cluster-wide from the Cells architecture perspective. ### Hybrid Services @@ -139,7 +139,7 @@ As per the architecture, the above services are required to be run Cell-local: | **GitLab Pages** | GitLab-built | Routing Service, Rails API | No problem | Serving CI generated pages under `.gitlab.io` or custom domains | | **GitLab Registry** | GitLab-built | Object Storage, PostgreSQL | Non-trivial data migration in case of split | Service to provide GitLab container registry | | **Gitaly Cluster** | GitLab-built | Disk storage, PostgreSQL | No problem: Built-in migration routines to balance Gitaly nodes | Gitaly holds Git repository data. Many Gitaly clusters can be configured in application. | -| **Elasticsearch** | Managed service | Many nodes required by sharding | Time consuming: Rebuild cluster from scratch | Search across all projects | +| **Elasticsearch** | Managed service | Many nodes required by sharding | Time-consuming: Rebuild cluster from scratch | Search across all projects | | **Object Storage** | Managed service | | Not straightforward: Rather hard to selectively migrate between buckets | Holds all user and CI uploaded files that is served by GitLab | As per the architecture, the above services are allowed to be run either cluster-wide or Cell-local: @@ -149,7 +149,7 @@ As per the architecture, the above services are allowed to be run either cluster | Service | Type | Uses | Description | | ------------------------------ | ------------ | ------------------------------- | --------------------------------------------------------------------------------------------------- | -| **Elasticsearch** | Managed service | Many nodes requires by sharding | Time consuming: Rebuild cluster from scratch | Search across all projects | +| **Elasticsearch** | Managed service | Many nodes requires by sharding | Time-consuming: Rebuild cluster from scratch | Search across all projects | | **Object Storage** | Managed service | | Not straightforward: Rather hard to selectively migrate between buckets | Holds all user and CI uploaded files that is served by GitLab | As per the architecture, the above services are allowed to be run either cluster-wide or Cell-local: diff --git a/doc/ci/services/index.md b/doc/ci/services/index.md index 24407a10c11..c1fa89b6898 100644 --- a/doc/ci/services/index.md +++ b/doc/ci/services/index.md @@ -262,13 +262,13 @@ test: > - Introduced in GitLab and GitLab Runner 9.4. -| Setting | Required | GitLab version | Description | -|------------|----------|----------------| ----------- | -| `name` | yes, when used with any other option | 9.4 | Full name of the image to use. If the full image name includes a registry hostname, use the `alias` option to define a shorter service access name. For more information, see [Accessing the services](#accessing-the-services). | -| `entrypoint` | no | 9.4 |Command or script to execute as the container's entrypoint. It's translated to the Docker `--entrypoint` option while creating the container. The syntax is similar to [`Dockerfile`'s `ENTRYPOINT`](https://docs.docker.com/engine/reference/builder/#entrypoint) directive, where each shell token is a separate string in the array. | -| `command` | no | 9.4 |Command or script that should be used as the container's command. It's translated to arguments passed to Docker after the image's name. The syntax is similar to [`Dockerfile`'s `CMD`](https://docs.docker.com/engine/reference/builder/#cmd) directive, where each shell token is a separate string in the array. | -| `alias` (1) | no | 9.4 | Additional alias that can be used to access the service from the job's container. Read [Accessing the services](#accessing-the-services) for more information. | -| `variables` (2) | no | 14.5 | Additional environment variables that are passed exclusively to the service. The syntax is the same as [Job Variables](../variables/index.md). Service variables cannot reference themselves. | +| Setting | Required | GitLab version | Description | +|-----------------|--------------------------------------|----------------|-------------| +| `name` | yes, when used with any other option | 9.4 | Full name of the image to use. If the full image name includes a registry hostname, use the `alias` option to define a shorter service access name. For more information, see [Accessing the services](#accessing-the-services). | +| `entrypoint` | no | 9.4 | Command or script to execute as the container's entrypoint. It's translated to the Docker `--entrypoint` option while creating the container. The syntax is similar to [`Dockerfile`'s `ENTRYPOINT`](https://docs.docker.com/engine/reference/builder/#entrypoint) directive, where each shell token is a separate string in the array. | +| `command` | no | 9.4 | Command or script that should be used as the container's command. It's translated to arguments passed to Docker after the image's name. The syntax is similar to [`Dockerfile`'s `CMD`](https://docs.docker.com/engine/reference/builder/#cmd) directive, where each shell token is a separate string in the array. | +| `alias` (1) | no | 9.4 | Additional alias that can be used to access the service from the job's container. Read [Accessing the services](#accessing-the-services) for more information. | +| `variables` (2) | no | 14.5 | Additional environment variables that are passed exclusively to the service. The syntax is the same as [Job Variables](../variables/index.md). Service variables cannot reference themselves. | (1) Alias support for the Kubernetes executor was [introduced](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2229) in GitLab Runner 12.8, and is only available for Kubernetes version 1.7 or later. diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md index e5c8dff3f66..83976bc0cfb 100644 --- a/doc/ci/yaml/index.md +++ b/doc/ci/yaml/index.md @@ -2557,6 +2557,8 @@ The name of the Docker image that the job runs in. Similar to [`image`](#image) - `:` - `@` +CI/CD variables [are supported](../variables/where_variables_can_be_used.md#gitlab-ciyml-file). + **Example of `image:name`**: ```yaml diff --git a/doc/operations/error_tracking.md b/doc/operations/error_tracking.md index 11976964b80..bfa22e31a47 100644 --- a/doc/operations/error_tracking.md +++ b/doc/operations/error_tracking.md @@ -228,3 +228,7 @@ you might see an error when you try to [enable Sentry integration for a project] The resulting request to `/project/path/-/error_tracking/projects.json?api_host=https:%2F%2Fsentry.example.com%2F&token=` returns a 404 status. To fix this issue, enable the Monitor feature for the project. + +## Data Retention + +GitLab has a retention limit of 90 days for all errors. diff --git a/doc/operations/tracing.md b/doc/operations/tracing.md index 8eb605c5b50..5746b93c9d7 100644 --- a/doc/operations/tracing.md +++ b/doc/operations/tracing.md @@ -93,3 +93,7 @@ Tracing ingests a maximum of 102,400 bytes per minute. After the limit is exceeded, a `429 Too Many Requests` response is returned. To request a limit increase to 104,8576 bytes per minute, contact GitLab support. + +## Data Retention + +GitLab has a retention limit of 30 days for all traces. diff --git a/doc/user/analytics/analytics_dashboards.md b/doc/user/analytics/analytics_dashboards.md index 3c62f148fad..ab81c885e3f 100644 --- a/doc/user/analytics/analytics_dashboards.md +++ b/doc/user/analytics/analytics_dashboards.md @@ -161,6 +161,10 @@ To view the Value Streams Dashboard as an analytics dashboard for a group: You can change the location of your project or group dashboards. +Prerequisites: + +- You must have at least the Maintainer role for the project or group the project belongs to. + ### Group dashboards NOTE: diff --git a/doc/user/project/deploy_keys/index.md b/doc/user/project/deploy_keys/index.md index 3b98c89b8ef..e848510cd84 100644 --- a/doc/user/project/deploy_keys/index.md +++ b/doc/user/project/deploy_keys/index.md @@ -103,7 +103,7 @@ Prerequisites: 1. Optional. Update the **Expiration date**. A project deploy key is enabled when it is created. You can modify only a project deploy key's -name and permissions. +name and permissions. If the deploy key is enabled in more than one project, you can't modify the deploy key name. ## Create a public deploy key diff --git a/doc/user/project/file_lock.md b/doc/user/project/file_lock.md index 607612cb490..375b25e16ce 100644 --- a/doc/user/project/file_lock.md +++ b/doc/user/project/file_lock.md @@ -27,8 +27,8 @@ said to have "released the lock". GitLab supports two different modes of file locking: -- [Exclusive file locks](#exclusive-file-locks) for binary files: done **through - the command line** with Git LFS and `.gitattributes`, it prevents locked +- [Exclusive file locks](#exclusive-file-locks) for binary files: done + **through the command line** with Git LFS and `.gitattributes`, it prevents locked files from being modified on any branch. - [Default branch locks](#default-branch-file-and-directory-locks): done **through the GitLab UI**, it prevents locked files and directories being diff --git a/doc/user/project/git_attributes.md b/doc/user/project/git_attributes.md index c013d6ba794..79dff080d9a 100644 --- a/doc/user/project/git_attributes.md +++ b/doc/user/project/git_attributes.md @@ -10,12 +10,16 @@ DETAILS: **Tier:** Free, Premium, Ultimate **Offering:** SaaS, self-managed -GitLab supports defining custom [Git attributes](https://git-scm.com/docs/gitattributes) such as what -files to treat as binary, and what language to use for syntax highlighting -diffs. +GitLab supports defining custom Git attributes in a `.gitattributes` file in the +root directory of your repository. Use the `.gitattributes` file to declare changes +to file handling and display, such as: -To define these attributes, create a file called `.gitattributes` in the root -directory of your repository and push it to the default branch of your project. +- [Collapse generated files](merge_requests/changes.md#collapse-generated-files) in diffs. +- Create [custom merge drivers](#custom-merge-drivers). +- Create [exclusive lock files](file_lock.md) to mark files as read-only. +- Change [syntax highlighting](highlighting.md) in diffs. +- Declare binary file handling with [Git LFS](../../topics/git/lfs/index.md). +- Declare [languages used in your repository](repository/index.md#add-repository-languages). ## Encoding requirements @@ -128,3 +132,7 @@ config/* merge=foo ``` In this case, every file under the `config/` folder uses the custom merge driver called `foo` defined in the GitLab configuration. + +## Resources + +- Official Git documentation for [Git attributes](https://git-scm.com/docs/gitattributes) diff --git a/doc/user/project/integrations/git_guardian.md b/doc/user/project/integrations/git_guardian.md index 79a10f06cf7..c7af4ab79c6 100644 --- a/doc/user/project/integrations/git_guardian.md +++ b/doc/user/project/integrations/git_guardian.md @@ -16,9 +16,6 @@ FLAG: On self-managed GitLab, by default this feature is available. To hide the feature, ask an administrator to [disable the feature flag](../../../administration/feature_flags.md) named `git_guardian_integration`. On GitLab.com, this feature is not available. -WARNING: -Pushes can be delayed or can time out. With the GitGuardian integration, pushes are sent to a third-party, and GitLab has no control over the connection with GitGuardian or the GitGuardian process. - [GitGuardian](https://www.gitguardian.com/) is a cybersecurity service that detects sensitive data such as API keys and passwords in source code repositories. It scans Git repositories, alerts on policy violations, and helps organizations @@ -74,3 +71,38 @@ To enable the integration for your project: 1. Select **Save changes**. GitLab is now ready to reject commits based on GitGuardian policies. + +## Known issues + +- Pushes can be delayed or can time out. With the GitGuardian integration, pushes are sent to a third-party, and GitLab has no control over the connection with GitGuardian or the GitGuardian process. +- Due to a [GitGuardian API limitation](https://api.gitguardian.com/docs#operation/multiple_scan), the integration ignores files over the size of 1 MB. They are not scanned. +- If a pushed file has a name over 256 characters long the push won't go through. +- For more information, see [GitGuardian API documentation](https://api.gitguardian.com/docs#operation/multiple_scan). + +Troubleshooting steps below show how to mitigate some of these problems. + +## Troubleshooting + +When working with the GitGuardian integration, you might encounter the following issues. + +### `500` HTTP errors + +You might get a HTTP `500` error. + +This issue occurs for when requests time out for commits with a lot of changed files. + +If this happens with a commit with more than 50 files changed, +the workaround is to break down your changes into smaller commits and push +them one by one. + +### `Filename: ensure this value has at most 256 characters` + +You might get a HTTP `400` error that states `Filename: ensure this value has at most 256 characters`. + +This issue occurs when some of the changed files you are pushing in that commit have the file name +(not the path) longer then 256 characters. + +The workaround is to shorten the file name if possible. +In case the file name cannot be shortened, for example, because it was automatically generated by a framework, +disable the integration and try to push again. +Don't forget to re-enable the integration afterwards if needed. diff --git a/doc/user/project/merge_requests/changes.md b/doc/user/project/merge_requests/changes.md index 48b63140e5a..5fb23674815 100644 --- a/doc/user/project/merge_requests/changes.md +++ b/doc/user/project/merge_requests/changes.md @@ -63,12 +63,18 @@ Files with many changes are collapsed to improve performance. GitLab displays th ### Collapse generated files +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/140180) in GitLab 16.8 [with a flag](../../../administration/feature_flags.md) named `collapse_generated_diff_files`. Disabled by default. +> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/145100) in GitLab 16.10. + DETAILS: **Tier:** Free, Premium, Ultimate **Offering:** Self-managed -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/140180) in GitLab 16.8 [with a flag](../../../administration/feature_flags.md) named `collapse_generated_diff_files`. Disabled by default. -> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/432670) in GitLab 16.10. +FLAG: +On self-managed GitLab, by default this feature is available. To disable it, +an administrator can [disable the feature flag](../../../administration/feature_flags.md) +named `collapse_generated_diff_files`. +On GitLab.com, this feature is available. To help reviewers focus on the files needed to perform a code review, GitLab collapses several common types of generated files. These files are collapsed by default, because @@ -81,9 +87,8 @@ they are unlikely to require code reviews: 1. Source map reference files. 1. Generated Go files, including the generated files by protocol buffer compiler. -If you want to automatically collapse additional files or file types, you can use -the `gitlab-generated` attribute, which marks or unmarks certain files/paths as generated. See [overriding syntax highlighting](../highlighting.md#override-syntax-highlighting-for-a-file-type) for more -detail on how to use override attributes. +To mark a file or path as generated, set the `gitlab-generated` attribute for it +in your [`.gitattributes` file](../git_attributes.md). #### View a collapsed file diff --git a/doc/user/project/service_desk/using_service_desk.md b/doc/user/project/service_desk/using_service_desk.md index 44e6c2e7c1f..87af46806a2 100644 --- a/doc/user/project/service_desk/using_service_desk.md +++ b/doc/user/project/service_desk/using_service_desk.md @@ -152,20 +152,34 @@ In GitLab 15.9 and earlier, uploads to a comment are sent as links in the email. ## Convert a regular issue to a Service Desk ticket > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/433376) in GitLab 16.9 [with a flag](../../../administration/feature_flags.md) named `convert_to_ticket_quick_action`. Disabled by default. +> - Enabled on GitLab.com in GitLab 16.10. FLAG: On self-managed GitLab, by default this feature is not available. To make it available per group, an administrator can [enable the feature flag](../../../administration/feature_flags.md) named `convert_to_ticket_quick_action`. -On GitLab.com, this feature is not available. +On GitLab.com, this feature is available. Use the quick action `/convert_to_ticket external-issue-author@example.com` to convert any regular issue into a Service Desk ticket. This assigns the provided email address as the external author of the ticket -and add them to the list of external participants. They receive Service Desk emails for any public +and adds them to the list of external participants. They receive Service Desk emails for any public comment on the ticket and can reply to these emails. Replies add a new comment on the ticket. GitLab doesn't send [the default `thank_you` email](configure.md#customize-emails-sent-to-the-requester). You can add a public comment on the ticket to let the end user know that the ticket has been created. + +To create a Service Desk ticket from the UI: + +1. [Create an issue](../issues/create_issues.md) +1. Add a comment that contains only the quick action `/convert_to_ticket user@example.com`. + You should see a comment from the [GitLab Support Bot](configure.md#support-bot-user). +1. Reload the page so the UI reflects the type change. +1. Optional. Add a comment on the ticket to send an initial Service Desk email to the external participant. + ## Privacy considerations > - [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/108901) the minimum required role to view the creator's and participant's email in GitLab 15.9. diff --git a/lib/api/deploy_keys.rb b/lib/api/deploy_keys.rb index f8379392531..1cf1228b210 100644 --- a/lib/api/deploy_keys.rb +++ b/lib/api/deploy_keys.rb @@ -172,7 +172,7 @@ module API update_params[:can_push] = params[:can_push] if params.key?(:can_push) update_params[:deploy_key_attributes] = { id: params[:key_id] } - if can?(current_user, :update_deploy_key, deploy_keys_project.deploy_key) + if can?(current_user, :update_deploy_key_title, deploy_keys_project.deploy_key) update_params[:deploy_key_attributes][:title] = params[:title] if params.key?(:title) end diff --git a/lib/gitlab/markdown_cache.rb b/lib/gitlab/markdown_cache.rb index f426f70800c..b0b4a851289 100644 --- a/lib/gitlab/markdown_cache.rb +++ b/lib/gitlab/markdown_cache.rb @@ -11,7 +11,7 @@ module Gitlab # this if the change to the renderer output is a new feature or a # minor bug fix. # See: https://gitlab.com/gitlab-org/gitlab/-/issues/330313 - CACHE_COMMONMARK_VERSION = 32 + CACHE_COMMONMARK_VERSION = 33 CACHE_COMMONMARK_VERSION_START = 10 BaseError = Class.new(StandardError) diff --git a/locale/gitlab.pot b/locale/gitlab.pot index ff00a85c8c5..b939fe97c68 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -12691,7 +12691,7 @@ msgstr "" msgid "ComplianceFrameworksReport|Edit framework" msgstr "" -msgid "ComplianceFrameworks| Frameworks export" +msgid "ComplianceFrameworks| Project frameworks export" msgstr "" msgid "ComplianceFrameworks|Active compliance frameworks" @@ -12820,10 +12820,10 @@ msgstr "" msgid "ComplianceFrameworks|You are about to permanently delete the compliance framework %{framework} from all projects which currently have it applied, which may remove other functionality. This cannot be undone." msgstr "" -msgid "ComplianceFrameworks|Your Compliance Frameworks CSV export for the group \"%{group_name}\" has been attached to this email." +msgid "ComplianceFrameworks|Your Compliance Project Frameworks CSV export for the group \"%{group_name}\" has been attached to this email." msgstr "" -msgid "ComplianceFrameworks|Your Compliance Frameworks CSV export for the group %{group_link} has been attached to this email." +msgid "ComplianceFrameworks|Your Compliance Project Frameworks CSV export for the group %{group_link} has been attached to this email." msgstr "" msgid "ComplianceFrameworks|default" @@ -54290,10 +54290,10 @@ msgstr "" msgid "UserProfile|Personal projects" msgstr "" -msgid "UserProfile|Pronounced as: %{div_start}%{pronunciation}%{div_end}" +msgid "UserProfile|Pronounced as:" msgstr "" -msgid "UserProfile|Pronouns: %{div_start}%{pronouns}%{div_end}" +msgid "UserProfile|Pronouns:" msgstr "" msgid "UserProfile|Retry" @@ -57077,9 +57077,6 @@ msgstr "" msgid "You are not allowed to download code from this project." msgstr "" -msgid "You are not allowed to log in using password" -msgstr "" - msgid "You are not allowed to reject a user" msgstr "" diff --git a/qa/qa/page/project/show.rb b/qa/qa/page/project/show.rb index 36c14054188..4130b43e34a 100644 --- a/qa/qa/page/project/show.rb +++ b/qa/qa/page/project/show.rb @@ -136,7 +136,7 @@ module QA end def new_merge_request - wait_until(reload: true) do + wait_until(reload: true, message: 'Wait for `Create merge request` push notification') do has_create_merge_request_button? end diff --git a/spec/controllers/passwords_controller_spec.rb b/spec/controllers/passwords_controller_spec.rb index cff84da7382..05da0eaa1fc 100644 --- a/spec/controllers/passwords_controller_spec.rb +++ b/spec/controllers/passwords_controller_spec.rb @@ -21,16 +21,6 @@ RSpec.describe PasswordsController, feature_category: :system_access do expect(flash[:alert]).to eq _('Password authentication is unavailable.') end end - - context 'when reset email belongs to an ldap user' do - let(:user) { create(:omniauth_user, provider: 'ldapmain', email: 'ldapuser@gitlab.com') } - - it 'prevents a password reset' do - post :create, params: { user: { email: user.email } } - - expect(flash[:alert]).to eq _('Password authentication is unavailable.') - end - end end describe '#update' do diff --git a/spec/controllers/projects/deploy_keys_controller_spec.rb b/spec/controllers/projects/deploy_keys_controller_spec.rb index a285a84ca0b..82087ec1247 100644 --- a/spec/controllers/projects/deploy_keys_controller_spec.rb +++ b/spec/controllers/projects/deploy_keys_controller_spec.rb @@ -320,105 +320,200 @@ RSpec.describe Projects::DeployKeysController, feature_category: :continuous_del { deploy_key: { title: title, deploy_keys_projects_attributes: deploy_keys_projects_attributes } } end - let(:deploy_key) { create(:deploy_key, public: true) } let(:project) { create(:project) } - let!(:deploy_keys_project) do - create(:deploy_keys_project, project: project, deploy_key: deploy_key) - end - context 'with project maintainer' do - before do - project.add_maintainer(user) + context 'public deploy key' do + let(:deploy_key) { create(:deploy_key, public: true) } + let!(:deploy_keys_project) do + create(:deploy_keys_project, project: project, deploy_key: deploy_key) end - context 'public deploy key attached to project' do - let(:extra_params) { deploy_key_params('updated title', '1') } - - it 'does not update the title of the deploy key' do - expect { subject }.not_to change { deploy_key.reload.title } + context 'with project maintainer' do + before do + project.add_maintainer(user) end - it 'updates can_push of deploy_keys_project' do - expect { subject }.to change { deploy_keys_project.reload.can_push }.from(false).to(true) - end - end - end + context 'public deploy key attached to project' do + let(:extra_params) { deploy_key_params('updated title', '1') } - context 'with admin', :enable_admin_mode do - before do - sign_in(admin) - end - - context 'public deploy key attached to project' do - let(:extra_params) { deploy_key_params('updated title', '1') } - - it 'updates the title of the deploy key' do - expect { subject }.to change { deploy_key.reload.title }.to('updated title') - end - - it 'updates can_push of deploy_keys_project' do - expect { subject }.to change { deploy_keys_project.reload.can_push }.from(false).to(true) - end - end - - context 'when a different deploy key id param is injected' do - let(:extra_params) { deploy_key_params('updated title', '1') } - let(:hacked_params) do - extra_params.reverse_merge(id: other_deploy_key_id, namespace_id: project.namespace, project_id: project) - end - - subject { put :update, params: hacked_params } - - context 'and that deploy key id exists' do - let(:other_project) { create(:project) } - let(:other_deploy_key) do - key = create(:deploy_key) - project.deploy_keys << key - key - end - - let(:other_deploy_key_id) { other_deploy_key.id } - - it 'does not update the can_push attribute' do - expect { subject }.not_to change { deploy_key.deploy_keys_project_for(project).can_push } - end - end - - context 'and that deploy key id does not exist' do - let(:other_deploy_key_id) { 9999 } - - it 'returns 404' do - subject - - expect(response).to have_gitlab_http_status(:not_found) - end - end - end - end - - context 'with admin as project maintainer' do - before do - sign_in(admin) - project.add_maintainer(admin) - end - - context 'public deploy key attached to project' do - let(:extra_params) { deploy_key_params('updated title', '1') } - - context 'admin mode disabled' do it 'does not update the title of the deploy key' do expect { subject }.not_to change { deploy_key.reload.title } end + + it 'updates can_push of deploy_keys_project' do + expect { subject }.to change { deploy_keys_project.reload.can_push }.from(false).to(true) + end + end + end + + context 'with admin', :enable_admin_mode do + before do + sign_in(admin) end - context 'admin mode enabled', :enable_admin_mode do + context 'public deploy key attached to project' do + let(:extra_params) { deploy_key_params('updated title', '1') } + + it 'updates the title of the deploy key' do + expect { subject }.to change { deploy_key.reload.title }.to('updated title') + end + + it 'updates can_push of deploy_keys_project' do + expect { subject }.to change { deploy_keys_project.reload.can_push }.from(false).to(true) + end + end + + context 'when a different deploy key id param is injected' do + let(:extra_params) { deploy_key_params('updated title', '1') } + let(:hacked_params) do + extra_params.reverse_merge(id: other_deploy_key_id, namespace_id: project.namespace, project_id: project) + end + + subject { put :update, params: hacked_params } + + context 'and that deploy key id exists' do + let(:other_project) { create(:project) } + let(:other_deploy_key) do + key = create(:deploy_key) + project.deploy_keys << key + key + end + + let(:other_deploy_key_id) { other_deploy_key.id } + + it 'does not update the can_push attribute' do + expect { subject }.not_to change { deploy_key.deploy_keys_project_for(project).can_push } + end + end + + context 'and that deploy key id does not exist' do + let(:other_deploy_key_id) { 9999 } + + it 'returns 404' do + subject + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + end + + context 'with admin as project maintainer' do + before do + sign_in(admin) + project.add_maintainer(admin) + end + + context 'public deploy key attached to project' do + let(:extra_params) { deploy_key_params('updated title', '1') } + + context 'admin mode disabled' do + it 'does not update the title of the deploy key' do + expect { subject }.not_to change { deploy_key.reload.title } + end + end + + context 'admin mode enabled', :enable_admin_mode do + it 'updates the title of the deploy key' do + expect { subject }.to change { deploy_key.reload.title }.to('updated title') + end + end + + it 'updates can_push of deploy_keys_project' do + expect { subject }.to change { deploy_keys_project.reload.can_push }.from(false).to(true) + end + end + end + end + + context 'private deploy key' do + let_it_be(:deploy_key) { create(:deploy_key) } + let_it_be(:extra_params) { deploy_key_params('updated title', '1') } + + context 'when attached to one project' do + let!(:deploy_keys_project) do + create(:deploy_keys_project, project: project, deploy_key: deploy_key) + end + + context 'with admin', :enable_admin_mode do + before do + sign_in(admin) + end + + it 'updates the title of the deploy key' do + expect { subject }.to change { deploy_key.reload.title }.to('updated title') + end + + it 'updates can_push of deploy_keys_project' do + expect { subject }.to change { deploy_keys_project.reload.can_push }.from(false).to(true) + end + end + + context 'with project maintainer' do + before do + project.add_maintainer(user) + end + + it 'updates the title of the deploy key' do + expect { subject }.to change { deploy_key.reload.title }.to('updated title') + end + + it 'updates can_push of deploy_keys_project' do + expect { subject }.to change { deploy_keys_project.reload.can_push }.from(false).to(true) + end + end + + context 'with project guest' do + before do + project.add_guest(user) + end + + it 'does not update the title of the deploy key' do + expect { subject }.not_to change { deploy_key.reload.title } + end + + it 'does not update can_push of deploy_keys_project' do + expect { subject }.not_to change { deploy_keys_project.reload.can_push } + end + end + end + + context 'when attached to multiple projects' do + let_it_be(:another_project) { create(:project) } + + before do + create(:deploy_keys_project, project: project, deploy_key: deploy_key) + create(:deploy_keys_project, project: another_project, deploy_key: deploy_key) + end + + context 'with admin', :enable_admin_mode do + before do + sign_in(admin) + end + it 'updates the title of the deploy key' do expect { subject }.to change { deploy_key.reload.title }.to('updated title') end end - it 'updates can_push of deploy_keys_project' do - expect { subject }.to change { deploy_keys_project.reload.can_push }.from(false).to(true) + context 'with project maintainer' do + before do + project.add_maintainer(user) + end + + it 'does not update the title of the deploy key' do + expect { subject }.not_to change { deploy_key.reload.title } + end + end + + context 'with project guest' do + before do + project.add_guest(user) + end + + it 'does not update the title of the deploy key' do + expect { subject }.not_to change { deploy_key.reload.title } + end end end end diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb index c0a3ad98ca4..c782138639c 100644 --- a/spec/features/users/login_spec.rb +++ b/spec/features/users/login_spec.rb @@ -509,6 +509,15 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ expect(page).not_to have_content(I18n.t('devise.failure.already_authenticated')) end + it 'does not allow LDAP user to sign in with local password' do + create(:identity, provider: 'ldapmain', user: user) + + gitlab_sign_in(user) + + expect(page).to have_content(I18n.t('devise.failure.invalid')) + expect(user.reload.failed_attempts).to eq(0) + end + it 'does not show already signed in message when opening sign in page after login' do expect(authentication_metrics) .to increment(:user_authenticated_counter) diff --git a/spec/frontend/merge_request_tabs_spec.js b/spec/frontend/merge_request_tabs_spec.js index 3a9751bc217..c748f9acda7 100644 --- a/spec/frontend/merge_request_tabs_spec.js +++ b/spec/frontend/merge_request_tabs_spec.js @@ -5,7 +5,7 @@ import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures'; import initMrPage from 'helpers/init_vue_mr_page_helper'; import { stubPerformanceWebAPI } from 'helpers/performance'; import axios from '~/lib/utils/axios_utils'; -import MergeRequestTabs from '~/merge_request_tabs'; +import MergeRequestTabs, { getActionFromHref } from '~/merge_request_tabs'; import Diff from '~/diff'; import '~/lib/utils/common_utils'; import '~/lib/utils/url_utility'; @@ -476,4 +476,17 @@ describe('MergeRequestTabs', () => { }); }); }); + + describe('getActionFromHref', () => { + it.each` + pathName | action + ${'/user/pipelines/-/merge_requests/1/diffs'} | ${'diffs'} + ${'/user/diffs/-/merge_requests/1/pipelines'} | ${'pipelines'} + ${'/user/pipelines/-/merge_requests/1/commits'} | ${'commits'} + ${'/user/pipelines/1/-/merge_requests/1/diffs'} | ${'diffs'} + ${'/user/pipelines/-/merge_requests/1'} | ${'show'} + `('returns $action for $location', ({ pathName, action }) => { + expect(getActionFromHref(pathName)).toBe(action); + }); + }); }); diff --git a/spec/graphql/types/ci/pipeline_type_spec.rb b/spec/graphql/types/ci/pipeline_type_spec.rb index 45fe33f34a1..7d7757f3a9e 100644 --- a/spec/graphql/types/ci/pipeline_type_spec.rb +++ b/spec/graphql/types/ci/pipeline_type_spec.rb @@ -16,7 +16,7 @@ RSpec.describe Types::Ci::PipelineType do upstream path project active user_permissions warnings commit commit_path uses_needs test_report_summary test_suite ref ref_path warning_messages merge_request_event_type name total_jobs triggered_by_path child source stuck - latest merge_request ref_text failure_reason yaml_errors trigger + latest merge_request ref_text failure_reason yaml_errors yaml_error_messages trigger ] if Gitlab.ee? diff --git a/spec/lib/gitlab/ci/config/yaml/fixtures/complex-included-ci.yml b/spec/lib/gitlab/ci/config/yaml/fixtures/complex-included-ci.yml new file mode 100644 index 00000000000..2000ae446b6 --- /dev/null +++ b/spec/lib/gitlab/ci/config/yaml/fixtures/complex-included-ci.yml @@ -0,0 +1,52 @@ +spec: + inputs: + compiler: + default: gcc + optimization_level: + type: number + default: 2 + test_framework: + default: unittest + coverage_enabled: + type: boolean + default: false + environment: + default: staging + deploy_strategy: + type: string + options: ['blue-green', 'rolling'] + job_prefix: + description: Define a prefix for the job name + default: my-job + job_stage: + version: + type: string + regex: ^\d+\.\d+\.\d+$ + default: 1.0.0 + parallel_jobs: + type: number + default: 2 + allow_failure: + type: boolean + default: false + +--- + +"$[[ inputs.job_prefix ]]-build": + stage: $[[ inputs.job_stage ]] + script: + - echo "Building with $[[ inputs.compiler ]] and optimization level $[[ inputs.optimization_level ]]" + - echo "$[[ inputs.version ]]" + parallel: $[[ inputs.parallel_jobs ]] + +"$[[ inputs.job_prefix ]]-test": + stage: $[[ inputs.job_stage ]] + script: + - echo "Testing with $[[ inputs.test_framework | expand_vars ]]" + - if [ $[[ inputs.coverage_enabled ]] == true ]; then echo "Coverage is enabled"; fi + allow_failure: $[[ inputs.allow_failure ]] + +"$[[ inputs.job_prefix ]]-deploy": + stage: $[[ inputs.job_stage ]] + script: + - echo "Deploying to $[[ inputs.environment ]] using $[[ inputs.deploy_strategy ]] strategy" diff --git a/spec/lib/gitlab/ci/config/yaml/loader_spec.rb b/spec/lib/gitlab/ci/config/yaml/loader_spec.rb index ae1a5bb66a2..f8563533b04 100644 --- a/spec/lib/gitlab/ci/config/yaml/loader_spec.rb +++ b/spec/lib/gitlab/ci/config/yaml/loader_spec.rb @@ -4,29 +4,56 @@ require 'spec_helper' RSpec.describe ::Gitlab::Ci::Config::Yaml::Loader, feature_category: :pipeline_composition do describe '#load' do - let_it_be(:project) { create(:project) } + let_it_be(:yaml) do + File.read(Rails.root.join('spec/lib/gitlab/ci/config/yaml/fixtures/complex-included-ci.yml')) + end - let(:inputs) { { test_input: 'hello test' } } - let(:variables) { [] } + let(:expected_config) do + { + 'my-job-build': { + stage: 'build', + script: [ + 'echo "Building with clang and optimization level 3"', + 'echo "1.0.0"' + ], + parallel: '2' + }, + 'my-job-test': { + stage: 'build', + script: [ + 'echo "Testing with pytest"', + 'if [ true == true ]; then echo "Coverage is enabled"; fi' + ], + allow_failure: 'false' + }, + 'my-job-deploy': { + stage: 'build', + script: ['echo "Deploying to production using blue-green strategy"'] + } + } + end - let(:yaml) do - <<~YAML - --- - spec: - inputs: - test_input: - --- - test_job: - script: - - echo "$[[ inputs.test_input ]]" - YAML + let(:inputs) do + { + compiler: 'clang', + optimization_level: 3, + test_framework: '$TEST_FRAMEWORK', + coverage_enabled: true, + environment: 'production', + deploy_strategy: 'blue-green', + job_stage: 'build' + } + end + + let(:variables) do + Gitlab::Ci::Variables::Collection.new([ + { key: 'TEST_FRAMEWORK', value: 'pytest', masked: false } + ]) end subject(:result) { described_class.new(yaml, inputs: inputs, variables: variables).load } it 'loads and interpolates CI config YAML' do - expected_config = { test_job: { script: ['echo "hello test"'] } } - expect(result).to be_valid expect(result).to be_interpolated expect(result.content).to eq(expected_config) @@ -50,102 +77,22 @@ RSpec.describe ::Gitlab::Ci::Config::Yaml::Loader, feature_category: :pipeline_c end end - context 'when there is an error interpolating the YAML' do - let(:inputs) { {} } - - it 'returns an error result' do - expect(result).not_to be_valid - expect(result.error).to eq('`test_input` input: required value has not been provided') - end - end - - context 'when interpolating into a YAML key' do - let(:yaml) do - <<~YAML - --- - spec: - inputs: - test_input: - --- - "$[[ inputs.test_input ]]_job": - script: - - echo "test" - YAML - end - - it 'loads and interpolates CI config YAML' do - expected_config = { 'hello test_job': { script: ['echo "test"'] } } - - expect(result).to be_valid - expect(result).to be_interpolated - expect(result.content).to eq(expected_config) - end - end - - context 'when interpolating values of different types' do + context 'when there are errors with the inputs' do let(:inputs) do { - test_boolean: true, - test_number: 8, - test_string: 'test' + coverage_enabled: 'true', + deploy_strategy: 'not-an-option', + version: 'test-version' } end - let(:yaml) do - <<~YAML - --- - spec: - inputs: - test_string: - type: string - test_boolean: - type: boolean - test_number: - type: number - --- - "$[[ inputs.test_string ]]_job": - allow_failure: $[[ inputs.test_boolean ]] - parallel: $[[ inputs.test_number ]] - YAML - end - - it 'loads and interpolates CI config YAML', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/434826' do - expected_config = { test_job: { allow_failure: true, parallel: 8 } } - - expect(result).to be_valid - expect(result).to be_interpolated - expect(result.content).to eq(expected_config) - end - end - - context 'when interpolating and expanding variables' do - let(:inputs) { { test_input: '$TEST_VAR' } } - - let(:variables) do - Gitlab::Ci::Variables::Collection.new([ - { key: 'TEST_VAR', value: 'test variable', masked: false } - ]) - end - - let(:yaml) do - <<~YAML - --- - spec: - inputs: - test_input: - --- - "test_job": - script: - - echo "$[[ inputs.test_input | expand_vars ]]" - YAML - end - - it 'loads and interpolates CI config YAML' do - expected_config = { test_job: { script: ['echo "test variable"'] } } - - expect(result).to be_valid - expect(result).to be_interpolated - expect(result.content).to eq(expected_config) + it 'returns up to 3 error messages for input errors' do + expect(result).not_to be_valid + expect(result.error).to eq( + '`coverage_enabled` input: provided value is not a boolean, ' \ + '`deploy_strategy` input: `not-an-option` cannot be used because it is not in the list of allowed options, ' \ + '`job_stage` input: required value has not been provided' + ) end end @@ -189,6 +136,8 @@ RSpec.describe ::Gitlab::Ci::Config::Yaml::Loader, feature_category: :pipeline_c YAML end + let(:inputs) { { test_input: 'test' } } + it 'returns an error result' do stub_const('::Gitlab::Ci::Config::Interpolation::Block::MAX_FUNCTIONS', 1) diff --git a/spec/models/concerns/recoverable_by_any_email_spec.rb b/spec/models/concerns/recoverable_by_any_email_spec.rb index ba0bb99effb..13910a1f435 100644 --- a/spec/models/concerns/recoverable_by_any_email_spec.rb +++ b/spec/models/concerns/recoverable_by_any_email_spec.rb @@ -67,11 +67,38 @@ RSpec.describe RecoverableByAnyEmail, feature_category: :system_access do end end + shared_examples "does not send 'Reset password instructions' email when password auth is not allowed" do + it 'find the user with error' do + expect(send_reset_password_instructions).to be_instance_of User + expect(send_reset_password_instructions.errors[:password]) + .to include(_('Password authentication is unavailable.')) + end + + it 'does not send email to anyone' do + reset_delivered_emails! + + expect { send_reset_password_instructions } + .not_to have_enqueued_mail(DeviseMailer, :reset_password_instructions) + + perform_enqueued_jobs + + should_not_email_anyone + end + end + context "when email param matches user's confirmed primary email" do let(:expected_user) { user } let(:email) { user_confirmed_primary_email } it_behaves_like "sends 'Reset password instructions' email" + + context 'when password authentication is not allowed' do + before do + allow(Gitlab::CurrentSettings).to receive_messages(password_authentication_enabled_for_web?: false) + end + + it_behaves_like "does not send 'Reset password instructions' email when password auth is not allowed" + end end context "when email param matches user's unconfirmed primary email" do @@ -139,5 +166,23 @@ RSpec.describe RecoverableByAnyEmail, feature_category: :system_access do it_behaves_like "does not send 'Reset password instructions' email" end + + context 'with an LDAP user' do + let_it_be(:ldap_user) { create(:omniauth_user, :ldap) } + + context 'with a confirmed primary email' do + let(:email) { ldap_user.email } + + it_behaves_like "does not send 'Reset password instructions' email when password auth is not allowed" + end + + context 'with a confirmed secondary email' do + let(:email) do + create(:email, :confirmed, user: ldap_user, email: 'confirmed-secondary-ldap-email@example.com').email + end + + it_behaves_like "does not send 'Reset password instructions' email when password auth is not allowed" + end + end end end diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index 848e5c836ef..f9f18a8b23e 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -694,19 +694,32 @@ RSpec.describe Group, feature_category: :groups_and_projects do it_behaves_like 'namespace traversal' describe '#self_and_descendants' do - it { expect(group.self_and_descendants.to_sql).to include 'traversal_ids @>' } + it { expect(group.self_and_descendants.to_sql).to include('traversal_ids >=').and(include('traversal_ids <')) } end describe '#self_and_descendant_ids' do - it { expect(group.self_and_descendant_ids.to_sql).to include 'traversal_ids @>' } + it { expect(group.self_and_descendant_ids.to_sql).to include('traversal_ids >=').and(include('traversal_ids <')) } end describe '#descendants' do - it { expect(group.descendants.to_sql).to include 'traversal_ids @>' } + it { expect(group.descendants.to_sql).to include('traversal_ids >=').and(include('traversal_ids <')) } end describe '#self_and_hierarchy' do - it { expect(group.self_and_hierarchy.to_sql).to include 'traversal_ids @>' } + it { expect(group.self_and_hierarchy.to_sql).to include('traversal_ids >=').and(include('traversal_ids <')) } + end + + context 'when optimize_top_bound_lineage_search is off' do + before do + stub_feature_flags(optimize_top_bound_lineage_search: false) + end + + it 'uses @> operator in queries' do + expect(group.self_and_descendants.to_sql).to include('traversal_ids @>') + expect(group.self_and_descendant_ids.to_sql).to include('traversal_ids @>') + expect(group.descendants.to_sql).to include('traversal_ids @>') + expect(group.self_and_hierarchy.to_sql).to include('traversal_ids @>') + end end describe '#ancestors' do diff --git a/spec/policies/deploy_key_policy_spec.rb b/spec/policies/deploy_key_policy_spec.rb index 754f36ce3b0..6e0e43de1bc 100644 --- a/spec/policies/deploy_key_policy_spec.rb +++ b/spec/policies/deploy_key_policy_spec.rb @@ -17,12 +17,16 @@ RSpec.describe DeployKeyPolicy, feature_category: :groups_and_projects do it { is_expected.to be_disallowed(:read_deploy_key) } it { is_expected.to be_disallowed(:update_deploy_key) } + + it { is_expected.to be_disallowed(:update_deploy_key_title) } end context 'and current_user is present' do it { is_expected.to be_allowed(:read_deploy_key) } it { is_expected.to be_disallowed(:update_deploy_key) } + + it { is_expected.to be_disallowed(:update_deploy_key_title) } end context 'when current_user is admin' do @@ -32,12 +36,16 @@ RSpec.describe DeployKeyPolicy, feature_category: :groups_and_projects do it { is_expected.to be_allowed(:read_deploy_key) } it { is_expected.to be_allowed(:update_deploy_key) } + + it { is_expected.to be_allowed(:update_deploy_key_title) } end context 'when admin mode disabled' do it { is_expected.to be_allowed(:read_deploy_key) } it { is_expected.to be_disallowed(:update_deploy_key) } + + it { is_expected.to be_disallowed(:update_deploy_key_title) } end end end @@ -51,6 +59,8 @@ RSpec.describe DeployKeyPolicy, feature_category: :groups_and_projects do it { is_expected.to be_disallowed(:read_deploy_key) } it { is_expected.to be_disallowed(:update_deploy_key) } + + it { is_expected.to be_disallowed(:update_deploy_key_title) } end context 'when current_user is admin' do @@ -60,12 +70,16 @@ RSpec.describe DeployKeyPolicy, feature_category: :groups_and_projects do it { is_expected.to be_allowed(:read_deploy_key) } it { is_expected.to be_allowed(:update_deploy_key) } + + it { is_expected.to be_allowed(:update_deploy_key_title) } end context 'when admin mode disabled' do it { is_expected.to be_disallowed(:read_deploy_key) } it { is_expected.to be_disallowed(:update_deploy_key) } + + it { is_expected.to be_disallowed(:update_deploy_key_title) } end end @@ -79,12 +93,34 @@ RSpec.describe DeployKeyPolicy, feature_category: :groups_and_projects do it { is_expected.to be_allowed(:read_deploy_key) } it { is_expected.to be_allowed(:update_deploy_key) } + + it { is_expected.to be_allowed(:update_deploy_key_title) } end context 'when assigned to another project' do it { is_expected.to be_disallowed(:read_deploy_key) } it { is_expected.to be_disallowed(:update_deploy_key) } + + it { is_expected.to be_disallowed(:update_deploy_key_title) } + end + + context 'when assigned to miltiple projects' do + let_it_be(:project_one) { create(:project) } + let_it_be(:project_two) { create(:project) } + + before_all do + create(:deploy_keys_project, project: project_one, deploy_key: deploy_key) + create(:deploy_keys_project, project: project_two, deploy_key: deploy_key) + + project_one.add_maintainer(current_user) + end + + it { is_expected.to be_allowed(:read_deploy_key) } + + it { is_expected.to be_allowed(:update_deploy_key) } + + it { is_expected.to be_disallowed(:update_deploy_key_title) } end end end diff --git a/spec/requests/api/deploy_keys_spec.rb b/spec/requests/api/deploy_keys_spec.rb index ca19a97ae49..98ddd40a283 100644 --- a/spec/requests/api/deploy_keys_spec.rb +++ b/spec/requests/api/deploy_keys_spec.rb @@ -367,6 +367,51 @@ RSpec.describe API::DeployKeys, :aggregate_failures, feature_category: :continuo expect(response).to have_gitlab_http_status(:ok) end end + + context 'private deploy key attached to one project' do + let_it_be(:deploy_key) { create(:deploy_key, public: false) } + let_it_be(:deploy_keys_project) do + create(:deploy_keys_project, project: project, deploy_key: deploy_key) + end + + let_it_be(:extra_params) { { title: 'new title', can_push: true } } + + it 'updates the title of the deploy key' do + expect { subject }.to change { deploy_key.reload.title }.to('new title') + expect(response).to have_gitlab_http_status(:ok) + end + + it 'updates can_push of deploy_keys_project' do + expect { subject }.to change { deploy_keys_project.reload.can_push }.from(false).to(true) + expect(response).to have_gitlab_http_status(:ok) + end + end + + context 'private deploy key attached to multiple projects' do + let_it_be(:deploy_key) { create(:deploy_key, public: false) } + let_it_be(:another_project) { create(:project, title: 'hello world') } + let_it_be(:extra_params) { { title: 'new title', can_push: true } } + + let_it_be(:deploy_keys_project) do + create(:deploy_keys_project, project: project, deploy_key: deploy_key) + end + + before do + create(:deploy_keys_project, project: another_project, deploy_key: deploy_key) + + another_project.add_maintainer(maintainer) + end + + it 'does not update the title of the deploy key' do + expect { subject }.not_to change { deploy_key.reload.title } + expect(response).to have_gitlab_http_status(:ok) + end + + it 'updates can_push of deploy_keys_project' do + expect { subject }.to change { deploy_keys_project.reload.can_push }.from(false).to(true) + expect(response).to have_gitlab_http_status(:ok) + end + end end end diff --git a/spec/requests/api/members_spec.rb b/spec/requests/api/members_spec.rb index 72b5b357483..682f0d57a31 100644 --- a/spec/requests/api/members_spec.rb +++ b/spec/requests/api/members_spec.rb @@ -665,7 +665,7 @@ RSpec.describe API::Members, feature_category: :groups_and_projects do it 'returns 400 when access level is not valid' do put api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", maintainer), - params: { access_level: non_existing_record_access_level } + params: { access_level: 15 } expect(response).to have_gitlab_http_status(:bad_request) end diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml index 2b1f7f0bf5d..58955a94e57 100644 --- a/spec/support/rspec_order_todo.yml +++ b/spec/support/rspec_order_todo.yml @@ -9364,7 +9364,6 @@ - './spec/workers/auto_merge_process_worker_spec.rb' - './spec/workers/background_migration/ci_database_worker_spec.rb' - './spec/workers/background_migration_worker_spec.rb' -- './spec/workers/build_hooks_worker_spec.rb' - './spec/workers/build_queue_worker_spec.rb' - './spec/workers/bulk_imports/entity_worker_spec.rb' - './spec/workers/bulk_imports/export_request_worker_spec.rb' diff --git a/spec/workers/build_hooks_worker_spec.rb b/spec/workers/build_hooks_worker_spec.rb deleted file mode 100644 index adae0417a9a..00000000000 --- a/spec/workers/build_hooks_worker_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe BuildHooksWorker, feature_category: :continuous_integration do - describe '#perform' do - context 'when build exists' do - let!(:build) { create(:ci_build) } - - it 'calls build hooks' do - expect_any_instance_of(Ci::Build) - .to receive(:execute_hooks) - - described_class.new.perform(build.id) - end - end - - context 'when build does not exist' do - it 'does not raise exception' do - expect { described_class.new.perform(123) } - .not_to raise_error - end - end - end - - describe '.perform_async', :sidekiq_inline do - it 'sends a message to the application logger, before performing' do - build = create(:ci_build) - - expect(Gitlab::AppLogger).to receive(:info).with( - message: include('Enqueuing hooks for Build'), - class: described_class.name, - build_id: build.id, - pipeline_id: build.pipeline_id, - project_id: build.project_id, - build_status: build.status - ) - - expect_any_instance_of(Ci::Build).to receive(:execute_hooks) - - described_class.perform_async(build) - end - end - - it_behaves_like 'worker with data consistency', described_class, data_consistency: :delayed -end diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb index 3f5a4db4331..bbd0a6f497f 100644 --- a/spec/workers/every_sidekiq_worker_spec.rb +++ b/spec/workers/every_sidekiq_worker_spec.rb @@ -135,7 +135,6 @@ RSpec.describe 'Every Sidekiq worker', feature_category: :shared do 'AutoMergeProcessWorker' => 3, 'BackgroundMigrationWorker' => 3, 'BackgroundMigration::CiDatabaseWorker' => 3, - 'BuildHooksWorker' => 3, 'BuildQueueWorker' => 3, 'BuildSuccessWorker' => 3, 'BulkImportWorker' => 3,