summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-01-08 00:07:43 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-01-08 00:07:43 +0000
commit2b3bfe8fc59ed4cdc385955cdb38cbd481b45426 (patch)
tree6b570a8d134fb2beeacf11bbcc79ff22123156ec
parentd203316c80aa27cf747aa29df9f7c2d374965b5f (diff)
downloadgitlab-ce-2b3bfe8fc59ed4cdc385955cdb38cbd481b45426.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/controllers/projects_controller.rb1
-rw-r--r--app/graphql/mutations/award_emojis/toggle.rb7
-rw-r--r--app/graphql/types/issue_type.rb2
-rw-r--r--app/graphql/types/permission_types/base_permission_type.rb2
-rw-r--r--app/graphql/types/project_type.rb4
-rw-r--r--app/models/diff_viewer/base.rb2
-rw-r--r--app/models/key.rb8
-rw-r--r--app/models/project.rb7
-rw-r--r--app/validators/key_restriction_validator.rb3
-rw-r--r--app/views/projects/blob/_render_error.html.haml2
-rw-r--r--app/views/projects/blob/viewers/_contributing.html.haml2
-rw-r--r--app/views/projects/default_branch/_show.html.haml24
-rw-r--r--app/views/shared/form_elements/_description.html.haml4
-rw-r--r--app/views/shared/issuable/_form.html.haml1
-rw-r--r--app/views/shared/issuable/form/_template_selector.html.haml2
-rw-r--r--app/workers/chat_notification_worker.rb16
-rw-r--r--changelogs/unreleased/119198-chat_notification-sidekiq-job-latency-has-increased.yml5
-rw-r--r--changelogs/unreleased/32273-fix-choose-template.yml5
-rw-r--r--changelogs/unreleased/feat-disable-issue-autoclose-feature.yml5
-rw-r--r--db/migrate/20200103195205_add_autoclose_referenced_issues_to_projects.rb9
-rw-r--r--db/schema.rb1
-rw-r--r--doc/administration/geo/replication/troubleshooting.md34
-rw-r--r--doc/api/graphql/reference/gitlab_schema.graphql177
-rw-r--r--doc/api/graphql/reference/gitlab_schema.json186
-rw-r--r--doc/api/graphql/reference/index.md173
-rw-r--r--doc/api/projects.md15
-rw-r--r--doc/development/api_graphql_styleguide.md2
-rw-r--r--doc/development/testing_guide/best_practices.md1
-rw-r--r--doc/user/project/issues/img/disable_issue_auto_close.pngbin0 -> 48055 bytes
-rw-r--r--doc/user/project/issues/managing_issues.md13
-rw-r--r--lib/api/entities.rb1
-rw-r--r--lib/api/helpers/projects_helpers.rb2
-rw-r--r--lib/gitlab/closing_issue_extractor.rb2
-rw-r--r--lib/gitlab/utils.rb6
-rw-r--r--locale/gitlab.pot12
-rw-r--r--spec/frontend/create_cluster/gke_cluster/components/gke_machine_type_dropdown_spec.js136
-rw-r--r--spec/frontend/create_cluster/gke_cluster/mock_data.js75
-rw-r--r--spec/graphql/types/project_type_spec.rb2
-rw-r--r--spec/javascripts/create_cluster/gke_cluster/components/gke_machine_type_dropdown_spec.js109
-rw-r--r--spec/lib/gitlab/closing_issue_extractor_spec.rb11
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml1
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml1
-rw-r--r--spec/lib/gitlab/utils_spec.rb35
-rw-r--r--spec/models/commit_spec.rb11
-rw-r--r--spec/models/merge_request_spec.rb9
-rw-r--r--spec/models/project_spec.rb26
-rw-r--r--spec/requests/api/projects_spec.rb17
-rw-r--r--spec/workers/chat_notification_worker_spec.rb35
48 files changed, 797 insertions, 407 deletions
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 5a65b0eb36b..dd392bd39a8 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -386,6 +386,7 @@ class ProjectsController < Projects::ApplicationController
:template_project_id,
:merge_method,
:initialize_with_readme,
+ :autoclose_referenced_issues,
project_feature_attributes: %i[
builds_access_level
diff --git a/app/graphql/mutations/award_emojis/toggle.rb b/app/graphql/mutations/award_emojis/toggle.rb
index d822048f3a6..22eab4812a1 100644
--- a/app/graphql/mutations/award_emojis/toggle.rb
+++ b/app/graphql/mutations/award_emojis/toggle.rb
@@ -5,10 +5,9 @@ module Mutations
class Toggle < Base
graphql_name 'ToggleAwardEmoji'
- field :toggledOn,
- GraphQL::BOOLEAN_TYPE,
- null: false,
- description: 'True when the emoji was awarded, false when it was removed'
+ field :toggledOn, GraphQL::BOOLEAN_TYPE, null: false,
+ description: 'Indicates the status of the emoji. ' \
+ 'True if the toggle awarded the emoji, and false if the toggle removed the emoji.'
def resolve(args)
awardable = authorized_find!(id: args[:awardable_id])
diff --git a/app/graphql/types/issue_type.rb b/app/graphql/types/issue_type.rb
index 4cbb849da3a..11850e5865f 100644
--- a/app/graphql/types/issue_type.rb
+++ b/app/graphql/types/issue_type.rb
@@ -69,7 +69,7 @@ module Types
field :participants, Types::UserType.connection_type, null: true, complexity: 5,
description: 'List of participants in the issue'
field :subscribed, GraphQL::BOOLEAN_TYPE, method: :subscribed?, null: false, complexity: 5,
- description: 'Boolean flag for whether the currently logged in user is subscribed to this issue'
+ description: 'Indicates the currently logged in user is subscribed to the issue'
field :time_estimate, GraphQL::INT_TYPE, null: false,
description: 'Time estimate of the issue'
field :total_time_spent, GraphQL::INT_TYPE, null: false,
diff --git a/app/graphql/types/permission_types/base_permission_type.rb b/app/graphql/types/permission_types/base_permission_type.rb
index 73049ebed7b..deb8560bd79 100644
--- a/app/graphql/types/permission_types/base_permission_type.rb
+++ b/app/graphql/types/permission_types/base_permission_type.rb
@@ -25,7 +25,7 @@ module Types
kword_args = kword_args.reverse_merge(
name: name,
type: GraphQL::BOOLEAN_TYPE,
- description: "Whether or not a user can perform `#{name}` on this resource",
+ description: "Indicates the user can perform `#{name}` on this resource",
null: false)
field(**kword_args) # rubocop:disable Graphql/Descriptions
diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb
index cd894f9775a..0bd2b0c81d9 100644
--- a/app/graphql/types/project_type.rb
+++ b/app/graphql/types/project_type.rb
@@ -46,7 +46,7 @@ module Types
description: 'Timestamp of the project last activity'
field :archived, GraphQL::BOOLEAN_TYPE, null: true,
- description: 'Archived status of the project'
+ description: 'Indicates the archived status of the project'
field :visibility, GraphQL::STRING_TYPE, null: true,
description: 'Visibility of the project'
@@ -102,6 +102,8 @@ module Types
description: 'Indicates if a link to create or view a merge request should display after a push to Git repositories of the project from the command line'
field :remove_source_branch_after_merge, GraphQL::BOOLEAN_TYPE, null: true,
description: 'Indicates if `Delete source branch` option should be enabled by default for all new merge requests of the project'
+ field :autoclose_referenced_issues, GraphQL::BOOLEAN_TYPE, null: true,
+ description: 'Indicates if issues referenced by merge requests and commits within the default branch are closed automatically'
field :namespace, Types::NamespaceType, null: true,
description: 'Namespace of the project'
diff --git a/app/models/diff_viewer/base.rb b/app/models/diff_viewer/base.rb
index 22c8fe73563..37831683555 100644
--- a/app/models/diff_viewer/base.rb
+++ b/app/models/diff_viewer/base.rb
@@ -89,7 +89,7 @@ module DiffViewer
{
viewer: switcher_title,
reason: render_error_reason,
- options: render_error_options.to_sentence(two_words_connector: _(' or '), last_word_connector: _(', or '))
+ options: Gitlab::Utils.to_exclusive_sentence(render_error_options)
}
end
diff --git a/app/models/key.rb b/app/models/key.rb
index e549c59b58f..71188f210bb 100644
--- a/app/models/key.rb
+++ b/app/models/key.rb
@@ -142,13 +142,9 @@ class Key < ApplicationRecord
end
def forbidden_key_type_message
- allowed_types =
- Gitlab::CurrentSettings
- .allowed_key_types
- .map(&:upcase)
- .to_sentence(last_word_connector: ', or ', two_words_connector: ' or ')
+ allowed_types = Gitlab::CurrentSettings.allowed_key_types.map(&:upcase)
- "type is forbidden. Must be #{allowed_types}"
+ "type is forbidden. Must be #{Gitlab::Utils.to_exclusive_sentence(allowed_types)}"
end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 057bcbabbeb..25819bc2b85 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -75,6 +75,7 @@ class Project < ApplicationRecord
default_value_for :snippets_enabled, gitlab_config_features.snippets
default_value_for :only_allow_merge_if_all_discussions_are_resolved, false
default_value_for :remove_source_branch_after_merge, true
+ default_value_for :autoclose_referenced_issues, true
default_value_for(:ci_config_path) { Gitlab::CurrentSettings.default_ci_config_path }
add_authentication_token_field :runners_token, encrypted: -> { Feature.enabled?(:projects_tokens_optional_encryption, default_enabled: true) ? :optional : :required }
@@ -679,6 +680,12 @@ class Project < ApplicationRecord
end
end
+ def autoclose_referenced_issues
+ return true if super.nil?
+
+ super
+ end
+
def preload_protected_branches
preloader = ActiveRecord::Associations::Preloader.new
preloader.preload(self, protected_branches: [:push_access_levels, :merge_access_levels])
diff --git a/app/validators/key_restriction_validator.rb b/app/validators/key_restriction_validator.rb
index 891d13b1596..9809047ae83 100644
--- a/app/validators/key_restriction_validator.rb
+++ b/app/validators/key_restriction_validator.rb
@@ -21,7 +21,8 @@ class KeyRestrictionValidator < ActiveModel::EachValidator
def supported_sizes_message
sizes = self.class.supported_sizes(options[:type])
- sizes.to_sentence(last_word_connector: ', or ', two_words_connector: ' or ')
+
+ Gitlab::Utils.to_exclusive_sentence(sizes)
end
def valid_restriction?(value)
diff --git a/app/views/projects/blob/_render_error.html.haml b/app/views/projects/blob/_render_error.html.haml
index 9eef6cafd04..1ff68cd2d11 100644
--- a/app/views/projects/blob/_render_error.html.haml
+++ b/app/views/projects/blob/_render_error.html.haml
@@ -3,5 +3,5 @@
The #{viewer.switcher_title} could not be displayed because #{blob_render_error_reason(viewer)}.
You can
- = blob_render_error_options(viewer).to_sentence(two_words_connector: ' or ', last_word_connector: ', or ').html_safe
+ = Gitlab::Utils.to_exclusive_sentence(blob_render_error_options(viewer)).html_safe
instead.
diff --git a/app/views/projects/blob/viewers/_contributing.html.haml b/app/views/projects/blob/viewers/_contributing.html.haml
index c78f04c9c7c..546c064c06f 100644
--- a/app/views/projects/blob/viewers/_contributing.html.haml
+++ b/app/views/projects/blob/viewers/_contributing.html.haml
@@ -4,6 +4,6 @@ After you've reviewed these contribution guidelines, you'll be all set to
- options = contribution_options(viewer.project)
- if options.any?
= succeed '.' do
- = options.to_sentence(two_words_connector: ' or ', last_word_connector: ', or ').html_safe
+ = Gitlab::Utils.to_exclusive_sentence(options).html_safe
- else
contribute to this project.
diff --git a/app/views/projects/default_branch/_show.html.haml b/app/views/projects/default_branch/_show.html.haml
index 59efcde5825..6a09004143e 100644
--- a/app/views/projects/default_branch/_show.html.haml
+++ b/app/views/projects/default_branch/_show.html.haml
@@ -9,13 +9,23 @@
= _('Select the branch you want to set as the default for this project. All merge requests and commits will automatically be made against this branch unless you specify a different one.')
.settings-content
- - if @project.empty_repo?
- .text-secondary
- = _('A default branch cannot be chosen for an empty project.')
- - else
- = form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, anchor: 'default-branch-settings' }, authenticity_token: true do |f|
- %fieldset
+ = form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, anchor: 'default-branch-settings' }, authenticity_token: true do |f|
+ %fieldset
+ - if @project.empty_repo?
+ .text-secondary
+ = _('A default branch cannot be chosen for an empty project.')
+ - else
.form-group
= f.label :default_branch, "Default Branch", class: 'label-bold'
= f.select(:default_branch, @project.repository.branch_names, {}, {class: 'select2 select-wide'})
- = f.submit 'Save changes', class: "btn btn-success"
+
+ .form-group
+ .form-check
+ = f.check_box :autoclose_referenced_issues, class: 'form-check-input'
+ = f.label :autoclose_referenced_issues, class: 'form-check-label' do
+ %strong= _("Auto-close referenced issues on default branch")
+ .form-text.text-muted
+ = _("Issues referenced by merge requests and commits within the default branch will be closed automatically")
+ = link_to icon('question-circle'), help_page_path('user/project/issues/managing_issues.html', anchor: 'disabling-automatic-issue-closing'), target: '_blank'
+
+ = f.submit 'Save changes', class: "btn btn-success"
diff --git a/app/views/shared/form_elements/_description.html.haml b/app/views/shared/form_elements/_description.html.haml
index 9db6184ebca..2f2e6d83f9f 100644
--- a/app/views/shared/form_elements/_description.html.haml
+++ b/app/views/shared/form_elements/_description.html.haml
@@ -1,6 +1,8 @@
- project = local_assigns.fetch(:project)
- model = local_assigns.fetch(:model)
+
+
- form = local_assigns.fetch(:form)
- placeholder = model.is_a?(MergeRequest) ? _('Describe the goal of the changes and what reviewers should be aware of.') : _('Write a comment or drag your files here…')
- supports_quick_actions = model.new_record?
@@ -14,6 +16,8 @@
= form.label :description, 'Description', class: 'col-form-label col-sm-2'
.col-sm-10
+ - if model.is_a?(Issuable)
+ = render 'shared/issuable/form/template_selector', issuable: model
= render layout: 'projects/md_preview', locals: { url: preview_url, referenced_users: true } do
= render 'projects/zen', f: form, attr: :description,
classes: 'note-textarea qa-issuable-form-description rspec-issuable-form-description',
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index 0fb23adc31f..a020a04e366 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -17,7 +17,6 @@
.form-group.row
= form.label :title, class: 'col-form-label col-sm-2'
- = render 'shared/issuable/form/template_selector', issuable: issuable
= render 'shared/issuable/form/title', issuable: issuable, form: form, has_wip_commits: commits && commits.detect(&:work_in_progress?)
#js-suggestions{ data: { project_path: @project.full_path } }
diff --git a/app/views/shared/issuable/form/_template_selector.html.haml b/app/views/shared/issuable/form/_template_selector.html.haml
index d613bd31d81..bf34ea4a1b2 100644
--- a/app/views/shared/issuable/form/_template_selector.html.haml
+++ b/app/views/shared/issuable/form/_template_selector.html.haml
@@ -2,7 +2,7 @@
- return unless issuable && issuable_templates(issuable).any?
-.col-sm-3.col-lg-2
+.issuable-form-select-holder.selectbox.form-group
.js-issuable-selector-wrap{ data: { issuable_type: issuable.to_ability_name } }
= template_dropdown_tag(issuable) do
%ul.dropdown-footer-list
diff --git a/app/workers/chat_notification_worker.rb b/app/workers/chat_notification_worker.rb
index 42a23cd472a..6162dcf9d38 100644
--- a/app/workers/chat_notification_worker.rb
+++ b/app/workers/chat_notification_worker.rb
@@ -3,6 +3,9 @@
class ChatNotificationWorker
include ApplicationWorker
+ TimeoutExceeded = Class.new(StandardError)
+
+ sidekiq_options retry: false
feature_category :chatops
latency_sensitive_worker!
# TODO: break this into multiple jobs
@@ -11,18 +14,21 @@ class ChatNotificationWorker
# worker_has_external_dependencies!
RESCHEDULE_INTERVAL = 2.seconds
+ RESCHEDULE_TIMEOUT = 5.minutes
# rubocop: disable CodeReuse/ActiveRecord
- def perform(build_id)
+ def perform(build_id, reschedule_count = 0)
Ci::Build.find_by(id: build_id).try do |build|
send_response(build)
end
rescue Gitlab::Chat::Output::MissingBuildSectionError
+ raise TimeoutExceeded if timeout_exceeded?(reschedule_count)
+
# The creation of traces and sections appears to be eventually consistent.
# As a result it's possible for us to run the above code before the trace
# sections are present. To better handle such cases we'll just reschedule
# the job instead of producing an error.
- self.class.perform_in(RESCHEDULE_INTERVAL, build_id)
+ self.class.perform_in(RESCHEDULE_INTERVAL, build_id, reschedule_count + 1)
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -37,4 +43,10 @@ class ChatNotificationWorker
end
end
end
+
+ private
+
+ def timeout_exceeded?(reschedule_count)
+ (reschedule_count * RESCHEDULE_INTERVAL) >= RESCHEDULE_TIMEOUT
+ end
end
diff --git a/changelogs/unreleased/119198-chat_notification-sidekiq-job-latency-has-increased.yml b/changelogs/unreleased/119198-chat_notification-sidekiq-job-latency-has-increased.yml
new file mode 100644
index 00000000000..158f062b3d6
--- /dev/null
+++ b/changelogs/unreleased/119198-chat_notification-sidekiq-job-latency-has-increased.yml
@@ -0,0 +1,5 @@
+---
+title: Limit the amount of time ChatNotificationWorker waits for the build trace
+merge_request: 22132
+author:
+type: fixed
diff --git a/changelogs/unreleased/32273-fix-choose-template.yml b/changelogs/unreleased/32273-fix-choose-template.yml
new file mode 100644
index 00000000000..384a46f4dae
--- /dev/null
+++ b/changelogs/unreleased/32273-fix-choose-template.yml
@@ -0,0 +1,5 @@
+---
+title: Changes to template dropdown location
+merge_request: 22049
+author:
+type: changed
diff --git a/changelogs/unreleased/feat-disable-issue-autoclose-feature.yml b/changelogs/unreleased/feat-disable-issue-autoclose-feature.yml
new file mode 100644
index 00000000000..02b0f820bad
--- /dev/null
+++ b/changelogs/unreleased/feat-disable-issue-autoclose-feature.yml
@@ -0,0 +1,5 @@
+---
+title: Add capability to disable issue auto-close feature per project
+merge_request: 21704
+author: Fabio Huser
+type: added
diff --git a/db/migrate/20200103195205_add_autoclose_referenced_issues_to_projects.rb b/db/migrate/20200103195205_add_autoclose_referenced_issues_to_projects.rb
new file mode 100644
index 00000000000..ac1aa2276fc
--- /dev/null
+++ b/db/migrate/20200103195205_add_autoclose_referenced_issues_to_projects.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddAutocloseReferencedIssuesToProjects < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ add_column :projects, :autoclose_referenced_issues, :boolean
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 328948dea66..ca27c33d6f1 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -3348,6 +3348,7 @@ ActiveRecord::Schema.define(version: 2020_01_06_085831) do
t.boolean "remove_source_branch_after_merge"
t.date "marked_for_deletion_at"
t.integer "marked_for_deletion_by_user_id"
+ t.boolean "autoclose_referenced_issues"
t.index "lower((name)::text)", name: "index_projects_on_lower_name"
t.index ["created_at", "id"], name: "index_projects_on_created_at_and_id"
t.index ["creator_id"], name: "index_projects_on_creator_id"
diff --git a/doc/administration/geo/replication/troubleshooting.md b/doc/administration/geo/replication/troubleshooting.md
index 0a2602261d1..e60a70d57c9 100644
--- a/doc/administration/geo/replication/troubleshooting.md
+++ b/doc/administration/geo/replication/troubleshooting.md
@@ -318,6 +318,40 @@ Slots where `active` is `f` are not active.
SELECT pg_drop_replication_slot('<name_of_extra_slot>');
```
+### Message: "ERROR: canceling statement due to conflict with recovery"
+
+This error may rarely occur under normal usage, and the system is resilient
+enough to recover.
+
+However, under certain conditions, some database queries on secondaries may run
+excessively long, which increases the frequency of this error. At some point,
+some of these queries will never be able to complete due to being canceled
+every time.
+
+These long-running queries are
+[planned to be removed in the future](https://gitlab.com/gitlab-org/gitlab/issues/34269),
+but as a workaround, we recommend enabling
+[hot_standby_feedback](https://www.postgresql.org/docs/10/hot-standby.html#HOT-STANDBY-CONFLICT).
+This increases the likelihood of bloat on the **primary** node as it prevents
+`VACUUM` from removing recently-dead rows. However, it has been used
+successfully in production on GitLab.com.
+
+To enable `hot_standby_feedback`, add the following to `/etc/gitlab/gitlab.rb`
+on the **secondary** node:
+
+```ruby
+postgresql['hot_standby_feedback'] = 'on'
+```
+
+Then reconfigure GitLab:
+
+```sh
+sudo gitlab-ctl reconfigure
+```
+
+To help us resolve this problem, consider commenting on
+[the issue](https://gitlab.com/gitlab-org/gitlab/issues/4489).
+
### Very large repositories never successfully synchronize on the **secondary** node
GitLab places a timeout on all repository clones, including project imports
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index 731d6dc05cd..5c6dd93a676 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -1668,7 +1668,7 @@ type Epic implements Noteable {
state: EpicState!
"""
- Boolean flag for whether the currently logged in user is subscribed to this epic
+ Indicates the currently logged in user is subscribed to the epic
"""
subscribed: Boolean!
@@ -1984,7 +1984,7 @@ type EpicIssue implements Noteable {
state: IssueState!
"""
- Boolean flag for whether the currently logged in user is subscribed to this issue
+ Indicates the currently logged in user is subscribed to the issue
"""
subscribed: Boolean!
@@ -2089,42 +2089,42 @@ Check permissions for the current user on an epic
"""
type EpicPermissions {
"""
- Whether or not a user can perform `admin_epic` on this resource
+ Indicates the user can perform `admin_epic` on this resource
"""
adminEpic: Boolean!
"""
- Whether or not a user can perform `award_emoji` on this resource
+ Indicates the user can perform `award_emoji` on this resource
"""
awardEmoji: Boolean!
"""
- Whether or not a user can perform `create_epic` on this resource
+ Indicates the user can perform `create_epic` on this resource
"""
createEpic: Boolean!
"""
- Whether or not a user can perform `create_note` on this resource
+ Indicates the user can perform `create_note` on this resource
"""
createNote: Boolean!
"""
- Whether or not a user can perform `destroy_epic` on this resource
+ Indicates the user can perform `destroy_epic` on this resource
"""
destroyEpic: Boolean!
"""
- Whether or not a user can perform `read_epic` on this resource
+ Indicates the user can perform `read_epic` on this resource
"""
readEpic: Boolean!
"""
- Whether or not a user can perform `read_epic_iid` on this resource
+ Indicates the user can perform `read_epic_iid` on this resource
"""
readEpicIid: Boolean!
"""
- Whether or not a user can perform `update_epic` on this resource
+ Indicates the user can perform `update_epic` on this resource
"""
updateEpic: Boolean!
}
@@ -2585,7 +2585,7 @@ type Group {
type GroupPermissions {
"""
- Whether or not a user can perform `read_group` on this resource
+ Indicates the user can perform `read_group` on this resource
"""
readGroup: Boolean!
}
@@ -2816,7 +2816,7 @@ type Issue implements Noteable {
state: IssueState!
"""
- Boolean flag for whether the currently logged in user is subscribed to this issue
+ Indicates the currently logged in user is subscribed to the issue
"""
subscribed: Boolean!
@@ -2921,42 +2921,42 @@ Check permissions for the current user on a issue
"""
type IssuePermissions {
"""
- Whether or not a user can perform `admin_issue` on this resource
+ Indicates the user can perform `admin_issue` on this resource
"""
adminIssue: Boolean!
"""
- Whether or not a user can perform `create_design` on this resource
+ Indicates the user can perform `create_design` on this resource
"""
createDesign: Boolean!
"""
- Whether or not a user can perform `create_note` on this resource
+ Indicates the user can perform `create_note` on this resource
"""
createNote: Boolean!
"""
- Whether or not a user can perform `destroy_design` on this resource
+ Indicates the user can perform `destroy_design` on this resource
"""
destroyDesign: Boolean!
"""
- Whether or not a user can perform `read_design` on this resource
+ Indicates the user can perform `read_design` on this resource
"""
readDesign: Boolean!
"""
- Whether or not a user can perform `read_issue` on this resource
+ Indicates the user can perform `read_issue` on this resource
"""
readIssue: Boolean!
"""
- Whether or not a user can perform `reopen_issue` on this resource
+ Indicates the user can perform `reopen_issue` on this resource
"""
reopenIssue: Boolean!
"""
- Whether or not a user can perform `update_issue` on this resource
+ Indicates the user can perform `update_issue` on this resource
"""
updateIssue: Boolean!
}
@@ -3714,42 +3714,42 @@ Check permissions for the current user on a merge request
"""
type MergeRequestPermissions {
"""
- Whether or not a user can perform `admin_merge_request` on this resource
+ Indicates the user can perform `admin_merge_request` on this resource
"""
adminMergeRequest: Boolean!
"""
- Whether or not a user can perform `cherry_pick_on_current_merge_request` on this resource
+ Indicates the user can perform `cherry_pick_on_current_merge_request` on this resource
"""
cherryPickOnCurrentMergeRequest: Boolean!
"""
- Whether or not a user can perform `create_note` on this resource
+ Indicates the user can perform `create_note` on this resource
"""
createNote: Boolean!
"""
- Whether or not a user can perform `push_to_source_branch` on this resource
+ Indicates the user can perform `push_to_source_branch` on this resource
"""
pushToSourceBranch: Boolean!
"""
- Whether or not a user can perform `read_merge_request` on this resource
+ Indicates the user can perform `read_merge_request` on this resource
"""
readMergeRequest: Boolean!
"""
- Whether or not a user can perform `remove_source_branch` on this resource
+ Indicates the user can perform `remove_source_branch` on this resource
"""
removeSourceBranch: Boolean!
"""
- Whether or not a user can perform `revert_on_current_merge_request` on this resource
+ Indicates the user can perform `revert_on_current_merge_request` on this resource
"""
revertOnCurrentMergeRequest: Boolean!
"""
- Whether or not a user can perform `update_merge_request` on this resource
+ Indicates the user can perform `update_merge_request` on this resource
"""
updateMergeRequest: Boolean!
}
@@ -4362,27 +4362,27 @@ type NoteEdge {
type NotePermissions {
"""
- Whether or not a user can perform `admin_note` on this resource
+ Indicates the user can perform `admin_note` on this resource
"""
adminNote: Boolean!
"""
- Whether or not a user can perform `award_emoji` on this resource
+ Indicates the user can perform `award_emoji` on this resource
"""
awardEmoji: Boolean!
"""
- Whether or not a user can perform `create_note` on this resource
+ Indicates the user can perform `create_note` on this resource
"""
createNote: Boolean!
"""
- Whether or not a user can perform `read_note` on this resource
+ Indicates the user can perform `read_note` on this resource
"""
readNote: Boolean!
"""
- Whether or not a user can perform `resolve_note` on this resource
+ Indicates the user can perform `resolve_note` on this resource
"""
resolveNote: Boolean!
}
@@ -4574,17 +4574,17 @@ type PipelineEdge {
type PipelinePermissions {
"""
- Whether or not a user can perform `admin_pipeline` on this resource
+ Indicates the user can perform `admin_pipeline` on this resource
"""
adminPipeline: Boolean!
"""
- Whether or not a user can perform `destroy_pipeline` on this resource
+ Indicates the user can perform `destroy_pipeline` on this resource
"""
destroyPipeline: Boolean!
"""
- Whether or not a user can perform `update_pipeline` on this resource
+ Indicates the user can perform `update_pipeline` on this resource
"""
updatePipeline: Boolean!
}
@@ -4605,11 +4605,16 @@ enum PipelineStatusEnum {
type Project {
"""
- Archived status of the project
+ Indicates the archived status of the project
"""
archived: Boolean
"""
+ Indicates if issues referenced by merge requests and commits within the default branch are closed automatically
+ """
+ autocloseReferencedIssues: Boolean
+
+ """
URL to avatar image file of the project
"""
avatarUrl: String
@@ -5145,207 +5150,207 @@ type ProjectEdge {
type ProjectPermissions {
"""
- Whether or not a user can perform `admin_operations` on this resource
+ Indicates the user can perform `admin_operations` on this resource
"""
adminOperations: Boolean!
"""
- Whether or not a user can perform `admin_project` on this resource
+ Indicates the user can perform `admin_project` on this resource
"""
adminProject: Boolean!
"""
- Whether or not a user can perform `admin_remote_mirror` on this resource
+ Indicates the user can perform `admin_remote_mirror` on this resource
"""
adminRemoteMirror: Boolean!
"""
- Whether or not a user can perform `admin_wiki` on this resource
+ Indicates the user can perform `admin_wiki` on this resource
"""
adminWiki: Boolean!
"""
- Whether or not a user can perform `archive_project` on this resource
+ Indicates the user can perform `archive_project` on this resource
"""
archiveProject: Boolean!
"""
- Whether or not a user can perform `change_namespace` on this resource
+ Indicates the user can perform `change_namespace` on this resource
"""
changeNamespace: Boolean!
"""
- Whether or not a user can perform `change_visibility_level` on this resource
+ Indicates the user can perform `change_visibility_level` on this resource
"""
changeVisibilityLevel: Boolean!
"""
- Whether or not a user can perform `create_deployment` on this resource
+ Indicates the user can perform `create_deployment` on this resource
"""
createDeployment: Boolean!
"""
- Whether or not a user can perform `create_design` on this resource
+ Indicates the user can perform `create_design` on this resource
"""
createDesign: Boolean!
"""
- Whether or not a user can perform `create_issue` on this resource
+ Indicates the user can perform `create_issue` on this resource
"""
createIssue: Boolean!
"""
- Whether or not a user can perform `create_label` on this resource
+ Indicates the user can perform `create_label` on this resource
"""
createLabel: Boolean!
"""
- Whether or not a user can perform `create_merge_request_from` on this resource
+ Indicates the user can perform `create_merge_request_from` on this resource
"""
createMergeRequestFrom: Boolean!
"""
- Whether or not a user can perform `create_merge_request_in` on this resource
+ Indicates the user can perform `create_merge_request_in` on this resource
"""
createMergeRequestIn: Boolean!
"""
- Whether or not a user can perform `create_pages` on this resource
+ Indicates the user can perform `create_pages` on this resource
"""
createPages: Boolean!
"""
- Whether or not a user can perform `create_pipeline` on this resource
+ Indicates the user can perform `create_pipeline` on this resource
"""
createPipeline: Boolean!
"""
- Whether or not a user can perform `create_pipeline_schedule` on this resource
+ Indicates the user can perform `create_pipeline_schedule` on this resource
"""
createPipelineSchedule: Boolean!
"""
- Whether or not a user can perform `create_snippet` on this resource
+ Indicates the user can perform `create_snippet` on this resource
"""
createSnippet: Boolean!
"""
- Whether or not a user can perform `create_wiki` on this resource
+ Indicates the user can perform `create_wiki` on this resource
"""
createWiki: Boolean!
"""
- Whether or not a user can perform `destroy_design` on this resource
+ Indicates the user can perform `destroy_design` on this resource
"""
destroyDesign: Boolean!
"""
- Whether or not a user can perform `destroy_pages` on this resource
+ Indicates the user can perform `destroy_pages` on this resource
"""
destroyPages: Boolean!
"""
- Whether or not a user can perform `destroy_wiki` on this resource
+ Indicates the user can perform `destroy_wiki` on this resource
"""
destroyWiki: Boolean!
"""
- Whether or not a user can perform `download_code` on this resource
+ Indicates the user can perform `download_code` on this resource
"""
downloadCode: Boolean!
"""
- Whether or not a user can perform `download_wiki_code` on this resource
+ Indicates the user can perform `download_wiki_code` on this resource
"""
downloadWikiCode: Boolean!
"""
- Whether or not a user can perform `fork_project` on this resource
+ Indicates the user can perform `fork_project` on this resource
"""
forkProject: Boolean!
"""
- Whether or not a user can perform `push_code` on this resource
+ Indicates the user can perform `push_code` on this resource
"""
pushCode: Boolean!
"""
- Whether or not a user can perform `push_to_delete_protected_branch` on this resource
+ Indicates the user can perform `push_to_delete_protected_branch` on this resource
"""
pushToDeleteProtectedBranch: Boolean!
"""
- Whether or not a user can perform `read_commit_status` on this resource
+ Indicates the user can perform `read_commit_status` on this resource
"""
readCommitStatus: Boolean!
"""
- Whether or not a user can perform `read_cycle_analytics` on this resource
+ Indicates the user can perform `read_cycle_analytics` on this resource
"""
readCycleAnalytics: Boolean!
"""
- Whether or not a user can perform `read_design` on this resource
+ Indicates the user can perform `read_design` on this resource
"""
readDesign: Boolean!
"""
- Whether or not a user can perform `read_pages_content` on this resource
+ Indicates the user can perform `read_pages_content` on this resource
"""
readPagesContent: Boolean!
"""
- Whether or not a user can perform `read_project` on this resource
+ Indicates the user can perform `read_project` on this resource
"""
readProject: Boolean!
"""
- Whether or not a user can perform `read_project_member` on this resource
+ Indicates the user can perform `read_project_member` on this resource
"""
readProjectMember: Boolean!
"""
- Whether or not a user can perform `read_wiki` on this resource
+ Indicates the user can perform `read_wiki` on this resource
"""
readWiki: Boolean!
"""
- Whether or not a user can perform `remove_fork_project` on this resource
+ Indicates the user can perform `remove_fork_project` on this resource
"""
removeForkProject: Boolean!
"""
- Whether or not a user can perform `remove_pages` on this resource
+ Indicates the user can perform `remove_pages` on this resource
"""
removePages: Boolean!
"""
- Whether or not a user can perform `remove_project` on this resource
+ Indicates the user can perform `remove_project` on this resource
"""
removeProject: Boolean!
"""
- Whether or not a user can perform `rename_project` on this resource
+ Indicates the user can perform `rename_project` on this resource
"""
renameProject: Boolean!
"""
- Whether or not a user can perform `request_access` on this resource
+ Indicates the user can perform `request_access` on this resource
"""
requestAccess: Boolean!
"""
- Whether or not a user can perform `update_pages` on this resource
+ Indicates the user can perform `update_pages` on this resource
"""
updatePages: Boolean!
"""
- Whether or not a user can perform `update_wiki` on this resource
+ Indicates the user can perform `update_wiki` on this resource
"""
updateWiki: Boolean!
"""
- Whether or not a user can perform `upload_file` on this resource
+ Indicates the user can perform `upload_file` on this resource
"""
uploadFile: Boolean!
}
@@ -5909,32 +5914,32 @@ type SnippetEdge {
type SnippetPermissions {
"""
- Whether or not a user can perform `admin_snippet` on this resource
+ Indicates the user can perform `admin_snippet` on this resource
"""
adminSnippet: Boolean!
"""
- Whether or not a user can perform `award_emoji` on this resource
+ Indicates the user can perform `award_emoji` on this resource
"""
awardEmoji: Boolean!
"""
- Whether or not a user can perform `create_note` on this resource
+ Indicates the user can perform `create_note` on this resource
"""
createNote: Boolean!
"""
- Whether or not a user can perform `read_snippet` on this resource
+ Indicates the user can perform `read_snippet` on this resource
"""
readSnippet: Boolean!
"""
- Whether or not a user can perform `report_snippet` on this resource
+ Indicates the user can perform `report_snippet` on this resource
"""
reportSnippet: Boolean!
"""
- Whether or not a user can perform `update_snippet` on this resource
+ Indicates the user can perform `update_snippet` on this resource
"""
updateSnippet: Boolean!
}
@@ -6360,7 +6365,7 @@ type ToggleAwardEmojiPayload {
errors: [String!]!
"""
- True when the emoji was awarded, false when it was removed
+ Indicates the status of the emoji. True if the toggle awarded the emoji, and false if the toggle removed the emoji.
"""
toggledOn: Boolean!
}
@@ -6873,7 +6878,7 @@ type UserEdge {
type UserPermissions {
"""
- Whether or not a user can perform `create_snippet` on this resource
+ Indicates the user can perform `create_snippet` on this resource
"""
createSnippet: Boolean!
}
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index a68fe0e0e52..1357cab54fe 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -310,7 +310,21 @@
"fields": [
{
"name": "archived",
- "description": "Archived status of the project",
+ "description": "Indicates the archived status of the project",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "autocloseReferencedIssues",
+ "description": "Indicates if issues referenced by merge requests and commits within the default branch are closed automatically",
"args": [
],
@@ -1600,7 +1614,7 @@
"fields": [
{
"name": "adminOperations",
- "description": "Whether or not a user can perform `admin_operations` on this resource",
+ "description": "Indicates the user can perform `admin_operations` on this resource",
"args": [
],
@@ -1618,7 +1632,7 @@
},
{
"name": "adminProject",
- "description": "Whether or not a user can perform `admin_project` on this resource",
+ "description": "Indicates the user can perform `admin_project` on this resource",
"args": [
],
@@ -1636,7 +1650,7 @@
},
{
"name": "adminRemoteMirror",
- "description": "Whether or not a user can perform `admin_remote_mirror` on this resource",
+ "description": "Indicates the user can perform `admin_remote_mirror` on this resource",
"args": [
],
@@ -1654,7 +1668,7 @@
},
{
"name": "adminWiki",
- "description": "Whether or not a user can perform `admin_wiki` on this resource",
+ "description": "Indicates the user can perform `admin_wiki` on this resource",
"args": [
],
@@ -1672,7 +1686,7 @@
},
{
"name": "archiveProject",
- "description": "Whether or not a user can perform `archive_project` on this resource",
+ "description": "Indicates the user can perform `archive_project` on this resource",
"args": [
],
@@ -1690,7 +1704,7 @@
},
{
"name": "changeNamespace",
- "description": "Whether or not a user can perform `change_namespace` on this resource",
+ "description": "Indicates the user can perform `change_namespace` on this resource",
"args": [
],
@@ -1708,7 +1722,7 @@
},
{
"name": "changeVisibilityLevel",
- "description": "Whether or not a user can perform `change_visibility_level` on this resource",
+ "description": "Indicates the user can perform `change_visibility_level` on this resource",
"args": [
],
@@ -1726,7 +1740,7 @@
},
{
"name": "createDeployment",
- "description": "Whether or not a user can perform `create_deployment` on this resource",
+ "description": "Indicates the user can perform `create_deployment` on this resource",
"args": [
],
@@ -1744,7 +1758,7 @@
},
{
"name": "createDesign",
- "description": "Whether or not a user can perform `create_design` on this resource",
+ "description": "Indicates the user can perform `create_design` on this resource",
"args": [
],
@@ -1762,7 +1776,7 @@
},
{
"name": "createIssue",
- "description": "Whether or not a user can perform `create_issue` on this resource",
+ "description": "Indicates the user can perform `create_issue` on this resource",
"args": [
],
@@ -1780,7 +1794,7 @@
},
{
"name": "createLabel",
- "description": "Whether or not a user can perform `create_label` on this resource",
+ "description": "Indicates the user can perform `create_label` on this resource",
"args": [
],
@@ -1798,7 +1812,7 @@
},
{
"name": "createMergeRequestFrom",
- "description": "Whether or not a user can perform `create_merge_request_from` on this resource",
+ "description": "Indicates the user can perform `create_merge_request_from` on this resource",
"args": [
],
@@ -1816,7 +1830,7 @@
},
{
"name": "createMergeRequestIn",
- "description": "Whether or not a user can perform `create_merge_request_in` on this resource",
+ "description": "Indicates the user can perform `create_merge_request_in` on this resource",
"args": [
],
@@ -1834,7 +1848,7 @@
},
{
"name": "createPages",
- "description": "Whether or not a user can perform `create_pages` on this resource",
+ "description": "Indicates the user can perform `create_pages` on this resource",
"args": [
],
@@ -1852,7 +1866,7 @@
},
{
"name": "createPipeline",
- "description": "Whether or not a user can perform `create_pipeline` on this resource",
+ "description": "Indicates the user can perform `create_pipeline` on this resource",
"args": [
],
@@ -1870,7 +1884,7 @@
},
{
"name": "createPipelineSchedule",
- "description": "Whether or not a user can perform `create_pipeline_schedule` on this resource",
+ "description": "Indicates the user can perform `create_pipeline_schedule` on this resource",
"args": [
],
@@ -1888,7 +1902,7 @@
},
{
"name": "createSnippet",
- "description": "Whether or not a user can perform `create_snippet` on this resource",
+ "description": "Indicates the user can perform `create_snippet` on this resource",
"args": [
],
@@ -1906,7 +1920,7 @@
},
{
"name": "createWiki",
- "description": "Whether or not a user can perform `create_wiki` on this resource",
+ "description": "Indicates the user can perform `create_wiki` on this resource",
"args": [
],
@@ -1924,7 +1938,7 @@
},
{
"name": "destroyDesign",
- "description": "Whether or not a user can perform `destroy_design` on this resource",
+ "description": "Indicates the user can perform `destroy_design` on this resource",
"args": [
],
@@ -1942,7 +1956,7 @@
},
{
"name": "destroyPages",
- "description": "Whether or not a user can perform `destroy_pages` on this resource",
+ "description": "Indicates the user can perform `destroy_pages` on this resource",
"args": [
],
@@ -1960,7 +1974,7 @@
},
{
"name": "destroyWiki",
- "description": "Whether or not a user can perform `destroy_wiki` on this resource",
+ "description": "Indicates the user can perform `destroy_wiki` on this resource",
"args": [
],
@@ -1978,7 +1992,7 @@
},
{
"name": "downloadCode",
- "description": "Whether or not a user can perform `download_code` on this resource",
+ "description": "Indicates the user can perform `download_code` on this resource",
"args": [
],
@@ -1996,7 +2010,7 @@
},
{
"name": "downloadWikiCode",
- "description": "Whether or not a user can perform `download_wiki_code` on this resource",
+ "description": "Indicates the user can perform `download_wiki_code` on this resource",
"args": [
],
@@ -2014,7 +2028,7 @@
},
{
"name": "forkProject",
- "description": "Whether or not a user can perform `fork_project` on this resource",
+ "description": "Indicates the user can perform `fork_project` on this resource",
"args": [
],
@@ -2032,7 +2046,7 @@
},
{
"name": "pushCode",
- "description": "Whether or not a user can perform `push_code` on this resource",
+ "description": "Indicates the user can perform `push_code` on this resource",
"args": [
],
@@ -2050,7 +2064,7 @@
},
{
"name": "pushToDeleteProtectedBranch",
- "description": "Whether or not a user can perform `push_to_delete_protected_branch` on this resource",
+ "description": "Indicates the user can perform `push_to_delete_protected_branch` on this resource",
"args": [
],
@@ -2068,7 +2082,7 @@
},
{
"name": "readCommitStatus",
- "description": "Whether or not a user can perform `read_commit_status` on this resource",
+ "description": "Indicates the user can perform `read_commit_status` on this resource",
"args": [
],
@@ -2086,7 +2100,7 @@
},
{
"name": "readCycleAnalytics",
- "description": "Whether or not a user can perform `read_cycle_analytics` on this resource",
+ "description": "Indicates the user can perform `read_cycle_analytics` on this resource",
"args": [
],
@@ -2104,7 +2118,7 @@
},
{
"name": "readDesign",
- "description": "Whether or not a user can perform `read_design` on this resource",
+ "description": "Indicates the user can perform `read_design` on this resource",
"args": [
],
@@ -2122,7 +2136,7 @@
},
{
"name": "readPagesContent",
- "description": "Whether or not a user can perform `read_pages_content` on this resource",
+ "description": "Indicates the user can perform `read_pages_content` on this resource",
"args": [
],
@@ -2140,7 +2154,7 @@
},
{
"name": "readProject",
- "description": "Whether or not a user can perform `read_project` on this resource",
+ "description": "Indicates the user can perform `read_project` on this resource",
"args": [
],
@@ -2158,7 +2172,7 @@
},
{
"name": "readProjectMember",
- "description": "Whether or not a user can perform `read_project_member` on this resource",
+ "description": "Indicates the user can perform `read_project_member` on this resource",
"args": [
],
@@ -2176,7 +2190,7 @@
},
{
"name": "readWiki",
- "description": "Whether or not a user can perform `read_wiki` on this resource",
+ "description": "Indicates the user can perform `read_wiki` on this resource",
"args": [
],
@@ -2194,7 +2208,7 @@
},
{
"name": "removeForkProject",
- "description": "Whether or not a user can perform `remove_fork_project` on this resource",
+ "description": "Indicates the user can perform `remove_fork_project` on this resource",
"args": [
],
@@ -2212,7 +2226,7 @@
},
{
"name": "removePages",
- "description": "Whether or not a user can perform `remove_pages` on this resource",
+ "description": "Indicates the user can perform `remove_pages` on this resource",
"args": [
],
@@ -2230,7 +2244,7 @@
},
{
"name": "removeProject",
- "description": "Whether or not a user can perform `remove_project` on this resource",
+ "description": "Indicates the user can perform `remove_project` on this resource",
"args": [
],
@@ -2248,7 +2262,7 @@
},
{
"name": "renameProject",
- "description": "Whether or not a user can perform `rename_project` on this resource",
+ "description": "Indicates the user can perform `rename_project` on this resource",
"args": [
],
@@ -2266,7 +2280,7 @@
},
{
"name": "requestAccess",
- "description": "Whether or not a user can perform `request_access` on this resource",
+ "description": "Indicates the user can perform `request_access` on this resource",
"args": [
],
@@ -2284,7 +2298,7 @@
},
{
"name": "updatePages",
- "description": "Whether or not a user can perform `update_pages` on this resource",
+ "description": "Indicates the user can perform `update_pages` on this resource",
"args": [
],
@@ -2302,7 +2316,7 @@
},
{
"name": "updateWiki",
- "description": "Whether or not a user can perform `update_wiki` on this resource",
+ "description": "Indicates the user can perform `update_wiki` on this resource",
"args": [
],
@@ -2320,7 +2334,7 @@
},
{
"name": "uploadFile",
- "description": "Whether or not a user can perform `upload_file` on this resource",
+ "description": "Indicates the user can perform `upload_file` on this resource",
"args": [
],
@@ -3654,7 +3668,7 @@
"fields": [
{
"name": "readGroup",
- "description": "Whether or not a user can perform `read_group` on this resource",
+ "description": "Indicates the user can perform `read_group` on this resource",
"args": [
],
@@ -4498,7 +4512,7 @@
},
{
"name": "subscribed",
- "description": "Boolean flag for whether the currently logged in user is subscribed to this epic",
+ "description": "Indicates the currently logged in user is subscribed to the epic",
"args": [
],
@@ -5142,7 +5156,7 @@
"fields": [
{
"name": "adminNote",
- "description": "Whether or not a user can perform `admin_note` on this resource",
+ "description": "Indicates the user can perform `admin_note` on this resource",
"args": [
],
@@ -5160,7 +5174,7 @@
},
{
"name": "awardEmoji",
- "description": "Whether or not a user can perform `award_emoji` on this resource",
+ "description": "Indicates the user can perform `award_emoji` on this resource",
"args": [
],
@@ -5178,7 +5192,7 @@
},
{
"name": "createNote",
- "description": "Whether or not a user can perform `create_note` on this resource",
+ "description": "Indicates the user can perform `create_note` on this resource",
"args": [
],
@@ -5196,7 +5210,7 @@
},
{
"name": "readNote",
- "description": "Whether or not a user can perform `read_note` on this resource",
+ "description": "Indicates the user can perform `read_note` on this resource",
"args": [
],
@@ -5214,7 +5228,7 @@
},
{
"name": "resolveNote",
- "description": "Whether or not a user can perform `resolve_note` on this resource",
+ "description": "Indicates the user can perform `resolve_note` on this resource",
"args": [
],
@@ -5604,7 +5618,7 @@
"fields": [
{
"name": "createSnippet",
- "description": "Whether or not a user can perform `create_snippet` on this resource",
+ "description": "Indicates the user can perform `create_snippet` on this resource",
"args": [
],
@@ -6746,7 +6760,7 @@
"fields": [
{
"name": "adminSnippet",
- "description": "Whether or not a user can perform `admin_snippet` on this resource",
+ "description": "Indicates the user can perform `admin_snippet` on this resource",
"args": [
],
@@ -6764,7 +6778,7 @@
},
{
"name": "awardEmoji",
- "description": "Whether or not a user can perform `award_emoji` on this resource",
+ "description": "Indicates the user can perform `award_emoji` on this resource",
"args": [
],
@@ -6782,7 +6796,7 @@
},
{
"name": "createNote",
- "description": "Whether or not a user can perform `create_note` on this resource",
+ "description": "Indicates the user can perform `create_note` on this resource",
"args": [
],
@@ -6800,7 +6814,7 @@
},
{
"name": "readSnippet",
- "description": "Whether or not a user can perform `read_snippet` on this resource",
+ "description": "Indicates the user can perform `read_snippet` on this resource",
"args": [
],
@@ -6818,7 +6832,7 @@
},
{
"name": "reportSnippet",
- "description": "Whether or not a user can perform `report_snippet` on this resource",
+ "description": "Indicates the user can perform `report_snippet` on this resource",
"args": [
],
@@ -6836,7 +6850,7 @@
},
{
"name": "updateSnippet",
- "description": "Whether or not a user can perform `update_snippet` on this resource",
+ "description": "Indicates the user can perform `update_snippet` on this resource",
"args": [
],
@@ -7217,7 +7231,7 @@
"fields": [
{
"name": "adminEpic",
- "description": "Whether or not a user can perform `admin_epic` on this resource",
+ "description": "Indicates the user can perform `admin_epic` on this resource",
"args": [
],
@@ -7235,7 +7249,7 @@
},
{
"name": "awardEmoji",
- "description": "Whether or not a user can perform `award_emoji` on this resource",
+ "description": "Indicates the user can perform `award_emoji` on this resource",
"args": [
],
@@ -7253,7 +7267,7 @@
},
{
"name": "createEpic",
- "description": "Whether or not a user can perform `create_epic` on this resource",
+ "description": "Indicates the user can perform `create_epic` on this resource",
"args": [
],
@@ -7271,7 +7285,7 @@
},
{
"name": "createNote",
- "description": "Whether or not a user can perform `create_note` on this resource",
+ "description": "Indicates the user can perform `create_note` on this resource",
"args": [
],
@@ -7289,7 +7303,7 @@
},
{
"name": "destroyEpic",
- "description": "Whether or not a user can perform `destroy_epic` on this resource",
+ "description": "Indicates the user can perform `destroy_epic` on this resource",
"args": [
],
@@ -7307,7 +7321,7 @@
},
{
"name": "readEpic",
- "description": "Whether or not a user can perform `read_epic` on this resource",
+ "description": "Indicates the user can perform `read_epic` on this resource",
"args": [
],
@@ -7325,7 +7339,7 @@
},
{
"name": "readEpicIid",
- "description": "Whether or not a user can perform `read_epic_iid` on this resource",
+ "description": "Indicates the user can perform `read_epic_iid` on this resource",
"args": [
],
@@ -7343,7 +7357,7 @@
},
{
"name": "updateEpic",
- "description": "Whether or not a user can perform `update_epic` on this resource",
+ "description": "Indicates the user can perform `update_epic` on this resource",
"args": [
],
@@ -8597,7 +8611,7 @@
},
{
"name": "subscribed",
- "description": "Boolean flag for whether the currently logged in user is subscribed to this issue",
+ "description": "Indicates the currently logged in user is subscribed to the issue",
"args": [
],
@@ -8840,7 +8854,7 @@
"fields": [
{
"name": "adminIssue",
- "description": "Whether or not a user can perform `admin_issue` on this resource",
+ "description": "Indicates the user can perform `admin_issue` on this resource",
"args": [
],
@@ -8858,7 +8872,7 @@
},
{
"name": "createDesign",
- "description": "Whether or not a user can perform `create_design` on this resource",
+ "description": "Indicates the user can perform `create_design` on this resource",
"args": [
],
@@ -8876,7 +8890,7 @@
},
{
"name": "createNote",
- "description": "Whether or not a user can perform `create_note` on this resource",
+ "description": "Indicates the user can perform `create_note` on this resource",
"args": [
],
@@ -8894,7 +8908,7 @@
},
{
"name": "destroyDesign",
- "description": "Whether or not a user can perform `destroy_design` on this resource",
+ "description": "Indicates the user can perform `destroy_design` on this resource",
"args": [
],
@@ -8912,7 +8926,7 @@
},
{
"name": "readDesign",
- "description": "Whether or not a user can perform `read_design` on this resource",
+ "description": "Indicates the user can perform `read_design` on this resource",
"args": [
],
@@ -8930,7 +8944,7 @@
},
{
"name": "readIssue",
- "description": "Whether or not a user can perform `read_issue` on this resource",
+ "description": "Indicates the user can perform `read_issue` on this resource",
"args": [
],
@@ -8948,7 +8962,7 @@
},
{
"name": "reopenIssue",
- "description": "Whether or not a user can perform `reopen_issue` on this resource",
+ "description": "Indicates the user can perform `reopen_issue` on this resource",
"args": [
],
@@ -8966,7 +8980,7 @@
},
{
"name": "updateIssue",
- "description": "Whether or not a user can perform `update_issue` on this resource",
+ "description": "Indicates the user can perform `update_issue` on this resource",
"args": [
],
@@ -9981,7 +9995,7 @@
},
{
"name": "subscribed",
- "description": "Boolean flag for whether the currently logged in user is subscribed to this issue",
+ "description": "Indicates the currently logged in user is subscribed to the issue",
"args": [
],
@@ -12284,7 +12298,7 @@
"fields": [
{
"name": "adminPipeline",
- "description": "Whether or not a user can perform `admin_pipeline` on this resource",
+ "description": "Indicates the user can perform `admin_pipeline` on this resource",
"args": [
],
@@ -12302,7 +12316,7 @@
},
{
"name": "destroyPipeline",
- "description": "Whether or not a user can perform `destroy_pipeline` on this resource",
+ "description": "Indicates the user can perform `destroy_pipeline` on this resource",
"args": [
],
@@ -12320,7 +12334,7 @@
},
{
"name": "updatePipeline",
- "description": "Whether or not a user can perform `update_pipeline` on this resource",
+ "description": "Indicates the user can perform `update_pipeline` on this resource",
"args": [
],
@@ -14828,7 +14842,7 @@
"fields": [
{
"name": "adminMergeRequest",
- "description": "Whether or not a user can perform `admin_merge_request` on this resource",
+ "description": "Indicates the user can perform `admin_merge_request` on this resource",
"args": [
],
@@ -14846,7 +14860,7 @@
},
{
"name": "cherryPickOnCurrentMergeRequest",
- "description": "Whether or not a user can perform `cherry_pick_on_current_merge_request` on this resource",
+ "description": "Indicates the user can perform `cherry_pick_on_current_merge_request` on this resource",
"args": [
],
@@ -14864,7 +14878,7 @@
},
{
"name": "createNote",
- "description": "Whether or not a user can perform `create_note` on this resource",
+ "description": "Indicates the user can perform `create_note` on this resource",
"args": [
],
@@ -14882,7 +14896,7 @@
},
{
"name": "pushToSourceBranch",
- "description": "Whether or not a user can perform `push_to_source_branch` on this resource",
+ "description": "Indicates the user can perform `push_to_source_branch` on this resource",
"args": [
],
@@ -14900,7 +14914,7 @@
},
{
"name": "readMergeRequest",
- "description": "Whether or not a user can perform `read_merge_request` on this resource",
+ "description": "Indicates the user can perform `read_merge_request` on this resource",
"args": [
],
@@ -14918,7 +14932,7 @@
},
{
"name": "removeSourceBranch",
- "description": "Whether or not a user can perform `remove_source_branch` on this resource",
+ "description": "Indicates the user can perform `remove_source_branch` on this resource",
"args": [
],
@@ -14936,7 +14950,7 @@
},
{
"name": "revertOnCurrentMergeRequest",
- "description": "Whether or not a user can perform `revert_on_current_merge_request` on this resource",
+ "description": "Indicates the user can perform `revert_on_current_merge_request` on this resource",
"args": [
],
@@ -14954,7 +14968,7 @@
},
{
"name": "updateMergeRequest",
- "description": "Whether or not a user can perform `update_merge_request` on this resource",
+ "description": "Indicates the user can perform `update_merge_request` on this resource",
"args": [
],
@@ -17089,7 +17103,7 @@
},
{
"name": "toggledOn",
- "description": "True when the emoji was awarded, false when it was removed",
+ "description": "Indicates the status of the emoji. True if the toggle awarded the emoji, and false if the toggle removed the emoji.",
"args": [
],
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index dbff0b1759b..8ca17d4107d 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -239,7 +239,7 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| `relativePosition` | Int | The relative position of the epic in the epic tree |
| `relationPath` | String | |
| `reference` | String! | |
-| `subscribed` | Boolean! | Boolean flag for whether the currently logged in user is subscribed to this epic |
+| `subscribed` | Boolean! | Indicates the currently logged in user is subscribed to the epic |
| `descendantCounts` | EpicDescendantCount | Number of open and closed descendant epics and issues |
### EpicDescendantCount
@@ -274,7 +274,7 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| `webPath` | String! | Web path of the issue |
| `webUrl` | String! | Web URL of the issue |
| `relativePosition` | Int | Relative position of the issue (used for positioning in epic tree and issue boards) |
-| `subscribed` | Boolean! | Boolean flag for whether the currently logged in user is subscribed to this issue |
+| `subscribed` | Boolean! | Indicates the currently logged in user is subscribed to the issue |
| `timeEstimate` | Int! | Time estimate of the issue |
| `totalTimeSpent` | Int! | Total time reported as spent on the issue |
| `closedAt` | Time | Timestamp of when the issue was closed |
@@ -293,14 +293,14 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| Name | Type | Description |
| --- | ---- | ---------- |
-| `readEpic` | Boolean! | Whether or not a user can perform `read_epic` on this resource |
-| `readEpicIid` | Boolean! | Whether or not a user can perform `read_epic_iid` on this resource |
-| `updateEpic` | Boolean! | Whether or not a user can perform `update_epic` on this resource |
-| `destroyEpic` | Boolean! | Whether or not a user can perform `destroy_epic` on this resource |
-| `adminEpic` | Boolean! | Whether or not a user can perform `admin_epic` on this resource |
-| `createEpic` | Boolean! | Whether or not a user can perform `create_epic` on this resource |
-| `createNote` | Boolean! | Whether or not a user can perform `create_note` on this resource |
-| `awardEmoji` | Boolean! | Whether or not a user can perform `award_emoji` on this resource |
+| `readEpic` | Boolean! | Indicates the user can perform `read_epic` on this resource |
+| `readEpicIid` | Boolean! | Indicates the user can perform `read_epic_iid` on this resource |
+| `updateEpic` | Boolean! | Indicates the user can perform `update_epic` on this resource |
+| `destroyEpic` | Boolean! | Indicates the user can perform `destroy_epic` on this resource |
+| `adminEpic` | Boolean! | Indicates the user can perform `admin_epic` on this resource |
+| `createEpic` | Boolean! | Indicates the user can perform `create_epic` on this resource |
+| `createNote` | Boolean! | Indicates the user can perform `create_note` on this resource |
+| `awardEmoji` | Boolean! | Indicates the user can perform `award_emoji` on this resource |
### EpicSetSubscriptionPayload
@@ -355,7 +355,7 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| Name | Type | Description |
| --- | ---- | ---------- |
-| `readGroup` | Boolean! | Whether or not a user can perform `read_group` on this resource |
+| `readGroup` | Boolean! | Indicates the user can perform `read_group` on this resource |
### Issue
@@ -380,7 +380,7 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| `webPath` | String! | Web path of the issue |
| `webUrl` | String! | Web URL of the issue |
| `relativePosition` | Int | Relative position of the issue (used for positioning in epic tree and issue boards) |
-| `subscribed` | Boolean! | Boolean flag for whether the currently logged in user is subscribed to this issue |
+| `subscribed` | Boolean! | Indicates the currently logged in user is subscribed to the issue |
| `timeEstimate` | Int! | Time estimate of the issue |
| `totalTimeSpent` | Int! | Total time reported as spent on the issue |
| `closedAt` | Time | Timestamp of when the issue was closed |
@@ -396,14 +396,14 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| Name | Type | Description |
| --- | ---- | ---------- |
-| `readIssue` | Boolean! | Whether or not a user can perform `read_issue` on this resource |
-| `adminIssue` | Boolean! | Whether or not a user can perform `admin_issue` on this resource |
-| `updateIssue` | Boolean! | Whether or not a user can perform `update_issue` on this resource |
-| `createNote` | Boolean! | Whether or not a user can perform `create_note` on this resource |
-| `reopenIssue` | Boolean! | Whether or not a user can perform `reopen_issue` on this resource |
-| `readDesign` | Boolean! | Whether or not a user can perform `read_design` on this resource |
-| `createDesign` | Boolean! | Whether or not a user can perform `create_design` on this resource |
-| `destroyDesign` | Boolean! | Whether or not a user can perform `destroy_design` on this resource |
+| `readIssue` | Boolean! | Indicates the user can perform `read_issue` on this resource |
+| `adminIssue` | Boolean! | Indicates the user can perform `admin_issue` on this resource |
+| `updateIssue` | Boolean! | Indicates the user can perform `update_issue` on this resource |
+| `createNote` | Boolean! | Indicates the user can perform `create_note` on this resource |
+| `reopenIssue` | Boolean! | Indicates the user can perform `reopen_issue` on this resource |
+| `readDesign` | Boolean! | Indicates the user can perform `read_design` on this resource |
+| `createDesign` | Boolean! | Indicates the user can perform `create_design` on this resource |
+| `destroyDesign` | Boolean! | Indicates the user can perform `destroy_design` on this resource |
### IssueSetConfidentialPayload
@@ -506,14 +506,14 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| Name | Type | Description |
| --- | ---- | ---------- |
-| `readMergeRequest` | Boolean! | Whether or not a user can perform `read_merge_request` on this resource |
-| `adminMergeRequest` | Boolean! | Whether or not a user can perform `admin_merge_request` on this resource |
-| `updateMergeRequest` | Boolean! | Whether or not a user can perform `update_merge_request` on this resource |
-| `createNote` | Boolean! | Whether or not a user can perform `create_note` on this resource |
-| `pushToSourceBranch` | Boolean! | Whether or not a user can perform `push_to_source_branch` on this resource |
-| `removeSourceBranch` | Boolean! | Whether or not a user can perform `remove_source_branch` on this resource |
-| `cherryPickOnCurrentMergeRequest` | Boolean! | Whether or not a user can perform `cherry_pick_on_current_merge_request` on this resource |
-| `revertOnCurrentMergeRequest` | Boolean! | Whether or not a user can perform `revert_on_current_merge_request` on this resource |
+| `readMergeRequest` | Boolean! | Indicates the user can perform `read_merge_request` on this resource |
+| `adminMergeRequest` | Boolean! | Indicates the user can perform `admin_merge_request` on this resource |
+| `updateMergeRequest` | Boolean! | Indicates the user can perform `update_merge_request` on this resource |
+| `createNote` | Boolean! | Indicates the user can perform `create_note` on this resource |
+| `pushToSourceBranch` | Boolean! | Indicates the user can perform `push_to_source_branch` on this resource |
+| `removeSourceBranch` | Boolean! | Indicates the user can perform `remove_source_branch` on this resource |
+| `cherryPickOnCurrentMergeRequest` | Boolean! | Indicates the user can perform `cherry_pick_on_current_merge_request` on this resource |
+| `revertOnCurrentMergeRequest` | Boolean! | Indicates the user can perform `revert_on_current_merge_request` on this resource |
### MergeRequestSetAssigneesPayload
@@ -622,11 +622,11 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| Name | Type | Description |
| --- | ---- | ---------- |
-| `readNote` | Boolean! | Whether or not a user can perform `read_note` on this resource |
-| `createNote` | Boolean! | Whether or not a user can perform `create_note` on this resource |
-| `adminNote` | Boolean! | Whether or not a user can perform `admin_note` on this resource |
-| `resolveNote` | Boolean! | Whether or not a user can perform `resolve_note` on this resource |
-| `awardEmoji` | Boolean! | Whether or not a user can perform `award_emoji` on this resource |
+| `readNote` | Boolean! | Indicates the user can perform `read_note` on this resource |
+| `createNote` | Boolean! | Indicates the user can perform `create_note` on this resource |
+| `adminNote` | Boolean! | Indicates the user can perform `admin_note` on this resource |
+| `resolveNote` | Boolean! | Indicates the user can perform `resolve_note` on this resource |
+| `awardEmoji` | Boolean! | Indicates the user can perform `award_emoji` on this resource |
### PageInfo
@@ -660,9 +660,9 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| Name | Type | Description |
| --- | ---- | ---------- |
-| `updatePipeline` | Boolean! | Whether or not a user can perform `update_pipeline` on this resource |
-| `adminPipeline` | Boolean! | Whether or not a user can perform `admin_pipeline` on this resource |
-| `destroyPipeline` | Boolean! | Whether or not a user can perform `destroy_pipeline` on this resource |
+| `updatePipeline` | Boolean! | Indicates the user can perform `update_pipeline` on this resource |
+| `adminPipeline` | Boolean! | Indicates the user can perform `admin_pipeline` on this resource |
+| `destroyPipeline` | Boolean! | Indicates the user can perform `destroy_pipeline` on this resource |
### Project
@@ -684,7 +684,7 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| `forksCount` | Int! | Number of times the project has been forked |
| `createdAt` | Time | Timestamp of the project creation |
| `lastActivityAt` | Time | Timestamp of the project last activity |
-| `archived` | Boolean | Archived status of the project |
+| `archived` | Boolean | Indicates the archived status of the project |
| `visibility` | String | Visibility of the project |
| `containerRegistryEnabled` | Boolean | Indicates if the project stores Docker container images in a container registry |
| `sharedRunnersEnabled` | Boolean | Indicates if shared runners are enabled on the project |
@@ -704,6 +704,7 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| `onlyAllowMergeIfAllDiscussionsAreResolved` | Boolean | Indicates if merge requests of the project can only be merged when all the discussions are resolved |
| `printingMergeRequestLinkEnabled` | Boolean | Indicates if a link to create or view a merge request should display after a push to Git repositories of the project from the command line |
| `removeSourceBranchAfterMerge` | Boolean | Indicates if `Delete source branch` option should be enabled by default for all new merge requests of the project |
+| `autocloseReferencedIssues` | Boolean | Indicates if issues referenced by merge requests and commits within the default branch are closed automatically |
| `namespace` | Namespace | Namespace of the project |
| `group` | Group | Group of the project |
| `statistics` | ProjectStatistics | Statistics of the project |
@@ -719,47 +720,47 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| Name | Type | Description |
| --- | ---- | ---------- |
-| `changeNamespace` | Boolean! | Whether or not a user can perform `change_namespace` on this resource |
-| `changeVisibilityLevel` | Boolean! | Whether or not a user can perform `change_visibility_level` on this resource |
-| `renameProject` | Boolean! | Whether or not a user can perform `rename_project` on this resource |
-| `removeProject` | Boolean! | Whether or not a user can perform `remove_project` on this resource |
-| `archiveProject` | Boolean! | Whether or not a user can perform `archive_project` on this resource |
-| `removeForkProject` | Boolean! | Whether or not a user can perform `remove_fork_project` on this resource |
-| `removePages` | Boolean! | Whether or not a user can perform `remove_pages` on this resource |
-| `readProject` | Boolean! | Whether or not a user can perform `read_project` on this resource |
-| `createMergeRequestIn` | Boolean! | Whether or not a user can perform `create_merge_request_in` on this resource |
-| `readWiki` | Boolean! | Whether or not a user can perform `read_wiki` on this resource |
-| `readProjectMember` | Boolean! | Whether or not a user can perform `read_project_member` on this resource |
-| `createIssue` | Boolean! | Whether or not a user can perform `create_issue` on this resource |
-| `uploadFile` | Boolean! | Whether or not a user can perform `upload_file` on this resource |
-| `readCycleAnalytics` | Boolean! | Whether or not a user can perform `read_cycle_analytics` on this resource |
-| `downloadCode` | Boolean! | Whether or not a user can perform `download_code` on this resource |
-| `downloadWikiCode` | Boolean! | Whether or not a user can perform `download_wiki_code` on this resource |
-| `forkProject` | Boolean! | Whether or not a user can perform `fork_project` on this resource |
-| `readCommitStatus` | Boolean! | Whether or not a user can perform `read_commit_status` on this resource |
-| `requestAccess` | Boolean! | Whether or not a user can perform `request_access` on this resource |
-| `createPipeline` | Boolean! | Whether or not a user can perform `create_pipeline` on this resource |
-| `createPipelineSchedule` | Boolean! | Whether or not a user can perform `create_pipeline_schedule` on this resource |
-| `createMergeRequestFrom` | Boolean! | Whether or not a user can perform `create_merge_request_from` on this resource |
-| `createWiki` | Boolean! | Whether or not a user can perform `create_wiki` on this resource |
-| `pushCode` | Boolean! | Whether or not a user can perform `push_code` on this resource |
-| `createDeployment` | Boolean! | Whether or not a user can perform `create_deployment` on this resource |
-| `pushToDeleteProtectedBranch` | Boolean! | Whether or not a user can perform `push_to_delete_protected_branch` on this resource |
-| `adminWiki` | Boolean! | Whether or not a user can perform `admin_wiki` on this resource |
-| `adminProject` | Boolean! | Whether or not a user can perform `admin_project` on this resource |
-| `updatePages` | Boolean! | Whether or not a user can perform `update_pages` on this resource |
-| `adminRemoteMirror` | Boolean! | Whether or not a user can perform `admin_remote_mirror` on this resource |
-| `createLabel` | Boolean! | Whether or not a user can perform `create_label` on this resource |
-| `updateWiki` | Boolean! | Whether or not a user can perform `update_wiki` on this resource |
-| `destroyWiki` | Boolean! | Whether or not a user can perform `destroy_wiki` on this resource |
-| `createPages` | Boolean! | Whether or not a user can perform `create_pages` on this resource |
-| `destroyPages` | Boolean! | Whether or not a user can perform `destroy_pages` on this resource |
-| `readPagesContent` | Boolean! | Whether or not a user can perform `read_pages_content` on this resource |
-| `adminOperations` | Boolean! | Whether or not a user can perform `admin_operations` on this resource |
-| `createSnippet` | Boolean! | Whether or not a user can perform `create_snippet` on this resource |
-| `readDesign` | Boolean! | Whether or not a user can perform `read_design` on this resource |
-| `createDesign` | Boolean! | Whether or not a user can perform `create_design` on this resource |
-| `destroyDesign` | Boolean! | Whether or not a user can perform `destroy_design` on this resource |
+| `changeNamespace` | Boolean! | Indicates the user can perform `change_namespace` on this resource |
+| `changeVisibilityLevel` | Boolean! | Indicates the user can perform `change_visibility_level` on this resource |
+| `renameProject` | Boolean! | Indicates the user can perform `rename_project` on this resource |
+| `removeProject` | Boolean! | Indicates the user can perform `remove_project` on this resource |
+| `archiveProject` | Boolean! | Indicates the user can perform `archive_project` on this resource |
+| `removeForkProject` | Boolean! | Indicates the user can perform `remove_fork_project` on this resource |
+| `removePages` | Boolean! | Indicates the user can perform `remove_pages` on this resource |
+| `readProject` | Boolean! | Indicates the user can perform `read_project` on this resource |
+| `createMergeRequestIn` | Boolean! | Indicates the user can perform `create_merge_request_in` on this resource |
+| `readWiki` | Boolean! | Indicates the user can perform `read_wiki` on this resource |
+| `readProjectMember` | Boolean! | Indicates the user can perform `read_project_member` on this resource |
+| `createIssue` | Boolean! | Indicates the user can perform `create_issue` on this resource |
+| `uploadFile` | Boolean! | Indicates the user can perform `upload_file` on this resource |
+| `readCycleAnalytics` | Boolean! | Indicates the user can perform `read_cycle_analytics` on this resource |
+| `downloadCode` | Boolean! | Indicates the user can perform `download_code` on this resource |
+| `downloadWikiCode` | Boolean! | Indicates the user can perform `download_wiki_code` on this resource |
+| `forkProject` | Boolean! | Indicates the user can perform `fork_project` on this resource |
+| `readCommitStatus` | Boolean! | Indicates the user can perform `read_commit_status` on this resource |
+| `requestAccess` | Boolean! | Indicates the user can perform `request_access` on this resource |
+| `createPipeline` | Boolean! | Indicates the user can perform `create_pipeline` on this resource |
+| `createPipelineSchedule` | Boolean! | Indicates the user can perform `create_pipeline_schedule` on this resource |
+| `createMergeRequestFrom` | Boolean! | Indicates the user can perform `create_merge_request_from` on this resource |
+| `createWiki` | Boolean! | Indicates the user can perform `create_wiki` on this resource |
+| `pushCode` | Boolean! | Indicates the user can perform `push_code` on this resource |
+| `createDeployment` | Boolean! | Indicates the user can perform `create_deployment` on this resource |
+| `pushToDeleteProtectedBranch` | Boolean! | Indicates the user can perform `push_to_delete_protected_branch` on this resource |
+| `adminWiki` | Boolean! | Indicates the user can perform `admin_wiki` on this resource |
+| `adminProject` | Boolean! | Indicates the user can perform `admin_project` on this resource |
+| `updatePages` | Boolean! | Indicates the user can perform `update_pages` on this resource |
+| `adminRemoteMirror` | Boolean! | Indicates the user can perform `admin_remote_mirror` on this resource |
+| `createLabel` | Boolean! | Indicates the user can perform `create_label` on this resource |
+| `updateWiki` | Boolean! | Indicates the user can perform `update_wiki` on this resource |
+| `destroyWiki` | Boolean! | Indicates the user can perform `destroy_wiki` on this resource |
+| `createPages` | Boolean! | Indicates the user can perform `create_pages` on this resource |
+| `destroyPages` | Boolean! | Indicates the user can perform `destroy_pages` on this resource |
+| `readPagesContent` | Boolean! | Indicates the user can perform `read_pages_content` on this resource |
+| `adminOperations` | Boolean! | Indicates the user can perform `admin_operations` on this resource |
+| `createSnippet` | Boolean! | Indicates the user can perform `create_snippet` on this resource |
+| `readDesign` | Boolean! | Indicates the user can perform `read_design` on this resource |
+| `createDesign` | Boolean! | Indicates the user can perform `create_design` on this resource |
+| `destroyDesign` | Boolean! | Indicates the user can perform `destroy_design` on this resource |
### ProjectStatistics
@@ -857,12 +858,12 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| Name | Type | Description |
| --- | ---- | ---------- |
-| `createNote` | Boolean! | Whether or not a user can perform `create_note` on this resource |
-| `awardEmoji` | Boolean! | Whether or not a user can perform `award_emoji` on this resource |
-| `readSnippet` | Boolean! | Whether or not a user can perform `read_snippet` on this resource |
-| `updateSnippet` | Boolean! | Whether or not a user can perform `update_snippet` on this resource |
-| `adminSnippet` | Boolean! | Whether or not a user can perform `admin_snippet` on this resource |
-| `reportSnippet` | Boolean! | Whether or not a user can perform `report_snippet` on this resource |
+| `createNote` | Boolean! | Indicates the user can perform `create_note` on this resource |
+| `awardEmoji` | Boolean! | Indicates the user can perform `award_emoji` on this resource |
+| `readSnippet` | Boolean! | Indicates the user can perform `read_snippet` on this resource |
+| `updateSnippet` | Boolean! | Indicates the user can perform `update_snippet` on this resource |
+| `adminSnippet` | Boolean! | Indicates the user can perform `admin_snippet` on this resource |
+| `reportSnippet` | Boolean! | Indicates the user can perform `report_snippet` on this resource |
### Submodule
@@ -938,7 +939,7 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
| `errors` | String! => Array | Reasons why the mutation failed. |
| `awardEmoji` | AwardEmoji | The award emoji after mutation |
-| `toggledOn` | Boolean! | True when the emoji was awarded, false when it was removed |
+| `toggledOn` | Boolean! | Indicates the status of the emoji. True if the toggle awarded the emoji, and false if the toggle removed the emoji. |
### Tree
@@ -996,4 +997,4 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| Name | Type | Description |
| --- | ---- | ---------- |
-| `createSnippet` | Boolean! | Whether or not a user can perform `create_snippet` on this resource |
+| `createSnippet` | Boolean! | Indicates the user can perform `create_snippet` on this resource |
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 209d41d62cd..33308ff8905 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -156,6 +156,7 @@ When the user is authenticated and `simple` is not set this returns something li
"remove_source_branch_after_merge": false,
"request_access_enabled": false,
"merge_method": "merge",
+ "autoclose_referenced_issues": true,
"statistics": {
"commit_count": 37,
"storage_size": 1038090,
@@ -254,6 +255,7 @@ When the user is authenticated and `simple` is not set this returns something li
"packages_enabled": true,
"service_desk_enabled": false,
"service_desk_address": null,
+ "autoclose_referenced_issues": true,
"statistics": {
"commit_count": 12,
"storage_size": 2066080,
@@ -385,6 +387,7 @@ This endpoint supports [keyset pagination](README.md#keyset-based-pagination) fo
"remove_source_branch_after_merge": false,
"request_access_enabled": false,
"merge_method": "merge",
+ "autoclose_referenced_issues": true,
"statistics": {
"commit_count": 37,
"storage_size": 1038090,
@@ -483,6 +486,7 @@ This endpoint supports [keyset pagination](README.md#keyset-based-pagination) fo
"packages_enabled": true,
"service_desk_enabled": false,
"service_desk_address": null,
+ "autoclose_referenced_issues": true,
"statistics": {
"commit_count": 12,
"storage_size": 2066080,
@@ -593,6 +597,7 @@ Example response:
"remove_source_branch_after_merge": false,
"request_access_enabled": false,
"merge_method": "merge",
+ "autoclose_referenced_issues": true,
"statistics": {
"commit_count": 37,
"storage_size": 1038090,
@@ -688,6 +693,7 @@ Example response:
"packages_enabled": true,
"service_desk_enabled": false,
"service_desk_address": null,
+ "autoclose_referenced_issues": true,
"statistics": {
"commit_count": 12,
"storage_size": 2066080,
@@ -829,6 +835,7 @@ GET /projects/:id
"packages_enabled": true,
"service_desk_enabled": false,
"service_desk_address": null,
+ "autoclose_referenced_issues": true,
"statistics": {
"commit_count": 37,
"storage_size": 1038090,
@@ -986,6 +993,7 @@ POST /projects
| `only_allow_merge_if_pipeline_succeeds` | boolean | no | Set whether merge requests can only be merged with successful jobs |
| `only_allow_merge_if_all_discussions_are_resolved` | boolean | no | Set whether merge requests can only be merged when all the discussions are resolved |
| `merge_method` | string | no | Set the [merge method](#project-merge-method) used |
+| `autoclose_referenced_issues` | boolean | no | Set whether auto-closing referenced issues on default branch |
| `remove_source_branch_after_merge` | boolean | no | Enable `Delete source branch` option by default for all new merge requests |
| `lfs_enabled` | boolean | no | Enable LFS |
| `request_access_enabled` | boolean | no | Allow users to request member access |
@@ -1050,6 +1058,7 @@ POST /projects/user/:user_id
| `only_allow_merge_if_pipeline_succeeds` | boolean | no | Set whether merge requests can only be merged with successful jobs |
| `only_allow_merge_if_all_discussions_are_resolved` | boolean | no | Set whether merge requests can only be merged when all the discussions are resolved |
| `merge_method` | string | no | Set the [merge method](#project-merge-method) used |
+| `autoclose_referenced_issues` | boolean | no | Set whether auto-closing referenced issues on default branch |
| `remove_source_branch_after_merge` | boolean | no | Enable `Delete source branch` option by default for all new merge requests |
| `lfs_enabled` | boolean | no | Enable LFS |
| `request_access_enabled` | boolean | no | Allow users to request member access |
@@ -1113,6 +1122,7 @@ PUT /projects/:id
| `only_allow_merge_if_pipeline_succeeds` | boolean | no | Set whether merge requests can only be merged with successful jobs |
| `only_allow_merge_if_all_discussions_are_resolved` | boolean | no | Set whether merge requests can only be merged when all the discussions are resolved |
| `merge_method` | string | no | Set the [merge method](#project-merge-method) used |
+| `autoclose_referenced_issues` | boolean | no | Set whether auto-closing referenced issues on default branch |
| `remove_source_branch_after_merge` | boolean | no | Enable `Delete source branch` option by default for all new merge requests |
| `lfs_enabled` | boolean | no | Enable LFS |
| `request_access_enabled` | boolean | no | Allow users to request member access |
@@ -1244,6 +1254,7 @@ Example responses:
"remove_source_branch_after_merge": false,
"request_access_enabled": false,
"merge_method": "merge",
+ "autoclose_referenced_issues": true,
"_links": {
"self": "http://example.com/api/v4/projects",
"issues": "http://example.com/api/v4/projects/1/issues",
@@ -1332,6 +1343,7 @@ Example response:
"remove_source_branch_after_merge": false,
"request_access_enabled": false,
"merge_method": "merge",
+ "autoclose_referenced_issues": true,
"_links": {
"self": "http://example.com/api/v4/projects",
"issues": "http://example.com/api/v4/projects/1/issues",
@@ -1419,6 +1431,7 @@ Example response:
"remove_source_branch_after_merge": false,
"request_access_enabled": false,
"merge_method": "merge",
+ "autoclose_referenced_issues": true,
"_links": {
"self": "http://example.com/api/v4/projects",
"issues": "http://example.com/api/v4/projects/1/issues",
@@ -1593,6 +1606,7 @@ Example response:
"remove_source_branch_after_merge": false,
"request_access_enabled": false,
"merge_method": "merge",
+ "autoclose_referenced_issues": true,
"_links": {
"self": "http://example.com/api/v4/projects",
"issues": "http://example.com/api/v4/projects/1/issues",
@@ -1699,6 +1713,7 @@ Example response:
"remove_source_branch_after_merge": false,
"request_access_enabled": false,
"merge_method": "merge",
+ "autoclose_referenced_issues": true,
"_links": {
"self": "http://example.com/api/v4/projects",
"issues": "http://example.com/api/v4/projects/1/issues",
diff --git a/doc/development/api_graphql_styleguide.md b/doc/development/api_graphql_styleguide.md
index 1ef0b928820..053eb55420e 100644
--- a/doc/development/api_graphql_styleguide.md
+++ b/doc/development/api_graphql_styleguide.md
@@ -210,7 +210,7 @@ class MergeRequestPermissionsType < BasePermissionType
abilities :admin_merge_request, :update_merge_request, :create_note
ability_field :resolve_note,
- description: 'Whether or not the user can resolve disussions on the merge request'
+ description: 'Indicates the user can resolve discussions on the merge request'
permission_field :push_to_source_branch, method: :can_push_to_source_branch?
end
```
diff --git a/doc/development/testing_guide/best_practices.md b/doc/development/testing_guide/best_practices.md
index 356e3f7a227..8dd5e2b1265 100644
--- a/doc/development/testing_guide/best_practices.md
+++ b/doc/development/testing_guide/best_practices.md
@@ -70,6 +70,7 @@ When using spring and guard together, use `SPRING=1 bundle exec guard` instead t
use a Capyabara matcher beforehand (e.g. `find('.js-foo')`) to ensure the element actually exists.
- Use `focus: true` to isolate parts of the specs you want to run.
- Use [`:aggregate_failures`](https://relishapp.com/rspec/rspec-core/docs/expectation-framework-integration/aggregating-failures) when there is more than one expectation in a test.
+- For [empty test description blocks](https://github.com/rubocop-hq/rspec-style-guide#it-and-specify), use `specify` rather than `it do` if the test is self-explanatory.
### System / Feature tests
diff --git a/doc/user/project/issues/img/disable_issue_auto_close.png b/doc/user/project/issues/img/disable_issue_auto_close.png
new file mode 100644
index 00000000000..2cf48a92331
--- /dev/null
+++ b/doc/user/project/issues/img/disable_issue_auto_close.png
Binary files differ
diff --git a/doc/user/project/issues/managing_issues.md b/doc/user/project/issues/managing_issues.md
index 38649b05593..c660c920ecb 100644
--- a/doc/user/project/issues/managing_issues.md
+++ b/doc/user/project/issues/managing_issues.md
@@ -211,6 +211,19 @@ as well as `#22` and `#23` in group/otherproject. `#17` won't be closed as it do
not match the pattern. It works with multi-line commit messages as well as one-liners
when used from the command line with `git commit -m`.
+#### Disabling automatic issue closing
+
+The automatic issue closing feature can be disabled on a per-project basis
+within the [project's repository settings](../settings/index.md). Referenced
+issues will still be displayed as such but won't be closed automatically.
+
+![disable issue auto close - settings](img/disable_issue_auto_close.png)
+
+This only applies to issues affected by new merge requests or commits. Already
+closed issues remain as-is. Disabling automatic issue closing only affects merge
+requests *within* the project and won't prevent other projects from closing it
+via cross-project issues.
+
#### Customizing the issue closing pattern **(CORE ONLY)**
In order to change the default issue closing pattern, GitLab administrators must edit the
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index b73eef9b7cb..c28d6797c56 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -331,6 +331,7 @@ module API
expose :auto_devops_deploy_strategy do |project, options|
project.auto_devops.nil? ? 'continuous' : project.auto_devops.deploy_strategy
end
+ expose :autoclose_referenced_issues
# rubocop: disable CodeReuse/ActiveRecord
def self.preload_relation(projects_relation, options = {})
diff --git a/lib/api/helpers/projects_helpers.rb b/lib/api/helpers/projects_helpers.rb
index 47b1f037eb8..0ca5b73e270 100644
--- a/lib/api/helpers/projects_helpers.rb
+++ b/lib/api/helpers/projects_helpers.rb
@@ -47,6 +47,7 @@ module API
optional :ci_default_git_depth, type: Integer, desc: 'Default number of revisions for shallow cloning'
optional :auto_devops_enabled, type: Boolean, desc: 'Flag indication if Auto DevOps is enabled'
optional :auto_devops_deploy_strategy, type: String, values: %w(continuous manual timed_incremental), desc: 'Auto Deploy strategy'
+ optional :autoclose_referenced_issues, type: Boolean, desc: 'Flag indication if referenced issues auto-closing is enabled'
end
params :optional_project_params_ee do
@@ -85,6 +86,7 @@ module API
:container_registry_enabled,
:default_branch,
:description,
+ :autoclose_referenced_issues,
:issues_access_level,
:lfs_enabled,
:merge_requests_access_level,
diff --git a/lib/gitlab/closing_issue_extractor.rb b/lib/gitlab/closing_issue_extractor.rb
index 4ba921569ad..8e624215065 100644
--- a/lib/gitlab/closing_issue_extractor.rb
+++ b/lib/gitlab/closing_issue_extractor.rb
@@ -11,11 +11,13 @@ module Gitlab
end
def initialize(project, current_user = nil)
+ @project = project
@extractor = Gitlab::ReferenceExtractor.new(project, current_user)
end
def closed_by_message(message)
return [] if message.nil?
+ return [] unless @project.autoclose_referenced_issues
closing_statements = []
message.scan(ISSUE_CLOSING_REGEX) do
diff --git a/lib/gitlab/utils.rb b/lib/gitlab/utils.rb
index 7fbfc4c45c4..7eddfc471f6 100644
--- a/lib/gitlab/utils.rb
+++ b/lib/gitlab/utils.rb
@@ -50,6 +50,12 @@ module Gitlab
.gsub(/(\A-+|-+\z)/, '')
end
+ # Wraps ActiveSupport's Array#to_sentence to convert the given array to a
+ # comma-separated sentence joined with localized 'or' Strings instead of 'and'.
+ def to_exclusive_sentence(array)
+ array.to_sentence(two_words_connector: _(' or '), last_word_connector: _(', or '))
+ end
+
# Converts newlines into HTML line break elements
def nlbr(str)
ActionView::Base.full_sanitizer.sanitize(+str, tags: []).gsub(/\r?\n/, '<br>').html_safe
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 8967ce8b994..7cefd08d38c 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -2381,6 +2381,9 @@ msgstr ""
msgid "Auto-cancel redundant, pending pipelines"
msgstr ""
+msgid "Auto-close referenced issues on default branch"
+msgstr ""
+
msgid "AutoDevOps|Auto DevOps"
msgstr ""
@@ -10077,6 +10080,9 @@ msgstr ""
msgid "Issues closed"
msgstr ""
+msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -21231,6 +21237,9 @@ msgstr ""
msgid "already being used for another group or project milestone."
msgstr ""
+msgid "already has a \"created\" issue link"
+msgstr ""
+
msgid "already shared with this group"
msgstr ""
@@ -21688,6 +21697,9 @@ msgstr ""
msgid "group"
msgstr ""
+msgid "has already been linked to another vulnerability"
+msgstr ""
+
msgid "has already been taken"
msgstr ""
diff --git a/spec/frontend/create_cluster/gke_cluster/components/gke_machine_type_dropdown_spec.js b/spec/frontend/create_cluster/gke_cluster/components/gke_machine_type_dropdown_spec.js
new file mode 100644
index 00000000000..d6a752d761d
--- /dev/null
+++ b/spec/frontend/create_cluster/gke_cluster/components/gke_machine_type_dropdown_spec.js
@@ -0,0 +1,136 @@
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import Vuex from 'vuex';
+import { selectedMachineTypeMock, gapiMachineTypesResponseMock } from '../mock_data';
+import createState from '~/create_cluster/gke_cluster/store/state';
+import DropdownButton from '~/vue_shared/components/dropdown/dropdown_button.vue';
+import DropdownHiddenInput from '~/vue_shared/components/dropdown/dropdown_hidden_input.vue';
+import GkeMachineTypeDropdown from '~/create_cluster/gke_cluster/components/gke_machine_type_dropdown.vue';
+
+const componentConfig = {
+ fieldId: 'cluster_provider_gcp_attributes_gcp_machine_type',
+ fieldName: 'cluster[provider_gcp_attributes][gcp_machine_type]',
+};
+const setMachineType = jest.fn();
+
+const LABELS = {
+ LOADING: 'Fetching machine types',
+ DISABLED_NO_PROJECT: 'Select project and zone to choose machine type',
+ DISABLED_NO_ZONE: 'Select zone to choose machine type',
+ DEFAULT: 'Select machine type',
+};
+
+const localVue = createLocalVue();
+
+localVue.use(Vuex);
+
+const createComponent = (store, propsData = componentConfig) =>
+ shallowMount(GkeMachineTypeDropdown, {
+ propsData,
+ store,
+ localVue,
+ sync: false,
+ });
+
+const createStore = (initialState = {}, getters = {}) =>
+ new Vuex.Store({
+ state: {
+ ...createState(),
+ ...initialState,
+ },
+ getters: {
+ hasZone: () => false,
+ ...getters,
+ },
+ actions: {
+ setMachineType,
+ },
+ });
+
+describe('GkeMachineTypeDropdown', () => {
+ let wrapper;
+ let store;
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ const dropdownButtonLabel = () => wrapper.find(DropdownButton).props('toggleText');
+ const dropdownHiddenInputValue = () => wrapper.find(DropdownHiddenInput).props('value');
+
+ describe('shows various toggle text depending on state', () => {
+ it('returns disabled state toggle text when no project and zone are selected', () => {
+ store = createStore({
+ projectHasBillingEnabled: false,
+ });
+ wrapper = createComponent(store);
+
+ expect(dropdownButtonLabel()).toBe(LABELS.DISABLED_NO_PROJECT);
+ });
+
+ it('returns disabled state toggle text when no zone is selected', () => {
+ store = createStore({
+ projectHasBillingEnabled: true,
+ });
+ wrapper = createComponent(store);
+
+ expect(dropdownButtonLabel()).toBe(LABELS.DISABLED_NO_ZONE);
+ });
+
+ it('returns loading toggle text', () => {
+ store = createStore();
+ wrapper = createComponent(store);
+
+ wrapper.setData({ isLoading: true });
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(dropdownButtonLabel()).toBe(LABELS.LOADING);
+ });
+ });
+
+ it('returns default toggle text', () => {
+ store = createStore(
+ {
+ projectHasBillingEnabled: true,
+ },
+ { hasZone: () => true },
+ );
+ wrapper = createComponent(store);
+
+ expect(dropdownButtonLabel()).toBe(LABELS.DEFAULT);
+ });
+
+ it('returns machine type name if machine type selected', () => {
+ store = createStore(
+ {
+ projectHasBillingEnabled: true,
+ selectedMachineType: selectedMachineTypeMock,
+ },
+ { hasZone: () => true },
+ );
+ wrapper = createComponent(store);
+
+ expect(dropdownButtonLabel()).toBe(selectedMachineTypeMock);
+ });
+ });
+
+ describe('form input', () => {
+ it('reflects new value when dropdown item is clicked', () => {
+ store = createStore({
+ machineTypes: gapiMachineTypesResponseMock.items,
+ });
+ wrapper = createComponent(store);
+
+ expect(dropdownHiddenInputValue()).toBe('');
+
+ wrapper.find('.dropdown-content button').trigger('click');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(setMachineType).toHaveBeenCalledWith(
+ expect.anything(),
+ selectedMachineTypeMock,
+ undefined,
+ );
+ });
+ });
+ });
+});
diff --git a/spec/frontend/create_cluster/gke_cluster/mock_data.js b/spec/frontend/create_cluster/gke_cluster/mock_data.js
new file mode 100644
index 00000000000..d9f5dbc636f
--- /dev/null
+++ b/spec/frontend/create_cluster/gke_cluster/mock_data.js
@@ -0,0 +1,75 @@
+export const emptyProjectMock = {
+ projectId: '',
+ name: '',
+};
+
+export const selectedProjectMock = {
+ projectId: 'gcp-project-123',
+ name: 'gcp-project',
+};
+
+export const selectedZoneMock = 'us-central1-a';
+
+export const selectedMachineTypeMock = 'n1-standard-2';
+
+export const gapiProjectsResponseMock = {
+ projects: [
+ {
+ projectNumber: '1234',
+ projectId: 'gcp-project-123',
+ lifecycleState: 'ACTIVE',
+ name: 'gcp-project',
+ createTime: '2017-12-16T01:48:29.129Z',
+ parent: {
+ type: 'organization',
+ id: '12345',
+ },
+ },
+ ],
+};
+
+export const gapiZonesResponseMock = {
+ kind: 'compute#zoneList',
+ id: 'projects/gitlab-internal-153318/zones',
+ items: [
+ {
+ kind: 'compute#zone',
+ id: '2000',
+ creationTimestamp: '1969-12-31T16:00:00.000-08:00',
+ name: 'us-central1-a',
+ description: 'us-central1-a',
+ status: 'UP',
+ region:
+ 'https://www.googleapis.com/compute/v1/projects/gitlab-internal-153318/regions/us-central1',
+ selfLink:
+ 'https://www.googleapis.com/compute/v1/projects/gitlab-internal-153318/zones/us-central1-a',
+ availableCpuPlatforms: ['Intel Skylake', 'Intel Broadwell', 'Intel Sandy Bridge'],
+ },
+ ],
+ selfLink: 'https://www.googleapis.com/compute/v1/projects/gitlab-internal-153318/zones',
+};
+
+export const gapiMachineTypesResponseMock = {
+ kind: 'compute#machineTypeList',
+ id: 'projects/gitlab-internal-153318/zones/us-central1-a/machineTypes',
+ items: [
+ {
+ kind: 'compute#machineType',
+ id: '3002',
+ creationTimestamp: '1969-12-31T16:00:00.000-08:00',
+ name: 'n1-standard-2',
+ description: '2 vCPUs, 7.5 GB RAM',
+ guestCpus: 2,
+ memoryMb: 7680,
+ imageSpaceGb: 10,
+ maximumPersistentDisks: 64,
+ maximumPersistentDisksSizeGb: '65536',
+ zone: 'us-central1-a',
+ selfLink:
+ 'https://www.googleapis.com/compute/v1/projects/gitlab-internal-153318/zones/us-central1-a/machineTypes/n1-standard-2',
+ isSharedCpu: false,
+ },
+ ],
+ selfLink:
+ 'https://www.googleapis.com/compute/v1/projects/gitlab-internal-153318/zones/us-central1-a/machineTypes',
+};
diff --git a/spec/graphql/types/project_type_spec.rb b/spec/graphql/types/project_type_spec.rb
index 3c16994495d..27fa98bbde4 100644
--- a/spec/graphql/types/project_type_spec.rb
+++ b/spec/graphql/types/project_type_spec.rb
@@ -23,7 +23,7 @@ describe GitlabSchema.types['Project'] do
only_allow_merge_if_all_discussions_are_resolved printing_merge_request_link_enabled
namespace group statistics repository merge_requests merge_request issues
issue pipelines removeSourceBranchAfterMerge sentryDetailedError snippets
- grafanaIntegration
+ grafanaIntegration autocloseReferencedIssues
]
is_expected.to include_graphql_fields(*expected_fields)
diff --git a/spec/javascripts/create_cluster/gke_cluster/components/gke_machine_type_dropdown_spec.js b/spec/javascripts/create_cluster/gke_cluster/components/gke_machine_type_dropdown_spec.js
deleted file mode 100644
index e687040ddf9..00000000000
--- a/spec/javascripts/create_cluster/gke_cluster/components/gke_machine_type_dropdown_spec.js
+++ /dev/null
@@ -1,109 +0,0 @@
-import Vue from 'vue';
-import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
-import GkeMachineTypeDropdown from '~/create_cluster/gke_cluster/components/gke_machine_type_dropdown.vue';
-import { createStore } from '~/create_cluster/gke_cluster/store';
-import {
- SET_PROJECT,
- SET_PROJECT_BILLING_STATUS,
- SET_ZONE,
- SET_MACHINE_TYPES,
-} from '~/create_cluster/gke_cluster/store/mutation_types';
-import {
- selectedZoneMock,
- selectedProjectMock,
- selectedMachineTypeMock,
- gapiMachineTypesResponseMock,
-} from '../mock_data';
-
-const componentConfig = {
- fieldId: 'cluster_provider_gcp_attributes_gcp_machine_type',
- fieldName: 'cluster[provider_gcp_attributes][gcp_machine_type]',
-};
-
-const LABELS = {
- LOADING: 'Fetching machine types',
- DISABLED_NO_PROJECT: 'Select project and zone to choose machine type',
- DISABLED_NO_ZONE: 'Select zone to choose machine type',
- DEFAULT: 'Select machine type',
-};
-
-const createComponent = (store, props = componentConfig) => {
- const Component = Vue.extend(GkeMachineTypeDropdown);
-
- return mountComponentWithStore(Component, {
- el: null,
- props,
- store,
- });
-};
-
-describe('GkeMachineTypeDropdown', () => {
- let vm;
- let store;
-
- beforeEach(() => {
- store = createStore();
- vm = createComponent(store);
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('shows various toggle text depending on state', () => {
- it('returns disabled state toggle text when no project and zone are selected', () => {
- expect(vm.toggleText).toBe(LABELS.DISABLED_NO_PROJECT);
- });
-
- it('returns disabled state toggle text when no zone is selected', () => {
- vm.$store.commit(SET_PROJECT, selectedProjectMock);
- vm.$store.commit(SET_PROJECT_BILLING_STATUS, true);
-
- expect(vm.toggleText).toBe(LABELS.DISABLED_NO_ZONE);
- });
-
- it('returns loading toggle text', () => {
- vm.isLoading = true;
-
- expect(vm.toggleText).toBe(LABELS.LOADING);
- });
-
- it('returns default toggle text', () => {
- expect(vm.toggleText).toBe(LABELS.DISABLED_NO_PROJECT);
-
- vm.$store.commit(SET_PROJECT, selectedProjectMock);
- vm.$store.commit(SET_PROJECT_BILLING_STATUS, true);
- vm.$store.commit(SET_ZONE, selectedZoneMock);
-
- expect(vm.toggleText).toBe(LABELS.DEFAULT);
- });
-
- it('returns machine type name if machine type selected', () => {
- vm.setItem(selectedMachineTypeMock);
-
- expect(vm.toggleText).toBe(selectedMachineTypeMock);
- });
- });
-
- describe('form input', () => {
- it('reflects new value when dropdown item is clicked', done => {
- expect(vm.$el.querySelector('input').value).toBe('');
- vm.$store.commit(SET_MACHINE_TYPES, gapiMachineTypesResponseMock.items);
-
- return vm
- .$nextTick()
- .then(() => {
- vm.$el.querySelector('.dropdown-content button').click();
-
- return vm
- .$nextTick()
- .then(() => {
- expect(vm.$el.querySelector('input').value).toBe(selectedMachineTypeMock);
- done();
- })
- .catch(done.fail);
- })
- .catch(done.fail);
- });
- });
-});
diff --git a/spec/lib/gitlab/closing_issue_extractor_spec.rb b/spec/lib/gitlab/closing_issue_extractor_spec.rb
index fdd01f58c9d..510876a5945 100644
--- a/spec/lib/gitlab/closing_issue_extractor_spec.rb
+++ b/spec/lib/gitlab/closing_issue_extractor_spec.rb
@@ -438,6 +438,17 @@ describe Gitlab::ClosingIssueExtractor do
.to match_array([issue])
end
end
+
+ context "with autoclose referenced issues disabled" do
+ before do
+ project.update!(autoclose_referenced_issues: false)
+ end
+
+ it do
+ message = "Awesome commit (Closes #{reference})"
+ expect(subject.closed_by_message(message)).to eq([])
+ end
+ end
end
def urls
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index dc0851294b5..07439880beb 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -463,6 +463,7 @@ project:
- import_failures
- container_expiration_policy
- resource_groups
+- autoclose_referenced_issues
award_emoji:
- awardable
- user
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index 79442c35797..adb49c8c7e7 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -534,6 +534,7 @@ Project:
- pages_https_only
- merge_requests_disable_committers_approval
- require_password_to_approve
+- autoclose_referenced_issues
ProjectTracingSetting:
- external_url
Author:
diff --git a/spec/lib/gitlab/utils_spec.rb b/spec/lib/gitlab/utils_spec.rb
index 890918d4a7c..85a536ee6ad 100644
--- a/spec/lib/gitlab/utils_spec.rb
+++ b/spec/lib/gitlab/utils_spec.rb
@@ -3,8 +3,9 @@
require 'spec_helper'
describe Gitlab::Utils do
- delegate :to_boolean, :boolean_to_yes_no, :slugify, :random_string, :which, :ensure_array_from_string,
- :bytes_to_megabytes, :append_path, :check_path_traversal!, to: :described_class
+ delegate :to_boolean, :boolean_to_yes_no, :slugify, :random_string, :which,
+ :ensure_array_from_string, :to_exclusive_sentence, :bytes_to_megabytes,
+ :append_path, :check_path_traversal!, to: :described_class
describe '.check_path_traversal!' do
it 'detects path traversal at the start of the string' do
@@ -46,6 +47,36 @@ describe Gitlab::Utils do
end
end
+ describe '.to_exclusive_sentence' do
+ it 'calls #to_sentence on the array' do
+ array = double
+
+ expect(array).to receive(:to_sentence)
+
+ to_exclusive_sentence(array)
+ end
+
+ it 'joins arrays with two elements correctly' do
+ array = %w(foo bar)
+
+ expect(to_exclusive_sentence(array)).to eq('foo or bar')
+ end
+
+ it 'joins arrays with more than two elements correctly' do
+ array = %w(foo bar baz)
+
+ expect(to_exclusive_sentence(array)).to eq('foo, bar, or baz')
+ end
+
+ it 'localizes the connector words' do
+ array = %w(foo bar baz)
+
+ expect(described_class).to receive(:_).with(' or ').and_return(' <1> ')
+ expect(described_class).to receive(:_).with(', or ').and_return(', <2> ')
+ expect(to_exclusive_sentence(array)).to eq('foo, bar, <2> baz')
+ end
+ end
+
describe '.nlbr' do
it 'replaces new lines with <br>' do
expect(described_class.nlbr("<b>hello</b>\n<i>world</i>".freeze)).to eq("hello<br>world")
diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb
index 930ec889206..a9d79454dd5 100644
--- a/spec/models/commit_spec.rb
+++ b/spec/models/commit_spec.rb
@@ -390,6 +390,17 @@ eos
expect(commit.closes_issues).to include(issue)
expect(commit.closes_issues).to include(other_issue)
end
+
+ it 'ignores referenced issues when auto-close is disabled' do
+ project.update!(autoclose_referenced_issues: false)
+
+ allow(commit).to receive_messages(
+ safe_message: "Fixes ##{issue.iid}",
+ committer_email: committer.email
+ )
+
+ expect(commit.closes_issues).to be_empty
+ end
end
it_behaves_like 'a mentionable' do
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 0e151475128..7e28736954c 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -963,6 +963,15 @@ describe MergeRequest do
expect(subject.closes_issues).to be_empty
end
+
+ it 'ignores referenced issues when auto-close is disabled' do
+ subject.project.update!(autoclose_referenced_issues: false)
+
+ allow(subject.project).to receive(:default_branch)
+ .and_return(subject.target_branch)
+
+ expect(subject.closes_issues).to be_empty
+ end
end
describe '#issues_mentioned_but_not_closing' do
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index c1c29ac9c29..e2fb7674d62 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -474,6 +474,32 @@ describe Project do
end
end
+ describe '#autoclose_referenced_issues' do
+ context 'when DB entry is nil' do
+ let(:project) { create(:project, autoclose_referenced_issues: nil) }
+
+ it 'returns true' do
+ expect(project.autoclose_referenced_issues).to be_truthy
+ end
+ end
+
+ context 'when DB entry is true' do
+ let(:project) { create(:project, autoclose_referenced_issues: true) }
+
+ it 'returns true' do
+ expect(project.autoclose_referenced_issues).to be_truthy
+ end
+ end
+
+ context 'when DB entry is false' do
+ let(:project) { create(:project, autoclose_referenced_issues: false) }
+
+ it 'returns false' do
+ expect(project.autoclose_referenced_issues).to be_falsey
+ end
+ end
+ end
+
describe 'project token' do
it 'sets an random token if none provided' do
project = FactoryBot.create(:project, runners_token: '')
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 975e59346b8..03efbc6bce7 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -635,6 +635,7 @@ describe API::Projects do
wiki_enabled: false,
resolve_outdated_diff_discussions: false,
remove_source_branch_after_merge: true,
+ autoclose_referenced_issues: true,
only_allow_merge_if_pipeline_succeeds: false,
request_access_enabled: true,
only_allow_merge_if_all_discussions_are_resolved: false,
@@ -807,6 +808,22 @@ describe API::Projects do
expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to be_truthy
end
+ it 'sets a project as enabling auto close referenced issues' do
+ project = attributes_for(:project, autoclose_referenced_issues: true)
+
+ post api('/projects', user), params: project
+
+ expect(json_response['autoclose_referenced_issues']).to be_truthy
+ end
+
+ it 'sets a project as disabling auto close referenced issues' do
+ project = attributes_for(:project, autoclose_referenced_issues: false)
+
+ post api('/projects', user), params: project
+
+ expect(json_response['autoclose_referenced_issues']).to be_falsey
+ end
+
it 'sets the merge method of a project to rebase merge' do
project = attributes_for(:project, merge_method: 'rebase_merge')
diff --git a/spec/workers/chat_notification_worker_spec.rb b/spec/workers/chat_notification_worker_spec.rb
index 91695674f5d..e4dccf2bf6b 100644
--- a/spec/workers/chat_notification_worker_spec.rb
+++ b/spec/workers/chat_notification_worker_spec.rb
@@ -8,6 +8,10 @@ describe ChatNotificationWorker do
create(:ci_build, pipeline: create(:ci_pipeline, source: :chat))
end
+ it 'instructs sidekiq not to retry on failure' do
+ expect(described_class.get_sidekiq_options['retry']).to eq(false)
+ end
+
describe '#perform' do
it 'does nothing when the build no longer exists' do
expect(worker).not_to receive(:send_response)
@@ -23,16 +27,31 @@ describe ChatNotificationWorker do
worker.perform(chat_build.id)
end
- it 'reschedules the job if the trace sections could not be found' do
- expect(worker)
- .to receive(:send_response)
- .and_raise(Gitlab::Chat::Output::MissingBuildSectionError)
+ context 'when the trace sections could not be found' do
+ it 'reschedules the job' do
+ expect(worker)
+ .to receive(:send_response)
+ .and_raise(Gitlab::Chat::Output::MissingBuildSectionError)
- expect(described_class)
- .to receive(:perform_in)
- .with(described_class::RESCHEDULE_INTERVAL, chat_build.id)
+ expect(described_class)
+ .to receive(:perform_in)
+ .with(described_class::RESCHEDULE_INTERVAL, chat_build.id, 1)
- worker.perform(chat_build.id)
+ worker.perform(chat_build.id)
+ end
+
+ it "raises an error after #{described_class::RESCHEDULE_TIMEOUT} seconds of retrying" do
+ allow(described_class).to receive(:new).and_return(worker)
+ allow(worker).to receive(:send_response).and_raise(Gitlab::Chat::Output::MissingBuildSectionError)
+
+ worker.perform(chat_build.id)
+
+ expect { described_class.drain }.to raise_error(described_class::TimeoutExceeded)
+
+ max_reschedules = described_class::RESCHEDULE_TIMEOUT / described_class::RESCHEDULE_INTERVAL
+
+ expect(worker).to have_received(:send_response).exactly(max_reschedules + 1).times
+ end
end
end