Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-05-05 21:10:31 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-05-05 21:10:31 +0300
commit8f4d63426a207611f71bc19dae62eb19765a4cf2 (patch)
treeb5843aaef889b0d1305e669404693f11ce414d22
parentcf05fd7f3956f0b1a17caf313e89bb7b3315d947 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/CODEOWNERS19
-rw-r--r--.rubocop_manual_todo.yml1
-rw-r--r--app/assets/javascripts/issuable/components/csv_export_modal.vue6
-rw-r--r--app/assets/stylesheets/page_bundles/pipelines.scss5
-rw-r--r--app/assets/stylesheets/utilities.scss7
-rw-r--r--app/controllers/invites_controller.rb4
-rw-r--r--app/controllers/registrations/welcome_controller.rb22
-rw-r--r--app/finders/issues_finder.rb2
-rw-r--r--app/graphql/types/base_enum.rb4
-rw-r--r--app/helpers/services_helper.rb4
-rw-r--r--app/models/concerns/enums/ci/commit_status.rb1
-rw-r--r--app/models/group.rb4
-rw-r--r--app/models/project.rb4
-rw-r--r--app/presenters/commit_status_presenter.rb3
-rw-r--r--app/views/layouts/nav/sidebar/_admin.html.haml23
-rw-r--r--changelogs/unreleased/extend_branch_support_for_sse.yml5
-rw-r--r--changelogs/unreleased/gmh-ensure-highlighting-limits-are-configurable-and-documented.yml5
-rw-r--r--changelogs/unreleased/sy-create-incidents-via-api.yml6
-rw-r--r--config/feature_flags/development/ci_minutes_track_live_consumption.yml8
-rw-r--r--config/feature_flags/development/disable_service_templates.yml8
-rw-r--r--config/gitlab.yml.example4
-rw-r--r--config/initializers/1_settings.rb1
-rw-r--r--config/metrics/counts_28d/20210216174956_i_analytics_cohorts_monthly.yml6
-rw-r--r--db/post_migrate/20210505092746_create_partial_covering_index_for_pending_builds.rb5
-rw-r--r--doc/administration/application_settings_cache.md20
-rw-r--r--doc/administration/incoming_email.md77
-rw-r--r--doc/api/group_relations_export.md101
-rw-r--r--doc/api/groups.md4
-rw-r--r--doc/api/issues.md19
-rw-r--r--doc/development/testing_guide/end_to_end/page_objects.md2
-rw-r--r--doc/development/usage_ping/dictionary.md4
-rw-r--r--doc/integration/jira/development_panel.md175
-rw-r--r--doc/integration/jira/dvcs.md2
-rw-r--r--doc/integration/jira/img/jira_dev_panel_jira_setup_5.pngbin11002 -> 10336 bytes
-rw-r--r--doc/integration/jira/issues.md2
-rw-r--r--doc/operations/incident_management/incidents.md16
-rw-r--r--doc/operations/incident_management/integrations.md21
-rw-r--r--doc/operations/metrics/alerts.md14
-rw-r--r--doc/user/project/settings/index.md18
-rw-r--r--lib/api/ci/runner.rb4
-rw-r--r--lib/api/entities/issue_basic.rb1
-rw-r--r--lib/api/helpers/issues_helpers.rb4
-rw-r--r--lib/api/helpers/runner.rb4
-rw-r--r--lib/api/issues.rb2
-rw-r--r--lib/gitlab/ci/pipeline/metrics.rb7
-rw-r--r--lib/gitlab/ci/queue/metrics.rb2
-rw-r--r--lib/gitlab/ci/status/build/failed.rb3
-rw-r--r--lib/gitlab/ci/templates/Security/Secure-Binaries.gitlab-ci.yml11
-rw-r--r--lib/gitlab/highlight.rb7
-rw-r--r--lib/gitlab/static_site_editor/config/generated_config.rb6
-rw-r--r--lib/sidebars/projects/menus/infrastructure_menu.rb93
-rw-r--r--lib/sidebars/projects/menus/operations_menu.rb5
-rw-r--r--lib/sidebars/projects/panel.rb1
-rw-r--r--locale/gitlab.pot12
-rw-r--r--package.json2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb2
-rw-r--r--spec/controllers/registrations/welcome_controller_spec.rb24
-rw-r--r--spec/features/admin/admin_settings_spec.rb69
-rw-r--r--spec/features/projects/navbar_spec.rb26
-rw-r--r--spec/features/projects/user_uses_shortcuts_spec.rb16
-rw-r--r--spec/frontend/issuable/components/csv_export_modal_spec.js2
-rw-r--r--spec/frontend/jobs/mock_data.js4
-rw-r--r--spec/frontend/pipeline_new/mock_data.js6
-rw-r--r--spec/frontend/projects/compare/components/app_legacy_spec.js2
-rw-r--r--spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js2
-rw-r--r--spec/lib/gitlab/highlight_spec.rb5
-rw-r--r--spec/lib/gitlab/static_site_editor/config/generated_config_spec.rb7
-rw-r--r--spec/lib/sidebars/projects/menus/operations_menu_spec.rb54
-rw-r--r--spec/models/group_spec.rb8
-rw-r--r--spec/models/project_spec.rb8
-rw-r--r--spec/requests/api/issues/issues_spec.rb29
-rw-r--r--spec/support/shared_contexts/navbar_structure_context.rb32
-rw-r--r--spec/support/shared_examples/requests/api/issuable_update_shared_examples.rb2
-rw-r--r--spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb135
-rw-r--r--yarn.lock8
76 files changed, 936 insertions, 305 deletions
diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS
index 9b41fee9ab9..c63ad882487 100644
--- a/.gitlab/CODEOWNERS
+++ b/.gitlab/CODEOWNERS
@@ -22,12 +22,14 @@
/doc/administration/reference_architectures/ @axil
/doc/administration/snippets/ @aqualls
/doc/administration/troubleshooting @axil @marcia @mjang1
+/doc/api/group_activity_analytics.md @msedlakjakubowski
/doc/ci/ @marcel.amirault @sselhorn
/doc/ci/environments/ @axil
/doc/ci/services/ @sselhorn
/doc/ci/test_cases/ @msedlakjakubowski
/doc/development/ @marcia @mjang1
/doc/development/documentation/ @cnorris
+/doc/development/value_stream_analytics.md @msedlakjakubowski
/doc/gitlab-basics/ @marcia
/doc/install/ @axil
/doc/integration/ @aqualls @mjang1
@@ -38,15 +40,18 @@
/doc/topics/autodevops/ @ngaskill @marcia
/doc/topics/git/ @aqualls
/doc/update/ @axil @marcia
-/doc/user/analytics/ @mjang1 @ngaskill
+/doc/user/analytics/ @msedlakjakubowski @ngaskill
/doc/user/application_security @rdickenson
/doc/user/clusters/ @marcia
/doc/user/compliance/ @mjang1 @rdickenson
-/doc/user/group/ @mjang1 @msedlakjakubowski
+/doc/user/group/ @msedlakjakubowski
/doc/user/group/bulk_editing/ @msedlakjakubowski
+/doc/user/group/devops_adoption/ @msedlakjakubowski
/doc/user/group/epics/ @msedlakjakubowski
+/doc/user/group/insights/ @msedlakjakubowski
/doc/user/group/iterations/ @msedlakjakubowski
/doc/user/group/roadmap/ @msedlakjakubowski
+/doc/user/group/value_stream_analytics/ @msedlakjakubowski
/doc/user/infrastructure/ @marcia
/doc/user/packages/ @ngaskill
/doc/user/profile/ @mjang1 @msedlakjakubowski
@@ -133,7 +138,7 @@
[Docs Growth]
/doc/administration/instance_review.md @aqualls
/doc/api/invitations.md @aqualls
-/doc/api/experiments.md @aqualls
+/doc/api/experiments.md @aqualls
/doc/development/experiment_guide/ @aqualls
/doc/development/snowplow/ @aqualls
/doc/development/usage_ping/ @aqualls
@@ -181,9 +186,9 @@ Dangerfile @gl-quality/eng-prod
.editorconfig @gl-quality/eng-prod
[Backend Static Code Analysis]
-.rubocop*.yml @dstull @splattael @gl-quality/eng-prod
-/rubocop/ @dstull @splattael @gl-quality/eng-prod
-/spec/rubocop/ @dstull @splattael @gl-quality/eng-prod
+.rubocop*.yml @dstull @splattael @gl-quality/eng-prod
+/rubocop/ @dstull @splattael @gl-quality/eng-prod
+/spec/rubocop/ @dstull @splattael @gl-quality/eng-prod
[End-to-end]
/qa/ @gl-quality
@@ -291,4 +296,4 @@ Dangerfile @gl-quality/eng-prod
/config/dependency_decisions.yml @gitlab-org/legal-reviewers
[Workhorse]
-/workhorse/ @jacobvosmaer-gitlab @nick.thomas @nolith @patrickbajao
+/workhorse/ @jacobvosmaer-gitlab @nick.thomas @nolith @patrickbajao
diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml
index 48a495a0ead..c1285c77e01 100644
--- a/.rubocop_manual_todo.yml
+++ b/.rubocop_manual_todo.yml
@@ -13,7 +13,6 @@
# WIP See https://gitlab.com/gitlab-org/gitlab/-/issues/322903
Graphql/Descriptions:
Exclude:
- - 'app/graphql/types/base_enum.rb'
- 'app/graphql/types/container_expiration_policy_cadence_enum.rb'
- 'app/graphql/types/container_expiration_policy_keep_enum.rb'
- 'app/graphql/types/container_expiration_policy_older_than_enum.rb'
diff --git a/app/assets/javascripts/issuable/components/csv_export_modal.vue b/app/assets/javascripts/issuable/components/csv_export_modal.vue
index 7bdd55ddda3..f17440a4a14 100644
--- a/app/assets/javascripts/issuable/components/csv_export_modal.vue
+++ b/app/assets/javascripts/issuable/components/csv_export_modal.vue
@@ -21,13 +21,11 @@ export default {
props: {
exportCsvPath: {
type: String,
- required: false,
- default: '',
+ required: true,
},
issuableCount: {
type: Number,
- required: false,
- default: 0,
+ required: true,
},
modalId: {
type: String,
diff --git a/app/assets/stylesheets/page_bundles/pipelines.scss b/app/assets/stylesheets/page_bundles/pipelines.scss
index 6ef7f912ea9..ace91d197b6 100644
--- a/app/assets/stylesheets/page_bundles/pipelines.scss
+++ b/app/assets/stylesheets/page_bundles/pipelines.scss
@@ -182,11 +182,6 @@ button.gl-button.btn-link.mini-pipeline-graph-dropdown-toggle {
border-bottom-color: $border-color;
}
- &::after {
- margin-top: 1px;
- border-bottom-color: $white;
- }
-
/**
* Center dropdown menu in mini graph
*/
diff --git a/app/assets/stylesheets/utilities.scss b/app/assets/stylesheets/utilities.scss
index f9e9a7a99b7..abf94c520c3 100644
--- a/app/assets/stylesheets/utilities.scss
+++ b/app/assets/stylesheets/utilities.scss
@@ -182,3 +182,10 @@
.gl-mb-n3 {
margin-bottom: -$gl-spacing-scale-3;
}
+
+// Will be moved to @gitlab/ui in https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1408
+$gl-line-height-42: px-to-rem(42px);
+
+.gl-line-height-42 {
+ line-height: $gl-line-height-42;
+}
diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb
index e85b282050c..e6aae144da6 100644
--- a/app/controllers/invites_controller.rb
+++ b/app/controllers/invites_controller.rb
@@ -125,14 +125,14 @@ class InvitesController < ApplicationController
name: member.source.full_name,
url: project_url(member.source),
title: _("project"),
- path: activity_project_path(member.source)
+ path: member.source.activity_path
}
when Group
{
name: member.source.name,
url: group_url(member.source),
title: _("group"),
- path: activity_group_path(member.source)
+ path: member.source.activity_path
}
end
end
diff --git a/app/controllers/registrations/welcome_controller.rb b/app/controllers/registrations/welcome_controller.rb
index 89fc1e4aa3c..b50b8597acd 100644
--- a/app/controllers/registrations/welcome_controller.rb
+++ b/app/controllers/registrations/welcome_controller.rb
@@ -18,8 +18,10 @@ module Registrations
if result[:status] == :success
return redirect_to new_users_sign_up_group_path if show_signup_onboarding?
- if current_user.members.count == 1
- redirect_to path_for_signed_in_user(current_user), notice: helpers.invite_accepted_notice(current_user.members.last)
+ members = current_user.members
+
+ if members.count == 1 && members.last.source.present?
+ redirect_to members_activity_path(members), notice: helpers.invite_accepted_notice(members.last)
else
redirect_to path_for_signed_in_user(current_user)
end
@@ -52,20 +54,14 @@ module Registrations
def path_for_signed_in_user(user)
return users_almost_there_path if requires_confirmation?(user)
- stored_location_for(user) || members_activity_path(user)
+ stored_location_for(user) || members_activity_path(user.members)
end
- def members_activity_path(user)
- return dashboard_projects_path unless user.members.count >= 1
+ def members_activity_path(members)
+ return dashboard_projects_path unless members.any?
+ return dashboard_projects_path unless members.last.source.present?
- case user.members.last.source
- when Project
- activity_project_path(user.members.last.source)
- when Group
- activity_group_path(user.members.last.source)
- else
- dashboard_projects_path
- end
+ members.last.source.activity_path
end
def show_signup_onboarding?
diff --git a/app/finders/issues_finder.rb b/app/finders/issues_finder.rb
index e1a334413f8..0866040d399 100644
--- a/app/finders/issues_finder.rb
+++ b/app/finders/issues_finder.rb
@@ -25,7 +25,7 @@
# updated_after: datetime
# updated_before: datetime
# confidential: boolean
-# issue_type: array of strings (one of Issue.issue_types)
+# issue_types: array of strings (one of Issue.issue_types)
#
class IssuesFinder < IssuableFinder
CONFIDENTIAL_ACCESS_LEVEL = Gitlab::Access::REPORTER
diff --git a/app/graphql/types/base_enum.rb b/app/graphql/types/base_enum.rb
index 518a902a5d7..7ef1cbddbd9 100644
--- a/app/graphql/types/base_enum.rb
+++ b/app/graphql/types/base_enum.rb
@@ -17,6 +17,9 @@ module Types
# declarative_enum MyDeclarativeEnum
# end
#
+ # Disabling descriptions rubocop for a false positive here
+ # rubocop: disable Graphql/Descriptions
+ #
def declarative_enum(enum_mod, use_name: true, use_description: true)
graphql_name(enum_mod.name) if use_name
description(enum_mod.description) if use_description
@@ -25,6 +28,7 @@ module Types
value(key.to_s.upcase, **content)
end
end
+ # rubocop: enable Graphql/Descriptions
# Helper to define an enum member for each element of a Rails AR enum
def from_rails_enum(enum, description:)
diff --git a/app/helpers/services_helper.rb b/app/helpers/services_helper.rb
index 0711a6b7e97..b197d8e1f7a 100644
--- a/app/helpers/services_helper.rb
+++ b/app/helpers/services_helper.rb
@@ -172,6 +172,10 @@ module ServicesHelper
name: integration.to_param
}
end
+
+ def show_service_templates_nav_link?
+ Feature.disabled?(:disable_service_templates, type: :development, default_enabled: :yaml)
+ end
end
ServicesHelper.prepend_if_ee('EE::ServicesHelper')
diff --git a/app/models/concerns/enums/ci/commit_status.rb b/app/models/concerns/enums/ci/commit_status.rb
index de17f50cd29..a1ebf420819 100644
--- a/app/models/concerns/enums/ci/commit_status.rb
+++ b/app/models/concerns/enums/ci/commit_status.rb
@@ -22,6 +22,7 @@ module Enums
forward_deployment_failure: 13,
user_blocked: 14,
project_deleted: 15,
+ ci_quota_exceeded: 16,
insufficient_bridge_permissions: 1_001,
downstream_bridge_project_not_found: 1_002,
invalid_bridge_trigger: 1_003,
diff --git a/app/models/group.rb b/app/models/group.rb
index a8626ce9ef8..625ecd516a4 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -708,6 +708,10 @@ class Group < Namespace
model_name.singular
end
+ def activity_path
+ Gitlab::Routing.url_helpers.activity_group_path(self)
+ end
+
private
def update_two_factor_requirement
diff --git a/app/models/project.rb b/app/models/project.rb
index b21f61ee11f..af203d90e73 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -2570,6 +2570,10 @@ class Project < ApplicationRecord
Feature.enabled?(:inherited_issuable_templates, self, default_enabled: :yaml)
end
+ def activity_path
+ Gitlab::Routing.url_helpers.activity_project_path(self)
+ end
+
private
def set_container_registry_access_level
diff --git a/app/presenters/commit_status_presenter.rb b/app/presenters/commit_status_presenter.rb
index c8d3457b04a..7b639c709e1 100644
--- a/app/presenters/commit_status_presenter.rb
+++ b/app/presenters/commit_status_presenter.rb
@@ -23,7 +23,8 @@ class CommitStatusPresenter < Gitlab::View::Presenter::Delegated
secrets_provider_not_found: 'The secrets provider can not be found',
reached_max_descendant_pipelines_depth: 'You reached the maximum depth of child pipelines',
project_deleted: 'The job belongs to a deleted project',
- user_blocked: 'The user who created this job is blocked'
+ user_blocked: 'The user who created this job is blocked',
+ ci_quota_exceeded: 'No more CI minutes available'
}.freeze
private_constant :CALLOUT_FAILURE_MESSAGES
diff --git a/app/views/layouts/nav/sidebar/_admin.html.haml b/app/views/layouts/nav/sidebar/_admin.html.haml
index aa6b0146df7..b71866c9138 100644
--- a/app/views/layouts/nav/sidebar/_admin.html.haml
+++ b/app/views/layouts/nav/sidebar/_admin.html.haml
@@ -202,17 +202,18 @@
= render_if_exists 'layouts/nav/sidebar/credentials_link'
- = nav_link(controller: :services) do
- = link_to admin_application_settings_services_path do
- .nav-icon-container
- = sprite_icon('template')
- %span.nav-item-name
- = _('Service Templates')
- %ul.sidebar-sub-level-items.is-fly-out-only
- = nav_link(controller: :services, html_options: { class: "fly-out-top-item" } ) do
- = link_to admin_application_settings_services_path do
- %strong.fly-out-top-item-name
- = _('Service Templates')
+ - if show_service_templates_nav_link?
+ = nav_link(controller: :services) do
+ = link_to admin_application_settings_services_path do
+ .nav-icon-container
+ = sprite_icon('template')
+ %span.nav-item-name
+ = _('Service Templates')
+ %ul.sidebar-sub-level-items.is-fly-out-only
+ = nav_link(controller: :services, html_options: { class: "fly-out-top-item" } ) do
+ = link_to admin_application_settings_services_path do
+ %strong.fly-out-top-item-name
+ = _('Service Templates')
= nav_link(controller: :labels) do
= link_to admin_labels_path do
diff --git a/changelogs/unreleased/extend_branch_support_for_sse.yml b/changelogs/unreleased/extend_branch_support_for_sse.yml
new file mode 100644
index 00000000000..df433ec436c
--- /dev/null
+++ b/changelogs/unreleased/extend_branch_support_for_sse.yml
@@ -0,0 +1,5 @@
+---
+title: Extend branch support for Static Site Editor
+merge_request: 60848
+author:
+type: changed
diff --git a/changelogs/unreleased/gmh-ensure-highlighting-limits-are-configurable-and-documented.yml b/changelogs/unreleased/gmh-ensure-highlighting-limits-are-configurable-and-documented.yml
new file mode 100644
index 00000000000..0b7d2577528
--- /dev/null
+++ b/changelogs/unreleased/gmh-ensure-highlighting-limits-are-configurable-and-documented.yml
@@ -0,0 +1,5 @@
+---
+title: Ensure highlighting limits are documented, configurable, and monitorable
+merge_request: 60445
+author:
+type: added
diff --git a/changelogs/unreleased/sy-create-incidents-via-api.yml b/changelogs/unreleased/sy-create-incidents-via-api.yml
new file mode 100644
index 00000000000..2752b1849b5
--- /dev/null
+++ b/changelogs/unreleased/sy-create-incidents-via-api.yml
@@ -0,0 +1,6 @@
+---
+title: Add support for create, updating, and filtering issues based on issue type
+ in REST API
+merge_request: 60687
+author:
+type: added
diff --git a/config/feature_flags/development/ci_minutes_track_live_consumption.yml b/config/feature_flags/development/ci_minutes_track_live_consumption.yml
new file mode 100644
index 00000000000..ddd21f3909e
--- /dev/null
+++ b/config/feature_flags/development/ci_minutes_track_live_consumption.yml
@@ -0,0 +1,8 @@
+---
+name: ci_minutes_track_live_consumption
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59263
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/329197
+milestone: '13.12'
+type: development
+group: group::continuous integration
+default_enabled: false
diff --git a/config/feature_flags/development/disable_service_templates.yml b/config/feature_flags/development/disable_service_templates.yml
new file mode 100644
index 00000000000..07e52224b98
--- /dev/null
+++ b/config/feature_flags/development/disable_service_templates.yml
@@ -0,0 +1,8 @@
+---
+name: disable_service_templates
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59098
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/327436
+milestone: '13.12'
+type: development
+group: group::ecosystem
+default_enabled: false
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index bd785977462..aee9dd455af 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -1270,6 +1270,10 @@ production: &base
# matomo_site_id: '_your_matomo_site_id'
# matomo_disable_cookies: false
+ ## Maximum file size for syntax highlighting
+ ## https://docs.gitlab.com/ee/user/project/highlighting.html
+ # maximum_text_highlight_size_kilobytes: 512
+
rack_attack:
git_basic_auth:
# Rack Attack IP banning enabled
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index 05e9259c106..64ae868735a 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -856,6 +856,7 @@ Settings['extra'] ||= Settingslogic.new({})
Settings.extra['matomo_site_id'] ||= Settings.extra['piwik_site_id'] if Settings.extra['piwik_site_id'].present?
Settings.extra['matomo_url'] ||= Settings.extra['piwik_url'] if Settings.extra['piwik_url'].present?
Settings.extra['matomo_disable_cookies'] = false if Settings.extra['matomo_disable_cookies'].nil?
+Settings.extra['maximum_text_highlight_size_kilobytes'] = Settings.extra.fetch('maximum_text_highlight_size_kilobytes', 512).kilobytes
#
# Rack::Attack settings
diff --git a/config/metrics/counts_28d/20210216174956_i_analytics_cohorts_monthly.yml b/config/metrics/counts_28d/20210216174956_i_analytics_cohorts_monthly.yml
index 3ac2e608210..dc0d7f35622 100644
--- a/config/metrics/counts_28d/20210216174956_i_analytics_cohorts_monthly.yml
+++ b/config/metrics/counts_28d/20210216174956_i_analytics_cohorts_monthly.yml
@@ -1,9 +1,9 @@
---
key_path: redis_hll_counters.analytics.i_analytics_cohorts_monthly
description:
-product_section: dev
-product_stage: manage
-product_group: group::optimize
+product_section: fulfillment
+product_stage: fulfillment
+product_group: group::utilization
product_category:
value_type: number
status: data_available
diff --git a/db/post_migrate/20210505092746_create_partial_covering_index_for_pending_builds.rb b/db/post_migrate/20210505092746_create_partial_covering_index_for_pending_builds.rb
index a1e1dbbeafe..81fe65c1945 100644
--- a/db/post_migrate/20210505092746_create_partial_covering_index_for_pending_builds.rb
+++ b/db/post_migrate/20210505092746_create_partial_covering_index_for_pending_builds.rb
@@ -9,13 +9,16 @@ class CreatePartialCoveringIndexForPendingBuilds < ActiveRecord::Migration[6.0]
NEW_INDEX = 'index_ci_builds_runner_id_pending_covering'
def up
- execute "CREATE INDEX CONCURRENTLY #{NEW_INDEX} ON ci_builds (runner_id, id) INCLUDE (project_id) WHERE status = 'pending' AND type = 'Ci::Build'" unless index_exists_by_name?(:ci_builds, NEW_INDEX)
+ disable_statement_timeout do
+ execute "CREATE INDEX CONCURRENTLY #{NEW_INDEX} ON ci_builds (runner_id, id) INCLUDE (project_id) WHERE status = 'pending' AND type = 'Ci::Build'" unless index_exists_by_name?(:ci_builds, NEW_INDEX)
+ end
remove_concurrent_index_by_name :ci_builds, EXISTING_INDEX
end
def down
add_concurrent_index :ci_builds, :runner_id, where: "status = 'pending' AND type = 'Ci::Build'", name: EXISTING_INDEX
+
remove_concurrent_index_by_name :ci_builds, NEW_INDEX
end
end
diff --git a/doc/administration/application_settings_cache.md b/doc/administration/application_settings_cache.md
index b6c09129c79..b3aac932fa8 100644
--- a/doc/administration/application_settings_cache.md
+++ b/doc/administration/application_settings_cache.md
@@ -4,16 +4,15 @@ group: Memory
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Changing application settings cache expiry interval **(FREE SELF)**
+# Change the expiration interval for application cache **(FREE SELF)**
-Application settings are cached for 60 seconds by default which should work
-for most installations. A higher value would mean a greater delay between
-changing an application setting and noticing that change come into effect.
-A value of `0` would result in the `application_settings` table being
-loaded for every request causing extra load on Redis and/or PostgreSQL.
-It is therefore recommended to keep the value above zero.
+By default, GitLab caches application settings for 60 seconds. Occasionally,
+you may need to increase that interval to have more delay between application
+setting changes and when users notice those changes in the application.
-## Change the application settings cache expiry
+We recommend you set this value to greater than `0` seconds. Setting it to `0`
+causes the `application_settings` table to load for every request. This causes
+extra load for Redis and PostgreSQL.
To change the expiry value:
@@ -25,7 +24,8 @@ To change the expiry value:
gitlab_rails['application_settings_cache_seconds'] = 60
```
-1. Save the file, and reconfigure and restart GitLab for the changes to take effect:
+1. Save the file, and then reconfigure and restart GitLab for the changes to
+ take effect:
```shell
gitlab-ctl reconfigure
@@ -43,5 +43,5 @@ To change the expiry value:
application_settings_cache_seconds: 60
```
-1. Save the file and [restart](restart_gitlab.md#installations-from-source)
+1. Save the file, and then [restart](restart_gitlab.md#installations-from-source)
GitLab for the changes to take effect.
diff --git a/doc/administration/incoming_email.md b/doc/administration/incoming_email.md
index 693c22f925c..9aa6bffdb98 100644
--- a/doc/administration/incoming_email.md
+++ b/doc/administration/incoming_email.md
@@ -185,8 +185,11 @@ Example for Omnibus installs:
```ruby
gitlab_rails['incoming_email_enabled'] = true
-# The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to.
-# The placeholder can be omitted but if present, it must appear in the "user" part of the address (before the `@`).
+# The email address including the %{key} placeholder that will be replaced to reference the
+# item being replied to. This %{key} should be included in its entirety within the email
+# address and not replaced by another value.
+# For example: emailaddress+%{key}@gitlab.example.com.
+# The placeholder must appear in the "user" part of the address (before the `@`).
gitlab_rails['incoming_email_address'] = "incoming+%{key}@gitlab.example.com"
# Email account username
@@ -223,7 +226,7 @@ incoming_email:
# The email address including the %{key} placeholder that will be replaced to reference the
# item being replied to. This %{key} should be included in its entirety within the email
# address and not replaced by another value.
- # For example: emailadress+%{key}@gmail.com.
+ # For example: emailaddress+%{key}@gitlab.example.com.
# The placeholder must appear in the "user" part of the address (before the `@`).
address: "incoming+%{key}@gitlab.example.com"
@@ -264,8 +267,11 @@ Example for Omnibus installs:
```ruby
gitlab_rails['incoming_email_enabled'] = true
-# The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to.
-# The placeholder can be omitted but if present, it must appear in the "user" part of the address (before the `@`).
+# The email address including the %{key} placeholder that will be replaced to reference the
+# item being replied to. This %{key} should be included in its entirety within the email
+# address and not replaced by another value.
+# For example: emailaddress+%{key}@gmail.com.
+# The placeholder must appear in the "user" part of the address (before the `@`).
gitlab_rails['incoming_email_address'] = "gitlab-incoming+%{key}@gmail.com"
# Email account username
@@ -299,8 +305,11 @@ Example for source installs:
incoming_email:
enabled: true
- # The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to.
- # The placeholder can be omitted but if present, it must appear in the "user" part of the address (before the `@`).
+ # The email address including the %{key} placeholder that will be replaced to reference the
+ # item being replied to. This %{key} should be included in its entirety within the email
+ # address and not replaced by another value.
+ # For example: emailaddress+%{key}@gmail.com.
+ # The placeholder must appear in the "user" part of the address (before the `@`).
address: "gitlab-incoming+%{key}@gmail.com"
# Email account username
@@ -345,8 +354,11 @@ Example for Omnibus installs:
```ruby
gitlab_rails['incoming_email_enabled'] = true
-# The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to.
-# The placeholder can be omitted but if present, it must appear in the "user" part of the address (before the `@`).
+# The email address including the %{key} placeholder that will be replaced to reference the
+# item being replied to. This %{key} should be included in its entirety within the email
+# address and not replaced by another value.
+# For example: emailaddress-%{key}@exchange.example.com.
+# The placeholder must appear in the "user" part of the address (before the `@`).
# Exchange does not support sub-addressing, so a catch-all mailbox must be used.
gitlab_rails['incoming_email_address'] = "incoming-%{key}@exchange.example.com"
@@ -370,8 +382,11 @@ Example for source installs:
incoming_email:
enabled: true
- # The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to.
- # The placeholder can be omitted but if present, it must appear in the "user" part of the address (before the `@`).
+ # The email address including the %{key} placeholder that will be replaced to reference the
+ # item being replied to. This %{key} should be included in its entirety within the email
+ # address and not replaced by another value.
+ # For example: emailaddress-%{key}@exchange.example.com.
+ # The placeholder must appear in the "user" part of the address (before the `@`).
# Exchange does not support sub-addressing, so a catch-all mailbox must be used.
address: "incoming-%{key}@exchange.example.com"
@@ -476,9 +491,11 @@ This example for Omnibus GitLab assumes the mailbox `incoming@office365.example.
```ruby
gitlab_rails['incoming_email_enabled'] = true
-# The email address including the `%{key}` placeholder that will be replaced
-# to reference the item being replied to. The placeholder can be omitted, but if
-# present, it must appear in the "user" part of the address (before the `@`).
+# The email address including the %{key} placeholder that will be replaced to reference the
+# item being replied to. This %{key} should be included in its entirety within the email
+# address and not replaced by another value.
+# For example: emailaddress+%{key}@office365.example.com.
+# The placeholder must appear in the "user" part of the address (before the `@`).
gitlab_rails['incoming_email_address'] = "incoming+%{key}@office365.example.com"
# Email account username
@@ -501,9 +518,11 @@ This example for source installs assumes the mailbox `incoming@office365.example
incoming_email:
enabled: true
- # The email address including the `%{key}` placeholder that will be replaced
- # to reference the item being replied to. The placeholder can be omitted, but
- # if present, it must appear in the "user" part of the address (before the `@`).
+ # The email address including the %{key} placeholder that will be replaced to reference the
+ # item being replied to. This %{key} should be included in its entirety within the email
+ # address and not replaced by another value.
+ # For example: emailaddress+%{key}@office365.example.com.
+ # The placeholder must appear in the "user" part of the address (before the `@`).
address: "incoming+%{key}@office365.example.comm"
# Email account username
@@ -527,9 +546,11 @@ This example for Omnibus installs assumes the catch-all mailbox `incoming@office
```ruby
gitlab_rails['incoming_email_enabled'] = true
-# The email address including the `%{key}` placeholder that will be replaced to
-# reference the item being replied to. The placeholder can be omitted, but if present,
-# it must appear in the "user" part of the address (before the `@`).
+# The email address including the %{key} placeholder that will be replaced to reference the
+# item being replied to. This %{key} should be included in its entirety within the email
+# address and not replaced by another value.
+# For example: emailaddress-%{key}@office365.example.com.
+# The placeholder must appear in the "user" part of the address (before the `@`).
gitlab_rails['incoming_email_address'] = "incoming-%{key}@office365.example.com"
# Email account username
@@ -552,9 +573,11 @@ This example for source installs assumes the catch-all mailbox `incoming@office3
incoming_email:
enabled: true
- # The email address including the `%{key}` placeholder that will be replaced
- # to reference the item being replied to. The placeholder can be omitted, but
- # if present, it must appear in the "user" part of the address (before the `@`).
+ # The email address including the %{key} placeholder that will be replaced to reference the
+ # item being replied to. This %{key} should be included in its entirety within the email
+ # address and not replaced by another value.
+ # For example: emailaddress+%{key}@office365.example.com.
+ # The placeholder must appear in the "user" part of the address (before the `@`).
address: "incoming-%{key}@office365.example.com"
# Email account username
@@ -653,9 +676,11 @@ This example for Omnibus GitLab assumes you're using the following mailbox: `inc
```ruby
gitlab_rails['incoming_email_enabled'] = true
-# The email address including the `%{key}` placeholder that will be replaced
-# to reference the item being replied to. The placeholder can be omitted, but if
-# present, it must appear in the "user" part of the address (before the `@`).
+# The email address including the %{key} placeholder that will be replaced to reference the
+# item being replied to. This %{key} should be included in its entirety within the email
+# address and not replaced by another value.
+# For example: emailaddress+%{key}@example.onmicrosoft.com.
+# The placeholder must appear in the "user" part of the address (before the `@`).
gitlab_rails['incoming_email_address'] = "incoming+%{key}@example.onmicrosoft.com"
# Email account username
diff --git a/doc/api/group_relations_export.md b/doc/api/group_relations_export.md
new file mode 100644
index 00000000000..bb19f7f0923
--- /dev/null
+++ b/doc/api/group_relations_export.md
@@ -0,0 +1,101 @@
+---
+stage: Manage
+group: Import
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Group Relations Export API
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59978) in GitLab 13.12.
+
+With the Group Relations Export API, you can partially export group structure. This API is similar
+to [group export](group_import_export.md),
+but it exports each top-level relation (for example, milestones/boards/labels) as a separate file
+instead of one archive. The group relations export API is primarily used in [group migration](../user/group/index.md).
+
+## Schedule new export
+
+Start a new group relations export:
+
+```plaintext
+POST /groups/:id/export_relations
+```
+
+| Attribute | Type | Required | Description |
+| --------- | -------------- | -------- | ---------------------------------------- |
+| `id` | integer/string | yes | ID of the group owned by the authenticated user. |
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/export_relations"
+```
+
+```json
+{
+ "message": "202 Accepted"
+}
+```
+
+## Export status
+
+View the status of the relations export:
+
+```plaintext
+GET /groups/:id/export_relations/status
+```
+
+| Attribute | Type | Required | Description |
+| --------- | -------------- | -------- | ---------------------------------------- |
+| `id` | integer/string | yes | ID of the group owned by the authenticated user. |
+
+```shell
+curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/export_relations/status"
+```
+
+The status can be one of the following:
+
+- `0`: `started`
+- `1`: `finished`
+- `-1`: `failed`
+
+- `0` - `started`
+- `1` - `finished`
+- `-1` - `failed`
+
+```json
+[
+ {
+ "relation": "badges",
+ "status": 1,
+ "error": null,
+ "updated_at": "2021-05-04T11:25:20.423Z"
+ },
+ {
+ "relation": "boards",
+ "status": 1,
+ "error": null,
+ "updated_at": "2021-05-04T11:25:20.085Z"
+ }
+]
+```
+
+## Export download
+
+Download the finished relations export:
+
+```plaintext
+GET /groups/:id/export_relations/download
+```
+
+| Attribute | Type | Required | Description |
+| --------------- | -------------- | -------- | ---------------------------------------- |
+| `id` | integer/string | yes | ID of the group owned by the authenticated user. |
+| `relation` | string | yes | Name of the group top-level relation to download. |
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" --remote-header-name --remote-name "https://gitlab.example.com/api/v4/groups/1/export_relations/download?relation=labels"
+```
+
+```shell
+ls labels.ndjson.gz
+labels.ndjson.gz
+```
diff --git a/doc/api/groups.md b/doc/api/groups.md
index b1e1e2bb6c5..86f44797254 100644
--- a/doc/api/groups.md
+++ b/doc/api/groups.md
@@ -1257,7 +1257,9 @@ Read more in the [Group Badges](group_badges.md) documentation.
## Group Import/Export
-Read more in the [Group Import/Export](group_import_export.md) documentation.
+Read more in the [Group Import/Export](group_import_export.md)
+and [Group Relations Export](group_relations_export.md)
+documentation.
## Share Groups with Groups
diff --git a/doc/api/issues.md b/doc/api/issues.md
index 5ed3526cd7f..08521cd2f94 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -62,6 +62,7 @@ GET /issues?state=opened
| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _(Introduced in [GitLab 13.3](https://gitlab.com/gitlab-org/gitlab/-/issues/233420))_ |
| `iids[]` | integer array | no | Return only the issues having the given `iid` |
| `in` | string | no | Modify the scope of the `search` attribute. `title`, `description`, or a string joining them with comma. Default is `title,description` |
+| `issue_type` | string | no | Filter to a given type of issue. One of `issue`, `incident`, or `test_case`. _(Introduced in [GitLab 13.12](https://gitlab.com/gitlab-org/gitlab/-/issues/260375))_ |
| `iteration_id` **(PREMIUM)** | integer | no | Return issues assigned to the given iteration ID. `None` returns issues that do not belong to an iteration. `Any` returns issues that belong to an iteration. Mutually exclusive with `iteration_title`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `iteration_title` **(PREMIUM)** | string | no | Return issues assigned to the iteration with the given title. Similar to `iteration_id` and mutually exclusive with `iteration_id`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `milestone` | string | no | The milestone title. `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. |
@@ -158,6 +159,7 @@ Example response:
"task_status": "10 of 15 tasks completed",
"confidential": false,
"discussion_locked": false,
+ "issue_type": "issue",
"_links":{
"self":"http://gitlab.example.com/api/v4/projects/1/issues/76",
"notes":"http://gitlab.example.com/api/v4/projects/1/issues/76/notes",
@@ -267,6 +269,7 @@ GET /groups/:id/issues?state=opened
| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _(Introduced in [GitLab 13.3](https://gitlab.com/gitlab-org/gitlab/-/issues/233420))_ |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user |
| `iids[]` | integer array | no | Return only the issues having the given `iid` |
+| `issue_type` | string | no | Filter to a given type of issue. One of `issue`, `incident`, or `test_case`. _(Introduced in [GitLab 13.12](https://gitlab.com/gitlab-org/gitlab/-/issues/260375))_ |
| `iteration_id` **(PREMIUM)** | integer | no | Return issues assigned to the given iteration ID. `None` returns issues that do not belong to an iteration. `Any` returns issues that belong to an iteration. Mutually exclusive with `iteration_title`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `iteration_title` **(PREMIUM)** | string | no | Return issues assigned to the iteration with the given title. Similar to `iteration_id` and mutually exclusive with `iteration_id`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. |
@@ -361,6 +364,7 @@ Example response:
"task_status": "10 of 15 tasks completed",
"confidential": false,
"discussion_locked": false,
+ "issue_type": "issue",
"_links":{
"self":"http://gitlab.example.com/api/v4/projects/4/issues/41",
"notes":"http://gitlab.example.com/api/v4/projects/4/issues/41/notes",
@@ -469,6 +473,7 @@ GET /projects/:id/issues?state=opened
| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _(Introduced in [GitLab 13.3](https://gitlab.com/gitlab-org/gitlab/-/issues/233420))_ |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `iids[]` | integer array | no | Return only the issues having the given `iid` |
+| `issue_type` | string | no | Filter to a given type of issue. One of `issue`, `incident`, or `test_case`. _(Introduced in [GitLab 13.12](https://gitlab.com/gitlab-org/gitlab/-/issues/260375))_ |
| `iteration_id` **(PREMIUM)** | integer | no | Return issues assigned to the given iteration ID. `None` returns issues that do not belong to an iteration. `Any` returns issues that belong to an iteration. Mutually exclusive with `iteration_title`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `iteration_title` **(PREMIUM)** | string | no | Return issues assigned to the iteration with the given title. Similar to `iteration_id` and mutually exclusive with `iteration_id`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. |
@@ -569,6 +574,7 @@ Example response:
"task_status": "10 of 15 tasks completed",
"confidential": false,
"discussion_locked": false,
+ "issue_type": "issue",
"_links":{
"self":"http://gitlab.example.com/api/v4/projects/4/issues/41",
"notes":"http://gitlab.example.com/api/v4/projects/4/issues/41/notes",
@@ -729,6 +735,7 @@ Example response:
},
"confidential": false,
"discussion_locked": false,
+ "issue_type": "issue",
"task_completion_status": {
"count": 0,
"completed_count": 0
@@ -895,6 +902,7 @@ Example response:
},
"confidential": false,
"discussion_locked": false,
+ "issue_type": "issue",
"_links": {
"self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
"notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
@@ -985,6 +993,7 @@ POST /projects/:id/issues
| `epic_iid` **(PREMIUM)** | integer | no | IID of the epic to add the issue to. Valid values are greater than or equal to 0. (deprecated, [scheduled for removal in API version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157)) |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `iid` | integer/string | no | The internal ID of the project's issue (requires administrator or project owner rights) |
+| `issue_type` | string | no | The type of issue. One of `issue`, `incident`, or `test_case`. Default is `issue`. |
| `labels` | string | no | Comma-separated label names for an issue |
| `merge_request_to_resolve_discussions_of` | integer | no | The IID of a merge request in which to resolve all issues. This fills out the issue with a default description and mark all discussions as resolved. When passing a description or title, these values take precedence over the default values.|
| `milestone_id` | integer | no | The global ID of a milestone to assign issue |
@@ -1044,6 +1053,7 @@ Example response:
},
"confidential": false,
"discussion_locked": false,
+ "issue_type": "issue",
"_links": {
"self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
"notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
@@ -1131,6 +1141,7 @@ At least one of the following parameters is required for the request to be succe
- `:description`
- `:discussion_locked`
- `:due_date`
+- `:issue_type`
- `:labels`
- `:milestone_id`
- `:state_event`
@@ -1152,6 +1163,7 @@ PUT /projects/:id/issues/:issue_iid
| `epic_iid` **(PREMIUM)** | integer | no | IID of the epic to add the issue to. Valid values are greater than or equal to 0. (deprecated, [scheduled for removal in API version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157)) |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `issue_iid` | integer | yes | The internal ID of a project's issue |
+| `issue_type` | string | no | Updates the type of issue. One of `issue`, `incident`, or `test_case`. |
| `labels` | string | no | Comma-separated label names for an issue. Set to an empty string to unassign all labels. |
| `milestone_id` | integer | no | The global ID of a milestone to assign the issue to. Set to `0` or provide an empty value to unassign a milestone.|
| `remove_labels`| string | no | Comma-separated label names to remove from an issue. |
@@ -1219,6 +1231,7 @@ Example response:
},
"confidential": false,
"discussion_locked": false,
+ "issue_type": "issue",
"_links": {
"self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
"notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
@@ -1405,6 +1418,7 @@ Example response:
},
"confidential": false,
"discussion_locked": false,
+ "issue_type": "issue",
"_links": {
"self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
"notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
@@ -1549,6 +1563,7 @@ Example response:
},
"confidential": false,
"discussion_locked": false,
+ "issue_type": "issue",
"_links": {
"self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
"notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
@@ -1680,6 +1695,7 @@ Example response:
},
"confidential": false,
"discussion_locked": false,
+ "issue_type": "issue",
"task_completion_status":{
"count":0,
"completed_count":0
@@ -1788,6 +1804,7 @@ Example response:
},
"confidential": false,
"discussion_locked": false,
+ "issue_type": "issue",
"task_completion_status":{
"count":0,
"completed_count":0
@@ -2013,7 +2030,7 @@ If the project is private or the issue is confidential, you need to provide cred
The preferred way to do this, is by using [personal access tokens](../user/profile/personal_access_tokens.md).
```plaintext
-GET /projects/:id/issues/:issue_id/related_merge_requests
+GET /projects/:id/issues/:issue_iid/related_merge_requests
```
| Attribute | Type | Required | Description |
diff --git a/doc/development/testing_guide/end_to_end/page_objects.md b/doc/development/testing_guide/end_to_end/page_objects.md
index b124ac430f6..d9d78a078b2 100644
--- a/doc/development/testing_guide/end_to_end/page_objects.md
+++ b/doc/development/testing_guide/end_to_end/page_objects.md
@@ -260,7 +260,7 @@ These modules must:
These steps ensure the sanity selectors check detect problems properly.
For example, `qa/qa/ee/page/merge_request/show.rb` adds EE-specific methods to `qa/qa/page/merge_request/show.rb` (with
-`QA::Page::MergeRequest::Show.prepend_if_ee('QA::EE::Page::MergeRequest::Show')`) and following is how it's implemented
+`QA::Page::MergeRequest::Show.prepend_if_ee('Page::MergeRequest::Show', namespace: QA)`) and following is how it's implemented
(only showing the relevant part and referring to the 4 steps described above with inline comments):
```ruby
diff --git a/doc/development/usage_ping/dictionary.md b/doc/development/usage_ping/dictionary.md
index e4c5e2806ec..def7ac9dee3 100644
--- a/doc/development/usage_ping/dictionary.md
+++ b/doc/development/usage_ping/dictionary.md
@@ -7466,7 +7466,7 @@ Missing description
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210216174956_i_analytics_cohorts_monthly.yml)
-Group: `group::optimize`
+Group: `group::utilization`
Status: `data_available`
@@ -7478,7 +7478,7 @@ Missing description
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_7d/20210216174955_i_analytics_cohorts_weekly.yml)
-Group: `group::optimize`
+Group: `group::utilization`
Status: `data_available`
diff --git a/doc/integration/jira/development_panel.md b/doc/integration/jira/development_panel.md
index cc1a3a96577..378955f5721 100644
--- a/doc/integration/jira/development_panel.md
+++ b/doc/integration/jira/development_panel.md
@@ -8,55 +8,75 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/233149) to GitLab Free in 13.4.
-The Jira Development panel integration allows you to reference Jira issues in GitLab, displaying
-activity in the [Development panel](https://support.atlassian.com/jira-software-cloud/docs/view-development-information-for-an-issue/)
-in the issue.
+With the Jira Development panel integration, you can reference Jira issues in GitLab.
+When configured, activity (such as pipeline, deployment, and feature flags) displays in the Jira issue's
+[Development panel](https://support.atlassian.com/jira-software-cloud/docs/view-development-information-for-an-issue/).
+From the Development panel, you can open a detailed view and
+[take various actions](#use-the-integration), including creating a new merge request from a branch:
-It complements the [GitLab Jira integration](../../user/project/integrations/jira.md). You may choose
-to configure both integrations to take advantage of both sets of features. See a
-[feature comparison](index.md#direct-feature-comparison).
+![Branch, Commit and Pull Requests links on Jira issue](img/jira_dev_panel_jira_setup_3.png)
-## Features
+The information displayed in the Jira Development panel depends on where you mention the Jira issue ID:
| Your mention of Jira issue ID in GitLab context | Automated effect in Jira issue |
|---------------------------------------------------|--------------------------------------------------------------------------------------------------------|
| In a merge request | Link to the MR is displayed in Development panel. |
| In a branch name | Link to the branch is displayed in Development panel. |
| In a commit message | Link to the commit is displayed in Development panel. |
-| In a commit message with Jira Smart Commit format | Displays your custom comment or logged time spent and/or performs specified issue transition on merge. |
-
-With this integration, you can access related GitLab merge requests, branches, and commits directly from a Jira issue, reflecting your work in GitLab. From the Development panel, you can open a detailed view and take actions including creating a new merge request from a branch. For more information, see [Usage](#usage).
+| In a commit message with Jira [Smart Commits](https://confluence.atlassian.com/fisheye/using-smart-commits-960155400.html) | Displays your custom comment or logged time spent and/or performs specified issue transition on merge. |
This integration connects all GitLab projects to projects in the Jira instance in either:
-- A top-level group. A top-level GitLab group is one that does not have any parent group itself. All
- the projects of that top-level group, as well as projects of the top-level group's subgroups nesting
- down, are connected.
-- A personal namespace, which then connects the projects in that personal namespace to Jira.
+- A top-level GitLab group: Connects the projects in a group with no parent group,
+ including the projects in its subgroups.
+- A personal namespace: Connects the projects in that personal namespace to Jira.
+
+This differs from the [Jira integration](../../user/project/integrations/jira.md),
+where the mapping is between one GitLab project and the entire Jira instance.
+You can install both integrations to take advantage of both sets of features.
+A [feature comparison](index.md#direct-feature-comparison) is available.
+
+## Use the integration
+
+After the integration is [set up on GitLab and Jira](#configure-the-integration), you can:
-This differs from the [Jira integration](../../user/project/integrations/jira.md), where the mapping is between one GitLab project and the entire Jira instance.
+- Refer to any Jira issue by its ID (in uppercase) in GitLab branch names,
+ commit messages, and merge request titles.
+- See the linked branches, commits, and merge requests in Jira issues:
-Additional features provided by the Jira Development Panel integration include:
+Merge requests are called "pull requests" in Jira issues.
+
+Select the links to see your GitLab repository data.
+
+![GitLab commits details on a Jira issue](img/jira_dev_panel_jira_setup_4.png)
+
+![GitLab merge requests details on a Jira issue](img/jira_dev_panel_jira_setup_5.png)
-- In a Jira issue, display relevant GitLab information in the [development panel](https://support.atlassian.com/jira-software-cloud/docs/view-development-information-for-an-issue/), including related branches, commits, and merge requests.
-- Use Jira [Smart Commits](https://confluence.atlassian.com/fisheye/using-smart-commits-960155400.html) in GitLab to add Jira comments, log time spent on the issue, or apply any issue transition.
-- Showing pipeline, deployment, and feature flags in Jira issues.
+### Use Jira Smart Commits
-## Configuration
+With Jira [Smart Commits](https://confluence.atlassian.com/fisheye/using-smart-commits-960155400.html),
+you can use GitLab to add Jira comments, log time spent on the issue, or apply any issue transition.
+
+For more information about using Jira Smart Commits to track time against an issue, specify
+an issue transition, or add a custom comment, read the Atlassian page
+[Using Smart Commits](https://confluence.atlassian.com/fisheye/using-smart-commits-960155400.html).
+
+## Configure the integration
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
-For an overview of how to configure Jira Development panel integration, see [Agile Management - GitLab Jira Development panel integration](https://www.youtube.com/watch?v=VjVTOmMl85M&feature=youtu.be).
+For an overview of how to configure Jira Development panel integration, see
+[Agile Management - GitLab Jira Development panel integration](https://www.youtube.com/watch?v=VjVTOmMl85M).
-We recommend that a GitLab group maintainer or group owner, or instance administrator (in the case of
-self-managed GitLab) set up the integration to simplify administration.
+To simplify administration, we recommend that a GitLab group maintainer or group owner
+(or instance administrator in the case of self-managed GitLab) set up the integration.
-| If you use Jira on: | GitLab.com customers need: | GitLab self-managed customers need: |
-|-|-|-|
+| Jira usage | GitLab.com customers need | GitLab self-managed customers need |
+|------------|---------------------------|------------------------------------|
| [Atlassian cloud](https://www.atlassian.com/cloud) | The [GitLab.com for Jira Cloud](https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud?hosting=cloud&tab=overview) application installed from the [Atlassian Marketplace](https://marketplace.atlassian.com). This offers real-time sync between GitLab and Jira. | The [GitLab.com for Jira Cloud](https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud?hosting=cloud&tab=overview), using a workaround process. See the documentation for [installing the GitLab Jira Cloud application for self-managed instances](connect-app.md#install-the-gitlabcom-for-jira-cloud-application-for-self-managed-instances) for more information. |
| Your own server | The Jira DVCS (distributed version control system) connector. This syncs data hourly. | The [Jira DVCS Connector](dvcs.md). |
-Each GitLab project can be configured to connect to an entire Jira instance. That means one GitLab
-project can interact with _all_ Jira projects in that instance, once configured. For:
+Each GitLab project can be configured to connect to an entire Jira instance. That means after
+configuration, one GitLab project can interact with all Jira projects in that instance. For:
- The [view Jira issues](issues.md#view-jira-issues) feature, you must associate a GitLab project with a
specific Jira project.
@@ -68,88 +88,67 @@ documentation for [central administration of project integrations](../../user/ad
To enable the Jira service in GitLab, you must:
-1. Configure the project in Jira.
-1. Enter the correct values in GitLab.
+1. [Configure the project in Jira](dvcs.md#configure-jira-for-dvcs).
+ The supported Jira versions are `v6.x`, `v7.x`, and `v8.x`.
+1. [Enter the correct values in GitLab](#configure-gitlab).
### Configure GitLab
-> **Notes:**
->
-> - The supported Jira versions are `v6.x`, `v7.x`, and `v8.x`.
-> - In order to support Oracle's Access Manager, GitLab sends additional cookies
-> to enable Basic Auth. The cookie being added to each request is `OBBasicAuth` with
-> a value of `fromDialog`.
-
-To enable the Jira integration in a project:
-
-1. Go to the project's [Integrations page](../../user/project/integrations/overview.md#accessing-integrations) and select the
- **Jira** service.
+To enable the integration in your GitLab project, after you
+[configure your Jira project](dvcs.md#configure-jira-for-dvcs):
+1. Ensure your GitLab installation does not use a relative URL, as described in
+ [Limitations](#limitations).
+1. Go to your project and select [**Settings > Integrations**](../../user/project/integrations/overview.md#accessing-integrations).
+1. Select **Jira**.
1. Select **Enable integration**.
-
-1. Select **Trigger** actions.
- This determines whether a mention of a Jira issue in GitLab commits, merge requests, or both,
- should link the Jira issue back to that source commit/MR and transition the Jira issue, if
- indicated.
-
-1. To include a comment on the Jira issue when the above reference is made in GitLab, select
+1. Select **Trigger** actions. Your choice determines whether a mention of Jira issue
+ (in a GitLab commit, merge request, or both) creates a cross-link in Jira back to GitLab.
+1. To comment in the Jira issue when a **Trigger** action is made in GitLab, select
**Enable comments**.
-
-1. To transition Jira issues when a [closing reference](../../user/project/issues/managing_issues.md#closing-issues-automatically) is made in GitLab,
- select **Enable Jira transitions**.
-
-1. Enter the further details on the page as described in the following table.
-
- | Field | Description |
- | ----- | ----------- |
- | `Web URL` | The base URL to the Jira instance web interface which is being linked to this GitLab project. For example, `https://jira.example.com`. |
- | `Jira API URL` | The base URL to the Jira instance API. Web URL value is used if not set. For example, `https://jira-api.example.com`. Leave this field blank (or use the same value of `Web URL`) if using **Jira on Atlassian cloud**. |
- | `Username or Email` | Created in [configure Jira](dvcs.md#configure-jira-for-dvcs) step. Use `username` for **Jira Server** or `email` for **Jira on Atlassian cloud**. |
- | `Password/API token` | Created in [configure Jira](dvcs.md#configure-jira-for-dvcs) step. Use `password` for **Jira Server** or `API token` for **Jira on Atlassian cloud**. |
-
+1. To transition Jira issues when a
+ [closing reference](../../user/project/issues/managing_issues.md#closing-issues-automatically)
+ is made in GitLab, select **Enable Jira transitions**.
+1. Provide Jira configuration information:
+ - **Web URL**: The base URL to the Jira instance web interface you're linking to
+ this GitLab project, such as `https://jira.example.com`.
+ - **Jira API URL**: The base URL to the Jira instance API, such as `https://jira-api.example.com`.
+ Defaults to the **Web URL** value if not set. Leave blank if using **Jira on Atlassian cloud**.
+ - **Username or Email**: Created when you [configured Jira](dvcs.md#configure-jira-for-dvcs).
+ For **Jira Server**, use `username`. For **Jira on Atlassian cloud**, use `email`.
+ - **Password/API token**: Created when you [configured Jira](dvcs.md#configure-jira-for-dvcs).
+ Use `password` for **Jira Server** or `API token` for **Jira on Atlassian cloud**.
1. To enable users to view Jira issues inside the GitLab project, select **Enable Jira issues** and
enter a Jira project key. **(PREMIUM)**
- You can only display issues from a single Jira project within a given GitLab project.
+ You can display issues only from a single Jira project in a given GitLab project.
WARNING:
- If you enable Jira issues with the setting above, all users that have access to this GitLab project
- are able to view all issues from the specified Jira project.
-
-1. To enable creation of issues for vulnerabilities, select **Enable Jira issues creation from vulnerabilities**.
-
- 1. Select the **Jira issue type**. If the dropdown is empty, select refresh (**{retry}**) and try again.
+ If you enable Jira issues with this setting, all users with access to this GitLab project
+ can view all issues from the specified Jira project.
+1. To enable issue creation for vulnerabilities, select **Enable Jira issues creation from vulnerabilities**.
+1. Select the **Jira issue type**. If the dropdown is empty, select refresh (**{retry}**) and try again.
1. To verify the Jira connection is working, select **Test settings**.
-
1. Select **Save changes**.
Your GitLab project can now interact with all Jira projects in your instance and the project now
displays a Jira link that opens the Jira project.
-## Usage
-
-After the integration is set up on GitLab and Jira, you can:
-
-- Refer to any Jira issue by its ID in GitLab branch names, commit messages, and merge request
- titles.
-- See the linked branches, commits, and merge requests in Jira issues (merge requests are
- called "pull requests" in Jira issues).
-
-Jira issue IDs must be formatted in uppercase for the integration to work.
-
-![Branch, Commit and Pull Requests links on Jira issue](img/jira_dev_panel_jira_setup_3.png)
+## Limitations
-Click the links to see your GitLab repository data.
+This integration is not supported on GitLab instances under a
+[relative URL](https://docs.gitlab.com/omnibus/settings/configuration.html#configuring-a-relative-url-for-gitlab).
+For example, `http://example.com/gitlab`.
-![GitLab commits details on a Jira issue](img/jira_dev_panel_jira_setup_4.png)
+## Related topics
-![GitLab merge requests details on a Jira issue](img/jira_dev_panel_jira_setup_5.png)
+- [Using Smart Commits](https://confluence.atlassian.com/fisheye/using-smart-commits-960155400.html) in Jira
-For more information on using Jira Smart Commits to track time against an issue, specify an issue transition, or add a custom comment, see the Atlassian page [Using Smart Commits](https://confluence.atlassian.com/fisheye/using-smart-commits-960155400.html).
+## Troubleshooting
-## Limitations
+### Cookies for Oracle's Access Manager
-This integration is not supported on GitLab instances under a
-[relative URL](https://docs.gitlab.com/omnibus/settings/configuration.html#configuring-a-relative-url-for-gitlab).
-For example, `http://example.com/gitlab`.
+To support Oracle's Access Manager, GitLab sends additional cookies
+to enable Basic Auth. The cookie being added to each request is `OBBasicAuth` with
+a value of `fromDialog`.
diff --git a/doc/integration/jira/dvcs.md b/doc/integration/jira/dvcs.md
index 3099c02ff36..9c6a5dc4386 100644
--- a/doc/integration/jira/dvcs.md
+++ b/doc/integration/jira/dvcs.md
@@ -99,7 +99,7 @@ it completes, refreshes every 60 minutes:
To connect additional GitLab projects from other GitLab top-level groups, or
personal namespaces, repeat the previous steps with additional Jira DVCS accounts.
-After you configure the integration, read more about [how to test and use it](development_panel.md#usage).
+After you configure the integration, read more about [how to test and use it](development_panel.md).
## Refresh data imported to Jira
diff --git a/doc/integration/jira/img/jira_dev_panel_jira_setup_5.png b/doc/integration/jira/img/jira_dev_panel_jira_setup_5.png
index 73dc867d301..b143fc24355 100644
--- a/doc/integration/jira/img/jira_dev_panel_jira_setup_5.png
+++ b/doc/integration/jira/img/jira_dev_panel_jira_setup_5.png
Binary files differ
diff --git a/doc/integration/jira/issues.md b/doc/integration/jira/issues.md
index 1f2ab3d79dc..4fd59c3608e 100644
--- a/doc/integration/jira/issues.md
+++ b/doc/integration/jira/issues.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Jira integration issue management **(FREE)**
-Integrating issue management with Jira requires you to [configure Jira](development_panel.md#configuration)
+Integrating issue management with Jira requires you to [configure Jira](development_panel.md#configure-the-integration)
and [enable the Jira service](development_panel.md#configure-gitlab) in GitLab.
After you configure and enable the integration, you can reference and close Jira
issues by mentioning the Jira ID in GitLab commits and merge requests.
diff --git a/doc/operations/incident_management/incidents.md b/doc/operations/incident_management/incidents.md
index 078a1a0be08..d09dbd2cb04 100644
--- a/doc/operations/incident_management/incidents.md
+++ b/doc/operations/incident_management/incidents.md
@@ -267,3 +267,19 @@ any other Markdown text field in GitLab by
You can embed both [GitLab-hosted metrics](../metrics/embed.md) and
[Grafana metrics](../metrics/embed_grafana.md) in incidents and issue
templates.
+
+### Automatically close incidents via recovery alerts
+
+> - [Introduced for Prometheus Integrations](https://gitlab.com/gitlab-org/gitlab/-/issues/13401) in GitLab 12.5.
+> - [Introduced for HTTP Integrations](https://gitlab.com/gitlab-org/gitlab/-/issues/13402) in GitLab 13.4.
+
+With Maintainer or higher [permissions](../../user/permissions.md), you can enable
+ GitLab to close an incident automatically when a **Recovery Alert** is received:
+
+1. Navigate to **Settings > Operations > Incidents** and expand **Incidents**.
+1. Check the **Automatically close associated Incident** checkbox.
+1. Click **Save changes**.
+
+When GitLab receives a **Recovery Alert**, it closes the associated incident.
+This action is recorded as a system message on the incident indicating that it
+was closed automatically by the GitLab Alert bot.
diff --git a/doc/operations/incident_management/integrations.md b/doc/operations/incident_management/integrations.md
index acfab79c0c3..07ffb92a000 100644
--- a/doc/operations/incident_management/integrations.md
+++ b/doc/operations/incident_management/integrations.md
@@ -97,17 +97,17 @@ to configure alerts for this integration.
## Customize the alert payload outside of GitLab
-For all integration types, you can customize the payload by sending the following
+For HTTP Endpoints without [custom mappings](#map-fields-in-custom-alerts), you can customize the payload by sending the following
parameters. All fields are optional. If the incoming alert does not contain a value for the `Title` field, a default value of `New: Alert` will be applied.
| Property | Type | Description |
| ------------------------- | --------------- | ----------- |
-| `title` | String | The title of the incident. |
+| `title` | String | The title of the alert.|
| `description` | String | A high-level summary of the problem. |
-| `start_time` | DateTime | The time of the incident. If none is provided, a timestamp of the issue is used. |
-| `end_time` | DateTime | For existing alerts only. When provided, the alert is resolved and the associated incident is closed. |
+| `start_time` | DateTime | The time of the alert. If none is provided, a current time is used. |
+| `end_time` | DateTime | The resolution time of the alert. If provided, the alert is resolved. |
| `service` | String | The affected service. |
-| `monitoring_tool` | String | The name of the associated monitoring tool. |
+| `monitoring_tool` | String | The name of the associated monitoring tool. |
| `hosts` | String or Array | One or more hosts, as to where this incident occurred. |
| `severity` | String | The severity of the alert. Case-insensitive. Can be one of: `critical`, `high`, `medium`, `low`, `info`, `unknown`. Defaults to `critical` if missing or value is not in this list. |
| `fingerprint` | String or Array | The unique identifier of the alert. This can be used to group occurrences of the same alert. |
@@ -189,6 +189,17 @@ If the existing alert is already `resolved`, GitLab creates a new alert instead.
![Alert Management List](img/alert_list_v13_1.png)
+## Recovery alerts
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13402) in GitLab 13.4.
+
+The alert in GitLab will be automatically resolved when an HTTP Endpoint
+receives a payload with the end time of the alert set. For HTTP Endpoints
+without [custom mappings](#map-fields-in-custom-alerts), the expected
+field is `end_time`. With custom mappings, you can select the expected field.
+
+You can also configure the associated [incident to be closed automatically](../incident_management/incidents.md#automatically-close-incidents-via-recovery-alerts) when the alert resolves.
+
## Link to your Opsgenie Alerts
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3066) in GitLab Premium 13.2.
diff --git a/doc/operations/metrics/alerts.md b/doc/operations/metrics/alerts.md
index ff62152363b..09cfea06198 100644
--- a/doc/operations/metrics/alerts.md
+++ b/doc/operations/metrics/alerts.md
@@ -96,7 +96,6 @@ Prometheus server to use the
## Trigger actions from alerts **(ULTIMATE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4925) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.11.
-> - [From GitLab Ultimate 12.5](https://gitlab.com/gitlab-org/gitlab/-/issues/13401), when GitLab receives a recovery alert, it automatically closes the associated issue.
Alerts can be used to trigger actions, like opening an issue automatically
(disabled by default since `13.1`). To configure the actions:
@@ -127,10 +126,6 @@ values extracted from the [`alerts` field in webhook payload](https://prometheus
- **Low**: `low`, `s4`, `p4`, `warn`, `warning`
- **Info**: `info`, `s5`, `p5`, `debug`, `information`, `notice`
-When GitLab receives a **Recovery Alert**, it closes the associated issue.
-This action is recorded as a system message on the issue indicating that it
-was closed automatically by the GitLab Alert bot.
-
To further customize the issue, you can add labels, mentions, or any other supported
[quick action](../../user/project/quick_actions.md) in the selected issue template,
which applies to all incidents. To limit quick actions or other information to
@@ -143,3 +138,12 @@ does not yet exist, it is also created automatically.
If the metric exceeds the threshold of the alert for over 5 minutes, GitLab sends
an email to all [Maintainers and Owners](../../user/permissions.md#project-members-permissions)
of the project.
+
+### Recovery alerts
+
+> - [From GitLab Ultimate 12.5](https://gitlab.com/gitlab-org/gitlab/-/issues/13401), when GitLab receives a recovery alert, it automatically closes the associated issue.
+
+The alert in GitLab will be automatically resolved when Prometheus
+sends a payload with the field `status` set to `resolved`.
+
+You can also configure the associated [incident to be closed automatically](../incident_management/incidents.md#automatically-close-incidents-via-recovery-alerts) when the alert resolves.
diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md
index ca7eb5a11d1..a816fb4b009 100644
--- a/doc/user/project/settings/index.md
+++ b/doc/user/project/settings/index.md
@@ -356,6 +356,24 @@ to remove a fork relationship.
## Operations settings
+### Alerts
+
+Configure [alert integrations](../../../operations/incident_management/integrations.md#configuration) to triage and manage critical problems in your application as [alerts](../../../operations/incident_management/alerts.md).
+
+### Incidents
+
+#### Alert integration
+
+Automatically [create](../../../operations/incident_management/incidents.md#create-incidents-automatically), [notify on](../../../operations/incident_management/paging.md#email-notifications), and [resolve](../../../operations/incident_management/incidents.md#automatically-close-incidents-via-recovery-alerts) incidents based on GitLab alerts.
+
+#### PagerDuty integration
+
+[Create incidents in GitLab for each PagerDuty incident](../../../operations/incident_management/incidents.md#create-incidents-via-the-pagerduty-webhook).
+
+#### Incident settings
+
+[Manage Service Level Agreements for incidents](../../../operations/incident_management/incidents.md#service-level-agreement-countdown-timer) with an SLA countdown timer.
+
### Error Tracking
Configure Error Tracking to discover and view [Sentry errors within GitLab](../../../operations/error_tracking.md).
diff --git a/lib/api/ci/runner.rb b/lib/api/ci/runner.rb
index c5249f1377b..33980b38e2b 100644
--- a/lib/api/ci/runner.rb
+++ b/lib/api/ci/runner.rb
@@ -184,6 +184,8 @@ module API
.new(job, declared_params(include_missing: false))
service.execute.then do |result|
+ track_ci_minutes_usage!(job, current_runner)
+
header 'X-GitLab-Trace-Update-Interval', result.backoff
status result.status
body result.status.to_s
@@ -214,6 +216,8 @@ module API
break error!('416 Range Not Satisfiable', 416, { 'Range' => "0-#{result.stream_size}" })
end
+ track_ci_minutes_usage!(job, current_runner)
+
status result.status
header 'Job-Status', job.status
header 'Range', "0-#{result.stream_size}"
diff --git a/lib/api/entities/issue_basic.rb b/lib/api/entities/issue_basic.rb
index a9ec2632ed4..754f8e2b6e4 100644
--- a/lib/api/entities/issue_basic.rb
+++ b/lib/api/entities/issue_basic.rb
@@ -36,6 +36,7 @@ module API
expose :due_date
expose :confidential
expose :discussion_locked
+ expose :issue_type
expose :web_url do |issue|
Gitlab::UrlBuilder.build(issue)
diff --git a/lib/api/helpers/issues_helpers.rb b/lib/api/helpers/issues_helpers.rb
index 2b1ed479692..452396689f8 100644
--- a/lib/api/helpers/issues_helpers.rb
+++ b/lib/api/helpers/issues_helpers.rb
@@ -28,7 +28,8 @@ module API
:remove_labels,
:milestone_id,
:state_event,
- :title
+ :title,
+ :issue_type
]
end
@@ -47,6 +48,7 @@ module API
args[:not][:label_name] ||= args[:not]&.delete(:labels)
args[:scope] = args[:scope].underscore if args[:scope]
args[:sort] = "#{args[:order_by]}_#{args[:sort]}"
+ args[:issue_types] ||= args.delete(:issue_type)
IssuesFinder.new(current_user, args)
end
diff --git a/lib/api/helpers/runner.rb b/lib/api/helpers/runner.rb
index 688cd2da994..a74fd7de2d8 100644
--- a/lib/api/helpers/runner.rb
+++ b/lib/api/helpers/runner.rb
@@ -87,6 +87,10 @@ module API
project: -> { current_job.project }
)
end
+
+ def track_ci_minutes_usage!(_build, _runner)
+ # noop: overridden in EE
+ end
end
end
end
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index c844655f0b3..23366505c4a 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -74,6 +74,7 @@ module API
desc: 'Return issues sorted in `asc` or `desc` order.'
optional :due_date, type: String, values: %w[0 overdue week month next_month_and_previous_two_weeks] << '',
desc: 'Return issues that have no due date (`0`), or whose due date is this week, this month, between two weeks ago and next month, or which are overdue. Accepts: `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`, `0`'
+ optional :issue_type, type: String, values: Issue.issue_types.keys, desc: "The type of the issue. Accepts: #{Issue.issue_types.keys.join(', ')}"
use :issues_stats_params
use :pagination
@@ -90,6 +91,7 @@ module API
optional :due_date, type: String, desc: 'Date string in the format YEAR-MONTH-DAY'
optional :confidential, type: Boolean, desc: 'Boolean parameter if the issue should be confidential'
optional :discussion_locked, type: Boolean, desc: " Boolean parameter indicating if the issue's discussion is locked"
+ optional :issue_type, type: String, values: Issue.issue_types.keys, desc: "The type of the issue. Accepts: #{Issue.issue_types.keys.join(', ')}"
use :optional_issue_params_ee
end
diff --git a/lib/gitlab/ci/pipeline/metrics.rb b/lib/gitlab/ci/pipeline/metrics.rb
index 35e88ded416..5ac69a21530 100644
--- a/lib/gitlab/ci/pipeline/metrics.rb
+++ b/lib/gitlab/ci/pipeline/metrics.rb
@@ -63,6 +63,13 @@ module Gitlab
Gitlab::Metrics.counter(name, comment)
end
+
+ def ci_minutes_exceeded_builds_counter
+ name = :ci_minutes_exceeded_builds_counter
+ comment = 'Count of builds dropped due to CI minutes exceeded'
+
+ Gitlab::Metrics.counter(name, comment)
+ end
end
end
end
diff --git a/lib/gitlab/ci/queue/metrics.rb b/lib/gitlab/ci/queue/metrics.rb
index 7ecb9a1db16..46e4373ec85 100644
--- a/lib/gitlab/ci/queue/metrics.rb
+++ b/lib/gitlab/ci/queue/metrics.rb
@@ -10,7 +10,7 @@ module Gitlab
QUEUE_ACTIVE_RUNNERS_BUCKETS = [1, 3, 10, 30, 60, 300, 900, 1800, 3600].freeze
QUEUE_DEPTH_TOTAL_BUCKETS = [1, 2, 3, 5, 8, 16, 32, 50, 100, 250, 500, 1000, 2000, 5000].freeze
QUEUE_SIZE_TOTAL_BUCKETS = [1, 5, 10, 50, 100, 500, 1000, 2000, 5000, 7500, 10000, 15000, 20000].freeze
- QUEUE_PROCESSING_DURATION_SECONDS_BUCKETS = [0.01, 0.05, 0.1, 0.3, 0.5, 1, 5, 10, 30, 60, 180, 300].freeze
+ QUEUE_PROCESSING_DURATION_SECONDS_BUCKETS = [0.01, 0.05, 0.1, 0.3, 0.5, 1, 5, 10, 15, 20, 30, 60].freeze
METRICS_SHARD_TAG_PREFIX = 'metrics_shard::'
DEFAULT_METRICS_SHARD = 'default'
diff --git a/lib/gitlab/ci/status/build/failed.rb b/lib/gitlab/ci/status/build/failed.rb
index 787dee3b267..4a9b9dbc52a 100644
--- a/lib/gitlab/ci/status/build/failed.rb
+++ b/lib/gitlab/ci/status/build/failed.rb
@@ -28,7 +28,8 @@ module Gitlab
secrets_provider_not_found: 'secrets provider can not be found',
reached_max_descendant_pipelines_depth: 'reached maximum depth of child pipelines',
project_deleted: 'pipeline project was deleted',
- user_blocked: 'pipeline user was blocked'
+ user_blocked: 'pipeline user was blocked',
+ ci_quota_exceeded: 'no more CI minutes available'
}.freeze
private_constant :REASONS
diff --git a/lib/gitlab/ci/templates/Security/Secure-Binaries.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/Secure-Binaries.gitlab-ci.yml
index 232c320562b..fddfc0deb28 100644
--- a/lib/gitlab/ci/templates/Security/Secure-Binaries.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/Secure-Binaries.gitlab-ci.yml
@@ -17,7 +17,7 @@ variables:
bundler-audit, retire.js, gemnasium, gemnasium-maven, gemnasium-python,
klar, clair-vulnerabilities-db,
license-finder,
- dast
+ dast, api-fuzzing
SECURE_BINARIES_DOWNLOAD_IMAGES: "true"
SECURE_BINARIES_PUSH_IMAGES: "true"
@@ -241,3 +241,12 @@ dast:
variables:
- $SECURE_BINARIES_DOWNLOAD_IMAGES == "true" &&
$SECURE_BINARIES_ANALYZERS =~ /\bdast\b/
+
+api-fuzzing:
+ extends: .download_images
+ variables:
+ SECURE_BINARIES_ANALYZER_VERSION: "1"
+ only:
+ variables:
+ - $SECURE_BINARIES_DOWNLOAD_IMAGES == "true" &&
+ $SECURE_BINARIES_ANALYZERS =~ /\bapi-fuzzing\b/
diff --git a/lib/gitlab/highlight.rb b/lib/gitlab/highlight.rb
index 45bc21b9a42..06558e1a212 100644
--- a/lib/gitlab/highlight.rb
+++ b/lib/gitlab/highlight.rb
@@ -4,7 +4,6 @@ module Gitlab
class Highlight
TIMEOUT_BACKGROUND = 30.seconds
TIMEOUT_FOREGROUND = 1.5.seconds
- MAXIMUM_TEXT_HIGHLIGHT_SIZE = 512.kilobytes
def self.highlight(blob_name, blob_content, language: nil, plain: false)
new(blob_name, blob_content, language: language)
@@ -23,7 +22,7 @@ module Gitlab
def highlight(text, continue: false, plain: false, context: {})
@context = context
- plain ||= text.length > MAXIMUM_TEXT_HIGHLIGHT_SIZE
+ plain ||= text.length > maximum_text_highlight_size
highlighted_text = highlight_text(text, continue: continue, plain: plain)
highlighted_text = link_dependencies(text, highlighted_text) if blob_name
@@ -78,5 +77,9 @@ module Gitlab
def link_dependencies(text, highlighted_text)
Gitlab::DependencyLinker.link(blob_name, text, highlighted_text)
end
+
+ def maximum_text_highlight_size
+ Gitlab.config.extra['maximum_text_highlight_size_kilobytes']
+ end
end
end
diff --git a/lib/gitlab/static_site_editor/config/generated_config.rb b/lib/gitlab/static_site_editor/config/generated_config.rb
index 0a2cee75af7..1555c3469a5 100644
--- a/lib/gitlab/static_site_editor/config/generated_config.rb
+++ b/lib/gitlab/static_site_editor/config/generated_config.rb
@@ -42,11 +42,11 @@ module Gitlab
end
def supported_content?
- master_branch? && extension_supported? && file_exists?
+ branch_supported? && extension_supported? && file_exists?
end
- def master_branch?
- ref == 'master'
+ def branch_supported?
+ ref.in?(%w[master main])
end
def extension_supported?
diff --git a/lib/sidebars/projects/menus/infrastructure_menu.rb b/lib/sidebars/projects/menus/infrastructure_menu.rb
new file mode 100644
index 00000000000..eccf264873e
--- /dev/null
+++ b/lib/sidebars/projects/menus/infrastructure_menu.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Projects
+ module Menus
+ class InfrastructureMenu < ::Sidebars::Menu
+ override :configure_menu_items
+ def configure_menu_items
+ return false if Feature.disabled?(:sidebar_refactor, context.current_user)
+ return false unless context.project.feature_available?(:operations, context.current_user)
+
+ add_item(kubernetes_menu_item)
+ add_item(serverless_menu_item)
+ add_item(terraform_menu_item)
+
+ true
+ end
+
+ override :link
+ def link
+ project_clusters_path(context.project)
+ end
+
+ override :extra_container_html_options
+ def extra_container_html_options
+ {
+ class: 'shortcuts-infrastructure'
+ }
+ end
+
+ override :title
+ def title
+ _('Infrastructure')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'cloud-gear'
+ end
+
+ private
+
+ def kubernetes_menu_item
+ return unless can?(context.current_user, :read_cluster, context.project)
+
+ ::Sidebars::MenuItem.new(
+ title: _('Kubernetes clusters'),
+ link: project_clusters_path(context.project),
+ active_routes: { controller: [:cluster_agents, :clusters] },
+ container_html_options: { class: 'shortcuts-kubernetes' },
+ hint_html_options: kubernetes_hint_html_options,
+ item_id: :kubernetes
+ )
+ end
+
+ def kubernetes_hint_html_options
+ return {} unless context.show_cluster_hint
+
+ { disabled: true,
+ data: { trigger: 'manual',
+ container: 'body',
+ placement: 'right',
+ highlight: UserCalloutsHelper::GKE_CLUSTER_INTEGRATION,
+ highlight_priority: UserCallout.feature_names[:GKE_CLUSTER_INTEGRATION],
+ dismiss_endpoint: user_callouts_path,
+ auto_devops_help_path: help_page_path('topics/autodevops/index.md') } }
+ end
+
+ def serverless_menu_item
+ return unless can?(context.current_user, :read_cluster, context.project)
+
+ ::Sidebars::MenuItem.new(
+ title: _('Serverless platform'),
+ link: project_serverless_functions_path(context.project),
+ active_routes: { controller: :functions },
+ item_id: :serverless
+ )
+ end
+
+ def terraform_menu_item
+ return unless can?(context.current_user, :read_terraform_state, context.project)
+
+ ::Sidebars::MenuItem.new(
+ title: _('Terraform'),
+ link: project_terraform_index_path(context.project),
+ active_routes: { controller: :terraform },
+ item_id: :terraform
+ )
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/projects/menus/operations_menu.rb b/lib/sidebars/projects/menus/operations_menu.rb
index adfb5fd2016..7678dedde24 100644
--- a/lib/sidebars/projects/menus/operations_menu.rb
+++ b/lib/sidebars/projects/menus/operations_menu.rb
@@ -47,7 +47,7 @@ module Sidebars
override :sprite_icon
def sprite_icon
- 'cloud-gear'
+ Feature.enabled?(:sidebar_refactor, context.current_user) ? 'monitor' : 'cloud-gear'
end
override :active_routes
@@ -127,6 +127,7 @@ module Sidebars
end
def serverless_menu_item
+ return if Feature.enabled?(:sidebar_refactor, context.current_user)
return unless can?(context.current_user, :read_cluster, context.project)
::Sidebars::MenuItem.new(
@@ -138,6 +139,7 @@ module Sidebars
end
def terraform_menu_item
+ return if Feature.enabled?(:sidebar_refactor, context.current_user)
return unless can?(context.current_user, :read_terraform_state, context.project)
::Sidebars::MenuItem.new(
@@ -149,6 +151,7 @@ module Sidebars
end
def kubernetes_menu_item
+ return if Feature.enabled?(:sidebar_refactor, context.current_user)
return unless can?(context.current_user, :read_cluster, context.project)
::Sidebars::MenuItem.new(
diff --git a/lib/sidebars/projects/panel.rb b/lib/sidebars/projects/panel.rb
index 8d81c197f71..f8320fe1acf 100644
--- a/lib/sidebars/projects/panel.rb
+++ b/lib/sidebars/projects/panel.rb
@@ -17,6 +17,7 @@ module Sidebars
add_menu(Sidebars::Projects::Menus::CiCdMenu.new(context))
add_menu(Sidebars::Projects::Menus::SecurityComplianceMenu.new(context))
add_menu(Sidebars::Projects::Menus::OperationsMenu.new(context))
+ add_menu(Sidebars::Projects::Menus::InfrastructureMenu.new(context))
add_menu(Sidebars::Projects::Menus::PackagesRegistriesMenu.new(context))
add_menu(Sidebars::Projects::Menus::AnalyticsMenu.new(context))
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 2097a1b5661..7ce3232567a 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -5597,6 +5597,9 @@ msgid_plural "CICDAnalytics|Releases"
msgstr[0] ""
msgstr[1] ""
+msgid "CICDAnalytics|Release statistics"
+msgstr ""
+
msgid "CICDAnalytics|Releases"
msgstr ""
@@ -17338,6 +17341,9 @@ msgstr ""
msgid "Information about additional Pages templates and how to install them can be found in our %{pages_getting_started_guide}."
msgstr ""
+msgid "Infrastructure"
+msgstr ""
+
msgid "Infrastructure Registry"
msgstr ""
@@ -18789,6 +18795,9 @@ msgstr ""
msgid "Kubernetes cluster was successfully updated."
msgstr ""
+msgid "Kubernetes clusters"
+msgstr ""
+
msgid "Kubernetes deployment not found"
msgstr ""
@@ -29116,6 +29125,9 @@ msgstr ""
msgid "Serverless domain"
msgstr ""
+msgid "Serverless platform"
+msgstr ""
+
msgid "ServerlessDetails|Function invocation metrics require Prometheus to be installed first."
msgstr ""
diff --git a/package.json b/package.json
index 47ca621611a..c677eb4ee26 100644
--- a/package.json
+++ b/package.json
@@ -101,7 +101,7 @@
"codesandbox-api": "0.0.23",
"compression-webpack-plugin": "^5.0.2",
"copy-webpack-plugin": "^6.4.1",
- "core-js": "^3.11.2",
+ "core-js": "^3.11.3",
"cron-validator": "^1.1.1",
"cropper": "^2.3.0",
"css-loader": "^2.1.1",
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
index b2b37fcd424..8c0b3da6004 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
@@ -9,7 +9,7 @@ module QA
Flow::Login.sign_in
end
- it 'creates an issue', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1167' do
+ it 'creates an issue', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1793' do
issue = Resource::Issue.fabricate_via_browser_ui!
Page::Project::Menu.perform(&:click_issues)
@@ -19,7 +19,7 @@ module QA
end
end
- it 'closes an issue', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1085' do
+ it 'closes an issue', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1792' do
closed_issue.visit!
Page::Project::Issue::Show.perform do |issue_page|
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb
index b67e0e54aa0..9d90ff189c6 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb
@@ -71,7 +71,7 @@ module QA
snippet.remove_via_api!
end
- it 'clones, pushes, and pulls a project snippet over SSH, deletes via UI', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/832' do
+ it 'clones, pushes, and pulls a project snippet over SSH, deletes via UI', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1794' do
Resource::Repository::Push.fabricate! do |push|
push.repository_ssh_uri = repository_uri_ssh
push.ssh_key = ssh_key
diff --git a/spec/controllers/registrations/welcome_controller_spec.rb b/spec/controllers/registrations/welcome_controller_spec.rb
index 008259a8bfa..6d34b56df09 100644
--- a/spec/controllers/registrations/welcome_controller_spec.rb
+++ b/spec/controllers/registrations/welcome_controller_spec.rb
@@ -77,6 +77,30 @@ RSpec.describe Registrations::WelcomeController do
it { is_expected.to redirect_to(dashboard_projects_path)}
+ context 'when the new user already has any accepted group membership' do
+ let!(:member1) { create(:group_member, user: user) }
+
+ it 'redirects to the group activity page' do
+ expect(subject).to redirect_to(activity_group_path(member1.source))
+ end
+
+ context 'when the new user already has more than 1 accepted group membership' do
+ it 'redirects to the most recent membership group activty page' do
+ member2 = create(:group_member, user: user)
+
+ expect(subject).to redirect_to(activity_group_path(member2.source))
+ end
+ end
+
+ context 'when the member has an orphaned source at the time of the welcome' do
+ it 'redirects to the project dashboard page' do
+ member1.source.delete
+
+ expect(subject).to redirect_to(dashboard_projects_path)
+ end
+ end
+ end
+
context 'when the user opted in' do
let(:email_opted_in) { '1' }
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index 4f17260f87d..0a7113a5559 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -251,41 +251,62 @@ RSpec.describe 'Admin updates settings' do
end
end
- context 'when the Slack Notifications Service template is active' do
+ context 'when Service Templates are enabled' do
before do
- create(:service, :template, type: 'SlackService', active: true)
-
+ stub_feature_flags(disable_service_templates: false)
visit general_admin_application_settings_path
end
- it 'change Slack Notifications Service template settings', :js do
- first(:link, 'Service Templates').click
- click_link 'Slack notifications'
- fill_in 'Webhook', with: 'http://localhost'
- fill_in 'Username', with: 'test_user'
- fill_in 'service[push_channel]', with: '#test_channel'
- page.check('Notify only broken pipelines')
- page.select 'All branches', from: 'Branches to be notified'
- page.select 'Match any of the labels', from: 'Labels to be notified behavior'
+ it 'shows Service Templates link' do
+ expect(page).to have_link('Service Templates')
+ end
- check_all_events
- click_button 'Save changes'
+ context 'when the Slack Notifications Service template is active' do
+ before do
+ create(:service, :template, type: 'SlackService', active: true)
- expect(page).to have_content 'Application settings saved successfully'
+ visit general_admin_application_settings_path
+ end
- click_link 'Slack notifications'
+ it 'change Slack Notifications Service template settings', :js do
+ first(:link, 'Service Templates').click
+ click_link 'Slack notifications'
+ fill_in 'Webhook', with: 'http://localhost'
+ fill_in 'Username', with: 'test_user'
+ fill_in 'service[push_channel]', with: '#test_channel'
+ page.check('Notify only broken pipelines')
+ page.select 'All branches', from: 'Branches to be notified'
+ page.select 'Match any of the labels', from: 'Labels to be notified behavior'
+
+ check_all_events
+ click_button 'Save changes'
+
+ expect(page).to have_content 'Application settings saved successfully'
- expect(page.all('input[type=checkbox]')).to all(be_checked)
- expect(find_field('Webhook').value).to eq 'http://localhost'
- expect(find_field('Username').value).to eq 'test_user'
- expect(find('[name="service[push_channel]"]').value).to eq '#test_channel'
+ click_link 'Slack notifications'
+
+ expect(page.all('input[type=checkbox]')).to all(be_checked)
+ expect(find_field('Webhook').value).to eq 'http://localhost'
+ expect(find_field('Username').value).to eq 'test_user'
+ expect(find('[name="service[push_channel]"]').value).to eq '#test_channel'
+ end
+
+ it 'defaults Deployment events to false for chat notification template settings', :js do
+ first(:link, 'Service Templates').click
+ click_link 'Slack notifications'
+
+ expect(find_field('Deployment')).not_to be_checked
+ end
end
+ end
- it 'defaults Deployment events to false for chat notification template settings', :js do
- first(:link, 'Service Templates').click
- click_link 'Slack notifications'
+ context 'When Service templates are disabled' do
+ before do
+ stub_feature_flags(disable_service_templates: true)
+ end
- expect(find_field('Deployment')).not_to be_checked
+ it 'does not show Service Templates link' do
+ expect(page).not_to have_link('Service Templates')
end
end
diff --git a/spec/features/projects/navbar_spec.rb b/spec/features/projects/navbar_spec.rb
index 5ab75a6b914..d01e4aa85ab 100644
--- a/spec/features/projects/navbar_spec.rb
+++ b/spec/features/projects/navbar_spec.rb
@@ -72,6 +72,20 @@ RSpec.describe 'Project navbar' do
end
context 'when sidebar refactor feature flag is on' do
+ let(:operations_menu_items) do
+ [
+ _('Metrics'),
+ _('Logs'),
+ _('Tracing'),
+ _('Error Tracking'),
+ _('Alerts'),
+ _('Incidents'),
+ _('Environments'),
+ _('Feature Flags'),
+ _('Product Analytics')
+ ]
+ end
+
before do
stub_feature_flags(sidebar_refactor: true)
stub_config(registry: { enabled: true })
@@ -84,6 +98,18 @@ RSpec.describe 'Project navbar' do
new_sub_nav_item_name: _('Packages & Registries')
)
+ insert_after_nav_item(
+ _('Operations'),
+ new_nav_item: {
+ nav_item: _('Infrastructure'),
+ nav_sub_items: [
+ _('Kubernetes clusters'),
+ _('Serverless platform'),
+ _('Terraform')
+ ]
+ }
+ )
+
visit project_path(project)
end
diff --git a/spec/features/projects/user_uses_shortcuts_spec.rb b/spec/features/projects/user_uses_shortcuts_spec.rb
index b6fde19e0d4..b73a1f6b9fa 100644
--- a/spec/features/projects/user_uses_shortcuts_spec.rb
+++ b/spec/features/projects/user_uses_shortcuts_spec.rb
@@ -182,11 +182,25 @@ RSpec.describe 'User uses shortcuts', :js do
expect(page).to have_active_sub_navigation('Environments')
end
+ context 'when feature flag :sidebar_refactor is disabled' do
+ it 'redirects to the Kubernetes page with active Operations' do
+ stub_feature_flags(sidebar_refactor: false)
+
+ find('body').native.send_key('g')
+ find('body').native.send_key('k')
+
+ expect(page).to have_active_navigation('Operations')
+ expect(page).to have_active_sub_navigation('Kubernetes')
+ end
+ end
+ end
+
+ context 'when navigating to the Infrastructure pages' do
it 'redirects to the Kubernetes page' do
find('body').native.send_key('g')
find('body').native.send_key('k')
- expect(page).to have_active_navigation('Operations')
+ expect(page).to have_active_navigation('Infrastructure')
expect(page).to have_active_sub_navigation('Kubernetes')
end
end
diff --git a/spec/frontend/issuable/components/csv_export_modal_spec.js b/spec/frontend/issuable/components/csv_export_modal_spec.js
index a327da2d63a..7eb85a946ae 100644
--- a/spec/frontend/issuable/components/csv_export_modal_spec.js
+++ b/spec/frontend/issuable/components/csv_export_modal_spec.js
@@ -13,6 +13,8 @@ describe('CsvExportModal', () => {
mount(CsvExportModal, {
propsData: {
modalId: 'csv-export-modal',
+ exportCsvPath: 'export/csv/path',
+ issuableCount: 1,
...props,
},
provide: {
diff --git a/spec/frontend/jobs/mock_data.js b/spec/frontend/jobs/mock_data.js
index 48d575ac0f6..85bdd87abc6 100644
--- a/spec/frontend/jobs/mock_data.js
+++ b/spec/frontend/jobs/mock_data.js
@@ -1464,8 +1464,8 @@ export const mockJobsQueryResponse = {
__typename: 'DetailedStatus',
},
id: 'gid://gitlab/Ci::Build/2336',
- refName: 'master',
- refPath: '/root/ci-project/-/commits/master',
+ refName: 'main',
+ refPath: '/root/ci-project/-/commits/main',
tags: [],
shortSha: '4408fa2a',
commitPath: '/root/ci-project/-/commit/4408fa2a27aaadfdf42d8dda3d6a9c01ce6cad78',
diff --git a/spec/frontend/pipeline_new/mock_data.js b/spec/frontend/pipeline_new/mock_data.js
index 3f49ffe9664..3174b73098a 100644
--- a/spec/frontend/pipeline_new/mock_data.js
+++ b/spec/frontend/pipeline_new/mock_data.js
@@ -46,16 +46,16 @@ export const mockTagRefs = ['1.0.0', '1.1.0', '1.2.0'];
export const mockVariables = [
{
- uniqueId: 'var-refs/heads/master2',
+ uniqueId: 'var-refs/heads/main2',
variable_type: 'env_var',
key: 'var_without_value',
value: '',
},
{
- uniqueId: 'var-refs/heads/master3',
+ uniqueId: 'var-refs/heads/main3',
variable_type: 'env_var',
key: 'var_with_value',
value: 'test_value',
},
- { uniqueId: 'var-refs/heads/master4', variable_type: 'env_var', key: '', value: '' },
+ { uniqueId: 'var-refs/heads/main4', variable_type: 'env_var', key: '', value: '' },
];
diff --git a/spec/frontend/projects/compare/components/app_legacy_spec.js b/spec/frontend/projects/compare/components/app_legacy_spec.js
index 93e96c8b9f7..6fdf4014575 100644
--- a/spec/frontend/projects/compare/components/app_legacy_spec.js
+++ b/spec/frontend/projects/compare/components/app_legacy_spec.js
@@ -7,7 +7,7 @@ jest.mock('~/lib/utils/csrf', () => ({ token: 'mock-csrf-token' }));
const projectCompareIndexPath = 'some/path';
const refsProjectPath = 'some/refs/path';
-const paramsFrom = 'master';
+const paramsFrom = 'main';
const paramsTo = 'some-other-branch';
describe('CompareApp component', () => {
diff --git a/spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js b/spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js
index ca208395e82..38e13dc5462 100644
--- a/spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js
+++ b/spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js
@@ -9,7 +9,7 @@ const defaultProps = {
refsProjectPath: 'some/refs/path',
revisionText: 'Target',
paramsName: 'from',
- paramsBranch: 'master',
+ paramsBranch: 'main',
};
jest.mock('~/flash');
diff --git a/spec/lib/gitlab/highlight_spec.rb b/spec/lib/gitlab/highlight_spec.rb
index 1a929373716..5dcee1ff724 100644
--- a/spec/lib/gitlab/highlight_spec.rb
+++ b/spec/lib/gitlab/highlight_spec.rb
@@ -47,8 +47,9 @@ RSpec.describe Gitlab::Highlight do
end
it 'returns plain version for long content' do
- stub_const('Gitlab::Highlight::MAXIMUM_TEXT_HIGHLIGHT_SIZE', 1)
- result = described_class.highlight(file_name, content)
+ stub_config(extra: { 'maximum_text_highlight_size_kilobytes' => 0.0001 } ) # 1.024 bytes
+
+ result = described_class.highlight(file_name, content) # content is 44 bytes
expect(result).to eq(%[<span id="LC1" class="line" lang="">(make-pathname :defaults name</span>\n<span id="LC2" class="line" lang="">:type "assem")</span>])
end
diff --git a/spec/lib/gitlab/static_site_editor/config/generated_config_spec.rb b/spec/lib/gitlab/static_site_editor/config/generated_config_spec.rb
index 0b2055d3db5..8cd3feba339 100644
--- a/spec/lib/gitlab/static_site_editor/config/generated_config_spec.rb
+++ b/spec/lib/gitlab/static_site_editor/config/generated_config_spec.rb
@@ -54,13 +54,14 @@ RSpec.describe Gitlab::StaticSiteEditor::Config::GeneratedConfig do
path,
'',
message: 'message',
- branch_name: 'master'
+ branch_name: ref
)
end
+ let(:ref) { 'main' }
let(:path) { 'README.md.erb' }
- it { is_expected.to include(is_supported_content: true) }
+ it { is_expected.to include(branch: ref, is_supported_content: true) }
end
context 'when file path is nested' do
@@ -69,7 +70,7 @@ RSpec.describe Gitlab::StaticSiteEditor::Config::GeneratedConfig do
it { is_expected.to include(base_url: '/namespace/project/-/sse/master%2Flib%2FREADME.md') }
end
- context 'when branch is not master' do
+ context 'when branch is not master or main' do
let(:ref) { 'my-branch' }
it { is_expected.to include(is_supported_content: false) }
diff --git a/spec/lib/sidebars/projects/menus/operations_menu_spec.rb b/spec/lib/sidebars/projects/menus/operations_menu_spec.rb
index f8b4fc3757d..6e764dbb83a 100644
--- a/spec/lib/sidebars/projects/menus/operations_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/operations_menu_spec.rb
@@ -131,36 +131,66 @@ RSpec.describe Sidebars::Projects::Menus::OperationsMenu do
describe 'Serverless' do
let(:item_id) { :serverless }
- specify { is_expected.not_to be_nil }
+ context 'when feature flag :sidebar_refactor is enabled' do
+ specify { is_expected.to be_nil }
+ end
- describe 'when the user does not have access' do
- let(:user) { nil }
+ context 'when feature flag :sidebar_refactor is disabled' do
+ before do
+ stub_feature_flags(sidebar_refactor: false)
+ end
- specify { is_expected.to be_nil }
+ specify { is_expected.not_to be_nil }
+
+ describe 'when the user does not have access' do
+ let(:user) { nil }
+
+ specify { is_expected.to be_nil }
+ end
end
end
describe 'Terraform' do
let(:item_id) { :terraform }
- specify { is_expected.not_to be_nil }
+ context 'when feature flag :sidebar_refactor is enabled' do
+ specify { is_expected.to be_nil }
+ end
- describe 'when the user does not have access' do
- let(:user) { nil }
+ context 'when feature flag :sidebar_refactor is disabled' do
+ before do
+ stub_feature_flags(sidebar_refactor: false)
+ end
- specify { is_expected.to be_nil }
+ specify { is_expected.not_to be_nil }
+
+ describe 'when the user does not have access' do
+ let(:user) { nil }
+
+ specify { is_expected.to be_nil }
+ end
end
end
describe 'Kubernetes' do
let(:item_id) { :kubernetes }
- specify { is_expected.not_to be_nil }
+ context 'when feature flag :sidebar_refactor is enabled' do
+ specify { is_expected.to be_nil }
+ end
- describe 'when the user does not have access' do
- let(:user) { nil }
+ context 'when feature flag :sidebar_refactor is disabled' do
+ before do
+ stub_feature_flags(sidebar_refactor: false)
+ end
- specify { is_expected.to be_nil }
+ specify { is_expected.not_to be_nil }
+
+ describe 'when the user does not have access' do
+ let(:user) { nil }
+
+ specify { is_expected.to be_nil }
+ end
end
end
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index 7c02029fa40..abb0b3d0b6f 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -2398,4 +2398,12 @@ RSpec.describe Group do
expect(group.to_ability_name).to eq('group')
end
end
+
+ describe '#activity_path' do
+ it 'returns the group activity_path' do
+ expected_path = "/groups/#{group.name}/-/activity"
+
+ expect(group.activity_path).to eq(expected_path)
+ end
+ end
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 55b13128c17..bf47e75cc7a 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -6890,6 +6890,14 @@ RSpec.describe Project, factory_default: :keep do
end
end
end
+
+ describe '#activity_path' do
+ it 'returns the project activity_path' do
+ expected_path = "/#{project.namespace.path}/#{project.name}/activity"
+
+ expect(project.activity_path).to eq(expected_path)
+ end
+ end
end
describe '#default_branch_or_main' do
diff --git a/spec/requests/api/issues/issues_spec.rb b/spec/requests/api/issues/issues_spec.rb
index 8f10de59526..125db58ed69 100644
--- a/spec/requests/api/issues/issues_spec.rb
+++ b/spec/requests/api/issues/issues_spec.rb
@@ -115,6 +115,7 @@ RSpec.describe API::Issues do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.dig('author', 'id')).to eq(issue.author.id)
expect(json_response['description']).to eq(issue.description)
+ expect(json_response['issue_type']).to eq('issue')
end
end
@@ -378,6 +379,14 @@ RSpec.describe API::Issues do
expect_paginated_array_response([issue.id, closed_issue.id])
end
+ it 'returns issues with a given issue_type' do
+ issue2 = create(:incident, project: project)
+
+ get api('/issues', user), params: { issue_type: 'incident' }
+
+ expect_paginated_array_response(issue2.id)
+ end
+
it 'returns issues matching given search string for title' do
get api('/issues', user), params: { search: issue.title }
@@ -939,7 +948,17 @@ RSpec.describe API::Issues do
end
end
- describe 'PUT /projects/:id/issues/:issue_id' do
+ describe "POST /projects/:id/issues" do
+ it 'creates a new project issue' do
+ post api("/projects/#{project.id}/issues", user), params: { title: 'new issue' }
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(json_response['title']).to eq('new issue')
+ expect(json_response['issue_type']).to eq('issue')
+ end
+ end
+
+ describe 'PUT /projects/:id/issues/:issue_iid' do
it_behaves_like 'issuable update endpoint' do
let(:entity) { issue }
end
@@ -971,6 +990,14 @@ RSpec.describe API::Issues do
expect(ResourceLabelEvent.last.created_at).to be_like_time(fixed_time)
end
end
+
+ describe 'issue_type param' do
+ it 'allows issue type to be converted' do
+ put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { issue_type: 'incident' }
+
+ expect(issue.reload.incident?).to be(true)
+ end
+ end
end
describe 'DELETE /projects/:id/issues/:issue_iid' do
diff --git a/spec/support/shared_contexts/navbar_structure_context.rb b/spec/support/shared_contexts/navbar_structure_context.rb
index 65528f3900f..37f18e52449 100644
--- a/spec/support/shared_contexts/navbar_structure_context.rb
+++ b/spec/support/shared_contexts/navbar_structure_context.rb
@@ -24,6 +24,23 @@ RSpec.shared_context 'project navbar structure' do
}
end
+ let(:operations_menu_items) do
+ [
+ _('Metrics'),
+ _('Logs'),
+ _('Tracing'),
+ _('Error Tracking'),
+ _('Alerts'),
+ _('Incidents'),
+ _('Serverless'),
+ _('Terraform'),
+ _('Kubernetes'),
+ _('Environments'),
+ _('Feature Flags'),
+ _('Product Analytics')
+ ]
+ end
+
let(:structure) do
[
{
@@ -75,20 +92,7 @@ RSpec.shared_context 'project navbar structure' do
security_and_compliance_nav_item,
{
nav_item: _('Operations'),
- nav_sub_items: [
- _('Metrics'),
- _('Logs'),
- _('Tracing'),
- _('Error Tracking'),
- _('Alerts'),
- _('Incidents'),
- _('Serverless'),
- _('Terraform'),
- _('Kubernetes'),
- _('Environments'),
- _('Feature Flags'),
- _('Product Analytics')
- ]
+ nav_sub_items: operations_menu_items
},
analytics_nav_item,
{
diff --git a/spec/support/shared_examples/requests/api/issuable_update_shared_examples.rb b/spec/support/shared_examples/requests/api/issuable_update_shared_examples.rb
index ded381fd402..a3378d4619b 100644
--- a/spec/support/shared_examples/requests/api/issuable_update_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/issuable_update_shared_examples.rb
@@ -3,7 +3,7 @@
RSpec.shared_examples 'issuable update endpoint' do
let(:area) { entity.class.name.underscore.pluralize }
- describe 'PUT /projects/:id/issues/:issue_id' do
+ describe 'PUT /projects/:id/issues/:issue_iid' do
let(:url) { "/projects/#{project.id}/#{area}/#{entity.iid}" }
it 'clears labels when labels param is nil' do
diff --git a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
index d5320b2d044..7bb9570e90a 100644
--- a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
+++ b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
@@ -471,56 +471,71 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
end
end
- describe 'Serverless' do
- it 'has a link to the serverless page' do
- render
-
- expect(rendered).to have_link('Serverless', href: project_serverless_functions_path(project))
+ context 'when feature flag :sidebar_refactor is disabled' do
+ before do
+ stub_feature_flags(sidebar_refactor: false)
end
- describe 'when the user does not have access' do
- let(:user) { nil }
-
- it 'does not have a link to the serverless page' do
+ describe 'Serverless' do
+ it 'has a link to the serverless page' do
render
- expect(rendered).not_to have_link('Serverless')
+ page = Nokogiri::HTML.parse(rendered)
+
+ expect(page.at_css('.shortcuts-operations').parent.css('[aria-label="Serverless"]')).not_to be_empty
+ expect(rendered).to have_link('Serverless', href: project_serverless_functions_path(project))
end
- end
- end
- describe 'Terraform' do
- it 'has a link to the terraform page' do
- render
+ describe 'when the user does not have access' do
+ let(:user) { nil }
- expect(rendered).to have_link('Terraform', href: project_terraform_index_path(project))
- end
+ it 'does not have a link to the serverless page' do
+ render
- describe 'when the user does not have access' do
- let(:user) { nil }
+ expect(rendered).not_to have_link('Serverless')
+ end
+ end
+ end
- it 'does not have a link to the terraform page' do
+ describe 'Terraform' do
+ it 'has a link to the terraform page' do
render
- expect(rendered).not_to have_link('Terraform')
+ page = Nokogiri::HTML.parse(rendered)
+
+ expect(page.at_css('.shortcuts-operations').parent.css('[aria-label="Terraform"]')).not_to be_empty
+ expect(rendered).to have_link('Terraform', href: project_terraform_index_path(project))
end
- end
- end
- describe 'Kubernetes' do
- it 'has a link to the kubernetes page' do
- render
+ describe 'when the user does not have access' do
+ let(:user) { nil }
- expect(rendered).to have_link('Kubernetes', href: project_clusters_path(project))
- end
+ it 'does not have a link to the terraform page' do
+ render
- describe 'when the user does not have access' do
- let(:user) { nil }
+ expect(rendered).not_to have_link('Terraform')
+ end
+ end
+ end
- it 'does not have a link to the kubernetes page' do
+ describe 'Kubernetes' do
+ it 'has a link to the kubernetes page' do
render
- expect(rendered).not_to have_link('Kubernetes')
+ page = Nokogiri::HTML.parse(rendered)
+
+ expect(page.at_css('.shortcuts-operations').parent.css('[aria-label="Kubernetes"]')).not_to be_empty
+ expect(rendered).to have_link('Kubernetes', href: project_clusters_path(project))
+ end
+
+ describe 'when the user does not have access' do
+ let(:user) { nil }
+
+ it 'does not have a link to the kubernetes page' do
+ render
+
+ expect(rendered).not_to have_link('Kubernetes')
+ end
end
end
end
@@ -580,6 +595,62 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
end
end
+ describe 'Infrastructure' do
+ describe 'Serverless platform' do
+ it 'has a link to the serverless page' do
+ render
+
+ expect(rendered).to have_link('Serverless platform', href: project_serverless_functions_path(project))
+ end
+
+ describe 'when the user does not have access' do
+ let(:user) { nil }
+
+ it 'does not have a link to the serverless page' do
+ render
+
+ expect(rendered).not_to have_link('Serverless platform')
+ end
+ end
+ end
+
+ describe 'Terraform' do
+ it 'has a link to the terraform page' do
+ render
+
+ expect(rendered).to have_link('Terraform', href: project_terraform_index_path(project))
+ end
+
+ describe 'when the user does not have access' do
+ let(:user) { nil }
+
+ it 'does not have a link to the terraform page' do
+ render
+
+ expect(rendered).not_to have_link('Terraform')
+ end
+ end
+ end
+
+ describe 'Kubernetes clusters' do
+ it 'has a link to the kubernetes page' do
+ render
+
+ expect(rendered).to have_link('Kubernetes clusters', href: project_clusters_path(project))
+ end
+
+ describe 'when the user does not have access' do
+ let(:user) { nil }
+
+ it 'does not have a link to the kubernetes page' do
+ render
+
+ expect(rendered).not_to have_link('Kubernetes clusters')
+ end
+ end
+ end
+ end
+
describe 'Packages and Registries' do
let(:registry_enabled) { true }
let(:packages_enabled) { true }
diff --git a/yarn.lock b/yarn.lock
index e510df1873c..ef5ed4520e8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3605,10 +3605,10 @@ core-js-pure@^3.0.0:
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.5.tgz#c79e75f5e38dbc85a662d91eea52b8256d53b813"
integrity sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==
-core-js@^3.1.3, core-js@^3.11.2:
- version "3.11.2"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.11.2.tgz#af087a43373fc6e72942917c4a4c3de43ed574d6"
- integrity sha512-3tfrrO1JpJSYGKnd9LKTBPqgUES/UYiCzMKeqwR1+jF16q4kD1BY2NvqkfuzXwQ6+CIWm55V9cjD7PQd+hijdw==
+core-js@^3.1.3, core-js@^3.11.3:
+ version "3.11.3"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.11.3.tgz#2835b1f4d10f6d0400bf820cfe6fe64ad067dd3f"
+ integrity sha512-DFEW9BllWw781Op5KdYGtXfj3s9Cmykzt16bY6elaVuqXHCUwF/5pv0H3IJ7/I3BGjK7OeU+GrjD1ChCkBJPuA==
core-js@~2.3.0:
version "2.3.0"