Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
cf05fd7f39
commit
8f4d63426a
76 changed files with 948 additions and 317 deletions
|
@ -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
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:)
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
5
changelogs/unreleased/extend_branch_support_for_sse.yml
Normal file
5
changelogs/unreleased/extend_branch_support_for_sse.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Extend branch support for Static Site Editor
|
||||
merge_request: 60848
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Ensure highlighting limits are documented, configurable, and monitorable
|
||||
merge_request: 60445
|
||||
author:
|
||||
type: added
|
6
changelogs/unreleased/sy-create-incidents-via-api.yml
Normal file
6
changelogs/unreleased/sy-create-incidents-via-api.yml
Normal file
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
101
doc/api/group_relations_export.md
Normal file
101
doc/api/group_relations_export.md
Normal file
|
@ -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
|
||||
```
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 |
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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`
|
||||
|
||||
|
|
|
@ -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.
|
||||
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.
|
||||
|
||||
Additional features provided by the Jira Development Panel integration include:
|
||||
## Use the integration
|
||||
|
||||
- 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.
|
||||
After the integration is [set up on GitLab and Jira](#configure-the-integration), you can:
|
||||
|
||||
## Configuration
|
||||
- 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:
|
||||
|
||||
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)
|
||||
|
||||
### Use Jira Smart Commits
|
||||
|
||||
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)
|
||||
|
||||
Click 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)
|
||||
|
||||
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).
|
||||
|
||||
## Limitations
|
||||
|
||||
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`.
|
||||
|
||||
## Related topics
|
||||
|
||||
- [Using Smart Commits](https://confluence.atlassian.com/fisheye/using-smart-commits-960155400.html) in Jira
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Cookies for Oracle's Access Manager
|
||||
|
||||
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`.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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}"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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?
|
||||
|
|
93
lib/sidebars/projects/menus/infrastructure_menu.rb
Normal file
93
lib/sidebars/projects/menus/infrastructure_menu.rb
Normal file
|
@ -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
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ""
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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|
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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' }
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
||||
check_all_events
|
||||
click_button 'Save changes'
|
||||
|
||||
expect(page).to have_content 'Application settings saved successfully'
|
||||
|
||||
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'
|
||||
it 'shows Service Templates link' do
|
||||
expect(page).to have_link('Service Templates')
|
||||
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 the Slack Notifications Service template is active' do
|
||||
before do
|
||||
create(:service, :template, type: 'SlackService', active: true)
|
||||
|
||||
expect(find_field('Deployment')).not_to be_checked
|
||||
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'
|
||||
|
||||
check_all_events
|
||||
click_button 'Save changes'
|
||||
|
||||
expect(page).to have_content 'Application settings saved successfully'
|
||||
|
||||
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
|
||||
|
||||
context 'When Service templates are disabled' do
|
||||
before do
|
||||
stub_feature_flags(disable_service_templates: true)
|
||||
end
|
||||
|
||||
it 'does not show Service Templates link' do
|
||||
expect(page).not_to have_link('Service Templates')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -13,6 +13,8 @@ describe('CsvExportModal', () => {
|
|||
mount(CsvExportModal, {
|
||||
propsData: {
|
||||
modalId: 'csv-export-modal',
|
||||
exportCsvPath: 'export/csv/path',
|
||||
issuableCount: 1,
|
||||
...props,
|
||||
},
|
||||
provide: {
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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: '' },
|
||||
];
|
||||
|
|
|
@ -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', () => {
|
||||
|
|
|
@ -9,7 +9,7 @@ const defaultProps = {
|
|||
refsProjectPath: 'some/refs/path',
|
||||
revisionText: 'Target',
|
||||
paramsName: 'from',
|
||||
paramsBranch: 'master',
|
||||
paramsBranch: 'main',
|
||||
};
|
||||
|
||||
jest.mock('~/flash');
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) }
|
||||
|
|
|
@ -131,37 +131,67 @@ RSpec.describe Sidebars::Projects::Menus::OperationsMenu do
|
|||
describe 'Serverless' do
|
||||
let(:item_id) { :serverless }
|
||||
|
||||
specify { is_expected.not_to be_nil }
|
||||
|
||||
describe 'when the user does not have access' do
|
||||
let(:user) { nil }
|
||||
|
||||
context 'when feature flag :sidebar_refactor is enabled' do
|
||||
specify { is_expected.to be_nil }
|
||||
end
|
||||
|
||||
context 'when feature flag :sidebar_refactor is disabled' do
|
||||
before do
|
||||
stub_feature_flags(sidebar_refactor: false)
|
||||
end
|
||||
|
||||
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 }
|
||||
|
||||
describe 'when the user does not have access' do
|
||||
let(:user) { nil }
|
||||
|
||||
context 'when feature flag :sidebar_refactor is enabled' do
|
||||
specify { is_expected.to be_nil }
|
||||
end
|
||||
|
||||
context 'when feature flag :sidebar_refactor is disabled' do
|
||||
before do
|
||||
stub_feature_flags(sidebar_refactor: false)
|
||||
end
|
||||
|
||||
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 }
|
||||
|
||||
describe 'when the user does not have access' do
|
||||
let(:user) { nil }
|
||||
|
||||
context 'when feature flag :sidebar_refactor is enabled' do
|
||||
specify { is_expected.to be_nil }
|
||||
end
|
||||
|
||||
context 'when feature flag :sidebar_refactor is disabled' do
|
||||
before do
|
||||
stub_feature_flags(sidebar_refactor: false)
|
||||
end
|
||||
|
||||
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 'Environments' do
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
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')
|
||||
end
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
describe 'Kubernetes' do
|
||||
it 'has a link to the kubernetes page' do
|
||||
render
|
||||
|
||||
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
|
||||
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 }
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in a new issue