Commit 0e78cc64 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 11aa231d 0ebd272f
...@@ -102,7 +102,7 @@ ...@@ -102,7 +102,7 @@
- name: postgres:11.6 - name: postgres:11.6
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"] command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- name: redis:5.0-alpine - name: redis:5.0-alpine
- name: elasticsearch:7.9.2 - name: elasticsearch:7.10.1
command: ["elasticsearch", "-E", "discovery.type=single-node"] command: ["elasticsearch", "-E", "discovery.type=single-node"]
variables: variables:
POSTGRES_HOST_AUTH_METHOD: trust POSTGRES_HOST_AUTH_METHOD: trust
...@@ -113,7 +113,7 @@ ...@@ -113,7 +113,7 @@
- name: postgres:12 - name: postgres:12
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"] command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- name: redis:5.0-alpine - name: redis:5.0-alpine
- name: elasticsearch:7.9.2 - name: elasticsearch:7.10.1
command: ["elasticsearch", "-E", "discovery.type=single-node"] command: ["elasticsearch", "-E", "discovery.type=single-node"]
variables: variables:
POSTGRES_HOST_AUTH_METHOD: trust POSTGRES_HOST_AUTH_METHOD: trust
......
...@@ -691,47 +691,6 @@ RSpec/TimecopTravel: ...@@ -691,47 +691,6 @@ RSpec/TimecopTravel:
- 'spec/workers/concerns/reenqueuer_spec.rb' - 'spec/workers/concerns/reenqueuer_spec.rb'
- 'spec/lib/gitlab/analytics/cycle_analytics/median_spec.rb' - 'spec/lib/gitlab/analytics/cycle_analytics/median_spec.rb'
Graphql/Descriptions:
Exclude:
- 'ee/app/graphql/types/epic_tree/epic_tree_node_input_type.rb'
- 'ee/app/graphql/types/external_issue_type.rb'
- 'ee/app/graphql/types/geo/geo_node_type.rb'
- 'ee/app/graphql/types/geo/merge_request_diff_registry_type.rb'
- 'ee/app/graphql/types/geo/package_file_registry_type.rb'
- 'ee/app/graphql/types/geo/snippet_repository_registry_type.rb'
- 'ee/app/graphql/types/geo/terraform_state_version_registry_type.rb'
- 'ee/app/graphql/types/group_stats_type.rb'
- 'ee/app/graphql/types/incident_management/oncall_schedule_type.rb'
- 'ee/app/graphql/types/instance_security_dashboard_type.rb'
- 'ee/app/graphql/types/iteration_type.rb'
- 'ee/app/graphql/types/metric_image_type.rb'
- 'ee/app/graphql/types/requirements_management/requirement_states_count_type.rb'
- 'ee/app/graphql/types/requirements_management/requirement_type.rb'
- 'ee/app/graphql/types/requirements_management/test_report_type.rb'
- 'ee/app/graphql/types/scanned_resource_type.rb'
- 'ee/app/graphql/types/security_report_summary_section_type.rb'
- 'ee/app/graphql/types/time_report_stats_type.rb'
- 'ee/app/graphql/types/timebox_metrics_type.rb'
- 'ee/app/graphql/types/timebox_report_interface.rb'
- 'ee/app/graphql/types/timebox_report_type.rb'
- 'ee/app/graphql/types/timelog_type.rb'
- 'ee/app/graphql/types/vulnerabilities_count_by_day_and_severity_type.rb'
- 'ee/app/graphql/types/vulnerabilities_count_by_day_type.rb'
- 'ee/app/graphql/types/vulnerability/external_issue_link_type.rb'
- 'ee/app/graphql/types/vulnerability/issue_link_type.rb'
- 'ee/app/graphql/types/vulnerability_identifier_type.rb'
- 'ee/app/graphql/types/vulnerability_location/container_scanning_type.rb'
- 'ee/app/graphql/types/vulnerability_location/coverage_fuzzing_type.rb'
- 'ee/app/graphql/types/vulnerability_location/dast_type.rb'
- 'ee/app/graphql/types/vulnerability_location/dependency_scanning_type.rb'
- 'ee/app/graphql/types/vulnerability_location/sast_type.rb'
- 'ee/app/graphql/types/vulnerability_location/secret_detection_type.rb'
- 'ee/app/graphql/types/vulnerability_scanner_type.rb'
- 'ee/app/graphql/types/vulnerability_type.rb'
- 'ee/app/graphql/types/vulnerable_dependency_type.rb'
- 'ee/app/graphql/types/vulnerable_package_type.rb'
- 'ee/app/graphql/types/vulnerable_projects_by_grade_type.rb'
# WIP: https://gitlab.com/gitlab-org/gitlab/-/issues/34997 # WIP: https://gitlab.com/gitlab-org/gitlab/-/issues/34997
RSpec/AnyInstanceOf: RSpec/AnyInstanceOf:
Exclude: Exclude:
......
...@@ -464,7 +464,7 @@ group :ed25519 do ...@@ -464,7 +464,7 @@ group :ed25519 do
end end
# Gitaly GRPC protocol definitions # Gitaly GRPC protocol definitions
gem 'gitaly', '~> 13.8.0.pre.rc3' gem 'gitaly', '~> 13.9.0.pre.rc1'
gem 'grpc', '~> 1.30.2' gem 'grpc', '~> 1.30.2'
......
...@@ -420,7 +420,7 @@ GEM ...@@ -420,7 +420,7 @@ GEM
rails (>= 3.2.0) rails (>= 3.2.0)
git (1.7.0) git (1.7.0)
rchardet (~> 1.8) rchardet (~> 1.8)
gitaly (13.8.0.pre.rc3) gitaly (13.9.0.pre.rc1)
grpc (~> 1.0) grpc (~> 1.0)
github-markup (1.7.0) github-markup (1.7.0)
gitlab-chronic (0.10.5) gitlab-chronic (0.10.5)
...@@ -1368,7 +1368,7 @@ DEPENDENCIES ...@@ -1368,7 +1368,7 @@ DEPENDENCIES
gettext (~> 3.3) gettext (~> 3.3)
gettext_i18n_rails (~> 1.8.0) gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.3) gettext_i18n_rails_js (~> 1.3)
gitaly (~> 13.8.0.pre.rc3) gitaly (~> 13.9.0.pre.rc1)
github-markup (~> 1.7.0) github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5) gitlab-chronic (~> 0.10.5)
gitlab-experiment (~> 0.4.9) gitlab-experiment (~> 0.4.9)
......
import { redirectTo, getBaseURL, stripFinalUrlSegment } from '~/lib/utils/url_utility'; import { redirectTo, getBaseURL, stripFinalUrlSegment } from '~/lib/utils/url_utility';
import { initRemoveTag } from '../remove_tag'; import { initRemoveTag } from '../remove_tag';
document.addEventListener('DOMContentLoaded', () => { initRemoveTag({
initRemoveTag({
onDelete: (path = '') => { onDelete: (path = '') => {
redirectTo(stripFinalUrlSegment([getBaseURL(), path].join(''))); redirectTo(stripFinalUrlSegment([getBaseURL(), path].join('')));
}, },
});
}); });
...@@ -109,7 +109,7 @@ export default { ...@@ -109,7 +109,7 @@ export default {
<div <div
v-for="(key, keyIndex) in keys" v-for="(key, keyIndex) in keys"
:key="key" :key="key"
class="break-word gl-text-black-normal" class="break-word"
:class="{ 'mb-3 bold': keyIndex == 0 }" :class="{ 'mb-3 bold': keyIndex == 0 }"
> >
{{ item[key] }} {{ item[key] }}
......
...@@ -9,7 +9,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController ...@@ -9,7 +9,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController
before_action :authorize_admin_project_member!, except: [:index, :leave, :request_access] before_action :authorize_admin_project_member!, except: [:index, :leave, :request_access]
before_action do before_action do
push_frontend_feature_flag(:vue_project_members_list, @project) push_frontend_feature_flag(:vue_project_members_list, @project, default_enabled: :yaml)
end end
feature_category :authentication_and_authorization feature_category :authentication_and_authorization
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
= render 'shared/group_tips' = render 'shared/group_tips'
.form-actions .form-actions
= f.submit _('Create group'), class: "gl-button btn btn-success" = f.submit _('Create group'), class: "gl-button btn btn-success"
= link_to _('Cancel'), admin_groups_path, class: "gl-button btn btn-cancel" = link_to _('Cancel'), admin_groups_path, class: "gl-button btn btn-default btn-cancel"
- else - else
.form-actions .form-actions
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
.d-flex.justify-content-between.flex-wrap .d-flex.justify-content-between.flex-wrap
- providers.each do |provider| - providers.each do |provider|
- has_icon = provider_has_icon?(provider) - has_icon = provider_has_icon?(provider)
= button_to omniauth_authorize_path(:user, provider), id: "oauth-login-#{provider}", class: "gl-button btn d-flex align-items-center omniauth-btn text-left oauth-login #{qa_class_for_provider(provider)}" do = button_to omniauth_authorize_path(:user, provider), id: "oauth-login-#{provider}", class: "btn gl-button btn-default d-flex align-items-center omniauth-btn text-left oauth-login #{qa_class_for_provider(provider)}" do
- if has_icon - if has_icon
= provider_image_tag(provider) = provider_image_tag(provider)
%span %span
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
= _("Create an account using:") = _("Create an account using:")
.d-flex.justify-content-between.flex-wrap .d-flex.justify-content-between.flex-wrap
- providers.each do |provider| - providers.each do |provider|
= link_to omniauth_authorize_path(:user, provider), method: :post, class: "btn gl-button gl-display-flex gl-align-items-center gl-text-left gl-mb-2 gl-p-2 omniauth-btn oauth-login #{qa_class_for_provider(provider)}", id: "oauth-login-#{provider}" do = link_to omniauth_authorize_path(:user, provider), method: :post, class: "btn gl-button btn-default gl-display-flex gl-align-items-center gl-text-left gl-mb-2 gl-p-2 omniauth-btn oauth-login #{qa_class_for_provider(provider)}", id: "oauth-login-#{provider}" do
- if provider_has_icon?(provider) - if provider_has_icon?(provider)
= provider_image_tag(provider) = provider_image_tag(provider)
%span.ml-2 %span.ml-2
......
...@@ -18,5 +18,5 @@ ...@@ -18,5 +18,5 @@
= render_if_exists 'shared/groups/invite_members' = render_if_exists 'shared/groups/invite_members'
.row .row
.form-actions.col-sm-12 .form-actions.col-sm-12
= f.submit _('Create group'), class: "btn btn-success" = f.submit _('Create group'), class: "btn gl-button btn-success"
= link_to _('Cancel'), dashboard_groups_path, class: 'btn btn-cancel' = link_to _('Cancel'), dashboard_groups_path, class: 'btn gl-button btn-default btn-cancel'
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
- read_only_help_text = readonly ? s_("Profiles|Your email address was automatically set based on your %{provider_label} account") % { provider_label: attribute_provider_label(:email) } : user_email_help_text(@user) - read_only_help_text = readonly ? s_("Profiles|Your email address was automatically set based on your %{provider_label} account") % { provider_label: attribute_provider_label(:email) } : user_email_help_text(@user)
- help_text = email_change_disabled ? s_("Your account uses dedicated credentials for the \"%{group_name}\" group and can only be updated through SSO.") % { group_name: @user.managing_group.name } : read_only_help_text - help_text = email_change_disabled ? s_("Your account uses dedicated credentials for the \"%{group_name}\" group and can only be updated through SSO.") % { group_name: @user.managing_group.name } : read_only_help_text
= form.text_field :email, required: true, class: 'input-lg', value: (@user.email unless @user.temp_oauth_email?), help: help_text.html_safe, readonly: readonly || email_change_disabled = form.text_field :email, required: true, class: 'input-lg gl-form-input', value: (@user.email unless @user.temp_oauth_email?), help: help_text.html_safe, readonly: readonly || email_change_disabled
= form.select :public_email, options_for_select(@user.public_verified_emails, selected: @user.public_email), = form.select :public_email, options_for_select(@user.public_verified_emails, selected: @user.public_email),
{ help: s_("Profiles|This email will be displayed on your public profile"), include_blank: s_("Profiles|Do not show on profile") }, { help: s_("Profiles|This email will be displayed on your public profile"), include_blank: s_("Profiles|Do not show on profile") },
control_class: 'select2 input-lg', disabled: email_change_disabled control_class: 'select2 input-lg', disabled: email_change_disabled
......
- if user.read_only_attribute?(:name) - if user.read_only_attribute?(:name)
= form.text_field :name, required: true, readonly: true, wrapper: { class: 'col-md-9 qa-full-name rspec-full-name' }, = form.text_field :name, class: 'gl-form-input', required: true, readonly: true, wrapper: { class: 'col-md-9 qa-full-name rspec-full-name' },
help: s_("Profiles|Your name was automatically set based on your %{provider_label} account, so people you know can recognize you") % { provider_label: attribute_provider_label(:name) } help: s_("Profiles|Your name was automatically set based on your %{provider_label} account, so people you know can recognize you") % { provider_label: attribute_provider_label(:name) }
- else - else
= form.text_field :name, label: s_('Profiles|Full name'), required: true, title: s_("Profiles|Using emojis in names seems fun, but please try to set a status message instead"), wrapper: { class: 'col-md-9 qa-full-name rspec-full-name' }, help: s_("Profiles|Enter your name, so people you know can recognize you") = form.text_field :name, class: 'gl-form-input', label: s_('Profiles|Full name'), required: true, title: s_("Profiles|Using emojis in names seems fun, but please try to set a status message instead"), wrapper: { class: 'col-md-9 qa-full-name rspec-full-name' }, help: s_("Profiles|Enter your name, so people you know can recognize you")
...@@ -65,7 +65,7 @@ ...@@ -65,7 +65,7 @@
= status_form.hidden_field :emoji, id: 'js-status-emoji-field' = status_form.hidden_field :emoji, id: 'js-status-emoji-field'
= status_form.text_field :message, = status_form.text_field :message,
id: 'js-status-message-field', id: 'js-status-message-field',
class: 'form-control input-lg', class: 'form-control gl-form-input input-lg',
label: s_("Profiles|Your status"), label: s_("Profiles|Your status"),
prepend: emoji_button, prepend: emoji_button,
append: reset_message_button, append: reset_message_button,
...@@ -100,20 +100,20 @@ ...@@ -100,20 +100,20 @@
.col-lg-8 .col-lg-8
.row .row
= render 'profiles/name', form: f, user: @user = render 'profiles/name', form: f, user: @user
= f.text_field :id, readonly: true, label: s_('Profiles|User ID'), wrapper: { class: 'col-md-3' } = f.text_field :id, class: 'gl-form-input', readonly: true, label: s_('Profiles|User ID'), wrapper: { class: 'col-md-3' }
= render_if_exists 'profiles/email_settings', form: f = render_if_exists 'profiles/email_settings', form: f
= f.text_field :skype, class: 'input-md', placeholder: s_("Profiles|username") = f.text_field :skype, class: 'input-md gl-form-input', placeholder: s_("Profiles|username")
= f.text_field :linkedin, class: 'input-md', help: s_("Profiles|Your LinkedIn profile name from linkedin.com/in/profilename") = f.text_field :linkedin, class: 'input-md gl-form-input', help: s_("Profiles|Your LinkedIn profile name from linkedin.com/in/profilename")
= f.text_field :twitter, class: 'input-md', placeholder: s_("Profiles|@username") = f.text_field :twitter, class: 'input-md gl-form-input', placeholder: s_("Profiles|@username")
= f.text_field :website_url, class: 'input-lg', placeholder: s_("Profiles|website.com") = f.text_field :website_url, class: 'input-lg gl-form-input', placeholder: s_("Profiles|website.com")
- if @user.read_only_attribute?(:location) - if @user.read_only_attribute?(:location)
= f.text_field :location, readonly: true, help: s_("Profiles|Your location was automatically set based on your %{provider_label} account") % { provider_label: attribute_provider_label(:location) } = f.text_field :location, class: 'gl-form-input', readonly: true, help: s_("Profiles|Your location was automatically set based on your %{provider_label} account") % { provider_label: attribute_provider_label(:location) }
- else - else
= f.text_field :location, label: s_('Profiles|Location'), class: 'input-lg', placeholder: s_("Profiles|City, country") = f.text_field :location, label: s_('Profiles|Location'), class: 'input-lg gl-form-input', placeholder: s_("Profiles|City, country")
= f.text_field :job_title, class: 'input-md' = f.text_field :job_title, class: 'input-md gl-form-input'
= f.text_field :organization, label: s_('Profiles|Organization'), class: 'input-md', help: s_("Profiles|Who you represent or work for") = f.text_field :organization, label: s_('Profiles|Organization'), class: 'input-md gl-form-input', help: s_("Profiles|Who you represent or work for")
= f.text_area :bio, label: s_('Profiles|Bio'), rows: 4, maxlength: 250, help: s_("Profiles|Tell us about yourself in fewer than 250 characters") = f.text_area :bio, class: 'gl-form-input', label: s_('Profiles|Bio'), rows: 4, maxlength: 250, help: s_("Profiles|Tell us about yourself in fewer than 250 characters")
%hr %hr
%h5= s_("Private profile") %h5= s_("Private profile")
.checkbox-icon-inline-wrapper .checkbox-icon-inline-wrapper
......
- f ||= local_assigns[:f] - f ||= local_assigns[:f]
.project-templates-buttons.col-sm-12 .project-templates-buttons
%ul.nav-tabs.nav-links.nav.scrolling-tabs %ul.nav-tabs.nav-links.nav.scrolling-tabs
%li.built-in-tab %li.built-in-tab
%a.nav-link.active{ href: "#built-in", data: { toggle: 'tab'} } %a.nav-link.active{ href: "#built-in", data: { toggle: 'tab'} }
......
- page_title _("Members") - page_title _("Members")
- group = @project.group - group = @project.group
- vue_project_members_list_enabled = Feature.enabled?(:vue_project_members_list, @project) - vue_project_members_list_enabled = Feature.enabled?(:vue_project_members_list, @project, default_enabled: :yaml)
.js-remove-member-modal .js-remove-member-modal
.row.gl-mt-3 .row.gl-mt-3
......
...@@ -12,4 +12,4 @@ ...@@ -12,4 +12,4 @@
data: todo_button_data } data: todo_button_data }
%span.issuable-todo-inner.js-issuable-todo-inner< %span.issuable-todo-inner.js-issuable-todo-inner<
= is_collapsed ? button_icon : button_title = is_collapsed ? button_icon : button_title
= loading_icon = loading_icon(css_class: is_collapsed ? '' : 'gl-ml-3')
---
title: Improve project members management, filtering, and sorting
merge_request: 53935
author:
type: changed
---
title: Apply new GitLab UI for buttons in new group page
merge_request: 53456
author: Yogi (@yo)
type: other
---
title: Add btn-default class for social buttons in login and signup page
merge_request: 53347
author: Yogi (@yo)
type: other
---
title: Apply new GitLab UI for input field in user profile settings
merge_request: 52424
author: Yogi (@yo)
type: other
---
title: Add Space before loading icon in toggle todo button
merge_request: 53463
author: Yogi (@yo)
type: other
---
title: Remove gl-text-black-normal from detailed metric which is not visible in dark
mode
merge_request: 53563
author: Yogi (@yo)
type: other
---
title: Remove extra margin below tab on project template page
merge_request: 52454
author: Yogi (@yo)
type: fixed
...@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/299954 ...@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/299954
milestone: '13.9' milestone: '13.9'
type: development type: development
group: group::access group: group::access
default_enabled: false default_enabled: true
# frozen_string_literal: true
require './spec/support/sidekiq_middleware'
class Gitlab::Seeder::ComposerPackages
def group
@group ||= Group.find_by(path: 'composer')
unless @group
@group = Group.create!(
name: 'Composer',
path: 'composer',
description: FFaker::Lorem.sentence
)
@group.add_owner(user)
@group.create_namespace_settings
end
@group
end
def user
@user ||= User.first
end
def create_real_project!(url)
project_path = url.split('/').last
project_path.gsub!(".git", "")
project = group.projects.find_by(name: project_path.titleize)
return project if project.present?
params = {
import_url: url,
namespace_id: group.id,
name: project_path.titleize,
description: FFaker::Lorem.sentence,
visibility_level: Gitlab::VisibilityLevel.values.sample,
skip_disk_validation: true
}
Sidekiq::Worker.skipping_transaction_check do
project = ::Projects::CreateService.new(user, params).execute
# Seed-Fu runs this entire fixture in a transaction, so the `after_commit`
# hook won't run until after the fixture is loaded. That is too late
# since the Sidekiq::Testing block has already exited. Force clearing
# the `after_commit` queue to ensure the job is run now.
project.send(:_run_after_commit_queue)
project.import_state.send(:_run_after_commit_queue)
# Expire repository cache after import to ensure
# valid_repo? call below returns a correct answer
project.repository.expire_all_method_caches
end
if project.valid? && project.valid_repo?
print '.'
return project
else
puts project.errors.full_messages
print 'F'
return nil
end
end
end
COMPOSER_PACKAGES = {
'https://github.com/php-fig/log.git' => [
{ branch: 'master' },
{ tag: 'v1.5.2' }
],
'https://github.com/ryssbowh/craft-themes.git' => [
{ tag: '1.0.2' }
],
'https://github.com/php-fig/http-message.git' => [
{ tag: '1.0.1' }
],
'https://github.com/doctrine/instantiator.git' => [
{ branch: '1.4.x' }
]
}.freeze
Gitlab::Seeder.quiet do
flag = 'SEED_COMPOSER'
unless ENV[flag]
puts "Use the `#{flag}` environment variable to seed composer packages"
next
end
Sidekiq::Testing.inline! do
COMPOSER_PACKAGES.each do |path, versions|
project = Gitlab::Seeder::ComposerPackages.new.create_real_project!(path)
versions.each do |version|
params = {}
if version[:branch]
params[:branch] = project.repository.find_branch(version[:branch])
elsif version[:tag]
params[:tag] = project.repository.find_tag(version[:tag])
end
if params[:branch].nil? && params[:tag].nil?
puts "version #{version.inspect} not found"
next
end
::Packages::Composer::CreatePackageService
.new(project, project.owner, params)
.execute
puts "version #{version.inspect} created!"
end
end
end
end
This diff is collapsed.
...@@ -69,7 +69,7 @@ The `whitespace` tokenizer was selected in order to have more control over how t ...@@ -69,7 +69,7 @@ The `whitespace` tokenizer was selected in order to have more control over how t
Please see the `code` filter for an explanation on how tokens are split. Please see the `code` filter for an explanation on how tokens are split.
NOTE: NOTE:
Currently the [Elasticsearch code_analyzer doesn't account for all code cases](../integration/elasticsearch.md#known-issues). The [Elasticsearch code_analyzer doesn't account for all code cases](../integration/elasticsearch.md#elasticsearch-code_analyzer-doesnt-account-for-all-code-cases).
#### `code_search_analyzer` #### `code_search_analyzer`
......
...@@ -668,6 +668,23 @@ However, some larger installations may wish to tune the merge policy settings: ...@@ -668,6 +668,23 @@ However, some larger installations may wish to tune the merge policy settings:
- Do not do a [force merge](https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-forcemerge.html "Force Merge") to remove deleted documents. A warning in the [documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-forcemerge.html "Force Merge") states that this can lead to very large segments that may never get reclaimed, and can also cause significant performance or availability issues. - Do not do a [force merge](https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-forcemerge.html "Force Merge") to remove deleted documents. A warning in the [documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-forcemerge.html "Force Merge") states that this can lead to very large segments that may never get reclaimed, and can also cause significant performance or availability issues.
## Reverting to Basic Search
Sometimes there may be issues with your Elasticsearch index data and as such
GitLab will allow you to revert to "basic search" when there are no search
results and assuming that basic search is supported in that scope. This "basic
search" will behave as though you don't have Advanced Search enabled at all for
your instance and search using other data sources (such as PostgreSQL data and Git
data).
## Data recovery: Elasticsearch is a secondary data store only
The use of Elasticsearch in GitLab is only ever as a secondary data store.
This means that all of the data stored in Elasticsearch can always be derived
again from other data sources, specifically PostgreSQL and Gitaly. Therefore, if
the Elasticsearch data store is ever corrupted for whatever reason, you can
simply reindex everything from scratch.
## Troubleshooting ## Troubleshooting
One of the most valuable tools for identifying issues with the Elasticsearch One of the most valuable tools for identifying issues with the Elasticsearch
...@@ -849,27 +866,12 @@ problem. ...@@ -849,27 +866,12 @@ problem.
There is a [more structured, lower-level troubleshooting document](../administration/troubleshooting/elasticsearch.md) for when you experience other issues, including poor performance. There is a [more structured, lower-level troubleshooting document](../administration/troubleshooting/elasticsearch.md) for when you experience other issues, including poor performance.
### Known issues ### Elasticsearch `code_analyzer` doesn't account for all code cases
[Elasticsearch `code_analyzer` doesn't account for all code cases](https://gitlab.com/groups/gitlab-org/-/epics/3621).
The `code_analyzer` pattern and filter configuration is being evaluated for improvement. We have fixed [most edge cases](https://gitlab.com/groups/gitlab-org/-/epics/3621#note_363429094) that were not returning expected search results due to our pattern and filter configuration. The `code_analyzer` pattern and filter configuration is being evaluated for improvement. We have fixed [most edge cases](https://gitlab.com/groups/gitlab-org/-/epics/3621#note_363429094) that were not returning expected search results due to our pattern and filter configuration.
Improvements to the `code_analyzer` pattern and filters are being discussed in [epic 3621](https://gitlab.com/groups/gitlab-org/-/epics/3621). Improvements to the `code_analyzer` pattern and filters are being discussed in [epic 3621](https://gitlab.com/groups/gitlab-org/-/epics/3621).
### Reverting to Basic Search ### Some binary files may not be searchable by name
Sometimes there may be issues with your Elasticsearch index data and as such
GitLab will allow you to revert to "basic search" when there are no search
results and assuming that basic search is supported in that scope. This "basic
search" will behave as though you don't have Advanced Search enabled at all for
your instance and search using other data sources (such as PostgreSQL data and Git
data).
### Data recovery: Elasticsearch is a secondary data store only
The use of Elasticsearch in GitLab is only ever as a secondary data store. In GitLab 13.9, a change was made where [binary file names are being indexed](https://gitlab.com/gitlab-org/gitlab/-/issues/301083). However, without indexing all projects' data from scratch, only binary files that are added or updated after the GitLab 13.9 release are searchable.
This means that all of the data stored in Elasticsearch can always be derived
again from other data sources, specifically PostgreSQL and Gitaly. Therefore, if
the Elasticsearch data store is ever corrupted for whatever reason, you can
simply reindex everything from scratch.
...@@ -122,7 +122,6 @@ ...@@ -122,7 +122,6 @@
.template-header, .template-header,
.template-option { .template-option {
padding: $gl-padding $gl-padding-8; padding: $gl-padding $gl-padding-8;
border-top: 1px solid $border-color;
} }
.template-header { .template-header {
......
...@@ -10,22 +10,22 @@ module Types ...@@ -10,22 +10,22 @@ module Types
argument :id, argument :id,
::Types::GlobalIDType[::EpicTreeSorting], ::Types::GlobalIDType[::EpicTreeSorting],
required: true, required: true,
description: 'The ID of the epic_issue or epic that is being moved' description: 'The ID of the epic_issue or epic that is being moved.'
argument :adjacent_reference_id, argument :adjacent_reference_id,
::Types::GlobalIDType[::EpicTreeSorting], ::Types::GlobalIDType[::EpicTreeSorting],
required: false, required: false,
description: 'The ID of the epic_issue or issue that the actual epic or issue is switched with' description: 'The ID of the epic_issue or issue that the actual epic or issue is switched with.'
argument :relative_position, argument :relative_position,
MoveTypeEnum, MoveTypeEnum,
required: false, required: false,
description: 'The type of the switch, after or before allowed' description: 'The type of the switch, after or before allowed.'
argument :new_parent_id, argument :new_parent_id,
::Types::GlobalIDType[::Epic], ::Types::GlobalIDType[::Epic],
required: false, required: false,
description: 'ID of the new parent epic' description: 'ID of the new parent epic.'
end end
# rubocop: enable Graphql/AuthorizeTypes # rubocop: enable Graphql/AuthorizeTypes
end end
......
...@@ -7,25 +7,25 @@ module Types ...@@ -7,25 +7,25 @@ module Types
description 'Represents an external issue' description 'Represents an external issue'
field :title, GraphQL::STRING_TYPE, null: true, field :title, GraphQL::STRING_TYPE, null: true,
description: 'Title of the issue in the external tracker' description: 'Title of the issue in the external tracker.'
field :relative_reference, GraphQL::STRING_TYPE, null: true, field :relative_reference, GraphQL::STRING_TYPE, null: true,
description: 'Relative reference of the issue in the external tracker' description: 'Relative reference of the issue in the external tracker.'
field :status, GraphQL::STRING_TYPE, null: true, field :status, GraphQL::STRING_TYPE, null: true,
description: 'Status of the issue in the external tracker' description: 'Status of the issue in the external tracker.'
field :external_tracker, GraphQL::STRING_TYPE, null: true, field :external_tracker, GraphQL::STRING_TYPE, null: true,
description: 'Type of external tracker' description: 'Type of external tracker.'
field :web_url, GraphQL::STRING_TYPE, null: true, field :web_url, GraphQL::STRING_TYPE, null: true,
description: 'URL to the issue in the external tracker' description: 'URL to the issue in the external tracker.'
field :created_at, Types::TimeType, null: true, field :created_at, Types::TimeType, null: true,
description: 'Timestamp of when the issue was created' description: 'Timestamp of when the issue was created.'
field :updated_at, Types::TimeType, null: true, field :updated_at, Types::TimeType, null: true,
description: 'Timestamp of when the issue was updated' description: 'Timestamp of when the issue was updated.'
def relative_reference def relative_reference
object.dig(:references, :relative) object.dig(:references, :relative)
......
...@@ -7,37 +7,37 @@ module Types ...@@ -7,37 +7,37 @@ module Types
authorize :read_geo_node authorize :read_geo_node
field :id, GraphQL::ID_TYPE, null: false, description: 'ID of this GeoNode' field :id, GraphQL::ID_TYPE, null: false, description: 'ID of this GeoNode.'
field :primary, GraphQL::BOOLEAN_TYPE, null: true, description: 'Indicates whether this Geo node is the primary' field :primary, GraphQL::BOOLEAN_TYPE, null: true, description: 'Indicates whether this Geo node is the primary.'
field :enabled, GraphQL::BOOLEAN_TYPE, null: true, description: 'Indicates whether this Geo node is enabled' field :enabled, GraphQL::BOOLEAN_TYPE, null: true, description: 'Indicates whether this Geo node is enabled.'
field :name, GraphQL::STRING_TYPE, null: true, description: 'The unique identifier for this Geo node' field :name, GraphQL::STRING_TYPE, null: true, description: 'The unique identifier for this Geo node.'
field :url, GraphQL::STRING_TYPE, null: true, description: 'The user-facing URL for this Geo node' field :url, GraphQL::STRING_TYPE, null: true, description: 'The user-facing URL for this Geo node.'
field :internal_url, GraphQL::STRING_TYPE, null: true, description: 'The URL defined on the primary node that secondary nodes should use to contact it' field :internal_url, GraphQL::STRING_TYPE, null: true, description: 'The URL defined on the primary node that secondary nodes should use to contact it.'
field :files_max_capacity, GraphQL::INT_TYPE, null: true, description: 'The maximum concurrency of LFS/attachment backfill for this secondary node' field :files_max_capacity, GraphQL::INT_TYPE, null: true, description: 'The maximum concurrency of LFS/attachment backfill for this secondary node.'
field :repos_max_capacity, GraphQL::INT_TYPE, null: true, description: 'The maximum concurrency of repository backfill for this secondary node' field :repos_max_capacity, GraphQL::INT_TYPE, null: true, description: 'The maximum concurrency of repository backfill for this secondary node.'
field :verification_max_capacity, GraphQL::INT_TYPE, null: true, description: 'The maximum concurrency of repository verification for this secondary node' field :verification_max_capacity, GraphQL::INT_TYPE, null: true, description: 'The maximum concurrency of repository verification for this secondary node.'
field :container_repositories_max_capacity, GraphQL::INT_TYPE, null: true, description: 'The maximum concurrency of container repository sync for this secondary node' field :container_repositories_max_capacity, GraphQL::INT_TYPE, null: true, description: 'The maximum concurrency of container repository sync for this secondary node.'
field :sync_object_storage, GraphQL::BOOLEAN_TYPE, null: true, description: 'Indicates if this secondary node will replicate blobs in Object Storage' field :sync_object_storage, GraphQL::BOOLEAN_TYPE, null: true, description: 'Indicates if this secondary node will replicate blobs in Object Storage.'
field :selective_sync_type, GraphQL::STRING_TYPE, null: true, description: 'Indicates if syncing is limited to only specific groups, or shards' field :selective_sync_type, GraphQL::STRING_TYPE, null: true, description: 'Indicates if syncing is limited to only specific groups, or shards.'
field :selective_sync_shards, type: [GraphQL::STRING_TYPE], null: true, description: 'The repository storages whose projects should be synced, if `selective_sync_type` == `shards`' field :selective_sync_shards, type: [GraphQL::STRING_TYPE], null: true, description: 'The repository storages whose projects should be synced, if `selective_sync_type` == `shards`.'
field :selective_sync_namespaces, ::Types::NamespaceType.connection_type, null: true, method: :namespaces, description: 'The namespaces that should be synced, if `selective_sync_type` == `namespaces`' field :selective_sync_namespaces, ::Types::NamespaceType.connection_type, null: true, method: :namespaces, description: 'The namespaces that should be synced, if `selective_sync_type` == `namespaces`.'
field :minimum_reverification_interval, GraphQL::INT_TYPE, null: true, description: 'The interval (in days) in which the repository verification is valid. Once expired, it will be reverified' field :minimum_reverification_interval, GraphQL::INT_TYPE, null: true, description: 'The interval (in days) in which the repository verification is valid. Once expired, it will be reverified.'
field :merge_request_diff_registries, ::Types::Geo::MergeRequestDiffRegistryType.connection_type, field :merge_request_diff_registries, ::Types::Geo::MergeRequestDiffRegistryType.connection_type,
null: true, null: true,
resolver: ::Resolvers::Geo::MergeRequestDiffRegistriesResolver, resolver: ::Resolvers::Geo::MergeRequestDiffRegistriesResolver,
description: 'Find merge request diff registries on this Geo node' description: 'Find merge request diff registries on this Geo node.'
field :package_file_registries, ::Types::Geo::PackageFileRegistryType.connection_type, field :package_file_registries, ::Types::Geo::PackageFileRegistryType.connection_type,
null: true, null: true,
resolver: ::Resolvers::Geo::PackageFileRegistriesResolver, resolver: ::Resolvers::Geo::PackageFileRegistriesResolver,
description: 'Package file registries of the GeoNode' description: 'Package file registries of the GeoNode.'
field :snippet_repository_registries, ::Types::Geo::SnippetRepositoryRegistryType.connection_type, field :snippet_repository_registries, ::Types::Geo::SnippetRepositoryRegistryType.connection_type,
null: true, null: true,
resolver: ::Resolvers::Geo::SnippetRepositoryRegistriesResolver, resolver: ::Resolvers::Geo::SnippetRepositoryRegistriesResolver,
description: 'Find snippet repository registries on this Geo node' description: 'Find snippet repository registries on this Geo node.'
field :terraform_state_version_registries, ::Types::Geo::TerraformStateVersionRegistryType.connection_type, field :terraform_state_version_registries, ::Types::Geo::TerraformStateVersionRegistryType.connection_type,
null: true, null: true,
resolver: ::Resolvers::Geo::TerraformStateVersionRegistriesResolver, resolver: ::Resolvers::Geo::TerraformStateVersionRegistriesResolver,
description: 'Find terraform state version registries on this Geo node' description: 'Find terraform state version registries on this Geo node.'
end end
end end
end end
...@@ -9,7 +9,7 @@ module Types ...@@ -9,7 +9,7 @@ module Types
graphql_name 'MergeRequestDiffRegistry' graphql_name 'MergeRequestDiffRegistry'
description 'Represents the Geo sync and verification state of a Merge Request diff' description 'Represents the Geo sync and verification state of a Merge Request diff'
field :merge_request_diff_id, GraphQL::ID_TYPE, null: false, description: 'ID of the Merge Request diff' field :merge_request_diff_id, GraphQL::ID_TYPE, null: false, description: 'ID of the Merge Request diff.'
end end
end end
end end
...@@ -9,7 +9,7 @@ module Types ...@@ -9,7 +9,7 @@ module Types
graphql_name 'PackageFileRegistry' graphql_name 'PackageFileRegistry'
description 'Represents the Geo sync and verification state of a package file' description 'Represents the Geo sync and verification state of a package file'
field :package_file_id, GraphQL::ID_TYPE, null: false, description: 'ID of the PackageFile' field :package_file_id, GraphQL::ID_TYPE, null: false, description: 'ID of the PackageFile.'
end end
end end
end end
...@@ -9,7 +9,7 @@ module Types ...@@ -9,7 +9,7 @@ module Types
graphql_name 'SnippetRepositoryRegistry' graphql_name 'SnippetRepositoryRegistry'
description 'Represents the Geo sync and verification state of a snippet repository' description 'Represents the Geo sync and verification state of a snippet repository'
field :snippet_repository_id, GraphQL::ID_TYPE, null: false, description: 'ID of the Snippet Repository' field :snippet_repository_id, GraphQL::ID_TYPE, null: false, description: 'ID of the Snippet Repository.'
end end
end end
end end
...@@ -9,7 +9,7 @@ module Types ...@@ -9,7 +9,7 @@ module Types
graphql_name 'TerraformStateVersionRegistry' graphql_name 'TerraformStateVersionRegistry'
description 'Represents the Geo sync and verification state of a terraform state version' description 'Represents the Geo sync and verification state of a terraform state version'
field :terraform_state_version_id, GraphQL::ID_TYPE, null: false, description: 'ID of the terraform state version' field :terraform_state_version_id, GraphQL::ID_TYPE, null: false, description: 'ID of the terraform state version.'
end end
end end
end end
...@@ -9,6 +9,6 @@ module Types ...@@ -9,6 +9,6 @@ module Types
field :release_stats, Types::GroupReleaseStatsType, field :release_stats, Types::GroupReleaseStatsType,
null: true, method: :itself, null: true, method: :itself,
description: 'Statistics related to releases within the group' description: 'Statistics related to releases within the group.'
end end
end end
...@@ -11,27 +11,27 @@ module Types ...@@ -11,27 +11,27 @@ module Types
field :iid, field :iid,
GraphQL::ID_TYPE, GraphQL::ID_TYPE,
null: false, null: false,
description: 'Internal ID of the on-call schedule' description: 'Internal ID of the on-call schedule.'
field :name, field :name,
GraphQL::STRING_TYPE, GraphQL::STRING_TYPE,
null: false, null: false,
description: 'Name of the on-call schedule' description: 'Name of the on-call schedule.'
field :description, field :description,
GraphQL::STRING_TYPE, GraphQL::STRING_TYPE,
null: true, null: true,
description: 'Description of the on-call schedule' description: 'Description of the on-call schedule.'
field :timezone, field :timezone,
GraphQL::STRING_TYPE, GraphQL::STRING_TYPE,
null: false, null: false,
description: 'Time zone of the on-call schedule' description: 'Time zone of the on-call schedule.'
field :rotations, field :rotations,
OncallRotationType.connection_type, OncallRotationType.connection_type,
null: false, null: false,
description: 'On-call rotations for the on-call schedule' description: 'On-call rotations for the on-call schedule.'
end end
end end
end end
...@@ -9,22 +9,22 @@ module Types ...@@ -9,22 +9,22 @@ module Types
field :projects, field :projects,
Types::ProjectType.connection_type, Types::ProjectType.connection_type,
null: false, null: false,
description: 'Projects selected in Instance Security Dashboard' description: 'Projects selected in Instance Security Dashboard.'
field :vulnerability_scanners, field :vulnerability_scanners,
::Types::VulnerabilityScannerType.connection_type, ::Types::VulnerabilityScannerType.connection_type,
null: true, null: true,
description: 'Vulnerability scanners reported on the vulnerabilities from projects selected in Instance Security Dashboard', description: 'Vulnerability scanners reported on the vulnerabilities from projects selected in Instance Security Dashboard.',
resolver: ::Resolvers::Vulnerabilities::ScannersResolver resolver: ::Resolvers::Vulnerabilities::ScannersResolver
field :vulnerability_severities_count, ::Types::VulnerabilitySeveritiesCountType, null: true, field :vulnerability_severities_count, ::Types::VulnerabilitySeveritiesCountType, null: true,
description: 'Counts for each vulnerability severity from projects selected in Instance Security Dashboard', description: 'Counts for each vulnerability severity from projects selected in Instance Security Dashboard.',
resolver: ::Resolvers::VulnerabilitySeveritiesCountResolver resolver: ::Resolvers::VulnerabilitySeveritiesCountResolver
field :vulnerability_grades, field :vulnerability_grades,
[Types::VulnerableProjectsByGradeType], [Types::VulnerableProjectsByGradeType],
null: false, null: false,
description: 'Represents vulnerable project counts for each grade' description: 'Represents vulnerable project counts for each grade.'
def vulnerability_grades def vulnerability_grades
::Gitlab::Graphql::Aggregations::VulnerabilityStatistics::LazyAggregate.new( ::Gitlab::Graphql::Aggregations::VulnerabilityStatistics::LazyAggregate.new(
......
...@@ -12,43 +12,43 @@ module Types ...@@ -12,43 +12,43 @@ module Types
implements ::Types::TimeboxReportInterface implements ::Types::TimeboxReportInterface
field :id, GraphQL::ID_TYPE, null: false, field :id, GraphQL::ID_TYPE, null: false,
description: 'ID of the iteration' description: 'ID of the iteration.'
field :iid, GraphQL::ID_TYPE, null: false, field :iid, GraphQL::ID_TYPE, null: false,
description: 'Internal ID of the iteration' description: 'Internal ID of the iteration.'
field :title, GraphQL::STRING_TYPE, null: false, field :title, GraphQL::STRING_TYPE, null: false,
description: 'Title of the iteration' description: 'Title of the iteration.'
field :description, GraphQL::STRING_TYPE, null: true, field :description, GraphQL::STRING_TYPE, null: true,
description: 'Description of the iteration' description: 'Description of the iteration.'
markdown_field :description_html, null: true markdown_field :description_html, null: true
field :state, Types::IterationStateEnum, null: false, field :state, Types::IterationStateEnum, null: false,
description: 'State of the iteration' description: 'State of the iteration.'
field :web_path, GraphQL::STRING_TYPE, null: false, method: :iteration_path, field :web_path, GraphQL::STRING_TYPE, null: false, method: :iteration_path,
description: 'Web path of the iteration' description: 'Web path of the iteration.'
field :web_url, GraphQL::STRING_TYPE, null: false, method: :iteration_url, field :web_url, GraphQL::STRING_TYPE, null: false, method: :iteration_url,
description: 'Web URL of the iteration' description: 'Web URL of the iteration.'
field :scoped_path, GraphQL::STRING_TYPE, null: true, method: :scoped_iteration_path, extras: [:parent], field :scoped_path, GraphQL::STRING_TYPE, null: true, method: :scoped_iteration_path, extras: [:parent],
description: 'Web path of the iteration, scoped to the query parent. Only valid for Project parents. Returns null in other contexts' description: 'Web path of the iteration, scoped to the query parent. Only valid for Project parents. Returns null in other contexts.'
field :scoped_url, GraphQL::STRING_TYPE, null: true, method: :scoped_iteration_url, extras: [:parent], field :scoped_url, GraphQL::STRING_TYPE, null: true, method: :scoped_iteration_url, extras: [:parent],
description: 'Web URL of the iteration, scoped to the query parent. Only valid for Project parents. Returns null in other contexts' description: 'Web URL of the iteration, scoped to the query parent. Only valid for Project parents. Returns null in other contexts.'
field :due_date, Types::TimeType, null: true, field :due_date, Types::TimeType, null: true,
description: 'Timestamp of the iteration due date' description: 'Timestamp of the iteration due date.'
field :start_date, Types::TimeType, null: true, field :start_date, Types::TimeType, null: true,
description: 'Timestamp of the iteration start date' description: 'Timestamp of the iteration start date.'
field :created_at, Types::TimeType, null: false, field :created_at, Types::TimeType, null: false,
description: 'Timestamp of iteration creation' description: 'Timestamp of iteration creation.'
field :updated_at, Types::TimeType, null: false, field :updated_at, Types::TimeType, null: false,
description: 'Timestamp of last iteration update' description: 'Timestamp of last iteration update.'
end end
end end
...@@ -8,19 +8,19 @@ module Types ...@@ -8,19 +8,19 @@ module Types
authorize :read_issuable_metric_image authorize :read_issuable_metric_image
field :id, GraphQL::ID_TYPE, null: false, field :id, GraphQL::ID_TYPE, null: false,
description: 'ID of the metric upload' description: 'ID of the metric upload.'
field :iid, GraphQL::ID_TYPE, null: false, field :iid, GraphQL::ID_TYPE, null: false,
description: 'Internal ID of the metric upload' description: 'Internal ID of the metric upload.'
field :url, GraphQL::STRING_TYPE, null: false, field :url, GraphQL::STRING_TYPE, null: false,
description: 'URL of the metric source' description: 'URL of the metric source.'
field :file_name, GraphQL::STRING_TYPE, null: true, field :file_name, GraphQL::STRING_TYPE, null: true,
description: 'File name of the metric image', description: 'File name of the metric image.',
method: :filename method: :filename
field :file_path, GraphQL::STRING_TYPE, null: true, field :file_path, GraphQL::STRING_TYPE, null: true,
description: 'File path of the metric image' description: 'File path of the metric image.'
end end
end end
...@@ -7,8 +7,8 @@ module Types ...@@ -7,8 +7,8 @@ module Types
graphql_name 'RequirementStatesCount' graphql_name 'RequirementStatesCount'
description 'Counts of requirements by their state' description 'Counts of requirements by their state'
field :opened, GraphQL::INT_TYPE, null: true, description: 'Number of opened requirements' field :opened, GraphQL::INT_TYPE, null: true, description: 'Number of opened requirements.'
field :archived, GraphQL::INT_TYPE, null: true, description: 'Number of archived requirements' field :archived, GraphQL::INT_TYPE, null: true, description: 'Number of archived requirements.'
end end
# rubocop: enable Graphql/AuthorizeTypes # rubocop: enable Graphql/AuthorizeTypes
end end
......
...@@ -11,46 +11,46 @@ module Types ...@@ -11,46 +11,46 @@ module Types
expose_permissions Types::PermissionTypes::Requirement expose_permissions Types::PermissionTypes::Requirement
field :id, GraphQL::ID_TYPE, null: false, field :id, GraphQL::ID_TYPE, null: false,
description: 'ID of the requirement' description: 'ID of the requirement.'
field :iid, GraphQL::ID_TYPE, null: false, field :iid, GraphQL::ID_TYPE, null: false,
description: 'Internal ID of the requirement' description: 'Internal ID of the requirement.'
field :title, GraphQL::STRING_TYPE, null: true, field :title, GraphQL::STRING_TYPE, null: true,
description: 'Title of the requirement' description: 'Title of the requirement.'
markdown_field :title_html, null: true markdown_field :title_html, null: true
field :description, GraphQL::STRING_TYPE, null: true, field :description, GraphQL::STRING_TYPE, null: true,
description: 'Description of the requirement' description: 'Description of the requirement.'
markdown_field :description_html, null: true markdown_field :description_html, null: true
field :state, RequirementsManagement::RequirementStateEnum, null: false, field :state, RequirementsManagement::RequirementStateEnum, null: false,
description: 'State of the requirement' description: 'State of the requirement.'
field :last_test_report_state, RequirementsManagement::TestReportStateEnum, null: true, field :last_test_report_state, RequirementsManagement::TestReportStateEnum, null: true,
description: 'Latest requirement test report state' description: 'Latest requirement test report state.'
field :last_test_report_manually_created, field :last_test_report_manually_created,
GraphQL::BOOLEAN_TYPE, GraphQL::BOOLEAN_TYPE,
method: :last_test_report_manually_created?, method: :last_test_report_manually_created?,
null: true, null: true,
description: 'Indicates if latest test report was created by user' description: 'Indicates if latest test report was created by user.'
field :project, ProjectType, null: false, field :project, ProjectType, null: false,
description: 'Project to which the requirement belongs' description: 'Project to which the requirement belongs.'
field :author, UserType, null: false, field :author, UserType, null: false,
description: 'Author of the requirement' description: 'Author of the requirement.'
field :test_reports, TestReportType.connection_type, null: true, complexity: 5, field :test_reports, TestReportType.connection_type, null: true, complexity: 5,
description: 'Test reports of the requirement', description: 'Test reports of the requirement.',
resolver: Resolvers::RequirementsManagement::TestReportsResolver resolver: Resolvers::RequirementsManagement::TestReportsResolver
field :created_at, Types::TimeType, null: false, field :created_at, Types::TimeType, null: false,
description: 'Timestamp of when the requirement was created' description: 'Timestamp of when the requirement was created.'
field :updated_at, Types::TimeType, null: false, field :updated_at, Types::TimeType, null: false,
description: 'Timestamp of when the requirement was last updated' description: 'Timestamp of when the requirement was last updated.'
def project def project
Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find
......
...@@ -9,16 +9,16 @@ module Types ...@@ -9,16 +9,16 @@ module Types
authorize :read_requirement authorize :read_requirement
field :id, GraphQL::ID_TYPE, null: false, field :id, GraphQL::ID_TYPE, null: false,
description: 'ID of the test report' description: 'ID of the test report.'
field :state, TestReportStateEnum, null: false, field :state, TestReportStateEnum, null: false,
description: 'State of the test report' description: 'State of the test report.'
field :author, UserType, null: true, field :author, UserType, null: true,
description: 'Author of the test report' description: 'Author of the test report.'
field :created_at, TimeType, null: false, field :created_at, TimeType, null: false,
description: 'Timestamp of when the test report was created' description: 'Timestamp of when the test report was created.'
def author def author
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find
......
...@@ -6,7 +6,7 @@ module Types ...@@ -6,7 +6,7 @@ module Types
graphql_name 'ScannedResource' graphql_name 'ScannedResource'
description 'Represents a resource scanned by a security scan' description 'Represents a resource scanned by a security scan'
field :url, GraphQL::STRING_TYPE, null: true, description: 'The URL scanned by the scanner' field :url, GraphQL::STRING_TYPE, null: true, description: 'The URL scanned by the scanner.'
field :request_method, GraphQL::STRING_TYPE, null: true, description: 'The HTTP request method used to access the URL' field :request_method, GraphQL::STRING_TYPE, null: true, description: 'The HTTP request method used to access the URL.'
end end
end end
...@@ -6,9 +6,9 @@ module Types ...@@ -6,9 +6,9 @@ module Types
graphql_name 'SecurityReportSummarySection' graphql_name 'SecurityReportSummarySection'
description 'Represents a section of a summary of a security report' description 'Represents a section of a summary of a security report'
field :vulnerabilities_count, GraphQL::INT_TYPE, null: true, description: 'Total number of vulnerabilities' field :vulnerabilities_count, GraphQL::INT_TYPE, null: true, description: 'Total number of vulnerabilities.'
field :scanned_resources_count, GraphQL::INT_TYPE, null: true, description: 'Total number of scanned resources' field :scanned_resources_count, GraphQL::INT_TYPE, null: true, description: 'Total number of scanned resources.'
field :scanned_resources, ::Types::ScannedResourceType.connection_type, null: true, description: 'A list of the first 20 scanned resources' field :scanned_resources, ::Types::ScannedResourceType.connection_type, null: true, description: 'A list of the first 20 scanned resources.'
field :scanned_resources_csv_path, GraphQL::STRING_TYPE, null: true, description: 'Path to download all the scanned resources in CSV format' field :scanned_resources_csv_path, GraphQL::STRING_TYPE, null: true, description: 'Path to download all the scanned resources in CSV format.'
end end
end end
...@@ -7,12 +7,12 @@ module Types ...@@ -7,12 +7,12 @@ module Types
description 'Represents the time report stats for timeboxes' description 'Represents the time report stats for timeboxes'
field :complete, ::Types::TimeboxMetricsType, null: true, field :complete, ::Types::TimeboxMetricsType, null: true,
description: 'Completed issues metrics' description: 'Completed issues metrics.'
field :incomplete, ::Types::TimeboxMetricsType, null: true, field :incomplete, ::Types::TimeboxMetricsType, null: true,
description: 'Incomplete issues metrics' description: 'Incomplete issues metrics.'
field :total, ::Types::TimeboxMetricsType, null: true, field :total, ::Types::TimeboxMetricsType, null: true,
description: 'Total issues metrics' description: 'Total issues metrics.'
end end
end end
...@@ -7,9 +7,9 @@ module Types ...@@ -7,9 +7,9 @@ module Types
description 'Represents measured stats metrics for timeboxes' description 'Represents measured stats metrics for timeboxes'
field :count, GraphQL::INT_TYPE, null: false, field :count, GraphQL::INT_TYPE, null: false,
description: 'The count metric' description: 'The count metric.'
field :weight, GraphQL::INT_TYPE, null: false, field :weight, GraphQL::INT_TYPE, null: false,
description: 'The weight metric' description: 'The weight metric.'
end end
end end
...@@ -6,7 +6,7 @@ module Types ...@@ -6,7 +6,7 @@ module Types
field :report, Types::TimeboxReportType, null: true, field :report, Types::TimeboxReportType, null: true,
resolver: ::Resolvers::TimeboxReportResolver, resolver: ::Resolvers::TimeboxReportResolver,
description: 'Historically accurate report about the timebox', description: 'Historically accurate report about the timebox.',
complexity: 175 complexity: 175
end end
end end
...@@ -7,8 +7,8 @@ module Types ...@@ -7,8 +7,8 @@ module Types
description 'Represents a historically accurate report about the timebox' description 'Represents a historically accurate report about the timebox'
field :stats, ::Types::TimeReportStatsType, null: true, field :stats, ::Types::TimeReportStatsType, null: true,
description: 'Represents the time report stats for the timebox' description: 'Represents the time report stats for the timebox.'
field :burnup_time_series, [::Types::BurnupChartDailyTotalsType], null: true, field :burnup_time_series, [::Types::BurnupChartDailyTotalsType], null: true,
description: 'Daily scope and completed totals for burnup charts' description: 'Daily scope and completed totals for burnup charts.'
end end
end end
...@@ -9,27 +9,27 @@ module Types ...@@ -9,27 +9,27 @@ module Types
field :spent_at, field :spent_at,
Types::TimeType, Types::TimeType,
null: true, null: true,
description: 'Timestamp of when the time tracked was spent at' description: 'Timestamp of when the time tracked was spent at.'
field :time_spent, field :time_spent,
GraphQL::INT_TYPE, GraphQL::INT_TYPE,
null: false, null: false,
description: 'The time spent displayed in seconds' description: 'The time spent displayed in seconds.'
field :user, field :user,
Types::UserType, Types::UserType,
null: false, null: false,
description: 'The user that logged the time' description: 'The user that logged the time.'
field :issue, field :issue,
Types::IssueType, Types::IssueType,
null: true, null: true,
description: 'The issue that logged time was added to' description: 'The issue that logged time was added to.'
field :note, field :note,
Types::Notes::NoteType, Types::Notes::NoteType,
null: true, null: true,
description: 'The note where the quick action to add the logged time was executed' description: 'The note where the quick action to add the logged time was executed.'
def user def user
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.user_id).find Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.user_id).find
......
...@@ -7,12 +7,12 @@ module Types ...@@ -7,12 +7,12 @@ module Types
description 'Represents the number of vulnerabilities for a particular severity on a particular day. This data is retained for 365 days' description 'Represents the number of vulnerabilities for a particular severity on a particular day. This data is retained for 365 days'
field :count, GraphQL::INT_TYPE, null: true, field :count, GraphQL::INT_TYPE, null: true,
description: 'Number of vulnerabilities' description: 'Number of vulnerabilities.'
field :day, GraphQL::Types::ISO8601Date, null: true, field :day, GraphQL::Types::ISO8601Date, null: true,
description: 'Date for the count' description: 'Date for the count.'
field :severity, VulnerabilitySeverityEnum, null: true, field :severity, VulnerabilitySeverityEnum, null: true,
description: 'Severity of the counted vulnerabilities' description: 'Severity of the counted vulnerabilities.'
end end
end end
...@@ -7,10 +7,10 @@ module Types ...@@ -7,10 +7,10 @@ module Types
description 'Represents the count of vulnerabilities by severity on a particular day. This data is retained for 365 days' description 'Represents the count of vulnerabilities by severity on a particular day. This data is retained for 365 days'
field :date, GraphQL::Types::ISO8601Date, null: false, field :date, GraphQL::Types::ISO8601Date, null: false,
description: 'Date for the count' description: 'Date for the count.'
field :total, GraphQL::INT_TYPE, null: false, field :total, GraphQL::INT_TYPE, null: false,
description: 'Total number of vulnerabilities on a particular day' description: 'Total number of vulnerabilities on a particular day.'
::Enums::Vulnerability.severity_levels.keys.each do |severity| ::Enums::Vulnerability.severity_levels.keys.each do |severity|
field severity.to_s, GraphQL::INT_TYPE, null: false, field severity.to_s, GraphQL::INT_TYPE, null: false,
......
...@@ -9,13 +9,13 @@ module Types ...@@ -9,13 +9,13 @@ module Types
authorize :read_vulnerability authorize :read_vulnerability
field :id, GlobalIDType[::Vulnerabilities::ExternalIssueLink], null: false, field :id, GlobalIDType[::Vulnerabilities::ExternalIssueLink], null: false,
description: 'GraphQL ID of the external issue link' description: 'GraphQL ID of the external issue link.'
field :link_type, ::Types::Vulnerability::ExternalIssueLinkTypeEnum, null: false, field :link_type, ::Types::Vulnerability::ExternalIssueLinkTypeEnum, null: false,
description: 'Type of the external issue link' description: 'Type of the external issue link.'
field :external_issue, ::Types::ExternalIssueType, null: true, field :external_issue, ::Types::ExternalIssueType, null: true,
description: 'The external issue attached to the issue link', description: 'The external issue attached to the issue link.',
resolver: Resolvers::ExternalIssueResolver resolver: Resolvers::ExternalIssueResolver
end end
end end
......
...@@ -8,13 +8,13 @@ module Types ...@@ -8,13 +8,13 @@ module Types
description 'Represents an issue link of a vulnerability' description 'Represents an issue link of a vulnerability'
field :id, GraphQL::ID_TYPE, null: false, field :id, GraphQL::ID_TYPE, null: false,
description: 'GraphQL ID of the vulnerability' description: 'GraphQL ID of the vulnerability.'
field :link_type, ::Types::Vulnerability::IssueLinkTypeEnum, null: false, field :link_type, ::Types::Vulnerability::IssueLinkTypeEnum, null: false,
description: "Type of the issue link" description: "Type of the issue link."
field :issue, ::Types::IssueType, null: false, field :issue, ::Types::IssueType, null: false,
description: 'The issue attached to issue link' description: 'The issue attached to issue link.'
end end
# rubocop: enable Graphql/AuthorizeTypes # rubocop: enable Graphql/AuthorizeTypes
end end
......
...@@ -7,16 +7,16 @@ module Types ...@@ -7,16 +7,16 @@ module Types
description 'Represents a vulnerability identifier' description 'Represents a vulnerability identifier'
field :name, GraphQL::STRING_TYPE, null: true, field :name, GraphQL::STRING_TYPE, null: true,
description: 'Name of the vulnerability identifier' description: 'Name of the vulnerability identifier.'
field :url, GraphQL::STRING_TYPE, null: true, field :url, GraphQL::STRING_TYPE, null: true,
description: 'URL of the vulnerability identifier' description: 'URL of the vulnerability identifier.'
field :external_type, GraphQL::STRING_TYPE, null: true, field :external_type, GraphQL::STRING_TYPE, null: true,
description: 'External type of the vulnerability identifier' description: 'External type of the vulnerability identifier.'
field :external_id, GraphQL::STRING_TYPE, null: true, field :external_id, GraphQL::STRING_TYPE, null: true,
description: 'External ID of the vulnerability identifier' description: 'External ID of the vulnerability identifier.'
end end
# rubocop: enable Graphql/AuthorizeTypes # rubocop: enable Graphql/AuthorizeTypes
end end
...@@ -8,13 +8,13 @@ module Types ...@@ -8,13 +8,13 @@ module Types
description 'Represents the location of a vulnerability found by a container security scan' description 'Represents the location of a vulnerability found by a container security scan'
field :dependency, ::Types::VulnerableDependencyType, null: true, field :dependency, ::Types::VulnerableDependencyType, null: true,
description: 'Dependency containing the vulnerability' description: 'Dependency containing the vulnerability.'
field :image, GraphQL::STRING_TYPE, null: true, field :image, GraphQL::STRING_TYPE, null: true,
description: 'Name of the vulnerable container image' description: 'Name of the vulnerable container image.'
field :operating_system, GraphQL::STRING_TYPE, null: true, field :operating_system, GraphQL::STRING_TYPE, null: true,
description: 'Operating system that runs on the vulnerable container image' description: 'Operating system that runs on the vulnerable container image.'
end end
end end
end end
...@@ -8,24 +8,24 @@ module Types ...@@ -8,24 +8,24 @@ module Types
description 'Represents the location of a vulnerability found by a Coverage Fuzzing scan' description 'Represents the location of a vulnerability found by a Coverage Fuzzing scan'
field :vulnerable_class, GraphQL::STRING_TYPE, null: true, field :vulnerable_class, GraphQL::STRING_TYPE, null: true,
description: 'Class containing the vulnerability', description: 'Class containing the vulnerability.',
hash_key: :class hash_key: :class
field :end_line, GraphQL::STRING_TYPE, null: true, field :end_line, GraphQL::STRING_TYPE, null: true,
description: 'Number of the last relevant line in the vulnerable file' description: 'Number of the last relevant line in the vulnerable file.'
field :file, GraphQL::STRING_TYPE, null: true, field :file, GraphQL::STRING_TYPE, null: true,
description: 'Path to the vulnerable file' description: 'Path to the vulnerable file.'
field :vulnerable_method, GraphQL::STRING_TYPE, null: true, field :vulnerable_method, GraphQL::STRING_TYPE, null: true,
description: 'Method containing the vulnerability', description: 'Method containing the vulnerability.',
hash_key: :method hash_key: :method
field :start_line, GraphQL::STRING_TYPE, null: true, field :start_line, GraphQL::STRING_TYPE, null: true,
description: 'Number of the first relevant line in the vulnerable file' description: 'Number of the first relevant line in the vulnerable file.'
field :blob_path, GraphQL::STRING_TYPE, null: true, field :blob_path, GraphQL::STRING_TYPE, null: true,
description: 'Blob path to the vulnerable file' description: 'Blob path to the vulnerable file.'
end end
end end
end end
...@@ -8,16 +8,16 @@ module Types ...@@ -8,16 +8,16 @@ module Types
description 'Represents the location of a vulnerability found by a DAST scan' description 'Represents the location of a vulnerability found by a DAST scan'
field :hostname, GraphQL::STRING_TYPE, null: true, field :hostname, GraphQL::STRING_TYPE, null: true,
description: 'Domain name of the vulnerable request' description: 'Domain name of the vulnerable request.'
field :param, GraphQL::STRING_TYPE, null: true, field :param, GraphQL::STRING_TYPE, null: true,
description: 'Query parameter for the URL on which the vulnerability occurred' description: 'Query parameter for the URL on which the vulnerability occurred.'
field :path, GraphQL::STRING_TYPE, null: true, field :path, GraphQL::STRING_TYPE, null: true,
description: 'URL path and query string of the vulnerable request' description: 'URL path and query string of the vulnerable request.'
field :request_method, GraphQL::STRING_TYPE, null: true, field :request_method, GraphQL::STRING_TYPE, null: true,
description: 'HTTP method of the vulnerable request' description: 'HTTP method of the vulnerable request.'
end end
end end
end end
...@@ -8,13 +8,13 @@ module Types ...@@ -8,13 +8,13 @@ module Types
description 'Represents the location of a vulnerability found by a dependency security scan' description 'Represents the location of a vulnerability found by a dependency security scan'
field :dependency, ::Types::VulnerableDependencyType, null: true, field :dependency, ::Types::VulnerableDependencyType, null: true,
description: 'Dependency containing the vulnerability' description: 'Dependency containing the vulnerability.'
field :file, GraphQL::STRING_TYPE, null: true, field :file, GraphQL::STRING_TYPE, null: true,
description: 'Path to the vulnerable file' description: 'Path to the vulnerable file.'
field :blob_path, GraphQL::STRING_TYPE, null: true, field :blob_path, GraphQL::STRING_TYPE, null: true,
description: 'Blob path to the vulnerable file' description: 'Blob path to the vulnerable file.'
end end
end end
end end
...@@ -8,24 +8,24 @@ module Types ...@@ -8,24 +8,24 @@ module Types
description 'Represents the location of a vulnerability found by a SAST scan' description 'Represents the location of a vulnerability found by a SAST scan'
field :vulnerable_class, GraphQL::STRING_TYPE, null: true, field :vulnerable_class, GraphQL::STRING_TYPE, null: true,
description: 'Class containing the vulnerability', description: 'Class containing the vulnerability.',
hash_key: :class hash_key: :class
field :end_line, GraphQL::STRING_TYPE, null: true, field :end_line, GraphQL::STRING_TYPE, null: true,
description: 'Number of the last relevant line in the vulnerable file' description: 'Number of the last relevant line in the vulnerable file.'
field :file, GraphQL::STRING_TYPE, null: true, field :file, GraphQL::STRING_TYPE, null: true,
description: 'Path to the vulnerable file' description: 'Path to the vulnerable file.'
field :vulnerable_method, GraphQL::STRING_TYPE, null: true, field :vulnerable_method, GraphQL::STRING_TYPE, null: true,
description: 'Method containing the vulnerability', description: 'Method containing the vulnerability.',
hash_key: :method hash_key: :method
field :start_line, GraphQL::STRING_TYPE, null: true, field :start_line, GraphQL::STRING_TYPE, null: true,
description: 'Number of the first relevant line in the vulnerable file' description: 'Number of the first relevant line in the vulnerable file.'
field :blob_path, GraphQL::STRING_TYPE, null: true, field :blob_path, GraphQL::STRING_TYPE, null: true,
description: 'Blob path to the vulnerable file' description: 'Blob path to the vulnerable file.'
end end
end end
end end
...@@ -8,24 +8,24 @@ module Types ...@@ -8,24 +8,24 @@ module Types
description 'Represents the location of a vulnerability found by a secret detection scan' description 'Represents the location of a vulnerability found by a secret detection scan'
field :vulnerable_class, GraphQL::STRING_TYPE, null: true, field :vulnerable_class, GraphQL::STRING_TYPE, null: true,
description: 'Class containing the vulnerability', description: 'Class containing the vulnerability.',
hash_key: :class hash_key: :class
field :end_line, GraphQL::STRING_TYPE, null: true, field :end_line, GraphQL::STRING_TYPE, null: true,
description: 'Number of the last relevant line in the vulnerable file' description: 'Number of the last relevant line in the vulnerable file.'
field :file, GraphQL::STRING_TYPE, null: true, field :file, GraphQL::STRING_TYPE, null: true,
description: 'Path to the vulnerable file' description: 'Path to the vulnerable file.'
field :vulnerable_method, GraphQL::STRING_TYPE, null: true, field :vulnerable_method, GraphQL::STRING_TYPE, null: true,
description: 'Method containing the vulnerability', description: 'Method containing the vulnerability.',
hash_key: :method hash_key: :method
field :start_line, GraphQL::STRING_TYPE, null: true, field :start_line, GraphQL::STRING_TYPE, null: true,
description: 'Number of the first relevant line in the vulnerable file' description: 'Number of the first relevant line in the vulnerable file.'
field :blob_path, GraphQL::STRING_TYPE, null: true, field :blob_path, GraphQL::STRING_TYPE, null: true,
description: 'Blob path to the vulnerable file' description: 'Blob path to the vulnerable file.'
end end
end end
end end
...@@ -8,15 +8,15 @@ module Types ...@@ -8,15 +8,15 @@ module Types
authorize :read_vulnerability_scanner authorize :read_vulnerability_scanner
field :name, GraphQL::STRING_TYPE, null: true, field :name, GraphQL::STRING_TYPE, null: true,
description: 'Name of the vulnerability scanner' description: 'Name of the vulnerability scanner.'
field :external_id, GraphQL::STRING_TYPE, null: true, field :external_id, GraphQL::STRING_TYPE, null: true,
description: 'External ID of the vulnerability scanner' description: 'External ID of the vulnerability scanner.'
field :vendor, GraphQL::STRING_TYPE, null: true, field :vendor, GraphQL::STRING_TYPE, null: true,
description: 'Vendor of the vulnerability scanner' description: 'Vendor of the vulnerability scanner.'
field :report_type, VulnerabilityReportTypeEnum, null: true, field :report_type, VulnerabilityReportTypeEnum, null: true,
description: 'Type of the vulnerability report' description: 'Type of the vulnerability report.'
end end
end end
...@@ -12,13 +12,13 @@ module Types ...@@ -12,13 +12,13 @@ module Types
expose_permissions Types::PermissionTypes::Vulnerability expose_permissions Types::PermissionTypes::Vulnerability
field :id, GraphQL::ID_TYPE, null: false, field :id, GraphQL::ID_TYPE, null: false,
description: 'GraphQL ID of the vulnerability' description: 'GraphQL ID of the vulnerability.'
field :title, GraphQL::STRING_TYPE, null: true, field :title, GraphQL::STRING_TYPE, null: true,
description: 'Title of the vulnerability' description: 'Title of the vulnerability.'
field :description, GraphQL::STRING_TYPE, null: true, field :description, GraphQL::STRING_TYPE, null: true,
description: 'Description of the vulnerability' description: 'Description of the vulnerability.'
field :state, VulnerabilityStateEnum, null: true, field :state, VulnerabilityStateEnum, null: true,
description: "State of the vulnerability (#{::Vulnerability.states.keys.join(', ').upcase})" description: "State of the vulnerability (#{::Vulnerability.states.keys.join(', ').upcase})"
...@@ -30,23 +30,23 @@ module Types ...@@ -30,23 +30,23 @@ module Types
description: "Type of the security report that found the vulnerability (#{::Enums::Vulnerability.report_types.keys.join(', ').upcase})" description: "Type of the security report that found the vulnerability (#{::Enums::Vulnerability.report_types.keys.join(', ').upcase})"
field :resolved_on_default_branch, GraphQL::BOOLEAN_TYPE, null: false, field :resolved_on_default_branch, GraphQL::BOOLEAN_TYPE, null: false,
description: "Indicates whether the vulnerability is fixed on the default branch or not" description: "Indicates whether the vulnerability is fixed on the default branch or not."
field :user_notes_count, GraphQL::INT_TYPE, null: false, field :user_notes_count, GraphQL::INT_TYPE, null: false,
description: 'Number of user notes attached to the vulnerability' description: 'Number of user notes attached to the vulnerability.'
field :vulnerability_path, GraphQL::STRING_TYPE, null: true, field :vulnerability_path, GraphQL::STRING_TYPE, null: true,
description: "URL to the vulnerability's details page" description: "URL to the vulnerability's details page."
field :issue_links, ::Types::Vulnerability::IssueLinkType.connection_type, null: false, field :issue_links, ::Types::Vulnerability::IssueLinkType.connection_type, null: false,
description: "List of issue links related to the vulnerability", description: "List of issue links related to the vulnerability.",
resolver: Resolvers::Vulnerabilities::IssueLinksResolver resolver: Resolvers::Vulnerabilities::IssueLinksResolver
field :external_issue_links, ::Types::Vulnerability::ExternalIssueLinkType.connection_type, null: false, field :external_issue_links, ::Types::Vulnerability::ExternalIssueLinkType.connection_type, null: false,
description: 'List of external issue links related to the vulnerability' description: 'List of external issue links related to the vulnerability.'
field :location, VulnerabilityLocationType, null: true, field :location, VulnerabilityLocationType, null: true,
description: 'Location metadata for the vulnerability. Its fields depend on the type of security scan that found the vulnerability' description: 'Location metadata for the vulnerability. Its fields depend on the type of security scan that found the vulnerability.'
field :scanner, VulnerabilityScannerType, null: true, field :scanner, VulnerabilityScannerType, null: true,
description: 'Scanner metadata for the vulnerability.' description: 'Scanner metadata for the vulnerability.'
...@@ -58,21 +58,21 @@ module Types ...@@ -58,21 +58,21 @@ module Types
description: 'Identifiers of the vulnerability.' description: 'Identifiers of the vulnerability.'
field :project, ::Types::ProjectType, null: true, field :project, ::Types::ProjectType, null: true,
description: 'The project on which the vulnerability was found', description: 'The project on which the vulnerability was found.',
authorize: :read_project authorize: :read_project
field :detected_at, Types::TimeType, null: false, field :detected_at, Types::TimeType, null: false,
description: 'Timestamp of when the vulnerability was first detected', description: 'Timestamp of when the vulnerability was first detected.',
method: :created_at method: :created_at
field :confirmed_at, Types::TimeType, null: true, field :confirmed_at, Types::TimeType, null: true,
description: 'Timestamp of when the vulnerability state was changed to confirmed' description: 'Timestamp of when the vulnerability state was changed to confirmed.'
field :resolved_at, Types::TimeType, null: true, field :resolved_at, Types::TimeType, null: true,
description: 'Timestamp of when the vulnerability state was changed to resolved' description: 'Timestamp of when the vulnerability state was changed to resolved.'
field :dismissed_at, Types::TimeType, null: true, field :dismissed_at, Types::TimeType, null: true,
description: 'Timestamp of when the vulnerability state was changed to dismissed' description: 'Timestamp of when the vulnerability state was changed to dismissed.'
field :has_solutions, GraphQL::BOOLEAN_TYPE, null: true, field :has_solutions, GraphQL::BOOLEAN_TYPE, null: true,
description: 'Indicates whether there is a solution available for this vulnerability.', description: 'Indicates whether there is a solution available for this vulnerability.',
...@@ -91,7 +91,7 @@ module Types ...@@ -91,7 +91,7 @@ module Types
description: 'The user that dismissed the vulnerability.' description: 'The user that dismissed the vulnerability.'
field :details, [VulnerabilityDetailType], null: false, field :details, [VulnerabilityDetailType], null: false,
description: 'Details of the vulnerability', description: 'Details of the vulnerability.',
resolver: Resolvers::Vulnerabilities::DetailsResolver resolver: Resolvers::Vulnerabilities::DetailsResolver
def confirmed_by def confirmed_by
......
...@@ -7,9 +7,9 @@ module Types ...@@ -7,9 +7,9 @@ module Types
description 'Represents a vulnerable dependency. Used in vulnerability location data' description 'Represents a vulnerable dependency. Used in vulnerability location data'
field :package, ::Types::VulnerablePackageType, null: true, field :package, ::Types::VulnerablePackageType, null: true,
description: 'The package associated with the vulnerable dependency' description: 'The package associated with the vulnerable dependency.'
field :version, GraphQL::STRING_TYPE, null: true, field :version, GraphQL::STRING_TYPE, null: true,
description: 'The version of the vulnerable dependency' description: 'The version of the vulnerable dependency.'
end end
end end
...@@ -7,6 +7,6 @@ module Types ...@@ -7,6 +7,6 @@ module Types
description 'Represents a vulnerable package. Used in vulnerability dependency data' description 'Represents a vulnerable package. Used in vulnerability dependency data'
field :name, GraphQL::STRING_TYPE, null: true, field :name, GraphQL::STRING_TYPE, null: true,
description: 'The name of the vulnerable package' description: 'The name of the vulnerable package.'
end end
end end
...@@ -7,14 +7,14 @@ module Types ...@@ -7,14 +7,14 @@ module Types
description 'Represents vulnerability letter grades with associated projects' description 'Represents vulnerability letter grades with associated projects'
field :grade, Types::VulnerabilityGradeEnum, null: false, field :grade, Types::VulnerabilityGradeEnum, null: false,
description: "Grade based on the highest severity vulnerability present" description: "Grade based on the highest severity vulnerability present."
field :count, GraphQL::INT_TYPE, null: false, field :count, GraphQL::INT_TYPE, null: false,
description: 'Number of projects within this grade', description: 'Number of projects within this grade.',
complexity: 5 complexity: 5
field :projects, Types::ProjectType.connection_type, null: false, field :projects, Types::ProjectType.connection_type, null: false,
description: 'Projects within this grade', description: 'Projects within this grade.',
complexity: 5 complexity: 5
end end
# rubocop: enable Graphql/AuthorizeTypes # rubocop: enable Graphql/AuthorizeTypes
......
- if user.read_only_attribute?(:name) - if user.read_only_attribute?(:name)
= form.text_field :name, required: true, readonly: true, wrapper: { class: 'col-md-9 qa-full-name rspec-full-name' }, = form.text_field :name, class: 'gl-form-input', required: true, readonly: true, wrapper: { class: 'col-md-9 qa-full-name rspec-full-name' },
help: s_("Profiles|Your name was automatically set based on your %{provider_label} account, so people you know can recognize you") % { provider_label: attribute_provider_label(:name) } help: s_("Profiles|Your name was automatically set based on your %{provider_label} account, so people you know can recognize you") % { provider_label: attribute_provider_label(:name) }
- elsif can?(current_user, :update_name, user) - elsif can?(current_user, :update_name, user)
= form.text_field :name, label: s_('Profiles|Full name'), required: true, title: s_("Profiles|Using emojis in names seems fun, but please try to set a status message instead"), wrapper: { class: 'col-md-9 qa-full-name rspec-full-name' }, help: s_("Profiles|Enter your name, so people you know can recognize you") = form.text_field :name, class: 'gl-form-input', label: s_('Profiles|Full name'), required: true, title: s_("Profiles|Using emojis in names seems fun, but please try to set a status message instead"), wrapper: { class: 'col-md-9 qa-full-name rspec-full-name' }, help: s_("Profiles|Enter your name, so people you know can recognize you")
- else - else
= form.text_field :name, required: true, readonly: true, wrapper: { class: 'col-md-9 qa-full-name rspec-full-name' }, = form.text_field :name, class: 'gl-form-input', required: true, readonly: true, wrapper: { class: 'col-md-9 qa-full-name rspec-full-name' },
help: s_("Profiles|The ability to update your name has been disabled by your administrator.") help: s_("Profiles|The ability to update your name has been disabled by your administrator.")
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
- project_template_count = current_user.available_custom_project_templates.count - project_template_count = current_user.available_custom_project_templates.count
- group_id = params[:namespace_id] - group_id = params[:namespace_id]
.project-templates-buttons.col-sm-12 .project-templates-buttons
%ul.nav-tabs.nav-links.nav.scrolling-tabs %ul.nav-tabs.nav-links.nav.scrolling-tabs
%li.built-in-tab %li.built-in-tab
%a.nav-link.active{ href: "#built-in", data: { toggle: 'tab'} } %a.nav-link.active{ href: "#built-in", data: { toggle: 'tab'} }
......
...@@ -67,7 +67,8 @@ module Gitlab ...@@ -67,7 +67,8 @@ module Gitlab
source_branch: encode_binary(source_branch), source_branch: encode_binary(source_branch),
target_branch: encode_binary(target_branch), target_branch: encode_binary(target_branch),
commit_message: encode_binary(resolution.commit_message), commit_message: encode_binary(resolution.commit_message),
user: Gitlab::Git::User.from_gitlab(resolution.user).to_gitaly user: Gitlab::Git::User.from_gitlab(resolution.user).to_gitaly,
timestamp: Google::Protobuf::Timestamp.new(seconds: Time.now.utc.to_i)
) )
end end
end end
......
...@@ -32,7 +32,8 @@ module Gitlab ...@@ -32,7 +32,8 @@ module Gitlab
user: Gitlab::Git::User.from_gitlab(user).to_gitaly, user: Gitlab::Git::User.from_gitlab(user).to_gitaly,
tag_name: encode_binary(tag_name), tag_name: encode_binary(tag_name),
target_revision: encode_binary(target), target_revision: encode_binary(target),
message: encode_binary(message.to_s) message: encode_binary(message.to_s),
timestamp: Google::Protobuf::Timestamp.new(seconds: Time.now.utc.to_i)
) )
response = GitalyClient.call(@repository.storage, :operation_service, :user_create_tag, request, timeout: GitalyClient.long_timeout) response = GitalyClient.call(@repository.storage, :operation_service, :user_create_tag, request, timeout: GitalyClient.long_timeout)
...@@ -111,7 +112,8 @@ module Gitlab ...@@ -111,7 +112,8 @@ module Gitlab
user: Gitlab::Git::User.from_gitlab(user).to_gitaly, user: Gitlab::Git::User.from_gitlab(user).to_gitaly,
message: encode_binary(message), message: encode_binary(message),
first_parent_ref: encode_binary(first_parent_ref), first_parent_ref: encode_binary(first_parent_ref),
allow_conflicts: allow_conflicts allow_conflicts: allow_conflicts,
timestamp: Google::Protobuf::Timestamp.new(seconds: Time.now.utc.to_i)
) )
response = GitalyClient.call(@repository.storage, :operation_service, response = GitalyClient.call(@repository.storage, :operation_service,
...@@ -140,7 +142,8 @@ module Gitlab ...@@ -140,7 +142,8 @@ module Gitlab
user: Gitlab::Git::User.from_gitlab(user).to_gitaly, user: Gitlab::Git::User.from_gitlab(user).to_gitaly,
commit_id: source_sha, commit_id: source_sha,
branch: encode_binary(target_branch), branch: encode_binary(target_branch),
message: encode_binary(message) message: encode_binary(message),
timestamp: Google::Protobuf::Timestamp.new(seconds: Time.now.utc.to_i)
) )
) )
...@@ -234,7 +237,8 @@ module Gitlab ...@@ -234,7 +237,8 @@ module Gitlab
branch_sha: branch_sha, branch_sha: branch_sha,
remote_repository: remote_repository.gitaly_repository, remote_repository: remote_repository.gitaly_repository,
remote_branch: encode_binary(remote_branch), remote_branch: encode_binary(remote_branch),
git_push_options: push_options git_push_options: push_options,
timestamp: Google::Protobuf::Timestamp.new(seconds: Time.now.utc.to_i)
) )
) )
) )
...@@ -255,7 +259,7 @@ module Gitlab ...@@ -255,7 +259,7 @@ module Gitlab
request_enum.close request_enum.close
end end
def user_squash(user, squash_id, start_sha, end_sha, author, message) def user_squash(user, squash_id, start_sha, end_sha, author, message, time = Time.now.utc)
request = Gitaly::UserSquashRequest.new( request = Gitaly::UserSquashRequest.new(
repository: @gitaly_repo, repository: @gitaly_repo,
user: Gitlab::Git::User.from_gitlab(user).to_gitaly, user: Gitlab::Git::User.from_gitlab(user).to_gitaly,
...@@ -263,7 +267,8 @@ module Gitlab ...@@ -263,7 +267,8 @@ module Gitlab
start_sha: start_sha, start_sha: start_sha,
end_sha: end_sha, end_sha: end_sha,
author: Gitlab::Git::User.from_gitlab(author).to_gitaly, author: Gitlab::Git::User.from_gitlab(author).to_gitaly,
commit_message: encode_binary(message) commit_message: encode_binary(message),
timestamp: Google::Protobuf::Timestamp.new(seconds: time.to_i)
) )
response = GitalyClient.call( response = GitalyClient.call(
...@@ -288,7 +293,8 @@ module Gitlab ...@@ -288,7 +293,8 @@ module Gitlab
commit_sha: commit_sha, commit_sha: commit_sha,
branch: encode_binary(branch), branch: encode_binary(branch),
submodule: encode_binary(submodule), submodule: encode_binary(submodule),
commit_message: encode_binary(message) commit_message: encode_binary(message),
timestamp: Google::Protobuf::Timestamp.new(seconds: Time.now.utc.to_i)
) )
response = GitalyClient.call( response = GitalyClient.call(
...@@ -357,7 +363,8 @@ module Gitlab ...@@ -357,7 +363,8 @@ module Gitlab
header = Gitaly::UserApplyPatchRequest::Header.new( header = Gitaly::UserApplyPatchRequest::Header.new(
repository: @gitaly_repo, repository: @gitaly_repo,
user: Gitlab::Git::User.from_gitlab(user).to_gitaly, user: Gitlab::Git::User.from_gitlab(user).to_gitaly,
target_branch: encode_binary(branch_name) target_branch: encode_binary(branch_name),
timestamp: Google::Protobuf::Timestamp.new(seconds: Time.now.utc.to_i)
) )
reader = binary_io(patches) reader = binary_io(patches)
...@@ -446,7 +453,8 @@ module Gitlab ...@@ -446,7 +453,8 @@ module Gitlab
start_branch_name: encode_binary(start_branch_name), start_branch_name: encode_binary(start_branch_name),
start_repository: start_repository.gitaly_repository, start_repository: start_repository.gitaly_repository,
force: force, force: force,
start_sha: encode_binary(start_sha) start_sha: encode_binary(start_sha),
timestamp: Google::Protobuf::Timestamp.new(seconds: Time.now.utc.to_i)
) )
end end
# rubocop:enable Metrics/ParameterLists # rubocop:enable Metrics/ParameterLists
......
...@@ -101,7 +101,7 @@ module QA ...@@ -101,7 +101,7 @@ module QA
two_fa_auth.click_copy_and_proceed two_fa_auth.click_copy_and_proceed
expect(two_fa_auth).to have_text('Congratulations! You have enabled Two-factor Authentication!') expect(two_fa_auth).to have_text('You have set up 2FA for your account!')
end end
end end
end end
......
...@@ -21,11 +21,11 @@ RSpec.describe 'Branches' do ...@@ -21,11 +21,11 @@ RSpec.describe 'Branches' do
before do before do
# Add 4 stale branches # Add 4 stale branches
(1..4).reverse_each do |i| (1..4).reverse_each do |i|
travel_to((threshold + i).ago) { create_file(message: "a commit in stale-#{i}", branch_name: "stale-#{i}") } travel_to((threshold + i.hours).ago) { create_file(message: "a commit in stale-#{i}", branch_name: "stale-#{i}") }
end end
# Add 6 active branches # Add 6 active branches
(1..6).each do |i| (1..6).each do |i|
travel_to((threshold - i).ago) { create_file(message: "a commit in active-#{i}", branch_name: "active-#{i}") } travel_to((threshold - i.hours).ago) { create_file(message: "a commit in active-#{i}", branch_name: "active-#{i}") }
end end
end end
...@@ -34,7 +34,7 @@ RSpec.describe 'Branches' do ...@@ -34,7 +34,7 @@ RSpec.describe 'Branches' do
visit project_branches_path(project) visit project_branches_path(project)
expect(page).to have_content(sorted_branches(repository, count: 5, sort_by: :updated_desc, state: 'active')) expect(page).to have_content(sorted_branches(repository, count: 5, sort_by: :updated_desc, state: 'active'))
expect(page).to have_content(sorted_branches(repository, count: 4, sort_by: :updated_desc, state: 'stale')) expect(page).to have_content(sorted_branches(repository, count: 4, sort_by: :updated_asc, state: 'stale'))
expect(page).to have_link('Show more active branches', href: project_branches_filtered_path(project, state: 'active')) expect(page).to have_link('Show more active branches', href: project_branches_filtered_path(project, state: 'active'))
expect(page).not_to have_content('Show more stale branches') expect(page).not_to have_content('Show more stale branches')
...@@ -50,10 +50,10 @@ RSpec.describe 'Branches' do ...@@ -50,10 +50,10 @@ RSpec.describe 'Branches' do
end end
describe 'Stale branches page' do describe 'Stale branches page' do
it 'shows 4 active branches sorted by last updated' do it 'shows 4 stale branches sorted by last updated' do
visit project_branches_filtered_path(project, state: 'stale') visit project_branches_filtered_path(project, state: 'stale')
expect(page).to have_content(sorted_branches(repository, count: 4, sort_by: :updated_desc, state: 'stale')) expect(page).to have_content(sorted_branches(repository, count: 4, sort_by: :updated_asc, state: 'stale'))
end end
end end
......
...@@ -299,6 +299,11 @@ RSpec.describe Gitlab::GitalyClient::OperationService do ...@@ -299,6 +299,11 @@ RSpec.describe Gitlab::GitalyClient::OperationService do
let(:start_sha) { 'b83d6e391c22777fca1ed3012fce84f633d7fed0' } let(:start_sha) { 'b83d6e391c22777fca1ed3012fce84f633d7fed0' }
let(:end_sha) { '54cec5282aa9f21856362fe321c800c236a61615' } let(:end_sha) { '54cec5282aa9f21856362fe321c800c236a61615' }
let(:commit_message) { 'Squash message' } let(:commit_message) { 'Squash message' }
let(:time) do
Time.now.utc
end
let(:request) do let(:request) do
Gitaly::UserSquashRequest.new( Gitaly::UserSquashRequest.new(
repository: repository.gitaly_repository, repository: repository.gitaly_repository,
...@@ -307,7 +312,8 @@ RSpec.describe Gitlab::GitalyClient::OperationService do ...@@ -307,7 +312,8 @@ RSpec.describe Gitlab::GitalyClient::OperationService do
start_sha: start_sha, start_sha: start_sha,
end_sha: end_sha, end_sha: end_sha,
author: gitaly_user, author: gitaly_user,
commit_message: commit_message commit_message: commit_message,
timestamp: Google::Protobuf::Timestamp.new(seconds: time.to_i)
) )
end end
...@@ -315,7 +321,7 @@ RSpec.describe Gitlab::GitalyClient::OperationService do ...@@ -315,7 +321,7 @@ RSpec.describe Gitlab::GitalyClient::OperationService do
let(:response) { Gitaly::UserSquashResponse.new(squash_sha: squash_sha) } let(:response) { Gitaly::UserSquashResponse.new(squash_sha: squash_sha) }
subject do subject do
client.user_squash(user, squash_id, start_sha, end_sha, user, commit_message) client.user_squash(user, squash_id, start_sha, end_sha, user, commit_message, time)
end end
it 'sends a user_squash message and returns the squash sha' do it 'sends a user_squash message and returns the squash sha' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment