diff --git a/.rubocop_todo/rails/active_record_callbacks_order.yml b/.rubocop_todo/rails/active_record_callbacks_order.yml
deleted file mode 100644
index 044bda81d22..00000000000
--- a/.rubocop_todo/rails/active_record_callbacks_order.yml
+++ /dev/null
@@ -1,22 +0,0 @@
----
-# Cop supports --autocorrect.
-Rails/ActiveRecordCallbacksOrder:
- Exclude:
- - 'app/models/award_emoji.rb'
- - 'app/models/gpg_key.rb'
- - 'app/models/group.rb'
- - 'app/models/issue.rb'
- - 'app/models/key.rb'
- - 'app/models/merge_request.rb'
- - 'app/models/namespace.rb'
- - 'app/models/namespace_statistics.rb'
- - 'app/models/note.rb'
- - 'app/models/pages_domain.rb'
- - 'app/models/prometheus_alert.rb'
- - 'app/models/remote_mirror.rb'
- - 'app/models/resource_label_event.rb'
- - 'app/models/snippet_statistics.rb'
- - 'app/models/upload.rb'
- - 'app/models/user.rb'
- - 'ee/app/models/dast_site_profile.rb'
- - 'ee/app/models/geo_node.rb'
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 034cce40162..3ee269cd5e3 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-52fb0853a49b14abddfc5a824d680bd255773d39
+06b92cf488942c6746795b581d27854339becc60
diff --git a/app/assets/javascripts/editor/schema/ci.json b/app/assets/javascripts/editor/schema/ci.json
index 3b40970e62d..d94aa73e43a 100644
--- a/app/assets/javascripts/editor/schema/ci.json
+++ b/app/assets/javascripts/editor/schema/ci.json
@@ -336,10 +336,10 @@
"include_item": {
"oneOf": [
{
- "description": "Will infer the method based on the value. E.g. `https://...` strings will be of type `include:remote`, and `/templates/...` will be of type `include:local`.",
+ "description": "Will infer the method based on the value. E.g. `https://...` strings will be of type `include:remote`, and `/templates/...` or `templates/...` will be of type `include:local`.",
"type": "string",
"format": "uri-reference",
- "pattern": "^(https?://|/).+\\.ya?ml$"
+ "pattern": "^(https?://|/?.?-?(?!\\w+://)\\w).+\\.ya?ml$"
},
{
"type": "object",
diff --git a/app/graphql/types/ci/runner_type.rb b/app/graphql/types/ci/runner_type.rb
index 6d136e9861c..de7329ee661 100644
--- a/app/graphql/types/ci/runner_type.rb
+++ b/app/graphql/types/ci/runner_type.rb
@@ -106,8 +106,25 @@ module Types
end
def job_count
- # We limit to 1 above the JOB_COUNT_LIMIT to indicate that more items exist after JOB_COUNT_LIMIT
- runner.builds.limit(JOB_COUNT_LIMIT + 1).count
+ BatchLoader::GraphQL.for(runner.id).batch(key: :job_count) do |runner_ids, loader, _args|
+ # rubocop: disable CodeReuse/ActiveRecord
+ # We limit to 1 above the JOB_COUNT_LIMIT to indicate that more items exist after JOB_COUNT_LIMIT
+ builds_tbl = ::Ci::Build.arel_table
+ runners_tbl = ::Ci::Runner.arel_table
+ lateral_query = ::Ci::Build.select(1)
+ .where(builds_tbl['runner_id'].eq(runners_tbl['id']))
+ .limit(JOB_COUNT_LIMIT)
+ counts = ::Ci::Runner.joins("JOIN LATERAL (#{lateral_query.to_sql}) builds_with_limit ON true")
+ .id_in(runner_ids)
+ .select(:id, Arel.star.count.as('count'))
+ .group(:id)
+ .index_by(&:id)
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ runner_ids.each do |runner_id|
+ loader.call(runner_id, counts[runner_id]&.count || 0)
+ end
+ end
end
def admin_url
diff --git a/app/models/award_emoji.rb b/app/models/award_emoji.rb
index 9d758cf75d8..f41f0a8be84 100644
--- a/app/models/award_emoji.rb
+++ b/app/models/award_emoji.rb
@@ -26,8 +26,8 @@ class AwardEmoji < ApplicationRecord
scope :named, ->(names) { where(name: names) }
scope :awarded_by, ->(users) { where(user: users) }
- after_save :expire_cache
after_destroy :expire_cache
+ after_save :expire_cache
class << self
def votes_for_collection(ids, type)
diff --git a/app/models/gpg_key.rb b/app/models/gpg_key.rb
index 2db074e733e..1bf35179393 100644
--- a/app/models/gpg_key.rb
+++ b/app/models/gpg_key.rb
@@ -40,8 +40,8 @@ class GpgKey < ApplicationRecord
unless: -> { errors.has_key?(:key) }
before_validation :extract_fingerprint, :extract_primary_keyid
- after_commit :update_invalid_gpg_signatures, on: :create
after_create :generate_subkeys
+ after_commit :update_invalid_gpg_signatures, on: :create
def primary_keyid
super&.upcase
diff --git a/app/models/group.rb b/app/models/group.rb
index afc31e38e81..0cdd7dd8596 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -155,10 +155,10 @@ class Group < Namespace
prefix: RunnersTokenPrefixable::RUNNERS_TOKEN_PREFIX
after_create :post_create_hook
+ after_create -> { create_or_load_association(:group_feature) }
+ after_update :path_changed_hook, if: :saved_change_to_path?
after_destroy :post_destroy_hook
after_commit :update_two_factor_requirement
- after_update :path_changed_hook, if: :saved_change_to_path?
- after_create -> { create_or_load_association(:group_feature) }
scope :with_users, -> { includes(:users) }
diff --git a/app/models/issue.rb b/app/models/issue.rb
index d1fe11cb49e..b338ecfce88 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -216,8 +216,8 @@ class Issue < ApplicationRecord
before_validation :ensure_namespace_id, :ensure_work_item_type
- after_commit :expire_etag_cache, unless: :importing?
after_save :ensure_metrics, unless: :importing?
+ after_commit :expire_etag_cache, unless: :importing?
after_create_commit :record_create_action, unless: :importing?
attr_spammable :title, spam_title: true
diff --git a/app/models/key.rb b/app/models/key.rb
index 35fc42a935f..1f2234129ed 100644
--- a/app/models/key.rb
+++ b/app/models/key.rb
@@ -38,12 +38,12 @@ class Key < ApplicationRecord
signing: 2
}
- after_commit :add_to_authorized_keys, on: :create
after_create :post_create_hook
after_create :refresh_user_cache
- after_commit :remove_from_authorized_keys, on: :destroy
after_destroy :post_destroy_hook
after_destroy :refresh_user_cache
+ after_commit :add_to_authorized_keys, on: :create
+ after_commit :remove_from_authorized_keys, on: :destroy
alias_attribute :fingerprint_md5, :fingerprint
alias_attribute :name, :title
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index de708a8c03d..78c6d983a3d 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -140,6 +140,7 @@ class MergeRequest < ApplicationRecord
after_create :ensure_merge_request_diff, unless: :skip_ensure_merge_request_diff
after_update :clear_memoized_shas
after_update :reload_diff_if_branch_changed
+ after_save :keep_around_commit, unless: :importing?
after_commit :ensure_metrics, on: [:create, :update], unless: :importing?
after_commit :expire_etag_cache, unless: :importing?
@@ -441,8 +442,6 @@ class MergeRequest < ApplicationRecord
.pick(MergeRequest::Metrics.time_to_merge_expression)
end
- after_save :keep_around_commit, unless: :importing?
-
alias_attribute :project, :target_project
alias_attribute :project_id, :target_project_id
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 54cd97253cf..d7d53956656 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -139,21 +139,21 @@ class Namespace < ApplicationRecord
:npm_package_requests_forwarding,
to: :package_settings
- after_save :reload_namespace_details
-
- after_commit :refresh_access_of_projects_invited_groups, on: :update, if: -> { previous_changes.key?('share_with_group_lock') }
-
before_create :sync_share_with_group_lock_with_parent
before_update :sync_share_with_group_lock_with_parent, if: :parent_changed?
after_update :force_share_with_group_lock_on_descendants, if: -> { saved_change_to_share_with_group_lock? && share_with_group_lock? }
after_update :expire_first_auto_devops_config_cache, if: -> { saved_change_to_auto_devops_enabled? }
+ after_update :move_dir, if: :saved_change_to_path_or_parent?, unless: -> { is_a?(Namespaces::ProjectNamespace) }
+ after_destroy :rm_dir
+ after_save :reload_namespace_details
+
+ after_commit :refresh_access_of_projects_invited_groups, on: :update, if: -> { previous_changes.key?('share_with_group_lock') }
+
after_sync_traversal_ids :schedule_sync_event_worker # custom callback defined in Namespaces::Traversal::Linear
# Legacy Storage specific hooks
- after_update :move_dir, if: :saved_change_to_path_or_parent?, unless: -> { is_a?(Namespaces::ProjectNamespace) }
before_destroy(prepend: true) { prepare_for_destroy }
- after_destroy :rm_dir
after_commit :expire_child_caches, on: :update, if: -> {
Feature.enabled?(:cached_route_lookups, self, type: :ops) &&
saved_change_to_name? || saved_change_to_path? || saved_change_to_parent_id?
diff --git a/app/models/namespace_statistics.rb b/app/models/namespace_statistics.rb
index 04ca05d85ff..a17ca2e2c1d 100644
--- a/app/models/namespace_statistics.rb
+++ b/app/models/namespace_statistics.rb
@@ -10,8 +10,8 @@ class NamespaceStatistics < ApplicationRecord # rubocop:disable Gitlab/Namespace
scope :for_namespaces, -> (namespaces) { where(namespace: namespaces) }
before_save :update_storage_size
- after_save :update_root_storage_statistics, if: :saved_change_to_storage_size?
after_destroy :update_root_storage_statistics
+ after_save :update_root_storage_statistics, if: :saved_change_to_storage_size?
delegate :group_namespace?, to: :namespace
diff --git a/app/models/note.rb b/app/models/note.rb
index 8e1f4979602..052df6142c5 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -168,10 +168,10 @@ class Note < ApplicationRecord
# Syncs `confidential` with `internal` as we rename the column.
# https://gitlab.com/gitlab-org/gitlab/-/issues/367923
before_create :set_internal_flag
+ after_destroy :expire_etag_cache
after_save :keep_around_commit, if: :for_project_noteable?, unless: -> { importing? || skip_keep_around_commits }
after_save :expire_etag_cache, unless: :importing?
after_save :touch_noteable, unless: :importing?
- after_destroy :expire_etag_cache
after_commit :notify_after_create, on: :create
after_commit :notify_after_destroy, on: :destroy
diff --git a/app/models/pages_domain.rb b/app/models/pages_domain.rb
index 328c67a0711..4e3f4b0c328 100644
--- a/app/models/pages_domain.rb
+++ b/app/models/pages_domain.rb
@@ -17,6 +17,7 @@ class PagesDomain < ApplicationRecord
has_many :acme_orders, class_name: "PagesDomainAcmeOrder"
has_many :serverless_domain_clusters, class_name: 'Serverless::DomainCluster', inverse_of: :pages_domain
+ after_initialize :set_verification_code
before_validation :clear_auto_ssl_failure, unless: :auto_ssl_enabled
validates :domain, hostname: { allow_numeric_hostname: true }
@@ -44,8 +45,6 @@ class PagesDomain < ApplicationRecord
key: Settings.attr_encrypted_db_key_base,
algorithm: 'aes-256-cbc'
- after_initialize :set_verification_code
-
scope :for_project, ->(project) { where(project: project) }
scope :enabled, -> { where('enabled_until >= ?', Time.current) }
diff --git a/app/models/prometheus_alert.rb b/app/models/prometheus_alert.rb
index 9080f3d9de1..59440947d71 100644
--- a/app/models/prometheus_alert.rb
+++ b/app/models/prometheus_alert.rb
@@ -20,8 +20,8 @@ class PrometheusAlert < ApplicationRecord
has_many :related_issues, through: :prometheus_alert_events
has_many :alert_management_alerts, class_name: 'AlertManagement::Alert', inverse_of: :prometheus_alert
- after_save :clear_prometheus_adapter_cache!
after_destroy :clear_prometheus_adapter_cache!
+ after_save :clear_prometheus_adapter_cache!
validates :environment, :project, :prometheus_metric, :threshold, :operator, presence: true
validates :runbook_url, length: { maximum: 255 }, allow_blank: true,
diff --git a/app/models/remote_mirror.rb b/app/models/remote_mirror.rb
index 45487cb908d..b830cf313af 100644
--- a/app/models/remote_mirror.rb
+++ b/app/models/remote_mirror.rb
@@ -22,10 +22,9 @@ class RemoteMirror < ApplicationRecord
validates :url, presence: true, public_url: { schemes: Project::VALID_MIRROR_PROTOCOLS, allow_blank: true, enforce_user: true }
- after_save :set_override_remote_mirror_available, unless: -> { Gitlab::CurrentSettings.current_application_settings.mirror_available }
- after_update :reset_fields, if: :saved_change_to_mirror_url?
-
before_validation :store_credentials
+ after_update :reset_fields, if: :saved_change_to_mirror_url?
+ after_save :set_override_remote_mirror_available, unless: -> { Gitlab::CurrentSettings.current_application_settings.mirror_available }
scope :enabled, -> { where(enabled: true) }
scope :started, -> { with_update_status(:started) }
diff --git a/app/models/resource_label_event.rb b/app/models/resource_label_event.rb
index a1753df9294..a1426540cf5 100644
--- a/app/models/resource_label_event.rb
+++ b/app/models/resource_label_event.rb
@@ -14,8 +14,8 @@ class ResourceLabelEvent < ResourceEvent
validates :label, presence: { unless: :importing? }, on: :create
validate :exactly_one_issuable, unless: :importing?
- after_save :expire_etag_cache
after_destroy :expire_etag_cache
+ after_save :expire_etag_cache
enum action: {
add: 1,
diff --git a/app/models/snippet_statistics.rb b/app/models/snippet_statistics.rb
index 6fb6f0ef713..44bff0e1e5b 100644
--- a/app/models/snippet_statistics.rb
+++ b/app/models/snippet_statistics.rb
@@ -12,8 +12,8 @@ class SnippetStatistics < ApplicationRecord
delegate :repository, :project, :project_id, to: :snippet
- after_save :update_author_root_storage_statistics, if: :update_author_root_storage_statistics?
after_destroy :update_author_root_storage_statistics, unless: :project_snippet?
+ after_save :update_author_root_storage_statistics, if: :update_author_root_storage_statistics?
def update_commit_count
self.commit_count = repository.commit_count
diff --git a/app/models/upload.rb b/app/models/upload.rb
index ac7ebb31abc..a4fbc703146 100644
--- a/app/models/upload.rb
+++ b/app/models/upload.rb
@@ -16,14 +16,13 @@ class Upload < ApplicationRecord
scope :with_files_stored_locally, -> { where(store: ObjectStorage::Store::LOCAL) }
scope :with_files_stored_remotely, -> { where(store: ObjectStorage::Store::REMOTE) }
- before_save :calculate_checksum!, if: :foreground_checksummable?
- after_commit :schedule_checksum, if: :needs_checksum?
-
- after_commit :update_project_statistics, on: [:create, :destroy], if: :project?
-
+ before_save :calculate_checksum!, if: :foreground_checksummable?
# as the FileUploader is not mounted, the default CarrierWave ActiveRecord
# hooks are not executed and the file will not be deleted
after_destroy :delete_file!, if: -> { uploader_class <= FileUploader }
+ after_commit :schedule_checksum, if: :needs_checksum?
+
+ after_commit :update_project_statistics, on: [:create, :destroy], if: :project?
class << self
def inner_join_local_uploads_projects
diff --git a/app/models/user.rb b/app/models/user.rb
index fb742e7c11f..d50605b4aa3 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -300,16 +300,17 @@ class User < ApplicationRecord
validates :website_url, allow_blank: true, url: true, if: :website_url_changed?
+ after_initialize :set_projects_limit
before_validation :sanitize_attrs
+ before_validation :ensure_namespace_correct
+ after_validation :set_username_errors
before_save :default_private_profile_to_false
before_save :ensure_incoming_email_token
before_save :ensure_user_rights_and_limits, if: ->(user) { user.new_record? || user.external_changed? }
before_save :skip_reconfirmation!, if: ->(user) { user.email_changed? && user.read_only_attribute?(:email) }
before_save :check_for_verified_email, if: ->(user) { user.email_changed? && !user.new_record? }
- before_validation :ensure_namespace_correct
before_save :ensure_namespace_correct # in case validation is skipped
before_save :ensure_user_detail_assigned
- after_validation :set_username_errors
after_update :username_changed_hook, if: :saved_change_to_username?
after_destroy :post_destroy_hook
after_destroy :remove_key_cache
@@ -330,8 +331,6 @@ class User < ApplicationRecord
update_invalid_gpg_signatures if previous_changes.key?('email')
end
- after_initialize :set_projects_limit
-
# User's Layout preference
enum layout: { fixed: 0, fluid: 1 }
diff --git a/data/deprecations/15-7-deprecate-dast-api-scan-in-dast-template.yml b/data/deprecations/15-7-deprecate-dast-api-scan-in-dast-template.yml
new file mode 100644
index 00000000000..172683dcb86
--- /dev/null
+++ b/data/deprecations/15-7-deprecate-dast-api-scan-in-dast-template.yml
@@ -0,0 +1,11 @@
+- title: "DAST API scans using DAST template is deprecated" # (required) Actionable title. e.g., The `confidential` field for a `Note` is deprecated. Use `internal` instead.
+ announcement_milestone: "15.7" # (required) The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-12-22" # (required) The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "16.0" # (required) The milestone when this feature is planned to be removed
+ removal_date: "2023-05-22" # (required) The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ breaking_change: true # (required) If this deprecation is a breaking change, set this value to true
+ reporter: derekferguson # (required) GitLab username of the person reporting the deprecation
+ stage: Secure # (required) String value of the stage that the feature was created in. e.g., Growth
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/384198 # (required) Link to the deprecation issue in GitLab
+ body: | # (required) Do not modify this line, instead modify the lines below.
+ With the move to the new DAST API analyzer and the `DAST-API.gitlab-ci.yml` template for DAST API scans, we will be removing the ability to scan APIs with the DAST analyzer. Use of the `DAST.gitlab-ci.yml` or `DAST-latest.gitlab-ci.yml` templates for API scans is deprecated as of GitLab 15.7 and will no longer work in GitLab 16.0. Please use `DAST-API.gitlab-ci.yml` template and refer to the [DAST API analyzer](https://docs.gitlab.com/ee/user/application_security/dast_api/#configure-dast-api-with-an-openapi-specification) documentation for configuration details.
diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md
index 7965e18e005..9e580d93609 100644
--- a/doc/update/deprecations.md
+++ b/doc/update/deprecations.md
@@ -52,6 +52,20 @@ sole discretion of GitLab Inc.
+### DAST API scans using DAST template is deprecated
+
+Planned removal: GitLab 16.0 (2023-05-22)
+
+WARNING:
+This is a [breaking change](https://docs.gitlab.com/ee/development/deprecation_guidelines/).
+Review the details carefully before upgrading.
+
+With the move to the new DAST API analyzer and the `DAST-API.gitlab-ci.yml` template for DAST API scans, we will be removing the ability to scan APIs with the DAST analyzer. Use of the `DAST.gitlab-ci.yml` or `DAST-latest.gitlab-ci.yml` templates for API scans is deprecated as of GitLab 15.7 and will no longer work in GitLab 16.0. Please use `DAST-API.gitlab-ci.yml` template and refer to the [DAST API analyzer](https://docs.gitlab.com/ee/user/application_security/dast_api/#configure-dast-api-with-an-openapi-specification) documentation for configuration details.
+
+
+
+
+
### DAST API variables
Planned removal: GitLab 16.0 (2023-05-22)
diff --git a/lib/api/entities/milestone.rb b/lib/api/entities/milestone.rb
index b191210a234..ea73ade46cd 100644
--- a/lib/api/entities/milestone.rb
+++ b/lib/api/entities/milestone.rb
@@ -10,7 +10,7 @@ module API
expose :state, :created_at, :updated_at
expose :due_date
expose :start_date
- expose :expired?, as: :expired
+ expose :expired
expose :web_url do |milestone, _options|
Gitlab::UrlBuilder.build(milestone)
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index f18fb382037..f0b142047aa 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -31537,7 +31537,13 @@ msgstr ""
msgid "Proceed"
msgstr ""
-msgid "Product Analytics|Onboarding view"
+msgid "Product Analytics|Analyze your product with Product Analytics"
+msgstr ""
+
+msgid "Product Analytics|Set up Product Analytics to track how your product is performing. Combine it with your GitLab data to better understand where you can improve your product and development processes."
+msgstr ""
+
+msgid "Product Analytics|Set up product analytics..."
msgstr ""
msgid "Product analytics"
@@ -36268,6 +36274,12 @@ msgstr ""
msgid "ScanExecutionPolicy|A pipeline is run"
msgstr ""
+msgid "ScanExecutionPolicy|Ex, tag-name-1, tag-name-2"
+msgstr ""
+
+msgid "ScanExecutionPolicy|If the field is empty, the runner will be automatically selected"
+msgstr ""
+
msgid "ScanExecutionPolicy|Scanner profile"
msgstr ""
@@ -36292,9 +36304,6 @@ msgstr ""
msgid "ScanExecutionPolicy|Select site profile"
msgstr ""
-msgid "ScanExecutionPolicy|Select tags (if any)"
-msgstr ""
-
msgid "ScanExecutionPolicy|Site profile"
msgstr ""
@@ -37187,7 +37196,7 @@ msgstr ""
msgid "SecurityOrchestration|Summary"
msgstr ""
-msgid "SecurityOrchestration|The following branches do not exist on this development project: %{branches}. Please review all branches to ensure the values are accurate before updating this policy."
+msgid "SecurityOrchestration|The following branches do not exist on this development project: %{branches}. Please review all protected branches to ensure the values are accurate before updating this policy."
msgstr ""
msgid "SecurityOrchestration|There was a problem creating the new security policy"
@@ -37250,10 +37259,10 @@ msgstr ""
msgid "SecurityOrchestration|a"
msgstr ""
-msgid "SecurityOrchestration|all branches"
+msgid "SecurityOrchestration|all namespaces"
msgstr ""
-msgid "SecurityOrchestration|all namespaces"
+msgid "SecurityOrchestration|all protected branches"
msgstr ""
msgid "SecurityOrchestration|an"
diff --git a/qa/qa/resource/runner.rb b/qa/qa/resource/runner.rb
index d755c73e790..30c4dd56633 100644
--- a/qa/qa/resource/runner.rb
+++ b/qa/qa/resource/runner.rb
@@ -119,7 +119,12 @@ module QA
end
def this_runner
- runners_list.find { |runner| runner[:description] == name }
+ runner = nil
+ Support::Retrier.retry_until(max_duration: 60, sleep_interval: 1) do
+ runner = runners_list.find { |runner| runner[:description] == name }
+ !runner.nil?
+ end
+ runner
end
def populate_runner_attributes
diff --git a/spec/features/jira_connect/branches_spec.rb b/spec/features/jira_connect/branches_spec.rb
index 585aa85b16d..489d3743a2a 100644
--- a/spec/features/jira_connect/branches_spec.rb
+++ b/spec/features/jira_connect/branches_spec.rb
@@ -65,7 +65,11 @@ RSpec.describe 'Create GitLab branches from Jira', :js, feature_category: :integ
end
click_on 'master'
+ wait_for_requests
+
fill_in 'Search', with: source_branch
+ wait_for_requests
+
within '[role="listbox"]' do
find('li', text: source_branch).click
end
diff --git a/spec/fixtures/api/schemas/public_api/v4/issue.json b/spec/fixtures/api/schemas/public_api/v4/issue.json
index 0e8de3cd3d7..9108d21c2ae 100644
--- a/spec/fixtures/api/schemas/public_api/v4/issue.json
+++ b/spec/fixtures/api/schemas/public_api/v4/issue.json
@@ -93,12 +93,31 @@
"format": "date-time"
},
"due_date": {
- "type": "string",
- "format": "date-time"
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": [
+ "date-time",
+ "date"
+ ]
},
"start_date": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": [
+ "date-time",
+ "date"
+ ]
+ },
+ "expired": {
+ "type": "boolean"
+ },
+ "web_url": {
"type": "string",
- "format": "date-time"
+ "format": "uri"
}
},
"additionalProperties": false
diff --git a/spec/fixtures/api/schemas/public_api/v4/issues.json b/spec/fixtures/api/schemas/public_api/v4/issues.json
index c76806705e8..5ef97b020f9 100644
--- a/spec/fixtures/api/schemas/public_api/v4/issues.json
+++ b/spec/fixtures/api/schemas/public_api/v4/issues.json
@@ -1,9 +1,6 @@
{
"type": "array",
"items": {
- "type": "object",
- "properties" : {
- "$ref": "./issue.json"
- }
+ "$ref": "./issue.json"
}
-}
+}
\ No newline at end of file
diff --git a/spec/fixtures/api/schemas/public_api/v4/merge_request.json b/spec/fixtures/api/schemas/public_api/v4/merge_request.json
index 1ef2f9f9534..9a6c1757eea 100644
--- a/spec/fixtures/api/schemas/public_api/v4/merge_request.json
+++ b/spec/fixtures/api/schemas/public_api/v4/merge_request.json
@@ -1,25 +1,75 @@
{
"type": "object",
- "properties" : {
- "id": { "type": "integer" },
- "iid": { "type": "integer" },
- "project_id": { "type": "integer" },
- "title": { "type": "string" },
- "description": { "type": ["string", "null"] },
- "state": { "type": "string" },
- "merged_by": { "$ref": "user/basic.json" },
- "merge_user": { "$ref": "user/basic.json" },
- "merged_at": { "type": ["string", "null"] },
- "closed_by": { "$ref": "user/basic.json" },
- "closed_at": { "type": ["string", "null"], "format": "date-time" },
- "created_at": { "type": "string", "format": "date-time" },
- "updated_at": { "type": "string", "format": "date-time" },
- "target_branch": { "type": "string" },
- "source_branch": { "type": "string" },
- "upvotes": { "type": "integer" },
- "downvotes": { "type": "integer" },
- "author": { "$ref": "user/basic.json" },
- "assignee": { "$ref": "user/basic.json" },
+ "properties": {
+ "id": {
+ "type": "integer"
+ },
+ "iid": {
+ "type": "integer"
+ },
+ "project_id": {
+ "type": "integer"
+ },
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "state": {
+ "type": "string"
+ },
+ "merged_by": {
+ "$ref": "user/basic.json"
+ },
+ "merge_user": {
+ "$ref": "user/basic.json"
+ },
+ "merged_at": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "closed_by": {
+ "$ref": "user/basic.json"
+ },
+ "closed_at": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "date-time"
+ },
+ "created_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updated_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "target_branch": {
+ "type": "string"
+ },
+ "source_branch": {
+ "type": "string"
+ },
+ "upvotes": {
+ "type": "integer"
+ },
+ "downvotes": {
+ "type": "integer"
+ },
+ "author": {
+ "$ref": "user/basic.json"
+ },
+ "assignee": {
+ "$ref": "user/basic.json"
+ },
"assignees": {
"type": "array",
"items": {
@@ -32,60 +82,159 @@
"$ref": "user/basic.json"
}
},
- "source_project_id": { "type": "integer" },
- "target_project_id": { "type": "integer" },
+ "source_project_id": {
+ "type": "integer"
+ },
+ "target_project_id": {
+ "type": "integer"
+ },
"labels": {
"type": "array",
"items": {
"type": "string"
}
},
- "work_in_progress": { "type": "boolean" },
+ "work_in_progress": {
+ "type": "boolean"
+ },
"milestone": {
"oneOf": [
- { "type": "null" },
- { "$ref": "milestone.json" }
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "milestone.json"
+ }
]
},
- "merge_when_pipeline_succeeds": { "type": "boolean" },
- "merge_status": { "type": "string" },
- "sha": { "type": "string" },
- "merge_commit_sha": { "type": ["string", "null"] },
- "user_notes_count": { "type": "integer" },
- "changes_count": { "type": "string" },
- "should_remove_source_branch": { "type": ["boolean", "null"] },
- "force_remove_source_branch": { "type": ["boolean", "null"] },
- "discussion_locked": { "type": ["boolean", "null"] },
- "web_url": { "type": "uri" },
- "squash": { "type": "boolean" },
- "time_stats": {
- "time_estimate": { "type": "integer" },
- "total_time_spent": { "type": "integer" },
- "human_time_estimate": { "type": ["string", "null"] },
- "human_total_time_spent": { "type": ["string", "null"] }
+ "merge_when_pipeline_succeeds": {
+ "type": "boolean"
+ },
+ "merge_status": {
+ "type": "string"
+ },
+ "sha": {
+ "type": "string"
+ },
+ "merge_commit_sha": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "user_notes_count": {
+ "type": "integer"
+ },
+ "changes_count": {
+ "type": "string"
+ },
+ "should_remove_source_branch": {
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "force_remove_source_branch": {
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "discussion_locked": {
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "web_url": {
+ "type": "string",
+ "format": "uri"
+ },
+ "squash": {
+ "type": "boolean"
+ },
+ "time_stats": {
+ "time_estimate": {
+ "type": "integer"
+ },
+ "total_time_spent": {
+ "type": "integer"
+ },
+ "human_time_estimate": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "human_total_time_spent": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "allow_collaboration": {
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "allow_maintainer_to_push": {
+ "type": [
+ "boolean",
+ "null"
+ ]
},
- "allow_collaboration": { "type": ["boolean", "null"] },
- "allow_maintainer_to_push": { "type": ["boolean", "null"] },
"references": {
- "short": {"type": "string"},
- "relative": {"type": "string"},
- "full": {"type": "string"}
+ "short": {
+ "type": "string"
+ },
+ "relative": {
+ "type": "string"
+ },
+ "full": {
+ "type": "string"
+ }
}
},
"required": [
- "id", "iid", "project_id", "title", "description",
- "state", "created_at", "updated_at", "target_branch",
- "source_branch", "upvotes", "downvotes", "author",
- "assignee", "source_project_id", "target_project_id",
- "labels", "work_in_progress", "milestone", "merge_when_pipeline_succeeds",
- "merge_status", "sha", "merge_commit_sha", "user_notes_count",
- "should_remove_source_branch", "force_remove_source_branch",
- "web_url", "squash"
+ "id",
+ "iid",
+ "project_id",
+ "title",
+ "description",
+ "state",
+ "created_at",
+ "updated_at",
+ "target_branch",
+ "source_branch",
+ "upvotes",
+ "downvotes",
+ "author",
+ "assignee",
+ "source_project_id",
+ "target_project_id",
+ "labels",
+ "work_in_progress",
+ "milestone",
+ "merge_when_pipeline_succeeds",
+ "merge_status",
+ "sha",
+ "merge_commit_sha",
+ "user_notes_count",
+ "should_remove_source_branch",
+ "force_remove_source_branch",
+ "web_url",
+ "squash"
],
"head_pipeline": {
"oneOf": [
- { "type": "null" },
- { "$ref": "pipeline/detail.json" }
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "pipeline/detail.json"
+ }
]
}
-}
+}
\ No newline at end of file
diff --git a/spec/fixtures/api/schemas/public_api/v4/merge_request_simple.json b/spec/fixtures/api/schemas/public_api/v4/merge_request_simple.json
index f176e5ee261..48de8f13547 100644
--- a/spec/fixtures/api/schemas/public_api/v4/merge_request_simple.json
+++ b/spec/fixtures/api/schemas/public_api/v4/merge_request_simple.json
@@ -1,26 +1,59 @@
{
"type": "object",
- "properties" : {
- "properties" : {
- "id": { "type": "integer" },
- "iid": { "type": "integer" },
- "project_id": { "type": "integer" },
- "title": { "type": "string" },
- "description": { "type": ["string", "null"] },
- "state": { "type": "string" },
- "created_at": { "type": "string", "format": "date-time" },
- "updated_at": { "type": "string", "format": "date-time" },
- "web_url": { "type": "uri" }
+ "properties": {
+ "id": {
+ "type": "integer"
+ },
+ "iid": {
+ "type": "integer"
+ },
+ "project_id": {
+ "type": "integer"
+ },
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "state": {
+ "type": "string"
+ },
+ "created_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updated_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "web_url": {
+ "type": "string",
+ "format": "uri"
},
- "required": [
- "id", "iid", "project_id", "title", "description",
- "state", "created_at", "updated_at", "web_url"
- ],
"head_pipeline": {
"oneOf": [
- { "type": "null" },
- { "$ref": "pipeline/detail.json" }
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "pipeline/detail.json"
+ }
]
}
- }
-}
+ },
+ "required": [
+ "id",
+ "iid",
+ "project_id",
+ "title",
+ "description",
+ "state",
+ "created_at",
+ "updated_at",
+ "web_url"
+ ]
+}
\ No newline at end of file
diff --git a/spec/fixtures/api/schemas/public_api/v4/milestone.json b/spec/fixtures/api/schemas/public_api/v4/milestone.json
index e7e0e57f02f..c33c4044a62 100644
--- a/spec/fixtures/api/schemas/public_api/v4/milestone.json
+++ b/spec/fixtures/api/schemas/public_api/v4/milestone.json
@@ -1,24 +1,77 @@
{
"type": "object",
- "properties" : {
- "id": { "type": "integer" },
- "iid": { "type": "integer" },
- "project_id": { "type": ["integer", "null"] },
- "group_id": { "type": ["integer", "null"] },
- "title": { "type": "string" },
- "description": { "type": ["string", "null"] },
- "state": { "type": "string" },
- "created_at": { "type": "string" },
- "updated_at": { "type": "string" },
- "start_date": { "type": ["string", "null"], "format": "date-time" },
- "due_date": { "type": ["string", "null"], "format": "date-time" },
- "expired": { "type": ["boolean", "null"] },
- "web_url": { "type": "string" }
+ "properties": {
+ "id": {
+ "type": "integer"
+ },
+ "iid": {
+ "type": "integer"
+ },
+ "project_id": {
+ "type": [
+ "integer",
+ "null"
+ ]
+ },
+ "group_id": {
+ "type": [
+ "integer",
+ "null"
+ ]
+ },
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "state": {
+ "type": "string"
+ },
+ "created_at": {
+ "type": "string"
+ },
+ "updated_at": {
+ "type": "string"
+ },
+ "start_date": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "date-time"
+ },
+ "due_date": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "date-time"
+ },
+ "expired": {
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "web_url": {
+ "type": "string"
+ }
},
"required": [
- "id", "iid", "title", "description", "state",
- "state", "created_at", "updated_at", "start_date",
- "due_date", "expired"
+ "id",
+ "iid",
+ "title",
+ "description",
+ "state",
+ "created_at",
+ "updated_at",
+ "start_date",
+ "due_date",
+ "expired"
],
"additionalProperties": false
-}
+}
\ No newline at end of file
diff --git a/spec/fixtures/api/schemas/public_api/v4/milestone_with_stats.json b/spec/fixtures/api/schemas/public_api/v4/milestone_with_stats.json
index d09d1634eb9..b5fa161ec2a 100644
--- a/spec/fixtures/api/schemas/public_api/v4/milestone_with_stats.json
+++ b/spec/fixtures/api/schemas/public_api/v4/milestone_with_stats.json
@@ -1,32 +1,95 @@
{
"type": "object",
- "properties" : {
- "id": { "type": "integer" },
- "iid": { "type": "integer" },
- "project_id": { "type": ["integer", "null"] },
- "group_id": { "type": ["integer", "null"] },
- "title": { "type": "string" },
- "description": { "type": ["string", "null"] },
- "state": { "type": "string" },
- "created_at": { "type": "string", "format": "date-time" },
- "updated_at": { "type": "string", "format": "date-time" },
- "start_date": { "type": ["string", "null"], "format": "date-time" },
- "due_date": { "type": ["string", "null"], "format": "date-time" },
- "expired": { "type": ["boolean", "null"] },
- "web_url": { "type": "string" },
+ "properties": {
+ "id": {
+ "type": "integer"
+ },
+ "iid": {
+ "type": "integer"
+ },
+ "project_id": {
+ "type": [
+ "integer",
+ "null"
+ ]
+ },
+ "group_id": {
+ "type": [
+ "integer",
+ "null"
+ ]
+ },
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "state": {
+ "type": "string"
+ },
+ "created_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updated_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "start_date": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "date-time"
+ },
+ "due_date": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "date-time"
+ },
+ "expired": {
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "web_url": {
+ "type": "string"
+ },
"issue_stats": {
- "required": ["total", "closed"],
+ "required": [
+ "total",
+ "closed"
+ ],
"properties": {
- "total": { "type": "integer" },
- "closed": { "type": "integer" }
+ "total": {
+ "type": "integer"
+ },
+ "closed": {
+ "type": "integer"
+ }
},
"additionalProperties": false
}
},
"required": [
- "id", "iid", "title", "description", "state",
- "state", "created_at", "updated_at", "start_date",
- "due_date", "expired", "issue_stats"
+ "id",
+ "iid",
+ "title",
+ "description",
+ "state",
+ "created_at",
+ "updated_at",
+ "start_date",
+ "due_date",
+ "expired",
+ "issue_stats"
],
"additionalProperties": false
-}
+}
\ No newline at end of file
diff --git a/spec/fixtures/api/schemas/public_api/v4/notes.json b/spec/fixtures/api/schemas/public_api/v4/notes.json
index d6d0300a64f..1987a0f2f71 100644
--- a/spec/fixtures/api/schemas/public_api/v4/notes.json
+++ b/spec/fixtures/api/schemas/public_api/v4/notes.json
@@ -2,43 +2,124 @@
"type": "array",
"items": {
"type": "object",
- "properties" : {
- "id": { "type": "integer" },
- "type": { "type": ["string", "null"] },
- "body": { "type": "string" },
- "attachment": { "type": ["string", "null"] },
+ "properties": {
+ "id": {
+ "type": "integer"
+ },
+ "type": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "body": {
+ "type": "string"
+ },
+ "attachment": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
"author": {
"type": "object",
"properties": {
- "name": { "type": "string" },
- "username": { "type": "string" },
- "id": { "type": "integer" },
- "state": { "type": "string" },
- "avatar_url": { "type": "uri" },
- "web_url": { "type": "uri" }
+ "name": {
+ "type": "string"
+ },
+ "username": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "state": {
+ "type": "string"
+ },
+ "avatar_url": {
+ "type": "string",
+ "format": "uri"
+ },
+ "web_url": {
+ "type": "string",
+ "format": "uri"
+ }
},
- "required" : [
- "id", "name", "username", "state", "avatar_url", "web_url"
+ "required": [
+ "id",
+ "name",
+ "username",
+ "state",
+ "avatar_url",
+ "web_url"
]
},
- "commands_changes": { "type": "object", "additionalProperties": true },
- "created_at": { "type": "string", "format": "date-time" },
- "updated_at": { "type": "string", "format": "date-time" },
- "system": { "type": "boolean" },
- "noteable_id": { "type": "integer" },
- "noteable_iid": { "type": "integer" },
- "noteable_type": { "type": "string" },
- "resolved": { "type": "boolean" },
- "resolvable": { "type": "boolean" },
- "resolved_by": { "type": ["string", "null"] },
- "resolved_at": { "type": ["string", "null"] },
- "confidential": { "type": ["boolean", "null"] },
- "internal": { "type": ["boolean", "null"] }
+ "commands_changes": {
+ "type": "object",
+ "additionalProperties": true
+ },
+ "created_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updated_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "system": {
+ "type": "boolean"
+ },
+ "noteable_id": {
+ "type": "integer"
+ },
+ "noteable_iid": {
+ "type": "integer"
+ },
+ "noteable_type": {
+ "type": "string"
+ },
+ "resolved": {
+ "type": "boolean"
+ },
+ "resolvable": {
+ "type": "boolean"
+ },
+ "resolved_by": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "resolved_at": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "confidential": {
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "internal": {
+ "type": [
+ "boolean",
+ "null"
+ ]
+ }
},
"required": [
- "id", "body", "attachment", "author", "created_at", "updated_at",
- "system", "noteable_id", "noteable_type"
+ "id",
+ "body",
+ "attachment",
+ "author",
+ "created_at",
+ "updated_at",
+ "system",
+ "noteable_id",
+ "noteable_type"
],
"additionalProperties": false
}
-}
+}
\ No newline at end of file
diff --git a/spec/fixtures/api/schemas/public_api/v4/pages_domain/basic.json b/spec/fixtures/api/schemas/public_api/v4/pages_domain/basic.json
index 66d4be529b1..9bcd191741f 100644
--- a/spec/fixtures/api/schemas/public_api/v4/pages_domain/basic.json
+++ b/spec/fixtures/api/schemas/public_api/v4/pages_domain/basic.json
@@ -1,23 +1,60 @@
{
"type": "object",
"properties": {
- "domain": { "type": "string" },
- "url": { "type": "uri" },
- "project_id": { "type": "integer" },
- "verified": { "type": "boolean" },
- "verification_code": { "type": ["string", "null"] },
- "enabled_until": { "type": ["string", "null"], "format": "date-time" },
- "auto_ssl_enabled": { "type": "boolean" },
+ "domain": {
+ "type": "string"
+ },
+ "url": {
+ "type": "string",
+ "format": "uri"
+ },
+ "project_id": {
+ "type": "integer"
+ },
+ "verified": {
+ "type": "boolean"
+ },
+ "verification_code": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "enabled_until": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "date-time"
+ },
+ "auto_ssl_enabled": {
+ "type": "boolean"
+ },
"certificate_expiration": {
"type": "object",
"properties": {
- "expired": { "type": "boolean" },
- "expiration": { "type": "string" }
+ "expired": {
+ "type": "boolean"
+ },
+ "expiration": {
+ "type": "string"
+ }
},
- "required": ["expired", "expiration"],
+ "required": [
+ "expired",
+ "expiration"
+ ],
"additionalProperties": false
}
},
- "required": ["domain", "url", "project_id", "verified", "verification_code", "enabled_until", "auto_ssl_enabled"],
+ "required": [
+ "domain",
+ "url",
+ "project_id",
+ "verified",
+ "verification_code",
+ "enabled_until",
+ "auto_ssl_enabled"
+ ],
"additionalProperties": false
-}
+}
\ No newline at end of file
diff --git a/spec/fixtures/api/schemas/public_api/v4/pages_domain/detail.json b/spec/fixtures/api/schemas/public_api/v4/pages_domain/detail.json
index bbbc610eb27..6ce431a274a 100644
--- a/spec/fixtures/api/schemas/public_api/v4/pages_domain/detail.json
+++ b/spec/fixtures/api/schemas/public_api/v4/pages_domain/detail.json
@@ -1,24 +1,61 @@
{
"type": "object",
"properties": {
- "domain": { "type": "string" },
- "url": { "type": "uri" },
- "verified": { "type": "boolean" },
- "verification_code": { "type": ["string", "null"] },
- "enabled_until": { "type": ["string", "null"] },
- "auto_ssl_enabled": { "type": "boolean" },
+ "domain": {
+ "type": "string"
+ },
+ "url": {
+ "type": "string",
+ "format": "uri"
+ },
+ "verified": {
+ "type": "boolean"
+ },
+ "verification_code": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "enabled_until": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "auto_ssl_enabled": {
+ "type": "boolean"
+ },
"certificate": {
"type": "object",
"properties": {
- "subject": { "type": "string" },
- "expired": { "type": "boolean" },
- "certificate": { "type": "string" },
- "certificate_text": { "type": "string" }
+ "subject": {
+ "type": "string"
+ },
+ "expired": {
+ "type": "boolean"
+ },
+ "certificate": {
+ "type": "string"
+ },
+ "certificate_text": {
+ "type": "string"
+ }
},
- "required": ["subject", "expired"],
+ "required": [
+ "subject",
+ "expired"
+ ],
"additionalProperties": false
}
},
- "required": ["domain", "url", "verified", "verification_code", "enabled_until", "auto_ssl_enabled"],
+ "required": [
+ "domain",
+ "url",
+ "verified",
+ "verification_code",
+ "enabled_until",
+ "auto_ssl_enabled"
+ ],
"additionalProperties": false
-}
+}
\ No newline at end of file
diff --git a/spec/fixtures/api/schemas/public_api/v4/project_hooks.json b/spec/fixtures/api/schemas/public_api/v4/project_hooks.json
index 8c542ebe3ad..8557e5cae40 100644
--- a/spec/fixtures/api/schemas/public_api/v4/project_hooks.json
+++ b/spec/fixtures/api/schemas/public_api/v4/project_hooks.json
@@ -1,10 +1,6 @@
{
"type": "array",
"items": {
- "type": "object",
- "properties" : {
- "$ref": "./project_hook.json"
- }
+ "$ref": "./project_hook.json"
}
-}
-
+}
\ No newline at end of file
diff --git a/spec/fixtures/api/schemas/public_api/v4/snippets.json b/spec/fixtures/api/schemas/public_api/v4/snippets.json
index 65299901128..dab6b69f1c1 100644
--- a/spec/fixtures/api/schemas/public_api/v4/snippets.json
+++ b/spec/fixtures/api/schemas/public_api/v4/snippets.json
@@ -2,46 +2,107 @@
"type": "array",
"items": {
"type": "object",
- "properties" : {
- "id": { "type": "integer" },
- "project_id": { "type": ["integer", "null"] },
- "title": { "type": "string" },
- "file_name": { "type": ["string", "null"] },
- "files" : {
+ "properties": {
+ "id": {
+ "type": "integer"
+ },
+ "project_id": {
+ "type": [
+ "integer",
+ "null"
+ ]
+ },
+ "title": {
+ "type": "string"
+ },
+ "file_name": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "files": {
"type": "array",
"items": {
"type": "object",
"properties": {
- "path": { "type": "string" },
- "raw_url": { "type": "string" }
+ "path": {
+ "type": "string"
+ },
+ "raw_url": {
+ "type": "string"
+ }
}
}
},
- "description": { "type": ["string", "null"] },
- "visibility": { "type": "string" },
- "web_url": { "type": "string" },
- "raw_url": { "type": "string" },
- "created_at": { "type": "string", "format": "date-time" },
- "updated_at": { "type": "string", "format": "date-time" },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "visibility": {
+ "type": "string"
+ },
+ "web_url": {
+ "type": "string"
+ },
+ "raw_url": {
+ "type": "string"
+ },
+ "created_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updated_at": {
+ "type": "string",
+ "format": "date-time"
+ },
"author": {
"type": "object",
"properties": {
- "name": { "type": "string" },
- "username": { "type": "string" },
- "id": { "type": "integer" },
- "state": { "type": "string" },
- "avatar_url": { "type": "uri" },
- "web_url": { "type": "uri" }
+ "name": {
+ "type": "string"
+ },
+ "username": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "state": {
+ "type": "string"
+ },
+ "avatar_url": {
+ "type": "string",
+ "format": "uri"
+ },
+ "web_url": {
+ "type": "string",
+ "format": "uri"
+ }
},
- "required" : [
- "id", "name", "username", "state", "avatar_url", "web_url"
+ "required": [
+ "id",
+ "name",
+ "username",
+ "state",
+ "avatar_url",
+ "web_url"
]
}
},
"required": [
- "id", "title", "file_name", "description", "web_url",
- "created_at", "updated_at", "author", "raw_url"
+ "id",
+ "title",
+ "file_name",
+ "description",
+ "web_url",
+ "created_at",
+ "updated_at",
+ "author",
+ "raw_url"
],
"additionalProperties": false
}
-}
+}
\ No newline at end of file
diff --git a/spec/fixtures/api/schemas/public_api/v4/system_hooks.json b/spec/fixtures/api/schemas/public_api/v4/system_hooks.json
index a56542a8b99..a0800e4bc97 100644
--- a/spec/fixtures/api/schemas/public_api/v4/system_hooks.json
+++ b/spec/fixtures/api/schemas/public_api/v4/system_hooks.json
@@ -1,9 +1,6 @@
{
"type": "array",
"items": {
- "type": "object",
- "properties" : {
- "$ref": "./system_hook.json"
- }
+ "$ref": "./system_hook.json"
}
-}
+}
\ No newline at end of file
diff --git a/spec/fixtures/api/schemas/public_api/v4/user/public.json b/spec/fixtures/api/schemas/public_api/v4/user/public.json
index c4549e3ef63..53d67e041a1 100644
--- a/spec/fixtures/api/schemas/public_api/v4/user/public.json
+++ b/spec/fixtures/api/schemas/public_api/v4/user/public.json
@@ -28,32 +28,95 @@
"external"
],
"properties": {
- "id": { "type": "integer" },
- "username": { "type": "string" },
+ "id": {
+ "type": "integer"
+ },
+ "username": {
+ "type": "string"
+ },
"email": {
"type": "string",
"pattern": "^[^@]+@[^@]+$"
},
- "name": { "type": "string" },
+ "name": {
+ "type": "string"
+ },
"state": {
"type": "string",
- "enum": ["active", "blocked"]
+ "enum": [
+ "active",
+ "blocked"
+ ]
+ },
+ "avatar_url": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "web_url": {
+ "type": "string"
+ },
+ "created_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "bio": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "location": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "skype": {
+ "type": "string"
+ },
+ "linkedin": {
+ "type": "string"
+ },
+ "twitter": {
+ "type": "string"
+ },
+ "website_url": {
+ "type": "string"
+ },
+ "organization": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "last_sign_in_at": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "date-time"
+ },
+ "confirmed_at": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "color_scheme_id": {
+ "type": "integer"
+ },
+ "projects_limit": {
+ "type": "integer"
+ },
+ "current_sign_in_at": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "date-time"
},
- "avatar_url": { "type": [ "string", "null" ] },
- "web_url": { "type": "string" },
- "created_at": { "type": "string", "format": "date-time" },
- "bio": { "type": ["string", "null"] },
- "location": { "type": ["string", "null"] },
- "skype": { "type": "string" },
- "linkedin": { "type": "string" },
- "twitter": { "type": "string "},
- "website_url": { "type": "string" },
- "organization": { "type": ["string", "null"] },
- "last_sign_in_at": { "type": ["string", "null"], "format": "date-time" },
- "confirmed_at": { "type": ["string", "null"] },
- "color_scheme_id": { "type": "integer" },
- "projects_limit": { "type": "integer" },
- "current_sign_in_at": { "type": ["string", "null"], "format": "date-time" },
"identities": {
"type": "array",
"items": {
@@ -61,16 +124,35 @@
"properties": {
"provider": {
"type": "string",
- "enum": ["github", "bitbucket", "google_oauth2"]
+ "enum": [
+ "github",
+ "bitbucket",
+ "google_oauth2"
+ ]
},
- "extern_uid": { "type": ["number", "string"] }
+ "extern_uid": {
+ "type": [
+ "number",
+ "string"
+ ]
+ }
}
}
},
- "can_create_group": { "type": "boolean" },
- "can_create_project": { "type": "boolean" },
- "two_factor_enabled": { "type": "boolean" },
- "external": { "type": "boolean" },
- "commit_email": { "type": "string" }
+ "can_create_group": {
+ "type": "boolean"
+ },
+ "can_create_project": {
+ "type": "boolean"
+ },
+ "two_factor_enabled": {
+ "type": "boolean"
+ },
+ "external": {
+ "type": "boolean"
+ },
+ "commit_email": {
+ "type": "string"
+ }
}
-}
+}
\ No newline at end of file
diff --git a/spec/fixtures/api/schemas/registry/repository.json b/spec/fixtures/api/schemas/registry/repository.json
index 18d2c68ac2f..078fba7a34a 100644
--- a/spec/fixtures/api/schemas/registry/repository.json
+++ b/spec/fixtures/api/schemas/registry/repository.json
@@ -1,6 +1,12 @@
{
"type": "object",
- "required": ["id", "name", "path", "location", "created_at"],
+ "required": [
+ "id",
+ "name",
+ "path",
+ "location",
+ "created_at"
+ ],
"properties": {
"id": {
"type": "integer"
@@ -18,10 +24,15 @@
"type": "string"
},
"created_at": {
- "type": "date-time"
+ "type": "string",
+ "format": "date-time"
},
"cleanup_policy_started_at": {
- "type": "date-time"
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "date-time"
},
"tags_path": {
"type": "string"
@@ -31,14 +42,24 @@
},
"status": {
"oneOf": [
- { "type": "null" },
- { "type": "string", "enum": ["delete_scheduled", "delete_failed"] }
+ {
+ "type": "null"
+ },
+ {
+ "type": "string",
+ "enum": [
+ "delete_scheduled",
+ "delete_failed"
+ ]
+ }
]
},
- "tags": { "$ref": "tags.json" },
+ "tags": {
+ "$ref": "tags.json"
+ },
"tags_count": {
"type": "integer"
}
},
"additionalProperties": false
-}
+}
\ No newline at end of file
diff --git a/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metric_label_values_variable_full_syntax.json b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metric_label_values_variable_full_syntax.json
index a74b557dabe..145cc476d64 100644
--- a/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metric_label_values_variable_full_syntax.json
+++ b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metric_label_values_variable_full_syntax.json
@@ -2,12 +2,21 @@
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
- "type", "options"
+ "type",
+ "options"
],
"properties": {
- "type": { "enum": "metric_label_values" },
- "label": { "type": "string" },
- "options": { "$ref": "spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metric_label_values_variable_options.json" }
+ "type": {
+ "enum": [
+ "metric_label_values"
+ ]
+ },
+ "label": {
+ "type": "string"
+ },
+ "options": {
+ "$ref": "spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metric_label_values_variable_options.json"
+ }
},
"additionalProperties": false
-}
+}
\ No newline at end of file
diff --git a/spec/requests/api/graphql/ci/runner_spec.rb b/spec/requests/api/graphql/ci/runner_spec.rb
index 2e840096814..b175ccf4c6f 100644
--- a/spec/requests/api/graphql/ci/runner_spec.rb
+++ b/spec/requests/api/graphql/ci/runner_spec.rb
@@ -232,6 +232,47 @@ RSpec.describe 'Query.runner(id)', feature_category: :runner_fleet do
end
end
+ describe 'jobCount' do
+ let_it_be(:pipeline1) { create(:ci_pipeline, project: project1) }
+ let_it_be(:pipeline2) { create(:ci_pipeline, project: project1) }
+ let_it_be(:build1) { create(:ci_build, :running, runner: active_project_runner, pipeline: pipeline1) }
+ let_it_be(:build2) { create(:ci_build, :running, runner: active_project_runner, pipeline: pipeline2) }
+
+ let(:runner_query_fragment) { 'id jobCount' }
+ let(:query) do
+ %(
+ query {
+ runner1: runner(id: "#{active_project_runner.to_global_id}") { #{runner_query_fragment} }
+ runner2: runner(id: "#{inactive_instance_runner.to_global_id}") { #{runner_query_fragment} }
+ }
+ )
+ end
+
+ it 'retrieves correct jobCount values' do
+ post_graphql(query, current_user: user)
+
+ expect(graphql_data).to match a_hash_including(
+ 'runner1' => a_graphql_entity_for(active_project_runner, job_count: 2),
+ 'runner2' => a_graphql_entity_for(inactive_instance_runner, job_count: 0)
+ )
+ end
+
+ context 'when JOB_COUNT_LIMIT is in effect' do
+ before do
+ stub_const('Types::Ci::RunnerType::JOB_COUNT_LIMIT', 1)
+ end
+
+ it 'retrieves correct capped jobCount values' do
+ post_graphql(query, current_user: user)
+
+ expect(graphql_data).to match a_hash_including(
+ 'runner1' => a_graphql_entity_for(active_project_runner, job_count: 1),
+ 'runner2' => a_graphql_entity_for(inactive_instance_runner, job_count: 0)
+ )
+ end
+ end
+ end
+
describe 'ownerProject' do
let_it_be(:project2) { create(:project) }
let_it_be(:runner1) { create(:ci_runner, :project, projects: [project2, project1]) }
@@ -510,8 +551,8 @@ RSpec.describe 'Query.runner(id)', feature_category: :runner_fleet do
let(:active_project_runner2) { create(:ci_runner, :project) }
let(:active_group_runner2) { create(:ci_runner, :group) }
- # Currently excluding known N+1 issues, see https://gitlab.com/gitlab-org/gitlab/-/issues/334759
- let(:excluded_fields) { %w[jobCount jobs groups projects ownerProject] }
+ # Exclude fields that are already hardcoded above
+ let(:excluded_fields) { %w[jobs groups projects ownerProject] }
let(:single_query) do
<<~QUERY
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index dc2f12628d0..23083203cfe 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -39,8 +39,6 @@ require 'test_prof/factory_default'
require 'test_prof/factory_prof/nate_heckler'
require 'parslet/rig/rspec'
-warn_missing_feature_category = Gitlab::Utils.to_boolean(ENV['RSPEC_WARN_MISSING_FEATURE_CATEGORY'], default: true)
-
rspec_profiling_is_configured =
ENV['RSPEC_PROFILING_POSTGRES_URL'].present? ||
ENV['RSPEC_PROFILING']
@@ -463,13 +461,6 @@ RSpec.configure do |config|
config.before(:each, :js) do
allow_any_instance_of(VersionCheck).to receive(:response).and_return({ "severity" => "success" })
end
-
- # Add warning for example missing feature_category
- config.before do |example|
- if warn_missing_feature_category && example.metadata[:feature_category].blank? && !ENV['CI']
- warn "Missing metadata feature_category: #{example.location} See https://docs.gitlab.com/ee/development/testing_guide/best_practices.html#feature-category-metadata"
- end
- end
end
ActiveRecord::Migration.maintain_test_schema!
diff --git a/spec/support/rspec.rb b/spec/support/rspec.rb
index 71dfc3fd5a3..ff0b5bebe33 100644
--- a/spec/support/rspec.rb
+++ b/spec/support/rspec.rb
@@ -8,6 +8,8 @@ require_relative "helpers/stub_object_storage"
require_relative "helpers/stub_env"
require_relative "helpers/fast_rails_root"
+require_relative "../../lib/gitlab/utils"
+
RSpec::Expectations.configuration.on_potential_false_positives = :raise
RSpec.configure do |config|
@@ -35,4 +37,13 @@ RSpec.configure do |config|
config.include StubObjectStorage
config.include StubENV
config.include FastRailsRoot
+
+ warn_missing_feature_category = Gitlab::Utils.to_boolean(ENV['RSPEC_WARN_MISSING_FEATURE_CATEGORY'], default: true)
+
+ # Add warning for example missing feature_category
+ config.before do |example|
+ if warn_missing_feature_category && example.metadata[:feature_category].blank? && !ENV['CI']
+ warn "Missing metadata feature_category: #{example.location} See https://docs.gitlab.com/ee/development/testing_guide/best_practices.html#feature-category-metadata"
+ end
+ end
end