diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-10-14 12:10:40 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-10-14 12:10:40 +0000 |
commit | a0d49dc011304985a8fd8a7ab337c003995c8ae1 (patch) | |
tree | a596d7ca659be1c02f5cce4d1f7a217c2ca153d6 | |
parent | efcfe56681dc8bd586e6ef56d1dc7df05a93197d (diff) | |
download | gitlab-ce-a0d49dc011304985a8fd8a7ab337c003995c8ae1.tar.gz |
Add latest changes from gitlab-org/gitlab@master
39 files changed, 486 insertions, 440 deletions
diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS index b3a81f42b52..ae28f64a215 100644 --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -351,9 +351,9 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/administration/audit_event_streaming.md @eread /doc/administration/audit_events.md @eread /doc/administration/audit_reports.md @eread -/doc/administration/auditor_users.md @eread -/doc/administration/auth/ @eread -/doc/administration/auth/ldap/ @eread +/doc/administration/auditor_users.md @jglassman1 +/doc/administration/auth/ @jglassman1 +/doc/administration/auth/ldap/ @jglassman1 /doc/administration/cicd.md @marcel.amirault /doc/administration/clusters/ @phillipwells /doc/administration/compliance.md @eread @@ -463,16 +463,16 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/administration/troubleshooting/ssl.md @axil /doc/administration/troubleshooting/test_environments.md @axil /doc/administration/uploads.md @axil -/doc/administration/user_settings.md @eread +/doc/administration/user_settings.md @jglassman1 /doc/administration/wikis/ @ashrafkhamis -/doc/api/access_requests.md @eread +/doc/api/access_requests.md @jglassman1 /doc/api/admin_sidekiq_queues.md @axil /doc/api/alert_management_alerts.md @msedlakjakubowski /doc/api/api_resources.md @ashrafkhamis -/doc/api/appearance.md @eread -/doc/api/applications.md @eread +/doc/api/appearance.md @jglassman1 +/doc/api/applications.md @jglassman1 /doc/api/audit_events.md @eread -/doc/api/avatar.md @eread +/doc/api/avatar.md @jglassman1 /doc/api/award_emoji.md @msedlakjakubowski /doc/api/boards.md @msedlakjakubowski /doc/api/branches.md @aqualls @@ -509,8 +509,8 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/api/graphql/reference/ @ashrafkhamis /doc/api/graphql/removed_items.md @ashrafkhamis /doc/api/graphql/sample_issue_boards.md @msedlakjakubowski -/doc/api/graphql/users_example.md @eread -/doc/api/group_access_tokens.md @eread +/doc/api/graphql/users_example.md @jglassman1 +/doc/api/group_access_tokens.md @jglassman1 /doc/api/group_activity_analytics.md @fneill /doc/api/group_badges.md @fneill /doc/api/group_boards.md @msedlakjakubowski @@ -545,7 +545,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/api/lint.md @marcel.amirault /doc/api/managed_licenses.md @fneill /doc/api/markdown.md @msedlakjakubowski -/doc/api/members.md @eread +/doc/api/members.md @jglassman1 /doc/api/merge_request_approvals.md @aqualls /doc/api/merge_request_context_commits.md @aqualls /doc/api/merge_requests.md @aqualls @@ -554,10 +554,10 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/api/metrics_dashboard_annotations.md @msedlakjakubowski /doc/api/metrics_user_starred_dashboards.md @msedlakjakubowski /doc/api/milestones.md @msedlakjakubowski -/doc/api/namespaces.md @eread +/doc/api/namespaces.md @jglassman1 /doc/api/notes.md @msedlakjakubowski /doc/api/notification_settings.md @msedlakjakubowski -/doc/api/oauth2.md @eread +/doc/api/oauth2.md @jglassman1 /doc/api/openapi/ @ashrafkhamis /doc/api/packages.md @claytoncornell /doc/api/packages/ @claytoncornell @@ -567,8 +567,8 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/api/pipeline_schedules.md @marcel.amirault /doc/api/pipeline_triggers.md @marcel.amirault /doc/api/pipelines.md @marcel.amirault -/doc/api/plan_limits.md @eread -/doc/api/project_access_tokens.md @eread +/doc/api/plan_limits.md @jglassman1 +/doc/api/project_access_tokens.md @jglassman1 /doc/api/project_aliases.md @aqualls /doc/api/project_badges.md @aqualls /doc/api/project_clusters.md @phillipwells @@ -596,14 +596,14 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/api/resource_state_events.md @msedlakjakubowski /doc/api/resource_weight_events.md @msedlakjakubowski /doc/api/runners.md @sselhorn -/doc/api/scim.md @eread +/doc/api/scim.md @jglassman1 /doc/api/search.md @ashrafkhamis /doc/api/secure_files.md @marcel.amirault -/doc/api/settings.md @eread +/doc/api/settings.md @jglassman1 /doc/api/sidekiq_metrics.md @axil /doc/api/snippet_repository_storage_moves.md @ashrafkhamis /doc/api/snippets.md @ashrafkhamis -/doc/api/statistics.md @eread +/doc/api/statistics.md @jglassman1 /doc/api/status_checks.md @eread /doc/api/suggestions.md @aqualls /doc/api/system_hooks.md @ashrafkhamis @@ -615,7 +615,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/api/todos.md @msedlakjakubowski /doc/api/topics.md @fneill /doc/api/usage_data.md @claytoncornell -/doc/api/users.md @eread +/doc/api/users.md @jglassman1 /doc/api/version.md @phillipwells /doc/api/visual_review_discussions.md @marcel.amirault /doc/api/vulnerabilities.md @claytoncornell @@ -691,7 +691,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/development/build_test_package.md @axil /doc/development/bulk_import.md @eread /doc/development/cached_queries.md @sselhorn -/doc/development/cascading_settings.md @eread +/doc/development/cascading_settings.md @jglassman1 /doc/development/chatops_on_gitlabcom.md @phillipwells /doc/development/cicd/ @marcel.amirault /doc/development/code_intelligence/ @aqualls @@ -802,7 +802,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/development/packages/ @claytoncornell /doc/development/pages/ @ashrafkhamis /doc/development/permissions.md @eread -/doc/development/policies.md @eread +/doc/development/policies.md @jglassman1 /doc/development/product_qualified_lead_guide/ @phillipwells /doc/development/project_templates.md @fneill /doc/development/prometheus_metrics.md @msedlakjakubowski @@ -811,7 +811,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/development/secure_coding_guidelines.md @sselhorn /doc/development/service_ping/ @claytoncornell /doc/development/snowplow/ @claytoncornell -/doc/development/spam_protection_and_captcha/ @eread +/doc/development/spam_protection_and_captcha/ @jglassman1 /doc/development/sql.md @aqualls /doc/development/testing_guide/ @sselhorn /doc/development/testing_guide/contract/ @sselhorn @@ -829,38 +829,38 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/install/ @axil /doc/integration/advanced_search/ @ashrafkhamis /doc/integration/akismet.md @phillipwells -/doc/integration/alicloud.md @eread +/doc/integration/alicloud.md @jglassman1 /doc/integration/arkose.md @phillipwells -/doc/integration/auth0.md @eread -/doc/integration/azure.md @eread -/doc/integration/bitbucket.md @eread -/doc/integration/cas.md @eread +/doc/integration/auth0.md @jglassman1 +/doc/integration/azure.md @jglassman1 +/doc/integration/bitbucket.md @jglassman1 +/doc/integration/cas.md @jglassman1 /doc/integration/datadog.md @ashrafkhamis -/doc/integration/ding_talk.md @eread +/doc/integration/ding_talk.md @jglassman1 /doc/integration/external-issue-tracker.md @ashrafkhamis -/doc/integration/facebook.md @eread -/doc/integration/github.md @eread -/doc/integration/gitlab.md @eread +/doc/integration/facebook.md @jglassman1 +/doc/integration/github.md @jglassman1 +/doc/integration/gitlab.md @jglassman1 /doc/integration/gitpod.md @ashrafkhamis /doc/integration/gmail_action_buttons_for_gitlab.md @ashrafkhamis -/doc/integration/google.md @eread +/doc/integration/google.md @jglassman1 /doc/integration/index.md @ashrafkhamis /doc/integration/jenkins.md @ashrafkhamis /doc/integration/jira/ @ashrafkhamis -/doc/integration/kerberos.md @eread +/doc/integration/kerberos.md @jglassman1 /doc/integration/mattermost/ @axil -/doc/integration/oauth2_generic.md @eread -/doc/integration/oauth_provider.md @eread -/doc/integration/omniauth.md @eread -/doc/integration/openid_connect_provider.md @eread -/doc/integration/recaptcha.md @eread -/doc/integration/salesforce.md @eread -/doc/integration/saml.md @eread +/doc/integration/oauth2_generic.md @jglassman1 +/doc/integration/oauth_provider.md @jglassman1 +/doc/integration/omniauth.md @jglassman1 +/doc/integration/openid_connect_provider.md @jglassman1 +/doc/integration/recaptcha.md @jglassman1 +/doc/integration/salesforce.md @jglassman1 +/doc/integration/saml.md @jglassman1 /doc/integration/security_partners/ @rdickenson /doc/integration/slash_commands.md @ashrafkhamis /doc/integration/sourcegraph.md @aqualls /doc/integration/trello_power_up.md @ashrafkhamis -/doc/integration/twitter.md @eread +/doc/integration/twitter.md @jglassman1 /doc/integration/vault.md @phillipwells /doc/operations/error_tracking.md msedlakjakubowski /doc/operations/feature_flags.md @rdickenson @@ -884,12 +884,12 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/raketasks/user_management.md @axil /doc/raketasks/web_hooks.md @axil /doc/raketasks/x509_signatures.md @aqualls -/doc/security/ @eread +/doc/security/ @jglassman1 /doc/subscriptions/ @fneill /doc/subscriptions/gitlab_com/ @fneill /doc/subscriptions/gitlab_dedicated/ @axil /doc/subscriptions/self_managed/ @fneill -/doc/topics/authentication/ @eread +/doc/topics/authentication/ @jglassman1 /doc/topics/autodevops/ @phillipwells /doc/topics/autodevops/cloud_deployments/ @phillipwells /doc/topics/git/ @aqualls @@ -913,7 +913,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/update/zero_downtime.md @axil /doc/user/admin_area/analytics/ @fneill /doc/user/admin_area/broadcast_messages.md @phillipwells -/doc/user/admin_area/credentials_inventory.md @eread +/doc/user/admin_area/credentials_inventory.md @jglassman1 /doc/user/admin_area/custom_project_templates.md @eread /doc/user/admin_area/diff_limits.md @aqualls /doc/user/admin_area/geo_sites.md @axil @@ -921,17 +921,17 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/user/admin_area/license.md @fneill /doc/user/admin_area/license_file.md @fneill /doc/user/admin_area/merge_requests_approvals.md @aqualls -/doc/user/admin_area/moderate_users.md @eread +/doc/user/admin_area/moderate_users.md @jglassman1 /doc/user/admin_area/monitoring/background_migrations.md @aqualls /doc/user/admin_area/monitoring/health_check.md @msedlakjakubowski /doc/user/admin_area/reporting/git_abuse_rate_limit.md @phillipwells /doc/user/admin_area/reporting/spamcheck.md @axil -/doc/user/admin_area/review_abuse_reports.md @eread +/doc/user/admin_area/review_abuse_reports.md @jglassman1 /doc/user/admin_area/settings/account_and_limit_settings.md @aqualls /doc/user/admin_area/settings/continuous_integration.md @marcel.amirault /doc/user/admin_area/settings/deprecated_api_rate_limits.md @aqualls /doc/user/admin_area/settings/email.md @msedlakjakubowski -/doc/user/admin_area/settings/external_authorization.md @eread +/doc/user/admin_area/settings/external_authorization.md @jglassman1 /doc/user/admin_area/settings/files_api_rate_limits.md @aqualls /doc/user/admin_area/settings/git_lfs_rate_limits.md @aqualls /doc/user/admin_area/settings/gitaly_timeouts.md @eread @@ -945,7 +945,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/user/admin_area/settings/rate_limit_on_issues_creation.md @msedlakjakubowski /doc/user/admin_area/settings/rate_limit_on_notes_creation.md @msedlakjakubowski /doc/user/admin_area/settings/rate_limit_on_pipelines_creation.md @marcel.amirault -/doc/user/admin_area/settings/rate_limit_on_users_api.md @eread +/doc/user/admin_area/settings/rate_limit_on_users_api.md @jglassman1 /doc/user/admin_area/settings/third_party_offers.md @fneill /doc/user/admin_area/settings/usage_statistics.md @claytoncornell /doc/user/admin_area/settings/visibility_and_access_controls.md @aqualls @@ -1007,7 +1007,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/user/group/planning_hierarchy/ @msedlakjakubowski /doc/user/group/repositories_analytics/ @marcel.amirault /doc/user/group/roadmap/ @msedlakjakubowski -/doc/user/group/saml_sso/ @eread +/doc/user/group/saml_sso/ @jglassman1 /doc/user/group/settings/ @eread /doc/user/group/subgroups/ @fneill /doc/user/group/value_stream_analytics/ @fneill @@ -1042,13 +1042,13 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/user/packages/rubygems_registry/ @claytoncornell /doc/user/packages/terraform_module_registry/ @phillipwells /doc/user/packages/workflows/ @claytoncornell -/doc/user/permissions.md @eread +/doc/user/permissions.md @jglassman1 /doc/user/profile/account/ @eread -/doc/user/profile/index.md @eread +/doc/user/profile/index.md @jglassman1 /doc/user/profile/notifications.md @msedlakjakubowski -/doc/user/profile/personal_access_tokens.md @eread -/doc/user/profile/unknown_sign_in_notification.md @eread -/doc/user/profile/wrong_two_factor_authentication_code_notification.md @eread +/doc/user/profile/personal_access_tokens.md @jglassman1 +/doc/user/profile/unknown_sign_in_notification.md @jglassman1 +/doc/user/profile/wrong_two_factor_authentication_code_notification.md @jglassman1 /doc/user/project/autocomplete_characters.md @aqualls /doc/user/project/badges.md @aqualls /doc/user/project/clusters/ @phillipwells @@ -1189,7 +1189,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/user/search/global_search/ @ashrafkhamis /doc/user/shortcuts.md @ashrafkhamis /doc/user/snippets.md @ashrafkhamis -/doc/user/ssh.md @eread +/doc/user/ssh.md @jglassman1 /doc/user/tasks.md @msedlakjakubowski /doc/user/todos.md @msedlakjakubowski /doc/user/usage_quotas.md @fneill diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb index 8ed67c26f19..4cf26d3e1e2 100644 --- a/app/controllers/profiles/personal_access_tokens_controller.rb +++ b/app/controllers/profiles/personal_access_tokens_controller.rb @@ -3,6 +3,8 @@ class Profiles::PersonalAccessTokensController < Profiles::ApplicationController feature_category :authentication_and_authorization + before_action :check_personal_access_tokens_enabled + def index set_index_vars scopes = params[:scopes].split(',').map(&:squish).select(&:present?).map(&:to_sym) unless params[:scopes].nil? @@ -83,4 +85,8 @@ class Profiles::PersonalAccessTokensController < Profiles::ApplicationController def page (params[:page] || 1).to_i end + + def check_personal_access_tokens_enabled + render_404 if Gitlab::CurrentSettings.personal_access_tokens_disabled? + end end diff --git a/app/graphql/types/notes/note_type.rb b/app/graphql/types/notes/note_type.rb index c254460a51f..eef5ce40bde 100644 --- a/app/graphql/types/notes/note_type.rb +++ b/app/graphql/types/notes/note_type.rb @@ -41,7 +41,7 @@ module Types deprecated: { reason: :renamed, replacement: 'internal', - milestone: '15.3' + milestone: '15.5' } field :internal, GraphQL::Types::Boolean, null: true, diff --git a/app/models/environment.rb b/app/models/environment.rb index 4b98cd02e3b..e8588c8d022 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -441,11 +441,15 @@ class Environment < ApplicationRecord end def auto_stop_in=(value) - return unless value + if value.nil? + # Handles edge case when auto_stop_at is already set and the new value is nil. + # Possible by setting `auto_stop_in: null` in the CI configuration yml. + self.auto_stop_at = nil - parser = ::Gitlab::Ci::Build::DurationParser.new(value) + return + end - return if parser.seconds_from_now.nil? && auto_stop_at.nil? + parser = ::Gitlab::Ci::Build::DurationParser.new(value) self.auto_stop_at = parser.seconds_from_now rescue ChronicDuration::DurationParseError => ex diff --git a/app/models/integration.rb b/app/models/integration.rb index aecf9529a14..23688a87cbd 100644 --- a/app/models/integration.rb +++ b/app/models/integration.rb @@ -147,6 +147,8 @@ class Integration < ApplicationRecord fields << ::Integrations::Field.new(name: name, integration_class: self, **attrs) case storage + when :attribute + # noop when :properties prop_accessor(name) when :data_fields @@ -155,7 +157,7 @@ class Integration < ApplicationRecord raise ArgumentError, "Unknown field storage: #{storage}" end - boolean_accessor(name) if attrs[:type] == 'checkbox' + boolean_accessor(name) if attrs[:type] == 'checkbox' && storage != :attribute end # :nocov: diff --git a/app/models/user.rb b/app/models/user.rb index 4bc2d8f76aa..b2f75959f15 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -199,6 +199,8 @@ class User < ApplicationRecord has_many :notes, dependent: :destroy, foreign_key: :author_id # rubocop:disable Cop/ActiveRecordDependent has_many :issues, dependent: :destroy, foreign_key: :author_id # rubocop:disable Cop/ActiveRecordDependent has_many :legacy_assigned_merge_requests, class_name: 'MergeRequest', dependent: :nullify, foreign_key: :assignee_id # rubocop:disable Cop/ActiveRecordDependent + has_many :merged_merge_requests, class_name: 'MergeRequest::Metrics', dependent: :nullify, foreign_key: :merged_by_id # rubocop:disable Cop/ActiveRecordDependent + has_many :closed_merge_requests, class_name: 'MergeRequest::Metrics', dependent: :nullify, foreign_key: :latest_closed_by_id # rubocop:disable Cop/ActiveRecordDependent has_many :updated_merge_requests, class_name: 'MergeRequest', dependent: :nullify, foreign_key: :updated_by_id # rubocop:disable Cop/ActiveRecordDependent has_many :updated_issues, class_name: 'Issue', dependent: :nullify, foreign_key: :updated_by_id # rubocop:disable Cop/ActiveRecordDependent has_many :closed_issues, class_name: 'Issue', dependent: :nullify, foreign_key: :closed_by_id # rubocop:disable Cop/ActiveRecordDependent diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb index 674d1ddb18b..d9aa204399e 100644 --- a/app/policies/group_policy.rb +++ b/app/policies/group_policy.rb @@ -84,7 +84,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy condition(:crm_enabled, score: 0, scope: :subject) { @subject.crm_enabled? } condition(:group_runner_registration_allowed, scope: :global) do - Feature.disabled?(:runner_registration_control) || Gitlab::CurrentSettings.valid_runner_registrars.include?('group') + Gitlab::CurrentSettings.valid_runner_registrars.include?('group') end condition(:runners_finder_all_available, scope: :subject) do diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb index 4f15b5f6ded..77bdf9d62fc 100644 --- a/app/policies/project_policy.rb +++ b/app/policies/project_policy.rb @@ -222,7 +222,7 @@ class ProjectPolicy < BasePolicy end condition(:project_runner_registration_allowed) do - Feature.disabled?(:runner_registration_control) || Gitlab::CurrentSettings.valid_runner_registrars.include?('project') + Gitlab::CurrentSettings.valid_runner_registrars.include?('project') end condition :registry_enabled do @@ -794,7 +794,7 @@ class ProjectPolicy < BasePolicy rule { project_bot }.enable :project_bot_access - rule { can?(:read_all_resources) }.enable :read_resource_access_tokens + rule { can?(:read_all_resources) & resource_access_token_feature_available }.enable :read_resource_access_tokens rule { can?(:admin_project) & resource_access_token_feature_available }.policy do enable :read_resource_access_tokens diff --git a/app/services/ci/runners/register_runner_service.rb b/app/services/ci/runners/register_runner_service.rb index ae9b8bc8a16..abd32610cec 100644 --- a/app/services/ci/runners/register_runner_service.rb +++ b/app/services/ci/runners/register_runner_service.rb @@ -59,7 +59,7 @@ module Ci end def runner_registrar_valid?(type) - Feature.disabled?(:runner_registration_control) || Gitlab::CurrentSettings.valid_runner_registrars.include?(type) + Gitlab::CurrentSettings.valid_runner_registrars.include?(type) end def token_scope diff --git a/app/views/admin/application_settings/ci_cd.html.haml b/app/views/admin/application_settings/ci_cd.html.haml index ff645e1183f..b7244c45871 100644 --- a/app/views/admin/application_settings/ci_cd.html.haml +++ b/app/views/admin/application_settings/ci_cd.html.haml @@ -38,12 +38,11 @@ .settings-content = render 'registry' -- if Feature.enabled?(:runner_registration_control) - %section.settings.as-runner.no-animate#js-runner-settings{ class: ('expanded' if expanded_by_default?) } - .settings-header - %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only - = s_('Runners|Runner registration') - = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do - = expanded_by_default? ? 'Collapse' : 'Expand' - .settings-content - = render 'runner_registrars_form' +%section.settings.as-runner.no-animate#js-runner-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only + = s_('Runners|Runner registration') + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do + = expanded_by_default? ? 'Collapse' : 'Expand' + .settings-content + = render 'runner_registrars_form' diff --git a/app/views/layouts/nav/sidebar/_profile.html.haml b/app/views/layouts/nav/sidebar/_profile.html.haml index a1393615e69..0e3327935ca 100644 --- a/app/views/layouts/nav/sidebar/_profile.html.haml +++ b/app/views/layouts/nav/sidebar/_profile.html.haml @@ -51,17 +51,18 @@ = link_to profile_chat_names_path do %strong.fly-out-top-item-name = _('Chat') - = nav_link(controller: :personal_access_tokens) do - = link_to profile_personal_access_tokens_path do - .nav-icon-container - = sprite_icon('token') - %span.nav-item-name - = _('Access Tokens') - %ul.sidebar-sub-level-items.is-fly-out-only - = nav_link(controller: :personal_access_tokens, html_options: { class: "fly-out-top-item" } ) do - = link_to profile_personal_access_tokens_path do - %strong.fly-out-top-item-name - = _('Access Tokens') + - unless Gitlab::CurrentSettings.personal_access_tokens_disabled? + = nav_link(controller: :personal_access_tokens) do + = link_to profile_personal_access_tokens_path do + .nav-icon-container + = sprite_icon('token') + %span.nav-item-name + = _('Access Tokens') + %ul.sidebar-sub-level-items.is-fly-out-only + = nav_link(controller: :personal_access_tokens, html_options: { class: "fly-out-top-item" } ) do + = link_to profile_personal_access_tokens_path do + %strong.fly-out-top-item-name + = _('Access Tokens') = nav_link(controller: :emails) do = link_to profile_emails_path, data: { qa_selector: 'profile_emails_link' } do .nav-icon-container diff --git a/config/feature_flags/development/runner_registration_control.yml b/config/feature_flags/development/runner_registration_control.yml deleted file mode 100644 index 56c01bf36e5..00000000000 --- a/config/feature_flags/development/runner_registration_control.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: runner_registration_control -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61407 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/336087 -milestone: '14.1' -type: development -group: group::runner -default_enabled: false diff --git a/data/deprecations/15-5-confidential-field-on-notes.yml b/data/deprecations/15-5-confidential-field-on-notes.yml new file mode 100644 index 00000000000..5ec5c3adab9 --- /dev/null +++ b/data/deprecations/15-5-confidential-field-on-notes.yml @@ -0,0 +1,12 @@ +- name: 'GraphQL field `confidential` changed to `internal` on notes' + announcement_milestone: '15.5' + announcement_date: '2022-10-22' + removal_milestone: '16.0' + removal_date: '2023-05-22' + breaking_change: true + reporter: nicolasdular + stage: plan + issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/371485 + body: | + The `confidential` field for a `Note` will be deprecated and renamed to `internal`. + documentation_url: https://docs.gitlab.com/ee/api/graphql/reference/index.html#note diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index c47cea4a1de..7aae413b54b 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -1,5 +1,5 @@ --- -stage: Ecosystem +stage: Manage group: Integrations info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments --- @@ -15433,7 +15433,7 @@ Represents the network policy. | <a id="noteauthor"></a>`author` | [`UserCore!`](#usercore) | User who wrote this note. | | <a id="notebody"></a>`body` | [`String!`](#string) | Content of the note. | | <a id="notebodyhtml"></a>`bodyHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `note`. | -| <a id="noteconfidential"></a>`confidential` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated** in 15.3. This was renamed. Use: `internal`. | +| <a id="noteconfidential"></a>`confidential` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated** in 15.5. This was renamed. Use: `internal`. | | <a id="notecreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp of the note creation. | | <a id="notediscussion"></a>`discussion` | [`Discussion`](#discussion) | Discussion this note is a part of. | | <a id="noteid"></a>`id` | [`NoteID!`](#noteid) | ID of the note. | diff --git a/doc/development/database/table_partitioning.md b/doc/development/database/table_partitioning.md index b1bcb92cb73..2350d5d0e9e 100644 --- a/doc/development/database/table_partitioning.md +++ b/doc/development/database/table_partitioning.md @@ -396,14 +396,15 @@ class PrepareForeignKeyForPartitioning < Gitlab::Database::Migration[2.0] end ``` -### Step 6 - Create parent table and attach existing table as the initial paritition +### Step 6 - Create parent table and attach existing table as the initial partition -You can now create the parent table attaching the existing table as the initial partition by using the following helpers provided by the database team. +You can now create the parent table attaching the existing table as the initial +partition by using the following helpers provided by the database team. -For example, using list partitioning in a Rails migration: +For example, using list partitioning in Rails post migrations: ```ruby -class ConvertTableToZeroPartitioning < Gitlab::Database::Migration[2.0] +class PrepareTableConstraintsForListPartitioning < Gitlab::Database::Migration[2.0] include Gitlab::Database::PartitioningMigrationHelpers::TableManagementHelpers disable_ddl_transaction! @@ -420,24 +421,41 @@ class ConvertTableToZeroPartitioning < Gitlab::Database::Migration[2.0] parent_table_name: PARENT_TABLE_NAME, initial_partitioning_value: FIRST_PARTITION ) + end - convert_table_to_first_list_partition( + def down + revert_preparing_constraint_for_list_partitioning( table_name: TABLE_NAME, partitioning_column: PARTITION_COLUMN, parent_table_name: PARENT_TABLE_NAME, initial_partitioning_value: FIRST_PARTITION ) end +end +``` - def down - revert_converting_table_to_first_list_partition( +```ruby +class ConvertTableToListPartitioning < Gitlab::Database::Migration[2.0] + include Gitlab::Database::PartitioningMigrationHelpers::TableManagementHelpers + + disable_ddl_transaction! + + TABLE_NAME = :table_name + PARENT_TABLE_NAME = :p_table_name + FIRST_PARTITION = 100 + PARTITION_COLUMN = :partition_id + + def up + convert_table_to_first_list_partition( table_name: TABLE_NAME, partitioning_column: PARTITION_COLUMN, parent_table_name: PARENT_TABLE_NAME, initial_partitioning_value: FIRST_PARTITION ) + end - revert_preparing_constraint_for_list_partitioning( + def down + revert_converting_table_to_first_list_partition( table_name: TABLE_NAME, partitioning_column: PARTITION_COLUMN, parent_table_name: PARENT_TABLE_NAME, diff --git a/doc/development/value_stream_analytics.md b/doc/development/value_stream_analytics.md index 4194da48229..b7e5a86d491 100644 --- a/doc/development/value_stream_analytics.md +++ b/doc/development/value_stream_analytics.md @@ -326,3 +326,24 @@ in your rails console (`rails c`): ```ruby Analytics::CycleAnalytics::ReaggregationWorker.new.perform ``` + +### Seed data + +#### Value stream analytics + +Seed issues and merge requests for value stream analytics: + + ```shell + // Seed 10 issues for the project specified by <project-id> + $ VSA_SEED_PROJECT_ID=<project-id> VSA_ISSUE_COUNT=10 SEED_VSA=true FILTER=cycle_analytics rake db:seed_fu + ``` + +#### DORA metrics + +Seed DORA daily metrics for value stream, insights and CI/CD analytics: + +1. [Create an environment from the UI](../ci/environments/index.md#create-a-static-environment) named `production`. +1. Open the rails console: + + ```shell + rails c diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md index e2d9692fcbc..ed9b812525e 100644 --- a/doc/update/deprecations.md +++ b/doc/update/deprecations.md @@ -49,6 +49,20 @@ sole discretion of GitLab Inc. <div class="deprecation removal-160 breaking-change"> +### GraphQL field `confidential` changed to `internal` on notes + +Planned removal: GitLab <span class="removal-milestone">16.0</span> (2023-05-22) + +WARNING: +This is a [breaking change](https://docs.gitlab.com/ee/development/deprecation_guidelines/). +Review the details carefully before upgrading. + +The `confidential` field for a `Note` will be deprecated and renamed to `internal`. + +</div> + +<div class="deprecation removal-160 breaking-change"> + ### vulnerabilityFindingDismiss GraphQL mutation Planned removal: GitLab <span class="removal-milestone">16.0</span> (2023-05-22) diff --git a/doc/user/admin_area/settings/continuous_integration.md b/doc/user/admin_area/settings/continuous_integration.md index 95e40d4acb6..afc9a006b39 100644 --- a/doc/user/admin_area/settings/continuous_integration.md +++ b/doc/user/admin_area/settings/continuous_integration.md @@ -328,10 +328,8 @@ To set the maximum file size: ## Prevent users from registering runners -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22225) in GitLab 14.1. - -FLAG: -On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../../feature_flags.md) named `runner_registration_control`. On GitLab.com, this feature is not available. +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22225) in GitLab 14.1. +> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/368008) in GitLab 15.5. GitLab administrators can adjust who is allowed to register runners, by showing and hiding areas of the UI. diff --git a/lib/api/notes.rb b/lib/api/notes.rb index 77c479c529a..8ce875cdc03 100644 --- a/lib/api/notes.rb +++ b/lib/api/notes.rb @@ -73,7 +73,7 @@ module API params do requires :noteable_id, type: Integer, desc: 'The ID of the noteable' requires :body, type: String, desc: 'The content of a note' - optional :confidential, type: Boolean, desc: '[Deprecated in 15.3] Renamed to internal' + optional :confidential, type: Boolean, desc: '[Deprecated in 15.5] Renamed to internal' optional :internal, type: Boolean, desc: 'Internal note flag, default is false' optional :created_at, type: String, desc: 'The creation date of the note' optional :merge_request_diff_head_sha, type: String, desc: 'The SHA of the head commit' diff --git a/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb b/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb index 0587220e156..07a3aff1862 100644 --- a/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb +++ b/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb @@ -12,7 +12,7 @@ module Gitlab # rubocop: disable CodeReuse/ActiveRecord def perform! ff_enabled = Feature.enabled?(:ci_skip_auto_cancelation_on_child_pipelines, project) - return if ff_enabled && pipeline.child? + return if ff_enabled && pipeline.parent_pipeline? # skip if child pipeline return unless project.auto_cancel_pending_pipelines? Gitlab::OptimisticLocking.retry_lock(auto_cancelable_pipelines(ff_enabled), name: 'cancel_pending_pipelines') do |cancelables| @@ -49,6 +49,14 @@ module Gitlab .id_in(pipeline_ids) .with_only_interruptible_builds .each do |cancelable_pipeline| + Gitlab::AppLogger.info( + class: self.class.name, + message: "Pipeline #{pipeline.id} auto-canceling pipeline #{cancelable_pipeline.id}", + canceled_pipeline_id: cancelable_pipeline.id, + canceled_by_pipeline_id: pipeline.id, + canceled_by_pipeline_source: pipeline.source + ) + # cascade_to_children not needed because we iterate through descendants here cancelable_pipeline.cancel_running( auto_canceled_by_pipeline_id: pipeline.id, diff --git a/lib/gitlab/database/migrations/base_background_runner.rb b/lib/gitlab/database/migrations/base_background_runner.rb index 76982a9da9b..dbb85bad95c 100644 --- a/lib/gitlab/database/migrations/base_background_runner.rb +++ b/lib/gitlab/database/migrations/base_background_runner.rb @@ -4,10 +4,11 @@ module Gitlab module Database module Migrations class BaseBackgroundRunner - attr_reader :result_dir + attr_reader :result_dir, :connection - def initialize(result_dir:) + def initialize(result_dir:, connection:) @result_dir = result_dir + @connection = connection end def jobs_by_migration_name @@ -45,7 +46,7 @@ module Gitlab instrumentation.observe(version: nil, name: batch_names.next, - connection: ActiveRecord::Migration.connection) do + connection: connection) do run_job(j) end end diff --git a/lib/gitlab/database/migrations/test_background_runner.rb b/lib/gitlab/database/migrations/test_background_runner.rb index 6da2e098d43..65db330b1a6 100644 --- a/lib/gitlab/database/migrations/test_background_runner.rb +++ b/lib/gitlab/database/migrations/test_background_runner.rb @@ -5,7 +5,7 @@ module Gitlab module Migrations class TestBackgroundRunner < BaseBackgroundRunner def initialize(result_dir:) - super(result_dir: result_dir) + super(result_dir: result_dir, connection: ActiveRecord::Migration.connection) @job_coordinator = Gitlab::BackgroundMigration.coordinator_for_database(Gitlab::Database::MAIN_DATABASE_NAME) end diff --git a/lib/gitlab/database/migrations/test_batched_background_runner.rb b/lib/gitlab/database/migrations/test_batched_background_runner.rb index c27ae6a2c5d..46855ca1921 100644 --- a/lib/gitlab/database/migrations/test_batched_background_runner.rb +++ b/lib/gitlab/database/migrations/test_batched_background_runner.rb @@ -5,65 +5,73 @@ module Gitlab module Migrations class TestBatchedBackgroundRunner < BaseBackgroundRunner include Gitlab::Database::DynamicModelHelpers - attr_reader :connection def initialize(result_dir:, connection:) - super(result_dir: result_dir) + super(result_dir: result_dir, connection: connection) @connection = connection end def jobs_by_migration_name - Gitlab::Database::BackgroundMigration::BatchedMigration - .executable - .created_after(3.hours.ago) # Simple way to exclude migrations already running before migration testing - .to_h do |migration| - batching_strategy = migration.batch_class.new(connection: connection) - - smallest_batch_start = migration.next_min_value - - table_max_value = define_batchable_model(migration.table_name, connection: connection) - .maximum(migration.column_name) - - largest_batch_start = table_max_value - migration.batch_size - - # variance is the portion of the batch range that we shrink between variance * 0 and variance * 1 - # to pick actual batches to sample. - variance = largest_batch_start - smallest_batch_start - - batch_starts = uniform_fractions - .lazy # frac varies from 0 to 1, values in smallest_batch_start..largest_batch_start - .map { |frac| (variance * frac).to_i + smallest_batch_start } - - # Track previously run batches so that we stop sampling if a new batch would intersect an older one - completed_batches = [] - - jobs_to_sample = batch_starts - # Stop sampling if a batch would intersect a previous batch - .take_while { |start| completed_batches.none? { |batch| batch.cover?(start) } } - .map do |batch_start| - next_bounds = batching_strategy.next_batch( - migration.table_name, - migration.column_name, - batch_min_value: batch_start, - batch_size: migration.batch_size, - job_arguments: migration.job_arguments - ) - - batch_min, batch_max = next_bounds - - job = migration.create_batched_job!(batch_min, batch_max) - - completed_batches << (batch_min..batch_max) + Gitlab::Database::SharedModel.using_connection(connection) do + Gitlab::Database::BackgroundMigration::BatchedMigration + .executable + .created_after(3.hours.ago) # Simple way to exclude migrations already running before migration testing + .to_h do |migration| + batching_strategy = migration.batch_class.new(connection: connection) + + smallest_batch_start = migration.next_min_value + + table_max_value = define_batchable_model(migration.table_name, connection: connection) + .maximum(migration.column_name) + + largest_batch_start = table_max_value - migration.batch_size + + # variance is the portion of the batch range that we shrink between variance * 0 and variance * 1 + # to pick actual batches to sample. + variance = largest_batch_start - smallest_batch_start + + batch_starts = uniform_fractions + .lazy # frac varies from 0 to 1, values in smallest_batch_start..largest_batch_start + .map { |frac| (variance * frac).to_i + smallest_batch_start } + + # Track previously run batches so that we stop sampling if a new batch would intersect an older one + completed_batches = [] + + jobs_to_sample = batch_starts + # Stop sampling if a batch would intersect a previous batch + .take_while { |start| completed_batches.none? { |batch| batch.cover?(start) } } + .map do |batch_start| + # The current block is lazily evaluated as part of the jobs_to_sample enumerable + # so it executes after the enclosing using_connection block has already executed + # Therefore we need to re-associate with the explicit connection again + Gitlab::Database::SharedModel.using_connection(connection) do + next_bounds = batching_strategy.next_batch( + migration.table_name, + migration.column_name, + batch_min_value: batch_start, + batch_size: migration.batch_size, + job_arguments: migration.job_arguments + ) + + batch_min, batch_max = next_bounds + + job = migration.create_batched_job!(batch_min, batch_max) + + completed_batches << (batch_min..batch_max) + + job + end + end - job + [migration.job_class_name, jobs_to_sample] end - - [migration.job_class_name, jobs_to_sample] end end def run_job(job) - Gitlab::Database::BackgroundMigration::BatchedMigrationWrapper.new(connection: connection).perform(job) + Gitlab::Database::SharedModel.using_connection(connection) do + Gitlab::Database::BackgroundMigration::BatchedMigrationWrapper.new(connection: connection).perform(job) + end end def uniform_fractions diff --git a/lib/tasks/gitlab/tw/codeowners.rake b/lib/tasks/gitlab/tw/codeowners.rake index 3f11aefc74f..5b2d538f709 100644 --- a/lib/tasks/gitlab/tw/codeowners.rake +++ b/lib/tasks/gitlab/tw/codeowners.rake @@ -22,7 +22,7 @@ namespace :tw do CodeOwnerRule.new('Activation', '@phillipwells'), CodeOwnerRule.new('Acquisition', '@phillipwells'), CodeOwnerRule.new('Anti-Abuse', '@phillipwells'), - CodeOwnerRule.new('Authentication and Authorization', '@eread'), + CodeOwnerRule.new('Authentication and Authorization', '@jglassman1'), CodeOwnerRule.new('Certify', '@msedlakjakubowski'), CodeOwnerRule.new('Code Review', '@aqualls'), CodeOwnerRule.new('Compliance', '@eread'), diff --git a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb index 160af8cf3f0..8dee0490fd6 100644 --- a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb +++ b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb @@ -36,6 +36,14 @@ RSpec.describe Profiles::PersonalAccessTokensController do expect(created_token.expires_at).to eq(expires_at) end + it 'does not allow creation when personal access tokens are disabled' do + allow(::Gitlab::CurrentSettings).to receive_messages(personal_access_tokens_disabled?: true) + + post :create, params: { personal_access_token: token_attributes } + + expect(response).to have_gitlab_http_status(:not_found) + end + it_behaves_like "#create access token" do let(:url) { :create } end @@ -70,6 +78,14 @@ RSpec.describe Profiles::PersonalAccessTokensController do ) end + it 'returns 404 when personal access tokens are disabled' do + allow(::Gitlab::CurrentSettings).to receive_messages(personal_access_tokens_disabled?: true) + + get :index + + expect(response).to have_gitlab_http_status(:not_found) + end + context "access_token_pagination feature flag is enabled" do before do stub_feature_flags(access_token_pagination: true) diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index b2e86112d98..9e7666b920f 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -400,39 +400,19 @@ RSpec.describe 'Admin updates settings' do end context 'Runner Registration' do - context 'when feature is enabled' do - before do - stub_feature_flags(runner_registration_control: true) - end - - it 'allows admins to control who has access to register runners' do - visit ci_cd_admin_application_settings_path - - expect(current_settings.valid_runner_registrars).to eq(ApplicationSetting::VALID_RUNNER_REGISTRAR_TYPES) + it 'allows admins to control who has access to register runners' do + visit ci_cd_admin_application_settings_path - page.within('.as-runner') do - find_all('input[type="checkbox"]').each(&:click) + expect(current_settings.valid_runner_registrars).to eq(ApplicationSetting::VALID_RUNNER_REGISTRAR_TYPES) - click_button 'Save changes' - end - - expect(current_settings.valid_runner_registrars).to eq([]) - expect(page).to have_content "Application settings saved successfully" - end - end + page.within('.as-runner') do + find_all('input[type="checkbox"]').each(&:click) - context 'when feature is disabled' do - before do - stub_feature_flags(runner_registration_control: false) + click_button 'Save changes' end - it 'does not allow admins to control who has access to register runners' do - visit ci_cd_admin_application_settings_path - - expect(current_settings.valid_runner_registrars).to eq(ApplicationSetting::VALID_RUNNER_REGISTRAR_TYPES) - - expect(page).not_to have_css('.as-runner') - end + expect(current_settings.valid_runner_registrars).to eq([]) + expect(page).to have_content "Application settings saved successfully" end end diff --git a/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb index 31f596e7e70..fc3de2a14cd 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb @@ -44,6 +44,20 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::CancelPendingPipelines do expect(build_statuses(pipeline)).to contain_exactly('pending') end + it 'logs canceled pipelines' do + allow(Gitlab::AppLogger).to receive(:info) + + perform + + expect(Gitlab::AppLogger).to have_received(:info).with( + class: described_class.name, + message: "Pipeline #{pipeline.id} auto-canceling pipeline #{prev_pipeline.id}", + canceled_pipeline_id: prev_pipeline.id, + canceled_by_pipeline_id: pipeline.id, + canceled_by_pipeline_source: pipeline.source + ) + end + it 'cancels the builds with 2 queries to avoid query timeout' do second_query_regex = /WHERE "ci_pipelines"\."id" = \d+ AND \(NOT EXISTS/ recorder = ActiveRecord::QueryRecorder.new { perform } diff --git a/spec/lib/gitlab/database/migrations/base_background_runner_spec.rb b/spec/lib/gitlab/database/migrations/base_background_runner_spec.rb index 34c83c42056..c2dc260b2ff 100644 --- a/spec/lib/gitlab/database/migrations/base_background_runner_spec.rb +++ b/spec/lib/gitlab/database/migrations/base_background_runner_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe Gitlab::Database::Migrations::BaseBackgroundRunner, :freeze_time do + let(:connection) { ApplicationRecord.connection } + let(:result_dir) { Dir.mktmpdir } after do @@ -10,7 +12,7 @@ RSpec.describe Gitlab::Database::Migrations::BaseBackgroundRunner, :freeze_time end context 'subclassing' do - subject { described_class.new(result_dir: result_dir) } + subject { described_class.new(result_dir: result_dir, connection: connection) } it 'requires that jobs_by_migration_name be implemented' do expect { subject.jobs_by_migration_name }.to raise_error(NotImplementedError) diff --git a/spec/lib/gitlab/database/migrations/test_batched_background_runner_spec.rb b/spec/lib/gitlab/database/migrations/test_batched_background_runner_spec.rb index 3ac483c8ab7..07226f3d025 100644 --- a/spec/lib/gitlab/database/migrations/test_batched_background_runner_spec.rb +++ b/spec/lib/gitlab/database/migrations/test_batched_background_runner_spec.rb @@ -6,106 +6,156 @@ RSpec.describe Gitlab::Database::Migrations::TestBatchedBackgroundRunner, :freez include Gitlab::Database::MigrationHelpers include Database::MigrationTestingHelpers - let(:result_dir) { Dir.mktmpdir } - - after do - FileUtils.rm_rf(result_dir) + def queue_migration( + job_class_name, + batch_table_name, + batch_column_name, + *job_arguments, + job_interval:, + batch_size: Gitlab::Database::Migrations::BatchedBackgroundMigrationHelpers::BATCH_SIZE, + sub_batch_size: Gitlab::Database::Migrations::BatchedBackgroundMigrationHelpers::SUB_BATCH_SIZE + ) + + batch_max_value = define_batchable_model(batch_table_name, connection: connection).maximum(batch_column_name) + + Gitlab::Database::SharedModel.using_connection(connection) do + Gitlab::Database::BackgroundMigration::BatchedMigration.create!( + job_class_name: job_class_name, + table_name: batch_table_name, + column_name: batch_column_name, + job_arguments: job_arguments, + interval: job_interval, + min_value: Gitlab::Database::Migrations::BatchedBackgroundMigrationHelpers::BATCH_MIN_VALUE, + max_value: batch_max_value, + batch_class_name: Gitlab::Database::Migrations::BatchedBackgroundMigrationHelpers::BATCH_CLASS_NAME, + batch_size: batch_size, + sub_batch_size: sub_batch_size, + status_event: :execute, + max_batch_size: nil, + gitlab_schema: gitlab_schema + ) + end end - let(:migration) do - ActiveRecord::Migration.new.extend(Gitlab::Database::Migrations::BatchedBackgroundMigrationHelpers) + where(:case_name, :base_model, :gitlab_schema) do + [ + ['main database', ApplicationRecord, :gitlab_main], + ['ci database', Ci::ApplicationRecord, :gitlab_ci] + ] end - let(:connection) { ApplicationRecord.connection } + with_them do + let(:result_dir) { Dir.mktmpdir } - let(:table_name) { "_test_column_copying" } + after do + FileUtils.rm_rf(result_dir) + end - before do - connection.execute(<<~SQL) - CREATE TABLE #{table_name} ( - id bigint primary key not null, - data bigint default 0 - ); + let(:connection) { base_model.connection } - insert into #{table_name} (id) select i from generate_series(1, 1000) g(i); - SQL + let(:table_name) { "_test_column_copying" } - allow(migration).to receive(:transaction_open?).and_return(false) - end + before do + connection.execute(<<~SQL) + CREATE TABLE #{table_name} ( + id bigint primary key not null, + data bigint default 0 + ); - context 'running a real background migration' do - it 'runs sampled jobs from the batched background migration' do - migration.queue_batched_background_migration('CopyColumnUsingBackgroundMigrationJob', - table_name, :id, - :id, :data, - batch_size: 100, - job_interval: 5.minutes) # job_interval is skipped when testing - - # Expect that running sampling for this migration processes some of the rows. Sampling doesn't run - # over every row in the table, so this does not completely migrate the table. - expect { described_class.new(result_dir: result_dir, connection: connection).run_jobs(for_duration: 1.minute) } - .to change { define_batchable_model(table_name).where('id IS DISTINCT FROM data').count } - .by_at_most(-1) + insert into #{table_name} (id) select i from generate_series(1, 1000) g(i); + SQL end - end - context 'with jobs to run' do - let(:migration_name) { 'TestBackgroundMigration' } + context 'running a real background migration' do + before do + queue_migration('CopyColumnUsingBackgroundMigrationJob', + table_name, :id, + :id, :data, + batch_size: 100, + job_interval: 5.minutes) # job_interval is skipped when testing + end - it 'samples jobs' do - calls = [] - define_background_migration(migration_name) do |*args| - calls << args + subject(:sample_migration) do + described_class.new(result_dir: result_dir, connection: connection).run_jobs(for_duration: 1.minute) end - migration.queue_batched_background_migration(migration_name, table_name, :id, - job_interval: 5.minutes, - batch_size: 100) + it 'runs sampled jobs from the batched background migration' do + # Expect that running sampling for this migration processes some of the rows. Sampling doesn't run + # over every row in the table, so this does not completely migrate the table. + expect { subject }.to change { + define_batchable_model(table_name, connection: connection) + .where('id IS DISTINCT FROM data').count + }.by_at_most(-1) + end - described_class.new(result_dir: result_dir, connection: connection).run_jobs(for_duration: 3.minutes) + it 'uses the correct connection to instrument the background migration' do + expect_next_instance_of(Gitlab::Database::Migrations::Instrumentation) do |instrumentation| + expect(instrumentation).to receive(:observe).with(hash_including(connection: connection)) + .at_least(:once).and_call_original + end - expect(calls).not_to be_empty + subject + end end - context 'with multiple jobs to run' do - it 'runs all jobs created within the last 3 hours' do - old_migration = define_background_migration(migration_name) - migration.queue_batched_background_migration(migration_name, table_name, :id, - job_interval: 5.minutes, - batch_size: 100) - - travel 4.hours - - new_migration = define_background_migration('NewMigration') { travel 1.second } - migration.queue_batched_background_migration('NewMigration', table_name, :id, - job_interval: 5.minutes, - batch_size: 10, - sub_batch_size: 5) - - other_new_migration = define_background_migration('NewMigration2') { travel 2.seconds } - migration.queue_batched_background_migration('NewMigration2', table_name, :id, - job_interval: 5.minutes, - batch_size: 10, - sub_batch_size: 5) - - expect_migration_runs(new_migration => 3, other_new_migration => 2, old_migration => 0) do - described_class.new(result_dir: result_dir, connection: connection).run_jobs(for_duration: 5.seconds) + context 'with jobs to run' do + let(:migration_name) { 'TestBackgroundMigration' } + + it 'samples jobs' do + calls = [] + define_background_migration(migration_name) do |*args| + calls << args + end + + queue_migration(migration_name, table_name, :id, + job_interval: 5.minutes, + batch_size: 100) + + described_class.new(result_dir: result_dir, connection: connection).run_jobs(for_duration: 3.minutes) + + expect(calls).not_to be_empty + end + + context 'with multiple jobs to run' do + it 'runs all jobs created within the last 3 hours' do + old_migration = define_background_migration(migration_name) + queue_migration(migration_name, table_name, :id, + job_interval: 5.minutes, + batch_size: 100) + + travel 4.hours + + new_migration = define_background_migration('NewMigration') { travel 1.second } + queue_migration('NewMigration', table_name, :id, + job_interval: 5.minutes, + batch_size: 10, + sub_batch_size: 5) + + other_new_migration = define_background_migration('NewMigration2') { travel 2.seconds } + queue_migration('NewMigration2', table_name, :id, + job_interval: 5.minutes, + batch_size: 10, + sub_batch_size: 5) + + expect_migration_runs(new_migration => 3, other_new_migration => 2, old_migration => 0) do + described_class.new(result_dir: result_dir, connection: connection).run_jobs(for_duration: 5.seconds) + end end end end - end - context 'choosing uniform batches to run' do - subject { described_class.new(result_dir: result_dir, connection: connection) } + context 'choosing uniform batches to run' do + subject { described_class.new(result_dir: result_dir, connection: connection) } - describe '#uniform_fractions' do - it 'generates evenly distributed sequences of fractions' do - received = subject.uniform_fractions.take(9) - expected = [0, 1, 1.0 / 2, 1.0 / 4, 3.0 / 4, 1.0 / 8, 3.0 / 8, 5.0 / 8, 7.0 / 8] + describe '#uniform_fractions' do + it 'generates evenly distributed sequences of fractions' do + received = subject.uniform_fractions.take(9) + expected = [0, 1, 1.0 / 2, 1.0 / 4, 3.0 / 4, 1.0 / 8, 3.0 / 8, 5.0 / 8, 7.0 / 8] - # All the fraction numerators are small integers, and all denominators are powers of 2, so these - # fit perfectly into floating point numbers with zero loss of precision - expect(received).to eq(expected) + # All the fraction numerators are small integers, and all denominators are powers of 2, so these + # fit perfectly into floating point numbers with zero loss of precision + expect(received).to eq(expected) + end end end end diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb index 3e1812aac9d..a5806910b23 100644 --- a/spec/models/environment_spec.rb +++ b/spec/models/environment_spec.rb @@ -1617,44 +1617,30 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do nil | nil 'never' | nil end - with_them do - it 'sets correct auto_stop_in' do - freeze_time do - if expected_result.is_a?(Integer) || expected_result.nil? - subject - expect(environment.auto_stop_in).to eq(expected_result) - else - expect(Gitlab::ErrorTracking).to receive(:track_exception).with( - an_instance_of(expected_result), - project_id: environment.project_id, - environment_id: environment.id - ) + with_them do + shared_examples 'for given values expected result is set' do + it do + freeze_time do + if expected_result.is_a?(Integer) || expected_result.nil? + subject - expect { subject }.to raise_error(expected_result) + expect(environment.auto_stop_in).to eq(expected_result) + else + expect { subject }.to raise_error(expected_result) + end end end end - end - context 'resets earlier value' do - let(:environment) { create(:environment, auto_stop_at: 1.day.since.round) } - - where(:value, :expected_result) do - '2 days' | 2.days.to_i - '1 week' | 1.week.to_i - '2h20min' | 2.hours.to_i + 20.minutes.to_i - '' | nil - 'never' | nil + context 'new assignment sets correct auto_stop_in' do + include_examples 'for given values expected result is set' end - with_them do - it 'assigns new value' do - freeze_time do - subject - expect(environment.auto_stop_in).to eq(expected_result) - end - end + context 'resets older value' do + let(:environment) { create(:environment, auto_stop_at: 1.day.since.round) } + + include_examples 'for given values expected result is set' end end end diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb index 5f8e582b1aa..184f7d676ba 100644 --- a/spec/policies/group_policy_spec.rb +++ b/spec/policies/group_policy_spec.rb @@ -1175,28 +1175,14 @@ RSpec.describe GroupPolicy do let(:current_user) { admin } context 'when admin mode is enabled', :enable_admin_mode do - context 'with runner_registration_control FF disabled' do - before do - stub_feature_flags(runner_registration_control: false) - end - - it { is_expected.to be_allowed(:register_group_runners) } - end + it { is_expected.to be_allowed(:register_group_runners) } - context 'with runner_registration_control FF enabled' do + context 'with group runner registration disabled' do before do - stub_feature_flags(runner_registration_control: true) + stub_application_setting(valid_runner_registrars: ['project']) end it { is_expected.to be_allowed(:register_group_runners) } - - context 'with group runner registration disabled' do - before do - stub_application_setting(valid_runner_registrars: ['project']) - end - - it { is_expected.to be_allowed(:register_group_runners) } - end end end @@ -1210,28 +1196,12 @@ RSpec.describe GroupPolicy do it { is_expected.to be_allowed(:register_group_runners) } - context 'with runner_registration_control FF disabled' do - before do - stub_feature_flags(runner_registration_control: false) - end - - it { is_expected.to be_allowed(:register_group_runners) } - end - - context 'with runner_registration_control FF enabled' do + context 'with group runner registration disabled' do before do - stub_feature_flags(runner_registration_control: true) + stub_application_setting(valid_runner_registrars: ['project']) end - it { is_expected.to be_allowed(:register_group_runners) } - - context 'with group runner registration disabled' do - before do - stub_application_setting(valid_runner_registrars: ['project']) - end - - it { is_expected.to be_disallowed(:register_group_runners) } - end + it { is_expected.to be_disallowed(:register_group_runners) } end end diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb index 49709d47645..a7662634793 100644 --- a/spec/policies/project_policy_spec.rb +++ b/spec/policies/project_policy_spec.rb @@ -2630,28 +2630,14 @@ RSpec.describe ProjectPolicy do let(:current_user) { admin } context 'when admin mode is enabled', :enable_admin_mode do - context 'with runner_registration_control FF disabled' do - before do - stub_feature_flags(runner_registration_control: false) - end - - it { is_expected.to be_allowed(:register_project_runners) } - end + it { is_expected.to be_allowed(:register_project_runners) } - context 'with runner_registration_control FF enabled' do + context 'with project runner registration disabled' do before do - stub_feature_flags(runner_registration_control: true) + stub_application_setting(valid_runner_registrars: ['group']) end it { is_expected.to be_allowed(:register_project_runners) } - - context 'with project runner registration disabled' do - before do - stub_application_setting(valid_runner_registrars: ['group']) - end - - it { is_expected.to be_allowed(:register_project_runners) } - end end end @@ -2665,28 +2651,12 @@ RSpec.describe ProjectPolicy do it { is_expected.to be_allowed(:register_project_runners) } - context 'with runner_registration_control FF disabled' do - before do - stub_feature_flags(runner_registration_control: false) - end - - it { is_expected.to be_allowed(:register_project_runners) } - end - - context 'with runner_registration_control FF enabled' do + context 'with project runner registration disabled' do before do - stub_feature_flags(runner_registration_control: true) + stub_application_setting(valid_runner_registrars: ['group']) end - it { is_expected.to be_allowed(:register_project_runners) } - - context 'with project runner registration disabled' do - before do - stub_application_setting(valid_runner_registrars: ['group']) - end - - it { is_expected.to be_disallowed(:register_project_runners) } - end + it { is_expected.to be_disallowed(:register_project_runners) } end end diff --git a/spec/requests/admin/impersonation_tokens_controller_spec.rb b/spec/requests/admin/impersonation_tokens_controller_spec.rb index 2017a512bce..ee0e12ad0c0 100644 --- a/spec/requests/admin/impersonation_tokens_controller_spec.rb +++ b/spec/requests/admin/impersonation_tokens_controller_spec.rb @@ -10,6 +10,18 @@ RSpec.describe Admin::ImpersonationTokensController, :enable_admin_mode do sign_in(admin) end + context 'when impersonation is enabled' do + before do + stub_config_setting(impersonation_enabled: true) + end + + it 'responds ok' do + get admin_user_impersonation_tokens_path(user_id: user.username) + + expect(response).to have_gitlab_http_status(:ok) + end + end + context "when impersonation is disabled" do before do stub_config_setting(impersonation_enabled: false) diff --git a/spec/requests/api/ci/runner/runners_reset_spec.rb b/spec/requests/api/ci/runner/runners_reset_spec.rb index 8a61012ead1..02b66a89a0a 100644 --- a/spec/requests/api/ci/runner/runners_reset_spec.rb +++ b/spec/requests/api/ci/runner/runners_reset_spec.rb @@ -9,7 +9,6 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do before do stub_feature_flags(ci_enable_live_trace: true) - stub_feature_flags(runner_registration_control: false) stub_gitlab_calls stub_application_setting(valid_runner_registrars: ApplicationSetting::VALID_RUNNER_REGISTRAR_TYPES) end diff --git a/spec/services/ci/runners/register_runner_service_spec.rb b/spec/services/ci/runners/register_runner_service_spec.rb index 6d7b39de21e..2d1b109072f 100644 --- a/spec/services/ci/runners/register_runner_service_spec.rb +++ b/spec/services/ci/runners/register_runner_service_spec.rb @@ -9,7 +9,6 @@ RSpec.describe ::Ci::Runners::RegisterRunnerService, '#execute' do let(:runner) { execute.payload[:runner] } before do - stub_feature_flags(runner_registration_control: false) stub_application_setting(runners_registration_token: registration_token) stub_application_setting(valid_runner_registrars: ApplicationSetting::VALID_RUNNER_REGISTRAR_TYPES) end @@ -166,25 +165,9 @@ RSpec.describe ::Ci::Runners::RegisterRunnerService, '#execute' do stub_application_setting(valid_runner_registrars: ['group']) end - context 'when feature flag is enabled' do - before do - stub_feature_flags(runner_registration_control: true) - end - - it 'returns 403 error' do - expect(execute).to be_error - expect(execute.http_status).to eq :forbidden - end - end - - context 'when feature flag is disabled' do - it 'registers the runner' do - expect(execute).to be_success - - expect(runner).to be_an_instance_of(::Ci::Runner) - expect(runner.errors).to be_empty - expect(runner.active).to be true - end + it 'returns 403 error' do + expect(execute).to be_error + expect(execute.http_status).to eq :forbidden end end end @@ -244,24 +227,8 @@ RSpec.describe ::Ci::Runners::RegisterRunnerService, '#execute' do stub_application_setting(valid_runner_registrars: ['project']) end - context 'when feature flag is enabled' do - before do - stub_feature_flags(runner_registration_control: true) - end - - it 'returns error response' do - is_expected.to be_error - end - end - - context 'when feature flag is disabled' do - it 'registers the runner' do - expect(execute).to be_success - - expect(runner).to be_an_instance_of(::Ci::Runner) - expect(runner.errors).to be_empty - expect(runner.active).to be true - end + it 'returns error response' do + is_expected.to be_error end end end diff --git a/spec/services/users/destroy_service_spec.rb b/spec/services/users/destroy_service_spec.rb index c8ea7f704e2..efaac06c1f2 100644 --- a/spec/services/users/destroy_service_spec.rb +++ b/spec/services/users/destroy_service_spec.rb @@ -408,9 +408,10 @@ RSpec.describe Users::DestroyService do expect(resource_label_event.user).to be_nil end - it 'nullifies assigned_merge_requests, last_updated_merge_requests' do + it 'nullifies merge request associations' do merge_request = create(:merge_request, source_project: project, target_project: project, assignee: other_user, updated_by: other_user, merge_user: other_user) + merge_request.metrics.update!(merged_by: other_user, latest_closed_by: other_user) described_class.new(user).execute(other_user, skip_authorization: true) @@ -420,6 +421,8 @@ RSpec.describe Users::DestroyService do expect(merge_request.updated_by).to be_nil expect(merge_request.assignee).to be_nil expect(merge_request.assignee_id).to be_nil + expect(merge_request.metrics.merged_by).to be_nil + expect(merge_request.metrics.latest_closed_by).to be_nil end end end diff --git a/spec/views/admin/application_settings/ci_cd.html.haml_spec.rb b/spec/views/admin/application_settings/ci_cd.html.haml_spec.rb index 4d40bf5671e..e4ebdd706d4 100644 --- a/spec/views/admin/application_settings/ci_cd.html.haml_spec.rb +++ b/spec/views/admin/application_settings/ci_cd.html.haml_spec.rb @@ -15,42 +15,17 @@ RSpec.describe 'admin/application_settings/ci_cd.html.haml' do end describe 'CI CD Runner Registration' do - context 'when feature flag is enabled' do - before do - stub_feature_flags(runner_registration_control: true) - end + it 'has the setting section' do + render - it 'has the setting section' do - render - - expect(rendered).to have_css("#js-runner-settings") - end - - it 'renders the correct setting section content' do - render - - expect(rendered).to have_content("Runner registration") - expect(rendered).to have_content("If no options are selected, only administrators can register runners.") - end + expect(rendered).to have_css("#js-runner-settings") end - context 'when feature flag is disabled' do - before do - stub_feature_flags(runner_registration_control: false) - end - - it 'does not have the setting section' do - render - - expect(rendered).not_to have_css("#js-runner-settings") - end - - it 'does not render the correct setting section content' do - render + it 'renders the correct setting section content' do + render - expect(rendered).not_to have_content("Runner registration") - expect(rendered).not_to have_content("If no options are selected, only administrators can register runners.") - end + expect(rendered).to have_content("Runner registration") + expect(rendered).to have_content("If no options are selected, only administrators can register runners.") end end end diff --git a/spec/views/layouts/nav/sidebar/_profile.html.haml_spec.rb b/spec/views/layouts/nav/sidebar/_profile.html.haml_spec.rb index 3d28be68b25..f5a0a7a935c 100644 --- a/spec/views/layouts/nav/sidebar/_profile.html.haml_spec.rb +++ b/spec/views/layouts/nav/sidebar/_profile.html.haml_spec.rb @@ -11,4 +11,20 @@ RSpec.describe 'layouts/nav/sidebar/_profile' do it_behaves_like 'has nav sidebar' it_behaves_like 'sidebar includes snowplow attributes', 'render', 'user_side_navigation', 'user_side_navigation' + + it 'has a link to access tokens' do + render + + expect(rendered).to have_link(_('Access Tokens'), href: profile_personal_access_tokens_path) + end + + context 'when personal access tokens are disabled' do + it 'does not have a link to access tokens' do + allow(::Gitlab::CurrentSettings).to receive_messages(personal_access_tokens_disabled?: true) + + render + + expect(rendered).not_to have_link(_('Access Tokens'), href: profile_personal_access_tokens_path) + end + end end diff --git a/tooling/graphql/docs/helper.rb b/tooling/graphql/docs/helper.rb index 3ac669855f0..f25e69a1e2f 100644 --- a/tooling/graphql/docs/helper.rb +++ b/tooling/graphql/docs/helper.rb @@ -55,7 +55,7 @@ module Tooling def auto_generated_comment <<-MD.strip_heredoc --- - stage: Ecosystem + stage: Manage group: Integrations info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments --- |