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

Automatic merge of gitlab-org/gitlab master

parents 11aa231d 0ebd272f
......@@ -102,7 +102,7 @@
- name: postgres:11.6
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- name: redis:5.0-alpine
- name: elasticsearch:7.9.2
- name: elasticsearch:7.10.1
command: ["elasticsearch", "-E", "discovery.type=single-node"]
variables:
POSTGRES_HOST_AUTH_METHOD: trust
......@@ -113,7 +113,7 @@
- name: postgres:12
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- name: redis:5.0-alpine
- name: elasticsearch:7.9.2
- name: elasticsearch:7.10.1
command: ["elasticsearch", "-E", "discovery.type=single-node"]
variables:
POSTGRES_HOST_AUTH_METHOD: trust
......
......@@ -691,47 +691,6 @@ RSpec/TimecopTravel:
- 'spec/workers/concerns/reenqueuer_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
RSpec/AnyInstanceOf:
Exclude:
......
......@@ -464,7 +464,7 @@ group :ed25519 do
end
# Gitaly GRPC protocol definitions
gem 'gitaly', '~> 13.8.0.pre.rc3'
gem 'gitaly', '~> 13.9.0.pre.rc1'
gem 'grpc', '~> 1.30.2'
......
......@@ -420,7 +420,7 @@ GEM
rails (>= 3.2.0)
git (1.7.0)
rchardet (~> 1.8)
gitaly (13.8.0.pre.rc3)
gitaly (13.9.0.pre.rc1)
grpc (~> 1.0)
github-markup (1.7.0)
gitlab-chronic (0.10.5)
......@@ -1368,7 +1368,7 @@ DEPENDENCIES
gettext (~> 3.3)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.3)
gitaly (~> 13.8.0.pre.rc3)
gitaly (~> 13.9.0.pre.rc1)
github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5)
gitlab-experiment (~> 0.4.9)
......
import { redirectTo, getBaseURL, stripFinalUrlSegment } from '~/lib/utils/url_utility';
import { initRemoveTag } from '../remove_tag';
document.addEventListener('DOMContentLoaded', () => {
initRemoveTag({
onDelete: (path = '') => {
redirectTo(stripFinalUrlSegment([getBaseURL(), path].join('')));
},
});
initRemoveTag({
onDelete: (path = '') => {
redirectTo(stripFinalUrlSegment([getBaseURL(), path].join('')));
},
});
......@@ -109,7 +109,7 @@ export default {
<div
v-for="(key, keyIndex) in keys"
:key="key"
class="break-word gl-text-black-normal"
class="break-word"
:class="{ 'mb-3 bold': keyIndex == 0 }"
>
{{ item[key] }}
......
......@@ -9,7 +9,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController
before_action :authorize_admin_project_member!, except: [:index, :leave, :request_access]
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
feature_category :authentication_and_authorization
......
......@@ -31,7 +31,7 @@
= render 'shared/group_tips'
.form-actions
= 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
.form-actions
......
......@@ -7,7 +7,7 @@
.d-flex.justify-content-between.flex-wrap
- providers.each do |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
= provider_image_tag(provider)
%span
......
......@@ -2,7 +2,7 @@
= _("Create an account using:")
.d-flex.justify-content-between.flex-wrap
- 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)
= provider_image_tag(provider)
%span.ml-2
......
......@@ -18,5 +18,5 @@
= render_if_exists 'shared/groups/invite_members'
.row
.form-actions.col-sm-12
= f.submit _('Create group'), class: "btn btn-success"
= link_to _('Cancel'), dashboard_groups_path, class: 'btn btn-cancel'
= f.submit _('Create group'), class: "btn gl-button btn-success"
= link_to _('Cancel'), dashboard_groups_path, class: 'btn gl-button btn-default btn-cancel'
......@@ -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)
- 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),
{ 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
......
- 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) }
- 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 @@
= status_form.hidden_field :emoji, id: 'js-status-emoji-field'
= status_form.text_field :message,
id: 'js-status-message-field',
class: 'form-control input-lg',
class: 'form-control gl-form-input input-lg',
label: s_("Profiles|Your status"),
prepend: emoji_button,
append: reset_message_button,
......@@ -100,20 +100,20 @@
.col-lg-8
.row
= 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
= f.text_field :skype, class: 'input-md', 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 :twitter, class: 'input-md', placeholder: s_("Profiles|@username")
= f.text_field :website_url, class: 'input-lg', placeholder: s_("Profiles|website.com")
= f.text_field :skype, class: 'input-md gl-form-input', placeholder: s_("Profiles|username")
= 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 gl-form-input', placeholder: s_("Profiles|@username")
= f.text_field :website_url, class: 'input-lg gl-form-input', placeholder: s_("Profiles|website.com")
- 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
= f.text_field :location, label: s_('Profiles|Location'), class: 'input-lg', placeholder: s_("Profiles|City, country")
= f.text_field :job_title, class: 'input-md'
= f.text_field :organization, label: s_('Profiles|Organization'), class: 'input-md', 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_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 gl-form-input'
= 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, 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
%h5= s_("Private profile")
.checkbox-icon-inline-wrapper
......
- f ||= local_assigns[:f]
.project-templates-buttons.col-sm-12
.project-templates-buttons
%ul.nav-tabs.nav-links.nav.scrolling-tabs
%li.built-in-tab
%a.nav-link.active{ href: "#built-in", data: { toggle: 'tab'} }
......
- page_title _("Members")
- 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
.row.gl-mt-3
......
......@@ -12,4 +12,4 @@
data: todo_button_data }
%span.issuable-todo-inner.js-issuable-todo-inner<
= 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
milestone: '13.9'
type: development
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
Please see the `code` filter for an explanation on how tokens are split.
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`
......
......@@ -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.
## 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
One of the most valuable tools for identifying issues with the Elasticsearch
......@@ -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.
### Known issues
[Elasticsearch `code_analyzer` doesn't account for all code cases](https://gitlab.com/groups/gitlab-org/-/epics/3621).
### Elasticsearch `code_analyzer` doesn't account for all code cases
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).
### 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
### Some binary files may not be searchable by name
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.
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.
......@@ -122,7 +122,6 @@
.template-header,
.template-option {
padding: $gl-padding $gl-padding-8;
border-top: 1px solid $border-color;
}
.template-header {
......
......@@ -10,22 +10,22 @@ module Types
argument :id,
::Types::GlobalIDType[::EpicTreeSorting],
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,
::Types::GlobalIDType[::EpicTreeSorting],
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,
MoveTypeEnum,
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,
::Types::GlobalIDType[::Epic],
required: false,
description: 'ID of the new parent epic'
description: 'ID of the new parent epic.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
......
......@@ -7,25 +7,25 @@ module Types
description 'Represents an external issue'
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,
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,
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,
description: 'Type of external tracker'
description: 'Type of external tracker.'
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,
description: 'Timestamp of when the issue was created'
description: 'Timestamp of when the issue was created.'
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
object.dig(:references, :relative)
......
......@@ -7,37 +7,37 @@ module Types
authorize :read_geo_node
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 :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 :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 :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 :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 :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_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 :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 :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 :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 :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 :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 :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 :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_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 :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,
null: true,
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,
null: true,
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,
null: true,
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,
null: true,
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
......@@ -9,7 +9,7 @@ module Types
graphql_name 'MergeRequestDiffRegistry'
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
......@@ -9,7 +9,7 @@ module Types
graphql_name 'PackageFileRegistry'
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
......@@ -9,7 +9,7 @@ module Types
graphql_name 'SnippetRepositoryRegistry'
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
......@@ -9,7 +9,7 @@ module Types
graphql_name 'TerraformStateVersionRegistry'
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
......@@ -9,6 +9,6 @@ module Types
field :release_stats, Types::GroupReleaseStatsType,
null: true, method: :itself,
description: 'Statistics related to releases within the group'
description: 'Statistics related to releases within the group.'
end
end
......@@ -11,27 +11,27 @@ module Types
field :iid,
GraphQL::ID_TYPE,
null: false,
description: 'Internal ID of the on-call schedule'
description: 'Internal ID of the on-call schedule.'
field :name,
GraphQL::STRING_TYPE,
null: false,
description: 'Name of the on-call schedule'
description: 'Name of the on-call schedule.'
field :description,
GraphQL::STRING_TYPE,
null: true,
description: 'Description of the on-call schedule'
description: 'Description of the on-call schedule.'
field :timezone,
GraphQL::STRING_TYPE,
null: false,
description: 'Time zone of the on-call schedule'
description: 'Time zone of the on-call schedule.'
field :rotations,
OncallRotationType.connection_type,
null: false,
description: 'On-call rotations for the on-call schedule'
description: 'On-call rotations for the on-call schedule.'
end
end
end
......@@ -9,22 +9,22 @@ module Types
field :projects,
Types::ProjectType.connection_type,
null: false,
description: 'Projects selected in Instance Security Dashboard'
description: 'Projects selected in Instance Security Dashboard.'
field :vulnerability_scanners,
::Types::VulnerabilityScannerType.connection_type,
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
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
field :vulnerability_grades,
[Types::VulnerableProjectsByGradeType],
null: false,
description: 'Represents vulnerable project counts for each grade'
description: 'Represents vulnerable project counts for each grade.'
def vulnerability_grades
::Gitlab::Graphql::Aggregations::VulnerabilityStatistics::LazyAggregate.new(
......
......@@ -12,43 +12,43 @@ module Types
implements ::Types::TimeboxReportInterface
field :id, GraphQL::ID_TYPE, null: false,
description: 'ID of the iteration'
description: 'ID of the iteration.'
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,
description: 'Title of the iteration'
description: 'Title of the iteration.'
field :description, GraphQL::STRING_TYPE, null: true,
description: 'Description of the iteration'
description: 'Description of the iteration.'
markdown_field :description_html, null: true
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,
description: 'Web path of the iteration'
description: 'Web path of the iteration.'
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],
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],
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,
description: 'Timestamp of the iteration due date'
description: 'Timestamp of the iteration due date.'
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,
description: 'Timestamp of iteration creation'
description: 'Timestamp of iteration creation.'
field :updated_at, Types::TimeType, null: false,
description: 'Timestamp of last iteration update'
description: 'Timestamp of last iteration update.'
end
end
......@@ -8,19 +8,19 @@ module Types
authorize :read_issuable_metric_image
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,
description: 'Internal ID of the metric upload'
description: 'Internal ID of the metric upload.'
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,
description: 'File name of the metric image',
description: 'File name of the metric image.',
method: :filename
field :file_path, GraphQL::STRING_TYPE, null: true,
description: 'File path of the metric image'
description: 'File path of the metric image.'
end
end
......@@ -7,8 +7,8 @@ module Types
graphql_name 'RequirementStatesCount'
description 'Counts of requirements by their state'
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 :opened, GraphQL::INT_TYPE, null: true, description: 'Number of opened requirements.'
field :archived, GraphQL::INT_TYPE, null: true, description: 'Number of archived requirements.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
......
......@@ -11,46 +11,46 @@ module Types
expose_permissions Types::PermissionTypes::Requirement
field :id, GraphQL::ID_TYPE, null: false,
description: 'ID of the requirement'
description: 'ID of the requirement.'
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,
description: 'Title of the requirement'
description: 'Title of the requirement.'
markdown_field :title_html, 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
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,
description: 'Latest requirement test report state'
description: 'Latest requirement test report state.'
field :last_test_report_manually_created,
GraphQL::BOOLEAN_TYPE,
method: :last_test_report_manually_created?,
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,
description: 'Project to which the requirement belongs'
description: 'Project to which the requirement belongs.'
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,
description: 'Test reports of the requirement',
description: 'Test reports of the requirement.',
resolver: Resolvers::RequirementsManagement::TestReportsResolver
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,
description: 'Timestamp of when the requirement was last updated'
description: 'Timestamp of when the requirement was last updated.'
def project
Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find
......
......@@ -9,16 +9,16 @@ module Types
authorize :read_requirement
field :id, GraphQL::ID_TYPE, null: false,
description: 'ID of the test report'
description: 'ID of the test report.'
field :state, TestReportStateEnum, null: false,
description: 'State of the test report'
description: 'State of the test report.'
field :author, UserType, null: true,
description: 'Author of the test report'
description: 'Author of the test report.'
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
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find
......
......@@ -6,7 +6,7 @@ module Types
graphql_name 'ScannedResource'
description 'Represents a resource scanned by a security scan'
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 :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.'
end
end
......@@ -6,9 +6,9 @@ module Types
graphql_name 'SecurityReportSummarySection'
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 :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_csv_path, GraphQL::STRING_TYPE, null: true, description: 'Path to download all the scanned resources in CSV format'
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, ::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.'
end
end
......@@ -7,12 +7,12 @@ module Types
description 'Represents the time report stats for timeboxes'
field :complete, ::Types::TimeboxMetricsType, null: true,
description: 'Completed issues metrics'
description: 'Completed issues metrics.'
field :incomplete, ::Types::TimeboxMetricsType, null: true,
description: 'Incomplete issues metrics'
description: 'Incomplete issues metrics.'
field :total, ::Types::TimeboxMetricsType, null: true,
description: 'Total issues metrics'
description: 'Total issues metrics.'
end
end
......@@ -7,9 +7,9 @@ module Types
description 'Represents measured stats metrics for timeboxes'
field :count, GraphQL::INT_TYPE, null: false,
description: 'The count metric'
description: 'The count metric.'
field :weight, GraphQL::INT_TYPE, null: false,
description: 'The weight metric'
description: 'The weight metric.'
end
end
......@@ -6,7 +6,7 @@ module Types
field :report, Types::TimeboxReportType, null: true,
resolver: ::Resolvers::TimeboxReportResolver,
description: 'Historically accurate report about the timebox',
description: 'Historically accurate report about the timebox.',
complexity: 175
end
end
......@@ -7,8 +7,8 @@ module Types
description 'Represents a historically accurate report about the timebox'
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,
description: 'Daily scope and completed totals for burnup charts'
description: 'Daily scope and completed totals for burnup charts.'
end
end
......@@ -9,27 +9,27 @@ module Types
field :spent_at,
Types::TimeType,
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,
GraphQL::INT_TYPE,
null: false,
description: 'The time spent displayed in seconds'
description: 'The time spent displayed in seconds.'
field :user,
Types::UserType,
null: false,
description: 'The user that logged the time'
description: 'The user that logged the time.'
field :issue,
Types::IssueType,
null: true,
description: 'The issue that logged time was added to'
description: 'The issue that logged time was added to.'
field :note,
Types::Notes::NoteType,
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
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.user_id).find
......
......@@ -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'
field :count, GraphQL::INT_TYPE, null: true,
description: 'Number of vulnerabilities'
description: 'Number of vulnerabilities.'
field :day, GraphQL::Types::ISO8601Date, null: true,
description: 'Date for the count'
description: 'Date for the count.'
field :severity, VulnerabilitySeverityEnum, null: true,
description: 'Severity of the counted vulnerabilities'
description: 'Severity of the counted vulnerabilities.'
end
end
......@@ -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'
field :date, GraphQL::Types::ISO8601Date, null: false,
description: 'Date for the count'
description: 'Date for the count.'
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|
field severity.to_s, GraphQL::INT_TYPE, null: false,
......
......@@ -9,13 +9,13 @@ module Types
authorize :read_vulnerability
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,
description: 'Type of the external issue link'
description: 'Type of the external issue link.'
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
end
end
......
......@@ -8,13 +8,13 @@ module Types
description 'Represents an issue link of a vulnerability'
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,
description: "Type of the issue link"
description: "Type of the issue link."
field :issue, ::Types::IssueType, null: false,
description: 'The issue attached to issue link'
description: 'The issue attached to issue link.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
......
......@@ -7,16 +7,16 @@ module Types
description 'Represents a vulnerability identifier'
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,
description: 'URL of the vulnerability identifier'
description: 'URL of the vulnerability identifier.'
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,
description: 'External ID of the vulnerability identifier'
description: 'External ID of the vulnerability identifier.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
......@@ -8,13 +8,13 @@ module Types
description 'Represents the location of a vulnerability found by a container security scan'
field :dependency, ::Types::VulnerableDependencyType, null: true,
description: 'Dependency containing the vulnerability'
description: 'Dependency containing the vulnerability.'
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,
description: 'Operating system that runs on the vulnerable container image'
description: 'Operating system that runs on the vulnerable container image.'
end
end
end
......@@ -8,24 +8,24 @@ module Types
description 'Represents the location of a vulnerability found by a Coverage Fuzzing scan'
field :vulnerable_class, GraphQL::STRING_TYPE, null: true,
description: 'Class containing the vulnerability',
description: 'Class containing the vulnerability.',
hash_key: :class
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,
description: 'Path to the vulnerable file'
description: 'Path to the vulnerable file.'
field :vulnerable_method, GraphQL::STRING_TYPE, null: true,
description: 'Method containing the vulnerability',
description: 'Method containing the vulnerability.',
hash_key: :method
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,
description: 'Blob path to the vulnerable file'
description: 'Blob path to the vulnerable file.'
end
end
end
......@@ -8,16 +8,16 @@ module Types
description 'Represents the location of a vulnerability found by a DAST scan'
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,
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,
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,
description: 'HTTP method of the vulnerable request'
description: 'HTTP method of the vulnerable request.'
end
end
end
......@@ -8,13 +8,13 @@ module Types
description 'Represents the location of a vulnerability found by a dependency security scan'
field :dependency, ::Types::VulnerableDependencyType, null: true,
description: 'Dependency containing the vulnerability'
description: 'Dependency containing the vulnerability.'
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,
description: 'Blob path to the vulnerable file'
description: 'Blob path to the vulnerable file.'
end
end
end
......@@ -8,24 +8,24 @@ module Types
description 'Represents the location of a vulnerability found by a SAST scan'
field :vulnerable_class, GraphQL::STRING_TYPE, null: true,
description: 'Class containing the vulnerability',
description: 'Class containing the vulnerability.',
hash_key: :class
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,
description: 'Path to the vulnerable file'
description: 'Path to the vulnerable file.'
field :vulnerable_method, GraphQL::STRING_TYPE, null: true,
description: 'Method containing the vulnerability',
description: 'Method containing the vulnerability.',
hash_key: :method
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,
description: 'Blob path to the vulnerable file'
description: 'Blob path to the vulnerable file.'
end
end
end
......@@ -8,24 +8,24 @@ module Types
description 'Represents the location of a vulnerability found by a secret detection scan'
field :vulnerable_class, GraphQL::STRING_TYPE, null: true,
description: 'Class containing the vulnerability',
description: 'Class containing the vulnerability.',
hash_key: :class
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,
description: 'Path to the vulnerable file'
description: 'Path to the vulnerable file.'
field :vulnerable_method, GraphQL::STRING_TYPE, null: true,
description: 'Method containing the vulnerability',
description: 'Method containing the vulnerability.',
hash_key: :method
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,
description: 'Blob path to the vulnerable file'
description: 'Blob path to the vulnerable file.'
end
end
end
......@@ -8,15 +8,15 @@ module Types
authorize :read_vulnerability_scanner
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,
description: 'External ID of the vulnerability scanner'
description: 'External ID of the vulnerability scanner.'
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,
description: 'Type of the vulnerability report'
description: 'Type of the vulnerability report.'
end
end
......@@ -12,13 +12,13 @@ module Types
expose_permissions Types::PermissionTypes::Vulnerability
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,
description: 'Title of the vulnerability'
description: 'Title of the vulnerability.'
field :description, GraphQL::STRING_TYPE, null: true,
description: 'Description of the vulnerability'
description: 'Description of the vulnerability.'
field :state, VulnerabilityStateEnum, null: true,
description: "State of the vulnerability (#{::Vulnerability.states.keys.join(', ').upcase})"
......@@ -30,23 +30,23 @@ module Types
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,
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,
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,
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,
description: "List of issue links related to the vulnerability",
description: "List of issue links related to the vulnerability.",
resolver: Resolvers::Vulnerabilities::IssueLinksResolver
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,
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,
description: 'Scanner metadata for the vulnerability.'
......@@ -58,21 +58,21 @@ module Types
description: 'Identifiers of the vulnerability.'
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
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
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,
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,
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,
description: 'Indicates whether there is a solution available for this vulnerability.',
......@@ -91,7 +91,7 @@ module Types
description: 'The user that dismissed the vulnerability.'
field :details, [VulnerabilityDetailType], null: false,
description: 'Details of the vulnerability',
description: 'Details of the vulnerability.',
resolver: Resolvers::Vulnerabilities::DetailsResolver
def confirmed_by
......
......@@ -7,9 +7,9 @@ module Types
description 'Represents a vulnerable dependency. Used in vulnerability location data'
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,
description: 'The version of the vulnerable dependency'
description: 'The version of the vulnerable dependency.'
end
end
......@@ -7,6 +7,6 @@ module Types
description 'Represents a vulnerable package. Used in vulnerability dependency data'
field :name, GraphQL::STRING_TYPE, null: true,
description: 'The name of the vulnerable package'
description: 'The name of the vulnerable package.'
end
end
......@@ -7,14 +7,14 @@ module Types
description 'Represents vulnerability letter grades with associated projects'
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,
description: 'Number of projects within this grade',
description: 'Number of projects within this grade.',
complexity: 5
field :projects, Types::ProjectType.connection_type, null: false,
description: 'Projects within this grade',
description: 'Projects within this grade.',
complexity: 5
end
# rubocop: enable Graphql/AuthorizeTypes
......
- 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) }
- 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
= 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.")
......@@ -2,7 +2,7 @@
- project_template_count = current_user.available_custom_project_templates.count
- group_id = params[:namespace_id]
.project-templates-buttons.col-sm-12
.project-templates-buttons
%ul.nav-tabs.nav-links.nav.scrolling-tabs
%li.built-in-tab
%a.nav-link.active{ href: "#built-in", data: { toggle: 'tab'} }
......
......@@ -67,7 +67,8 @@ module Gitlab
source_branch: encode_binary(source_branch),
target_branch: encode_binary(target_branch),
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
......
......@@ -32,7 +32,8 @@ module Gitlab
user: Gitlab::Git::User.from_gitlab(user).to_gitaly,
tag_name: encode_binary(tag_name),
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)
......@@ -111,7 +112,8 @@ module Gitlab
user: Gitlab::Git::User.from_gitlab(user).to_gitaly,
message: encode_binary(message),
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,
......@@ -140,7 +142,8 @@ module Gitlab
user: Gitlab::Git::User.from_gitlab(user).to_gitaly,
commit_id: source_sha,
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
branch_sha: branch_sha,
remote_repository: remote_repository.gitaly_repository,
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
request_enum.close
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(
repository: @gitaly_repo,
user: Gitlab::Git::User.from_gitlab(user).to_gitaly,
......@@ -263,7 +267,8 @@ module Gitlab
start_sha: start_sha,
end_sha: end_sha,
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(
......@@ -288,7 +293,8 @@ module Gitlab
commit_sha: commit_sha,
branch: encode_binary(branch),
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(
......@@ -357,7 +363,8 @@ module Gitlab
header = Gitaly::UserApplyPatchRequest::Header.new(
repository: @gitaly_repo,
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)
......@@ -446,7 +453,8 @@ module Gitlab
start_branch_name: encode_binary(start_branch_name),
start_repository: start_repository.gitaly_repository,
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
# rubocop:enable Metrics/ParameterLists
......
......@@ -101,7 +101,7 @@ module QA
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
......
......@@ -21,11 +21,11 @@ RSpec.describe 'Branches' do
before do
# Add 4 stale branches
(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
# Add 6 active branches
(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
......@@ -34,7 +34,7 @@ RSpec.describe 'Branches' do
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: 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).not_to have_content('Show more stale branches')
......@@ -50,10 +50,10 @@ RSpec.describe 'Branches' do
end
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')
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
......
......@@ -299,6 +299,11 @@ RSpec.describe Gitlab::GitalyClient::OperationService do
let(:start_sha) { 'b83d6e391c22777fca1ed3012fce84f633d7fed0' }
let(:end_sha) { '54cec5282aa9f21856362fe321c800c236a61615' }
let(:commit_message) { 'Squash message' }
let(:time) do
Time.now.utc
end
let(:request) do
Gitaly::UserSquashRequest.new(
repository: repository.gitaly_repository,
......@@ -307,7 +312,8 @@ RSpec.describe Gitlab::GitalyClient::OperationService do
start_sha: start_sha,
end_sha: end_sha,
author: gitaly_user,
commit_message: commit_message
commit_message: commit_message,
timestamp: Google::Protobuf::Timestamp.new(seconds: time.to_i)
)
end
......@@ -315,7 +321,7 @@ RSpec.describe Gitlab::GitalyClient::OperationService do
let(:response) { Gitaly::UserSquashResponse.new(squash_sha: squash_sha) }
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
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