Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
8b7a679616
commit
d81f7fc0b3
|
@ -13,8 +13,6 @@ inherit_from:
|
|||
<% end %>
|
||||
- '.rubocop_todo.yml'
|
||||
<% end %>
|
||||
<%# See https://gitlab.com/gitlab-org/gitlab/-/issues/321982#rubymine-note for context on why namespaced_class has special handling here %>
|
||||
- ./.rubocop_todo/gitlab/namespaced_class.yml
|
||||
- ./rubocop/rubocop-migrations.yml
|
||||
- ./rubocop/rubocop-usage-data.yml
|
||||
- ./rubocop/rubocop-code_reuse.yml
|
||||
|
|
|
@ -10,8 +10,8 @@ export const OPENED = 'opened';
|
|||
export const REOPENED = 'reopened';
|
||||
export const CLOSED = 'closed';
|
||||
export const MERGED = 'merged';
|
||||
export const ISSUE_NOTEABLE_TYPE = 'issue';
|
||||
export const EPIC_NOTEABLE_TYPE = 'epic';
|
||||
export const ISSUE_NOTEABLE_TYPE = 'Issue';
|
||||
export const EPIC_NOTEABLE_TYPE = 'Epic';
|
||||
export const MERGE_REQUEST_NOTEABLE_TYPE = 'MergeRequest';
|
||||
export const UNRESOLVE_NOTE_METHOD_NAME = 'delete';
|
||||
export const RESOLVE_NOTE_METHOD_NAME = 'post';
|
||||
|
|
|
@ -83,14 +83,17 @@ export const setExpandDiscussions = ({ commit }, { discussionIds, expanded }) =>
|
|||
commit(types.SET_EXPAND_DISCUSSIONS, { discussionIds, expanded });
|
||||
};
|
||||
|
||||
export const fetchDiscussions = ({ commit, dispatch }, { path, filter, persistFilter }) => {
|
||||
export const fetchDiscussions = (
|
||||
{ commit, dispatch, getters },
|
||||
{ path, filter, persistFilter },
|
||||
) => {
|
||||
const config =
|
||||
filter !== undefined
|
||||
? { params: { notes_filter: filter, persist_filter: persistFilter } }
|
||||
: null;
|
||||
|
||||
if (
|
||||
window.gon?.features?.paginatedIssueDiscussions ||
|
||||
getters.noteableType === constants.ISSUE_NOTEABLE_TYPE ||
|
||||
window.gon?.features?.paginatedMrDiscussions
|
||||
) {
|
||||
return dispatch('fetchDiscussionsBatch', { path, config, perPage: 20 });
|
||||
|
@ -114,7 +117,7 @@ export const fetchDiscussionsBatch = ({ commit, dispatch }, { path, config, curs
|
|||
return axios.get(path, { params }).then(({ data, headers }) => {
|
||||
commit(types.ADD_OR_UPDATE_DISCUSSIONS, data);
|
||||
|
||||
if (headers['x-next-page-cursor']) {
|
||||
if (headers && headers['x-next-page-cursor']) {
|
||||
const nextConfig = { ...config };
|
||||
|
||||
if (config?.params?.persist_filter) {
|
||||
|
|
|
@ -184,7 +184,6 @@ module IssuableActions
|
|||
|
||||
def paginated_discussions
|
||||
return if params[:per_page].blank?
|
||||
return if issuable.instance_of?(Issue) && Feature.disabled?(:paginated_issue_discussions, project)
|
||||
return if issuable.instance_of?(MergeRequest) && Feature.disabled?(:paginated_mr_discussions, project)
|
||||
|
||||
strong_memoize(:paginated_discussions) do
|
||||
|
|
|
@ -47,7 +47,6 @@ class Projects::IssuesController < Projects::ApplicationController
|
|||
before_action only: :show do
|
||||
push_frontend_feature_flag(:confidential_notes, project&.group)
|
||||
push_frontend_feature_flag(:issue_assignees_widget, project)
|
||||
push_frontend_feature_flag(:paginated_issue_discussions, project)
|
||||
push_frontend_feature_flag(:realtime_labels, project)
|
||||
push_force_frontend_feature_flag(:work_items, project&.work_items_feature_flag_enabled?)
|
||||
push_frontend_feature_flag(:work_items_mvc_2)
|
||||
|
|
|
@ -6,13 +6,15 @@
|
|||
module NotificationBranchSelection
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def branch_choices
|
||||
[
|
||||
[_('All branches'), 'all'].freeze,
|
||||
[_('Default branch'), 'default'].freeze,
|
||||
[_('Protected branches'), 'protected'].freeze,
|
||||
[_('Default branch and protected branches'), 'default_and_protected'].freeze
|
||||
].freeze
|
||||
class_methods do
|
||||
def branch_choices
|
||||
[
|
||||
[_('All branches'), 'all'].freeze,
|
||||
[_('Default branch'), 'default'].freeze,
|
||||
[_('Protected branches'), 'protected'].freeze,
|
||||
[_('Default branch and protected branches'), 'default_and_protected'].freeze
|
||||
].freeze
|
||||
end
|
||||
end
|
||||
|
||||
def notify_for_branch?(data)
|
||||
|
|
|
@ -4,9 +4,22 @@ require 'asana'
|
|||
|
||||
module Integrations
|
||||
class Asana < Integration
|
||||
prop_accessor :api_key, :restrict_to_branch
|
||||
validates :api_key, presence: true, if: :activated?
|
||||
|
||||
field :api_key,
|
||||
type: 'password',
|
||||
title: 'API key',
|
||||
help: -> { s_('AsanaService|User Personal Access Token. User must have access to the task. All comments are attributed to this user.') },
|
||||
non_empty_password_title: -> { s_('ProjectService|Enter new API key') },
|
||||
non_empty_password_help: -> { s_('ProjectService|Leave blank to use your current API key.') },
|
||||
# Example Personal Access Token from Asana docs
|
||||
placeholder: '0/68a9e79b868c6789e79a124c30b0',
|
||||
required: true
|
||||
|
||||
field :restrict_to_branch,
|
||||
title: -> { s_('Integrations|Restrict to branch (optional)') },
|
||||
help: -> { s_('AsanaService|Comma-separated list of branches to be automatically inspected. Leave blank to include all branches.') }
|
||||
|
||||
def title
|
||||
'Asana'
|
||||
end
|
||||
|
@ -24,28 +37,6 @@ module Integrations
|
|||
'asana'
|
||||
end
|
||||
|
||||
def fields
|
||||
[
|
||||
{
|
||||
type: 'password',
|
||||
name: 'api_key',
|
||||
title: 'API key',
|
||||
help: s_('AsanaService|User Personal Access Token. User must have access to the task. All comments are attributed to this user.'),
|
||||
non_empty_password_title: s_('ProjectService|Enter new API key'),
|
||||
non_empty_password_help: s_('ProjectService|Leave blank to use your current API key.'),
|
||||
# Example Personal Access Token from Asana docs
|
||||
placeholder: '0/68a9e79b868c6789e79a124c30b0',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'restrict_to_branch',
|
||||
title: 'Restrict to branch (optional)',
|
||||
help: s_('AsanaService|Comma-separated list of branches to be automatically inspected. Leave blank to include all branches.')
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
def self.supported_events
|
||||
%w(push)
|
||||
end
|
||||
|
|
|
@ -2,9 +2,18 @@
|
|||
|
||||
module Integrations
|
||||
class Assembla < Integration
|
||||
prop_accessor :token, :subdomain
|
||||
validates :token, presence: true, if: :activated?
|
||||
|
||||
field :token,
|
||||
type: 'password',
|
||||
non_empty_password_title: -> { s_('ProjectService|Enter new token') },
|
||||
non_empty_password_help: -> { s_('ProjectService|Leave blank to use your current token.') },
|
||||
placeholder: '',
|
||||
required: true
|
||||
|
||||
field :subdomain,
|
||||
placeholder: ''
|
||||
|
||||
def title
|
||||
'Assembla'
|
||||
end
|
||||
|
@ -17,24 +26,6 @@ module Integrations
|
|||
'assembla'
|
||||
end
|
||||
|
||||
def fields
|
||||
[
|
||||
{
|
||||
type: 'password',
|
||||
name: 'token',
|
||||
non_empty_password_title: s_('ProjectService|Enter new token'),
|
||||
non_empty_password_help: s_('ProjectService|Leave blank to use your current token.'),
|
||||
placeholder: '',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'subdomain',
|
||||
placeholder: ''
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
def self.supported_events
|
||||
%w(push)
|
||||
end
|
||||
|
|
|
@ -78,7 +78,7 @@ module Integrations
|
|||
type: 'select',
|
||||
name: 'branches_to_be_notified',
|
||||
title: s_('Integrations|Branches for which notifications are to be sent'),
|
||||
choices: branch_choices
|
||||
choices: self.class.branch_choices
|
||||
}.freeze,
|
||||
{
|
||||
type: 'text',
|
||||
|
@ -118,7 +118,7 @@ module Integrations
|
|||
|
||||
event_type = data[:event_type] || object_kind
|
||||
|
||||
channel_names = get_channel_field(event_type).presence || channel.presence
|
||||
channel_names = event_channel_value(event_type).presence || channel.presence
|
||||
channels = channel_names&.split(',')&.map(&:strip)
|
||||
|
||||
opts = {}
|
||||
|
@ -161,7 +161,7 @@ module Integrations
|
|||
EVENT_CHANNEL[event]
|
||||
end
|
||||
|
||||
def get_channel_field(event)
|
||||
def event_channel_value(event)
|
||||
field_name = event_channel_name(event)
|
||||
self.public_send(field_name) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
|
|
@ -6,11 +6,14 @@ module Integrations
|
|||
VALID_HOST_MATCH = %r{\A.+\.atlassian\.net\Z}.freeze
|
||||
VALID_PATH_MATCH = %r{\A/wiki(/|\Z)}.freeze
|
||||
|
||||
prop_accessor :confluence_url
|
||||
|
||||
validates :confluence_url, presence: true, if: :activated?
|
||||
validate :validate_confluence_url_is_cloud, if: :activated?
|
||||
|
||||
field :confluence_url,
|
||||
title: -> { s_('Confluence Cloud Workspace URL') },
|
||||
placeholder: 'https://example.atlassian.net/wiki',
|
||||
required: true
|
||||
|
||||
def self.to_param
|
||||
'confluence'
|
||||
end
|
||||
|
@ -38,18 +41,6 @@ module Integrations
|
|||
end
|
||||
end
|
||||
|
||||
def fields
|
||||
[
|
||||
{
|
||||
type: 'text',
|
||||
name: 'confluence_url',
|
||||
title: s_('Confluence Cloud Workspace URL'),
|
||||
placeholder: 'https://example.atlassian.net/wiki',
|
||||
required: true
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
def testable?
|
||||
false
|
||||
end
|
||||
|
|
|
@ -39,7 +39,7 @@ module Integrations
|
|||
type: 'select',
|
||||
name: 'branches_to_be_notified',
|
||||
title: s_('Integrations|Branches for which notifications are to be sent'),
|
||||
choices: branch_choices
|
||||
choices: self.class.branch_choices
|
||||
}
|
||||
]
|
||||
end
|
||||
|
|
|
@ -6,12 +6,35 @@ module Integrations
|
|||
|
||||
RECIPIENTS_LIMIT = 750
|
||||
|
||||
boolean_accessor :send_from_committer_email
|
||||
boolean_accessor :disable_diffs
|
||||
prop_accessor :recipients, :branches_to_be_notified
|
||||
validates :recipients, presence: true, if: :validate_recipients?
|
||||
validate :number_of_recipients_within_limit, if: :validate_recipients?
|
||||
|
||||
field :send_from_committer_email,
|
||||
type: 'checkbox',
|
||||
title: -> { s_("EmailsOnPushService|Send from committer") },
|
||||
help: -> do
|
||||
@help ||= begin
|
||||
domains = Notify.allowed_email_domains.map { |domain| "user@#{domain}" }.join(", ")
|
||||
|
||||
s_("EmailsOnPushService|Send notifications from the committer's email address if the domain matches the domain used by your GitLab instance (such as %{domains}).") % { domains: domains }
|
||||
end
|
||||
end
|
||||
|
||||
field :disable_diffs,
|
||||
type: 'checkbox',
|
||||
title: -> { s_("EmailsOnPushService|Disable code diffs") },
|
||||
help: -> { s_("EmailsOnPushService|Don't include possibly sensitive code diffs in notification body.") }
|
||||
|
||||
field :branches_to_be_notified,
|
||||
type: 'select',
|
||||
title: -> { s_('Integrations|Branches for which notifications are to be sent') },
|
||||
choices: branch_choices
|
||||
|
||||
field :recipients,
|
||||
type: 'textarea',
|
||||
placeholder: -> { s_('EmailsOnPushService|tanuki@example.com gitlab@example.com') },
|
||||
help: -> { s_('EmailsOnPushService|Emails separated by whitespace.') }
|
||||
|
||||
def self.valid_recipients(recipients)
|
||||
recipients.split.grep(Devise.email_regexp).uniq(&:downcase)
|
||||
end
|
||||
|
@ -67,28 +90,6 @@ module Integrations
|
|||
Gitlab::Utils.to_boolean(self.disable_diffs)
|
||||
end
|
||||
|
||||
def fields
|
||||
domains = Notify.allowed_email_domains.map { |domain| "user@#{domain}" }.join(", ")
|
||||
[
|
||||
{ type: 'checkbox', name: 'send_from_committer_email', title: s_("EmailsOnPushService|Send from committer"),
|
||||
help: s_("EmailsOnPushService|Send notifications from the committer's email address if the domain matches the domain used by your GitLab instance (such as %{domains}).") % { domains: domains } },
|
||||
{ type: 'checkbox', name: 'disable_diffs', title: s_("EmailsOnPushService|Disable code diffs"),
|
||||
help: s_("EmailsOnPushService|Don't include possibly sensitive code diffs in notification body.") },
|
||||
{
|
||||
type: 'select',
|
||||
name: 'branches_to_be_notified',
|
||||
title: s_('Integrations|Branches for which notifications are to be sent'),
|
||||
choices: branch_choices
|
||||
},
|
||||
{
|
||||
type: 'textarea',
|
||||
name: 'recipients',
|
||||
placeholder: s_('EmailsOnPushService|tanuki@example.com gitlab@example.com'),
|
||||
help: s_('EmailsOnPushService|Emails separated by whitespace.')
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def number_of_recipients_within_limit
|
||||
|
|
|
@ -2,9 +2,14 @@
|
|||
|
||||
module Integrations
|
||||
class ExternalWiki < Integration
|
||||
prop_accessor :external_wiki_url
|
||||
validates :external_wiki_url, presence: true, public_url: true, if: :activated?
|
||||
|
||||
field :external_wiki_url,
|
||||
title: -> { s_('ExternalWikiService|External wiki URL') },
|
||||
placeholder: -> { s_('ExternalWikiService|https://example.com/xxx/wiki/...') },
|
||||
help: -> { s_('ExternalWikiService|Enter the URL to the external wiki.') },
|
||||
required: true
|
||||
|
||||
def title
|
||||
s_('ExternalWikiService|External wiki')
|
||||
end
|
||||
|
@ -17,19 +22,6 @@ module Integrations
|
|||
'external_wiki'
|
||||
end
|
||||
|
||||
def fields
|
||||
[
|
||||
{
|
||||
type: 'text',
|
||||
name: 'external_wiki_url',
|
||||
title: s_('ExternalWikiService|External wiki URL'),
|
||||
placeholder: s_('ExternalWikiService|https://example.com/xxx/wiki/...'),
|
||||
help: 'Enter the URL to the external wiki.',
|
||||
required: true
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
def help
|
||||
docs_link = ActionController::Base.helpers.link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/wiki/index', anchor: 'link-an-external-wiki'), target: '_blank', rel: 'noopener noreferrer'
|
||||
|
||||
|
|
|
@ -2,9 +2,16 @@
|
|||
|
||||
module Integrations
|
||||
class Flowdock < Integration
|
||||
prop_accessor :token
|
||||
validates :token, presence: true, if: :activated?
|
||||
|
||||
field :token,
|
||||
type: 'password',
|
||||
help: -> { s_('FlowdockService|Enter your Flowdock token.') },
|
||||
non_empty_password_title: -> { s_('ProjectService|Enter new token') },
|
||||
non_empty_password_help: -> { s_('ProjectService|Leave blank to use your current token.') },
|
||||
placeholder: '1b609b52537...',
|
||||
required: true
|
||||
|
||||
def title
|
||||
'Flowdock'
|
||||
end
|
||||
|
@ -22,20 +29,6 @@ module Integrations
|
|||
'flowdock'
|
||||
end
|
||||
|
||||
def fields
|
||||
[
|
||||
{
|
||||
type: 'password',
|
||||
name: 'token',
|
||||
help: s_('FlowdockService|Enter your Flowdock token.'),
|
||||
non_empty_password_title: s_('ProjectService|Enter new token'),
|
||||
non_empty_password_help: s_('ProjectService|Leave blank to use your current token.'),
|
||||
placeholder: '1b609b52537...',
|
||||
required: true
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
def self.supported_events
|
||||
%w(push)
|
||||
end
|
||||
|
|
|
@ -39,7 +39,7 @@ module Integrations
|
|||
type: 'select',
|
||||
name: 'branches_to_be_notified',
|
||||
title: s_('Integrations|Branches for which notifications are to be sent'),
|
||||
choices: branch_choices
|
||||
choices: self.class.branch_choices
|
||||
}
|
||||
]
|
||||
end
|
||||
|
|
|
@ -44,7 +44,7 @@ module Integrations
|
|||
section: SECTION_TYPE_CONFIGURATION,
|
||||
name: 'branches_to_be_notified',
|
||||
title: s_('Integrations|Branches for which notifications are to be sent'),
|
||||
choices: branch_choices
|
||||
choices: self.class.branch_choices
|
||||
}
|
||||
]
|
||||
end
|
||||
|
|
|
@ -76,7 +76,7 @@ module Integrations
|
|||
{ type: 'select',
|
||||
name: 'branches_to_be_notified',
|
||||
title: s_('Integrations|Branches for which notifications are to be sent'),
|
||||
choices: branch_choices }
|
||||
choices: self.class.branch_choices }
|
||||
]
|
||||
end
|
||||
|
||||
|
|
|
@ -4,9 +4,22 @@ module Integrations
|
|||
class Pivotaltracker < Integration
|
||||
API_ENDPOINT = 'https://www.pivotaltracker.com/services/v5/source_commits'
|
||||
|
||||
prop_accessor :token, :restrict_to_branch
|
||||
validates :token, presence: true, if: :activated?
|
||||
|
||||
field :token,
|
||||
type: 'password',
|
||||
help: -> { s_('PivotalTrackerService|Pivotal Tracker API token. User must have access to the story. All comments are attributed to this user.') },
|
||||
non_empty_password_title: -> { s_('ProjectService|Enter new token') },
|
||||
non_empty_password_help: -> { s_('ProjectService|Leave blank to use your current token.') },
|
||||
required: true
|
||||
|
||||
field :restrict_to_branch,
|
||||
title: -> { s_('Integrations|Restrict to branch (optional)') },
|
||||
help: -> do
|
||||
s_('PivotalTrackerService|Comma-separated list of branches to ' \
|
||||
'automatically inspect. Leave blank to include all branches.')
|
||||
end
|
||||
|
||||
def title
|
||||
'Pivotal Tracker'
|
||||
end
|
||||
|
@ -24,26 +37,6 @@ module Integrations
|
|||
'pivotaltracker'
|
||||
end
|
||||
|
||||
def fields
|
||||
[
|
||||
{
|
||||
type: 'password',
|
||||
name: 'token',
|
||||
help: s_('PivotalTrackerService|Pivotal Tracker API token. User must have access to the story. All comments are attributed to this user.'),
|
||||
non_empty_password_title: s_('ProjectService|Enter new token'),
|
||||
non_empty_password_help: s_('ProjectService|Leave blank to use your current token.'),
|
||||
required: true
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'restrict_to_branch',
|
||||
title: 'Restrict to branch (optional)',
|
||||
help: s_('PivotalTrackerService|Comma-separated list of branches to ' \
|
||||
'automatically inspect. Leave blank to include all branches.')
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
def self.supported_events
|
||||
%w(push)
|
||||
end
|
||||
|
|
|
@ -4,11 +4,30 @@ module Integrations
|
|||
class Prometheus < BaseMonitoring
|
||||
include PrometheusAdapter
|
||||
|
||||
# Access to prometheus is directly through the API
|
||||
prop_accessor :api_url
|
||||
prop_accessor :google_iap_service_account_json
|
||||
prop_accessor :google_iap_audience_client_id
|
||||
boolean_accessor :manual_configuration
|
||||
field :manual_configuration,
|
||||
type: 'checkbox',
|
||||
title: -> { s_('PrometheusService|Active') },
|
||||
help: -> { s_('PrometheusService|Select this checkbox to override the auto configuration settings with your own settings.') },
|
||||
required: true
|
||||
|
||||
field :api_url,
|
||||
title: 'API URL',
|
||||
placeholder: -> { s_('PrometheusService|https://prometheus.example.com/') },
|
||||
help: -> { s_('PrometheusService|The Prometheus API base URL.') },
|
||||
required: true
|
||||
|
||||
field :google_iap_audience_client_id,
|
||||
title: 'Google IAP Audience Client ID',
|
||||
placeholder: -> { s_('PrometheusService|IAP_CLIENT_ID.apps.googleusercontent.com') },
|
||||
help: -> { s_('PrometheusService|The ID of the IAP-secured resource.') },
|
||||
required: false
|
||||
|
||||
field :google_iap_service_account_json,
|
||||
type: 'textarea',
|
||||
title: 'Google IAP Service Account JSON',
|
||||
placeholder: -> { s_('PrometheusService|{ "type": "service_account", "project_id": ... }') },
|
||||
help: -> { s_('PrometheusService|The contents of the credentials.json file of your service account.') },
|
||||
required: false
|
||||
|
||||
# We need to allow the self-monitoring project to connect to the internal
|
||||
# Prometheus instance.
|
||||
|
@ -45,43 +64,6 @@ module Integrations
|
|||
'prometheus'
|
||||
end
|
||||
|
||||
def fields
|
||||
[
|
||||
{
|
||||
type: 'checkbox',
|
||||
name: 'manual_configuration',
|
||||
title: s_('PrometheusService|Active'),
|
||||
help: s_('PrometheusService|Select this checkbox to override the auto configuration settings with your own settings.'),
|
||||
required: true
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'api_url',
|
||||
title: 'API URL',
|
||||
placeholder: s_('PrometheusService|https://prometheus.example.com/'),
|
||||
help: s_('PrometheusService|The Prometheus API base URL.'),
|
||||
required: true
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'google_iap_audience_client_id',
|
||||
title: 'Google IAP Audience Client ID',
|
||||
placeholder: s_('PrometheusService|IAP_CLIENT_ID.apps.googleusercontent.com'),
|
||||
help: s_('PrometheusService|The ID of the IAP-secured resource.'),
|
||||
autocomplete: 'off',
|
||||
required: false
|
||||
},
|
||||
{
|
||||
type: 'textarea',
|
||||
name: 'google_iap_service_account_json',
|
||||
title: 'Google IAP Service Account JSON',
|
||||
placeholder: s_('PrometheusService|{ "type": "service_account", "project_id": ... }'),
|
||||
help: s_('PrometheusService|The contents of the credentials.json file of your service account.'),
|
||||
required: false
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
# Check we can connect to the Prometheus API
|
||||
def test(*args)
|
||||
return { success: false, result: 'Prometheus configuration error' } unless prometheus_client
|
||||
|
|
|
@ -35,7 +35,7 @@ module Integrations
|
|||
type: 'select',
|
||||
name: 'branches_to_be_notified',
|
||||
title: s_('Integrations|Branches for which notifications are to be sent'),
|
||||
choices: branch_choices
|
||||
choices: self.class.branch_choices
|
||||
}
|
||||
]
|
||||
end
|
||||
|
|
|
@ -35,7 +35,7 @@ module Integrations
|
|||
type: 'select',
|
||||
name: 'branches_to_be_notified',
|
||||
title: s_('Integrations|Branches for which notifications are to be sent'),
|
||||
choices: branch_choices
|
||||
choices: self.class.branch_choices
|
||||
}
|
||||
]
|
||||
end
|
||||
|
|
|
@ -23,7 +23,7 @@ module Integrations
|
|||
integration.event_channel_name(event)
|
||||
end
|
||||
expose :value do |event|
|
||||
integration.get_channel_field(event)
|
||||
integration.event_channel_value(event)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
- add_page_startup_api_call Feature.enabled?(:paginated_issue_discussions, @project) ? discussions_path(@issue, per_page: 20) : discussions_path(@issue)
|
||||
- add_page_startup_api_call discussions_path(@issue, per_page: 20)
|
||||
|
||||
- @gfm_form = true
|
||||
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: paginated_issue_discussions
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69933
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/345351
|
||||
milestone: '14.5'
|
||||
type: development
|
||||
group: group::project management
|
||||
default_enabled: false
|
|
@ -3,7 +3,7 @@ table_name: ci_job_token_project_scope_links
|
|||
classes:
|
||||
- Ci::JobToken::ProjectScopeLink
|
||||
feature_categories:
|
||||
- pipeline_authoring
|
||||
description: TODO
|
||||
- continuous_integration
|
||||
description: The connection between a source project, which defines the job token scope, and a target project, which is the one allowed to be accessed by the job token.
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62733
|
||||
milestone: '14.0'
|
||||
|
|
|
@ -475,16 +475,16 @@ end
|
|||
Developers can add [feature flags](../development/feature_flags/index.md) to GraphQL
|
||||
fields in the following ways:
|
||||
|
||||
- Add the `feature_flag` property to a field. This allows the field to be _hidden_
|
||||
- Add the [`feature_flag` property](#feature_flag-property) to a field. This allows the field to be _hidden_
|
||||
from the GraphQL schema when the flag is disabled.
|
||||
- Toggle the return value when resolving the field.
|
||||
- [Toggle the return value](#toggle-the-value-of-a-field) when resolving the field.
|
||||
|
||||
You can refer to these guidelines to decide which approach to use:
|
||||
|
||||
- If your field is experimental, and its name or type is subject to
|
||||
change, use the `feature_flag` property.
|
||||
change, use the [`feature_flag` property](#feature_flag-property).
|
||||
- If your field is stable and its definition doesn't change, even after the flag is
|
||||
removed, toggle the return value of the field instead. Note that
|
||||
removed, [toggle the return value](#toggle-the-value-of-a-field) of the field instead. Note that
|
||||
[all fields should be nullable](#nullable-fields) anyway.
|
||||
|
||||
### `feature_flag` property
|
||||
|
@ -524,6 +524,12 @@ return value of the field. This can be done in the resolver, in the
|
|||
type, or even in a model method, depending on your preference and
|
||||
situation.
|
||||
|
||||
Consider also [marking the field as Alpha](#marking-schema-items-as-alpha)
|
||||
while the value of the field can be toggled. You can
|
||||
[change or remove Alpha fields at any time](#breaking-change-exemptions) without needing to deprecate them.
|
||||
This also signals to consumers of the public GraphQL API that the field is not
|
||||
meant to be used yet.
|
||||
|
||||
When applying a feature flag to toggle the value of a field, the
|
||||
`description` of the field must:
|
||||
|
||||
|
@ -537,6 +543,7 @@ Example:
|
|||
```ruby
|
||||
field :foo, GraphQL::Types::String,
|
||||
null: true,
|
||||
deprecated: { reason: :alpha, milestone: '10.0' },
|
||||
description: 'Some test field. Returns `null`' \
|
||||
'if `my_feature_flag` feature flag is disabled.'
|
||||
|
||||
|
@ -2007,13 +2014,13 @@ end
|
|||
.to contain_exactly(a_graphql_entity_for(issue, :iid, :title, created_at: some_time))
|
||||
```
|
||||
|
||||
- Use `GraphqlHelpers#empty_schema` to create an empty schema, rather than creating
|
||||
- Use `GraphqlHelpers#empty_schema` to create an empty schema, rather than creating
|
||||
one by hand. For example:
|
||||
|
||||
|
||||
```ruby
|
||||
# good
|
||||
let(:schema) { empty_schema }
|
||||
|
||||
|
||||
# bad
|
||||
let(:query_type) { GraphQL::ObjectType.new }
|
||||
let(:schema) { GraphQL::Schema.define(query: query_type, mutation: nil)}
|
||||
|
@ -2024,7 +2031,7 @@ end
|
|||
```ruby
|
||||
# good
|
||||
let(:query) { query_double(schema: GitlabSchema) }
|
||||
|
||||
|
||||
# bad
|
||||
let(:query) { double('Query', schema: GitlabSchema) }
|
||||
```
|
||||
|
@ -2092,9 +2099,9 @@ end
|
|||
```ruby
|
||||
type Types::IssueType.connection_type, null: true
|
||||
```
|
||||
|
||||
|
||||
However this might cause a cyclic definition, which can result in errors like:
|
||||
|
||||
|
||||
```ruby
|
||||
NameError: uninitialized constant Resolvers::GroupIssuesResolver
|
||||
```
|
||||
|
@ -2109,7 +2116,7 @@ end
|
|||
class IssueConnectionType < CountableConnectionType
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Types::IssueConnectionType.prepend_mod_with('Types::IssueConnectionType')
|
||||
```
|
||||
|
||||
|
@ -2120,22 +2127,22 @@ end
|
|||
```ruby
|
||||
type "Types::IssueConnection", null: true
|
||||
```
|
||||
|
||||
|
||||
Only use this style if you are having spec failures. This is not intended to be a new
|
||||
pattern that we use. This issue may disappear after we've upgraded to `2.x`.
|
||||
|
||||
- There can be instances where a spec fails because the class is not loaded correctly.
|
||||
It relates to the
|
||||
- There can be instances where a spec fails because the class is not loaded correctly.
|
||||
It relates to the
|
||||
[circular dependencies problem](https://github.com/rmosolgo/graphql-ruby/issues/1929) and
|
||||
[Adding field with resolver on a Type causes "Can't determine the return type " error on a different Type](https://github.com/rmosolgo/graphql-ruby/issues/3974).
|
||||
|
||||
Unfortunately, the errors generated don't really indicate what the problem is. For example,
|
||||
remove the quotes from the `Rspec.descrbe` in
|
||||
remove the quotes from the `Rspec.descrbe` in
|
||||
[ee/spec/graphql/resolvers/compliance_management/merge_requests/compliance_violation_resolver_spec.rb](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/spec/graphql/resolvers/compliance_management/merge_requests/compliance_violation_resolver_spec.rb).
|
||||
Then run `rspec ee/spec/graphql/resolvers/compliance_management/merge_requests/compliance_violation_resolver_spec.rb`.
|
||||
|
||||
|
||||
This generates errors with the expectations. For example:
|
||||
|
||||
|
||||
```ruby
|
||||
1) Resolvers::ComplianceManagement::MergeRequests::ComplianceViolationResolver#resolve user is authorized filtering the results when given an array of project IDs finds the filtered compliance violations
|
||||
Failure/Error: expect(subject).to contain_exactly(compliance_violation)
|
||||
|
@ -2145,10 +2152,10 @@ end
|
|||
the extra elements were: [#<MergeRequests::ComplianceViolation id: 5, violating_user_id: 27, merge_request_id: 5, reason: "approved_by_merge_request_author", severity_level: "high">]
|
||||
# ./ee/spec/graphql/resolvers/compliance_management/merge_requests/compliance_violation_resolver_spec.rb:55:in `block (6 levels) in <top (required)>'
|
||||
```
|
||||
|
||||
|
||||
However, this is not a case of the wrong result being generated, it's because of the loading order
|
||||
of the `ComplianceViolationResolver` class.
|
||||
|
||||
|
||||
The only way we've found to fix this is by quoting the class name in the spec. For example, changing
|
||||
|
||||
```ruby
|
||||
|
@ -2198,7 +2205,7 @@ end
|
|||
[removed eventually](https://gitlab.com/gitlab-org/gitlab/-/issues/363121),
|
||||
and writing unit tests for resolvers/mutations is
|
||||
[already deprecated](#writing-unit-tests-deprecated)
|
||||
|
||||
|
||||
## Notes about Query flow and GraphQL infrastructure
|
||||
|
||||
The GitLab GraphQL infrastructure can be found in `lib/gitlab/graphql`.
|
||||
|
|
|
@ -104,7 +104,10 @@ for the section. For example:
|
|||
> `widget_message` [introduced](<link-to-issue>) in GitLab 14.3.
|
||||
```
|
||||
|
||||
## Attribute deprecation
|
||||
## Deprecations
|
||||
|
||||
To document the deprecation of an API endpoint, follow the steps to
|
||||
[deprecate a page or topic](versions.md#deprecate-a-page-or-topic).
|
||||
|
||||
To deprecate an attribute:
|
||||
|
||||
|
@ -122,8 +125,8 @@ To deprecate an attribute:
|
|||
| `widget_name` | string | **{dotted-circle}** No | [Deprecated](<link-to-issue>) in GitLab 14.7 and is planned for removal in 15.4. Use `widget_id` instead. The name of the widget. |
|
||||
```
|
||||
|
||||
1. Optional. To widely announce the change, or if it's a breaking change,
|
||||
[update the deprecations and removals documentation](../deprecation_guidelines/#update-the-deprecations-and-removals-documentation).
|
||||
To widely announce a deprecation, or if it's a breaking change,
|
||||
[update the deprecations and removals documentation](../deprecation_guidelines/#update-the-deprecations-and-removals-documentation).
|
||||
|
||||
## Method description
|
||||
|
||||
|
|
|
@ -15520,6 +15520,9 @@ msgstr ""
|
|||
msgid "ExternalIssueIntegration|This issue is synchronized with %{trackerName}"
|
||||
msgstr ""
|
||||
|
||||
msgid "ExternalWikiService|Enter the URL to the external wiki."
|
||||
msgstr ""
|
||||
|
||||
msgid "ExternalWikiService|External wiki"
|
||||
msgstr ""
|
||||
|
||||
|
@ -20767,6 +20770,9 @@ msgstr ""
|
|||
msgid "Integrations|Resetting this integration will clear the settings and deactivate this integration."
|
||||
msgstr ""
|
||||
|
||||
msgid "Integrations|Restrict to branch (optional)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Integrations|Return to GitLab for Jira"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@
|
|||
"pikaday": "^1.8.0",
|
||||
"popper.js": "^1.16.1",
|
||||
"portal-vue": "^2.1.7",
|
||||
"postcss": "8.4.5",
|
||||
"postcss": "8.4.14",
|
||||
"prismjs": "^1.21.0",
|
||||
"prosemirror-markdown": "1.8.0",
|
||||
"prosemirror-model": "^1.16.1",
|
||||
|
@ -201,7 +201,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@gitlab/eslint-plugin": "12.1.0",
|
||||
"@gitlab/stylelint-config": "4.0.0",
|
||||
"@gitlab/stylelint-config": "4.1.0",
|
||||
"@graphql-eslint/eslint-plugin": "3.10.4",
|
||||
"@testing-library/dom": "^7.16.2",
|
||||
"@types/jest": "^26.0.24",
|
||||
|
@ -248,7 +248,7 @@
|
|||
"purgecss": "^4.0.3",
|
||||
"purgecss-from-html": "^4.0.3",
|
||||
"sass": "^1.49.9",
|
||||
"stylelint": "^14.3.0",
|
||||
"stylelint": "^14.9.1",
|
||||
"timezone-mock": "^1.0.8",
|
||||
"vue-jest": "4.0.1",
|
||||
"webpack-dev-server": "4.9.2",
|
||||
|
|
|
@ -34,7 +34,7 @@ module RuboCop
|
|||
#
|
||||
# class Gitlab::MyDomain::MyClass
|
||||
# end
|
||||
class NamespacedClass < RuboCop::Cop::Cop
|
||||
class NamespacedClass < RuboCop::Cop::Base
|
||||
MSG = 'Classes must be declared inside a module indicating a product domain namespace. For more info: https://gitlab.com/gitlab-org/gitlab/-/issues/321982'
|
||||
|
||||
# These namespaces are considered top-level semantically.
|
||||
|
@ -51,7 +51,7 @@ module RuboCop
|
|||
# Remove class name because it's not a domain namespace.
|
||||
add_potential_domain_namespace(node) { _1.pop }
|
||||
|
||||
add_offense(node) if domain_namespaces.none?
|
||||
add_offense(node.loc.name) if domain_namespaces.none?
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -14,7 +14,7 @@ jq -crM '.vulnerabilities |
|
|||
) |
|
||||
sort |
|
||||
if length > 0 then
|
||||
{ body: ("The findings below have been detected based on the [AppSec custom Semgrep rules](https://gitlab.com/gitlab-com/gl-security/appsec/sast-custom-rules/) and need attention:\n\n" + join("\n") + "\n\n/cc @gitlab-com/gl-security/appsec") }
|
||||
{ body: ("The findings below have been detected based on the AppSec custom SAST rules. For more information about this bot and what to do with this comment head over to the [README](https://gitlab.com/gitlab-com/gl-security/appsec/sast-custom-rules/-/tree/main/appsec-pings). The following lines of code possibly need attention:\n\n" + join("\n") + "\n\n/cc @gitlab-com/gl-security/appsec") }
|
||||
else
|
||||
empty
|
||||
end' gl-sast-report.json >findings.txt
|
||||
|
|
|
@ -217,8 +217,7 @@ describe('note_app', () => {
|
|||
});
|
||||
|
||||
afterEach(() => {
|
||||
waitForDiscussionsRequest();
|
||||
resetHTMLFixture();
|
||||
return waitForDiscussionsRequest().then(() => resetHTMLFixture());
|
||||
});
|
||||
|
||||
it('renders skeleton notes', () => {
|
||||
|
@ -471,7 +470,7 @@ describe('note_app', () => {
|
|||
wrapper = shallowMount(NotesApp, { propsData, store: createStore() });
|
||||
await waitForPromises();
|
||||
|
||||
expect(axiosMock.history.get[0].params).toBeUndefined();
|
||||
expect(axiosMock.history.get[0].params).toEqual({ per_page: 20 });
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -496,14 +495,14 @@ describe('note_app', () => {
|
|||
wrapper = mountWithNotesFilter(undefined);
|
||||
await waitForPromises();
|
||||
|
||||
expect(axiosMock.history.get[0].params).toBeUndefined();
|
||||
expect(axiosMock.history.get[0].params).toEqual({ per_page: 20 });
|
||||
});
|
||||
|
||||
it('does not include extra query params when filter is already set to default', async () => {
|
||||
wrapper = mountWithNotesFilter(constants.DISCUSSION_FILTERS_DEFAULT_VALUE);
|
||||
await waitForPromises();
|
||||
|
||||
expect(axiosMock.history.get[0].params).toBeUndefined();
|
||||
expect(axiosMock.history.get[0].params).toEqual({ per_page: 20 });
|
||||
});
|
||||
|
||||
it('includes extra query params when filter is not set to default', async () => {
|
||||
|
@ -512,6 +511,7 @@ describe('note_app', () => {
|
|||
|
||||
expect(axiosMock.history.get[0].params).toEqual({
|
||||
notes_filter: constants.DISCUSSION_FILTERS_DEFAULT_VALUE,
|
||||
per_page: 20,
|
||||
persist_filter: false,
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1351,7 +1351,7 @@ describe('Actions Notes Store', () => {
|
|||
return testAction(
|
||||
actions.fetchDiscussions,
|
||||
{},
|
||||
null,
|
||||
{ noteableType: notesConstants.MERGE_REQUEST_NOTEABLE_TYPE },
|
||||
[
|
||||
{ type: mutationTypes.ADD_OR_UPDATE_DISCUSSIONS, payload: { discussion } },
|
||||
{ type: mutationTypes.SET_FETCHING_DISCUSSIONS, payload: false },
|
||||
|
@ -1360,13 +1360,11 @@ describe('Actions Notes Store', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('dispatches `fetchDiscussionsBatch` action if `paginatedIssueDiscussions` feature flag is enabled', () => {
|
||||
window.gon = { features: { paginatedIssueDiscussions: true } };
|
||||
|
||||
it('dispatches `fetchDiscussionsBatch` action if noteable is an Issue', () => {
|
||||
return testAction(
|
||||
actions.fetchDiscussions,
|
||||
{ path: 'test-path', filter: 'test-filter', persistFilter: 'test-persist-filter' },
|
||||
null,
|
||||
{ noteableType: notesConstants.ISSUE_NOTEABLE_TYPE },
|
||||
[],
|
||||
[
|
||||
{
|
||||
|
@ -1389,7 +1387,7 @@ describe('Actions Notes Store', () => {
|
|||
return testAction(
|
||||
actions.fetchDiscussions,
|
||||
{ path: 'test-path', filter: 'test-filter', persistFilter: 'test-persist-filter' },
|
||||
null,
|
||||
{ noteableType: notesConstants.MERGE_REQUEST_NOTEABLE_TYPE },
|
||||
[],
|
||||
[
|
||||
{
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Elasticsearch::Logs::Lines do
|
||||
let(:client) { Elasticsearch::Transport::Client }
|
||||
|
||||
let(:es_message_1) { { timestamp: "2019-12-13T14:35:34.034Z", pod: "production-6866bc8974-m4sk4", message: "10.8.2.1 - - [25/Oct/2019:08:03:22 UTC] \"GET / HTTP/1.1\" 200 13" } }
|
||||
let(:es_message_2) { { timestamp: "2019-12-13T14:35:35.034Z", pod: "production-6866bc8974-m4sk4", message: "10.8.2.1 - - [27/Oct/2019:23:49:54 UTC] \"GET / HTTP/1.1\" 200 13" } }
|
||||
let(:es_message_3) { { timestamp: "2019-12-13T14:35:36.034Z", pod: "production-6866bc8974-m4sk4", message: "10.8.2.1 - - [04/Nov/2019:23:09:24 UTC] \"GET / HTTP/1.1\" 200 13" } }
|
||||
let(:es_message_4) { { timestamp: "2019-12-13T14:35:37.034Z", pod: "production-6866bc8974-m4sk4", message: "- -\u003e /" } }
|
||||
|
||||
let(:es_response) { Gitlab::Json.parse(fixture_file('lib/elasticsearch/logs_response.json')) }
|
||||
|
||||
subject { described_class.new(client) }
|
||||
|
||||
let(:namespace) { "autodevops-deploy-9-production" }
|
||||
let(:pod_name) { "production-6866bc8974-m4sk4" }
|
||||
let(:container_name) { "auto-deploy-app" }
|
||||
let(:search) { "foo +bar "}
|
||||
let(:start_time) { "2019-12-13T14:35:34.034Z" }
|
||||
let(:end_time) { "2019-12-13T14:35:34.034Z" }
|
||||
let(:cursor) { "9999934,1572449784442" }
|
||||
|
||||
let(:body) { Gitlab::Json.parse(fixture_file('lib/elasticsearch/query.json')) }
|
||||
let(:body_with_container) { Gitlab::Json.parse(fixture_file('lib/elasticsearch/query_with_container.json')) }
|
||||
let(:body_with_search) { Gitlab::Json.parse(fixture_file('lib/elasticsearch/query_with_search.json')) }
|
||||
let(:body_with_times) { Gitlab::Json.parse(fixture_file('lib/elasticsearch/query_with_times.json')) }
|
||||
let(:body_with_start_time) { Gitlab::Json.parse(fixture_file('lib/elasticsearch/query_with_start_time.json')) }
|
||||
let(:body_with_end_time) { Gitlab::Json.parse(fixture_file('lib/elasticsearch/query_with_end_time.json')) }
|
||||
let(:body_with_cursor) { Gitlab::Json.parse(fixture_file('lib/elasticsearch/query_with_cursor.json')) }
|
||||
let(:body_with_filebeat_6) { Gitlab::Json.parse(fixture_file('lib/elasticsearch/query_with_filebeat_6.json')) }
|
||||
|
||||
RSpec::Matchers.define :a_hash_equal_to_json do |expected|
|
||||
match do |actual|
|
||||
actual.as_json == expected
|
||||
end
|
||||
end
|
||||
|
||||
describe '#pod_logs' do
|
||||
it 'returns the logs as an array' do
|
||||
expect(client).to receive(:search).with(body: a_hash_equal_to_json(body)).and_return(es_response)
|
||||
|
||||
result = subject.pod_logs(namespace, pod_name: pod_name)
|
||||
expect(result).to eq(logs: [es_message_4, es_message_3, es_message_2, es_message_1], cursor: cursor)
|
||||
end
|
||||
|
||||
it 'can further filter the logs by container name' do
|
||||
expect(client).to receive(:search).with(body: a_hash_equal_to_json(body_with_container)).and_return(es_response)
|
||||
|
||||
result = subject.pod_logs(namespace, pod_name: pod_name, container_name: container_name)
|
||||
expect(result).to eq(logs: [es_message_4, es_message_3, es_message_2, es_message_1], cursor: cursor)
|
||||
end
|
||||
|
||||
it 'can further filter the logs by search' do
|
||||
expect(client).to receive(:search).with(body: a_hash_equal_to_json(body_with_search)).and_return(es_response)
|
||||
|
||||
result = subject.pod_logs(namespace, pod_name: pod_name, search: search)
|
||||
expect(result).to eq(logs: [es_message_4, es_message_3, es_message_2, es_message_1], cursor: cursor)
|
||||
end
|
||||
|
||||
it 'can further filter the logs by start_time and end_time' do
|
||||
expect(client).to receive(:search).with(body: a_hash_equal_to_json(body_with_times)).and_return(es_response)
|
||||
|
||||
result = subject.pod_logs(namespace, pod_name: pod_name, start_time: start_time, end_time: end_time)
|
||||
expect(result).to eq(logs: [es_message_4, es_message_3, es_message_2, es_message_1], cursor: cursor)
|
||||
end
|
||||
|
||||
it 'can further filter the logs by only start_time' do
|
||||
expect(client).to receive(:search).with(body: a_hash_equal_to_json(body_with_start_time)).and_return(es_response)
|
||||
|
||||
result = subject.pod_logs(namespace, pod_name: pod_name, start_time: start_time)
|
||||
expect(result).to eq(logs: [es_message_4, es_message_3, es_message_2, es_message_1], cursor: cursor)
|
||||
end
|
||||
|
||||
it 'can further filter the logs by only end_time' do
|
||||
expect(client).to receive(:search).with(body: a_hash_equal_to_json(body_with_end_time)).and_return(es_response)
|
||||
|
||||
result = subject.pod_logs(namespace, pod_name: pod_name, end_time: end_time)
|
||||
expect(result).to eq(logs: [es_message_4, es_message_3, es_message_2, es_message_1], cursor: cursor)
|
||||
end
|
||||
|
||||
it 'can search after a cursor' do
|
||||
expect(client).to receive(:search).with(body: a_hash_equal_to_json(body_with_cursor)).and_return(es_response)
|
||||
|
||||
result = subject.pod_logs(namespace, pod_name: pod_name, cursor: cursor)
|
||||
expect(result).to eq(logs: [es_message_4, es_message_3, es_message_2, es_message_1], cursor: cursor)
|
||||
end
|
||||
|
||||
it 'can search on filebeat 6' do
|
||||
expect(client).to receive(:search).with(body: a_hash_equal_to_json(body_with_filebeat_6)).and_return(es_response)
|
||||
|
||||
result = subject.pod_logs(namespace, pod_name: pod_name, chart_above_v2: false)
|
||||
expect(result).to eq(logs: [es_message_4, es_message_3, es_message_2, es_message_1], cursor: cursor)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,35 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Elasticsearch::Logs::Pods do
|
||||
let(:client) { Elasticsearch::Transport::Client }
|
||||
|
||||
let(:es_query) { Gitlab::Json.parse(fixture_file('lib/elasticsearch/pods_query.json'), symbolize_names: true) }
|
||||
let(:es_response) { Gitlab::Json.parse(fixture_file('lib/elasticsearch/pods_response.json')) }
|
||||
let(:namespace) { "autodevops-deploy-9-production" }
|
||||
|
||||
subject { described_class.new(client) }
|
||||
|
||||
describe '#pods' do
|
||||
it 'returns the pods' do
|
||||
expect(client).to receive(:search).with(body: es_query).and_return(es_response)
|
||||
|
||||
result = subject.pods(namespace)
|
||||
expect(result).to eq([
|
||||
{
|
||||
name: "runner-gitlab-runner-7bbfb5dcb5-p6smb",
|
||||
container_names: %w[runner-gitlab-runner]
|
||||
},
|
||||
{
|
||||
name: "elastic-stack-elasticsearch-master-1",
|
||||
container_names: %w[elasticsearch chown sysctl]
|
||||
},
|
||||
{
|
||||
name: "ingress-nginx-ingress-controller-76449bcc8d-8qgl6",
|
||||
container_names: %w[nginx-ingress-controller]
|
||||
}
|
||||
])
|
||||
end
|
||||
end
|
||||
end
|
|
@ -292,15 +292,15 @@ RSpec.describe Integrations::BaseChatNotification do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#get_channel_field' do
|
||||
describe '#event_channel_value' do
|
||||
it 'returns the channel field value for the given event' do
|
||||
subject.push_channel = '#pushes'
|
||||
|
||||
expect(subject.get_channel_field(:push)).to eq('#pushes')
|
||||
expect(subject.event_channel_value(:push)).to eq('#pushes')
|
||||
end
|
||||
|
||||
it 'raises an error for unsupported events' do
|
||||
expect { subject.get_channel_field(:foo) }.to raise_error(NoMethodError)
|
||||
expect { subject.event_channel_value(:foo) }.to raise_error(NoMethodError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -475,47 +475,4 @@ RSpec.describe Integrations::Prometheus, :use_clean_rails_memory_store_caching,
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#fields' do
|
||||
let(:expected_fields) do
|
||||
[
|
||||
{
|
||||
type: 'checkbox',
|
||||
name: 'manual_configuration',
|
||||
title: s_('PrometheusService|Active'),
|
||||
help: s_('PrometheusService|Select this checkbox to override the auto configuration settings with your own settings.'),
|
||||
required: true
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'api_url',
|
||||
title: 'API URL',
|
||||
placeholder: s_('PrometheusService|https://prometheus.example.com/'),
|
||||
help: s_('PrometheusService|The Prometheus API base URL.'),
|
||||
required: true
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'google_iap_audience_client_id',
|
||||
title: 'Google IAP Audience Client ID',
|
||||
placeholder: s_('PrometheusService|IAP_CLIENT_ID.apps.googleusercontent.com'),
|
||||
help: s_('PrometheusService|The ID of the IAP-secured resource.'),
|
||||
autocomplete: 'off',
|
||||
required: false
|
||||
},
|
||||
{
|
||||
type: 'textarea',
|
||||
name: 'google_iap_service_account_json',
|
||||
title: 'Google IAP Service Account JSON',
|
||||
placeholder: s_('PrometheusService|{ "type": "service_account", "project_id": ... }'),
|
||||
help: s_('PrometheusService|The contents of the credentials.json file of your service account.'),
|
||||
required: false
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
it 'returns fields' do
|
||||
expect(integration.fields).to eq(expected_fields)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,90 +26,7 @@ RSpec.describe API::Environments do
|
|||
expect(json_response.first['tier']).to eq(environment.tier)
|
||||
expect(json_response.first['external_url']).to eq(environment.external_url)
|
||||
expect(json_response.first['project']).to match_schema('public_api/v4/project')
|
||||
expect(json_response.first['enable_advanced_logs_querying']).to eq(false)
|
||||
expect(json_response.first).not_to have_key('last_deployment')
|
||||
expect(json_response.first).not_to have_key('gitlab_managed_apps_logs_path')
|
||||
end
|
||||
|
||||
context 'when the user can read pod logs' do
|
||||
context 'with successful deployment on cluster' do
|
||||
let_it_be(:deployment) { create(:deployment, :on_cluster, :success, environment: environment, project: project) }
|
||||
|
||||
it 'returns environment with enable_advanced_logs_querying and logs_api_path' do
|
||||
get api("/projects/#{project.id}/environments", user)
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response).to include_pagination_headers
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.size).to eq(1)
|
||||
expect(json_response.first['gitlab_managed_apps_logs_path']).to eq(
|
||||
"/#{project.full_path}/-/logs/k8s.json?cluster_id=#{deployment.cluster_id}"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when elastic stack is available' do
|
||||
before do
|
||||
allow_next_found_instance_of(Environment) do |env|
|
||||
allow(env).to receive(:elastic_stack_available?).and_return(true)
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns environment with enable_advanced_logs_querying and logs_api_path' do
|
||||
get api("/projects/#{project.id}/environments", user)
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response).to include_pagination_headers
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.size).to eq(1)
|
||||
expect(json_response.first['enable_advanced_logs_querying']).to eq(true)
|
||||
expect(json_response.first['logs_api_path']).to eq(
|
||||
"/#{project.full_path}/-/logs/elasticsearch.json?environment_name=#{environment.name}"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when elastic stack is not available' do
|
||||
before do
|
||||
allow_next_found_instance_of(Environment) do |env|
|
||||
allow(env).to receive(:elastic_stack_available?).and_return(false)
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns environment with enable_advanced_logs_querying logs_api_path' do
|
||||
get api("/projects/#{project.id}/environments", user)
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response).to include_pagination_headers
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.size).to eq(1)
|
||||
expect(json_response.first['enable_advanced_logs_querying']).to eq(false)
|
||||
expect(json_response.first['logs_api_path']).to eq(
|
||||
"/#{project.full_path}/-/logs/k8s.json?environment_name=#{environment.name}"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user cannot read pod logs' do
|
||||
before do
|
||||
allow_next_found_instance_of(User) do |user|
|
||||
allow(user).to receive(:can?).and_call_original
|
||||
allow(user).to receive(:can?).with(:read_pod_logs, project).and_return(false)
|
||||
end
|
||||
end
|
||||
|
||||
it 'does not contain enable_advanced_logs_querying' do
|
||||
get api("/projects/#{project.id}/environments", user)
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response).to include_pagination_headers
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.size).to eq(1)
|
||||
expect(json_response.first).not_to have_key('enable_advanced_logs_querying')
|
||||
expect(json_response.first).not_to have_key('logs_api_path')
|
||||
expect(json_response.first).not_to have_key('gitlab_managed_apps_logs_path')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when filtering' do
|
||||
|
|
|
@ -50,22 +50,6 @@ RSpec.describe Projects::IssuesController do
|
|||
a_hash_including('id' => discussion_2.id.to_s)
|
||||
])
|
||||
end
|
||||
|
||||
context 'when paginated_issue_discussions is disabled' do
|
||||
before do
|
||||
stub_feature_flags(paginated_issue_discussions: false)
|
||||
end
|
||||
|
||||
it 'returns all discussions and ignores per_page param' do
|
||||
get_discussions(per_page: 2)
|
||||
|
||||
discussions = Gitlab::Json.parse(response.body)
|
||||
notes = discussions.flat_map { |d| d['notes'] }
|
||||
|
||||
expect(discussions.count).to eq(4)
|
||||
expect(notes.count).to eq(5)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ RSpec.describe RuboCop::Cop::Gitlab::NamespacedClass do
|
|||
it 'flags a class definition without additional namespace' do
|
||||
expect_offense(namespaced(<<~SOURCE))
|
||||
class MyClass
|
||||
^^^^^^^^^^^^^ #{described_class::MSG}
|
||||
^^^^^^^ #{described_class::MSG}
|
||||
end
|
||||
SOURCE
|
||||
end
|
||||
|
@ -28,7 +28,7 @@ RSpec.describe RuboCop::Cop::Gitlab::NamespacedClass do
|
|||
it 'flags a compact class definition without additional namespace' do
|
||||
expect_offense(<<~SOURCE, namespace: namespace)
|
||||
class %{namespace}::MyClass
|
||||
^{namespace}^^^^^^^^^^^^^^^ #{described_class::MSG}
|
||||
^{namespace}^^^^^^^^^ #{described_class::MSG}
|
||||
end
|
||||
SOURCE
|
||||
end
|
||||
|
@ -36,7 +36,7 @@ RSpec.describe RuboCop::Cop::Gitlab::NamespacedClass do
|
|||
it 'flags a class definition with inheritance without additional namespace' do
|
||||
expect_offense(namespaced(<<~SOURCE))
|
||||
class MyClass < ApplicationRecord
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{described_class::MSG}
|
||||
^^^^^^^ #{described_class::MSG}
|
||||
def some_method
|
||||
true
|
||||
end
|
||||
|
|
|
@ -56,37 +56,6 @@ RSpec.describe ClusterEntity do
|
|||
end
|
||||
end
|
||||
|
||||
context 'gitlab_managed_apps_logs_path' do
|
||||
let(:cluster) { create(:cluster, :project) }
|
||||
let(:user) { create(:user) }
|
||||
|
||||
subject { described_class.new(cluster, request: request).as_json }
|
||||
|
||||
before do
|
||||
allow_next_instance_of(Clusters::ClusterPresenter) do |presenter|
|
||||
allow(presenter).to receive(:show_path).and_return(nil)
|
||||
end
|
||||
end
|
||||
|
||||
it 'return projects log explorer path' do
|
||||
log_explorer_path = project_logs_path(cluster.project, cluster_id: cluster.id)
|
||||
|
||||
expect_next_instance_of(Clusters::ClusterPresenter, cluster, current_user: user) do |presenter|
|
||||
expect(presenter).to receive(:gitlab_managed_apps_logs_path).and_return(log_explorer_path)
|
||||
end
|
||||
|
||||
expect(subject[:gitlab_managed_apps_logs_path]).to eq(log_explorer_path)
|
||||
end
|
||||
|
||||
context 'when feature is disabled' do
|
||||
before do
|
||||
stub_feature_flags(monitor_logging: false)
|
||||
end
|
||||
|
||||
specify { is_expected.not_to include(:gitlab_managed_apps_logs_path) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'enable_advanced_logs_querying' do
|
||||
let(:cluster) { create(:cluster, :project) }
|
||||
let(:user) { create(:user) }
|
||||
|
|
|
@ -133,54 +133,6 @@ RSpec.describe EnvironmentEntity do
|
|||
end
|
||||
end
|
||||
|
||||
context 'pod_logs' do
|
||||
context 'with reporter access' do
|
||||
before do
|
||||
project.add_reporter(user)
|
||||
end
|
||||
|
||||
it 'does not expose logs keys' do
|
||||
expect(subject).not_to include(:logs_path)
|
||||
expect(subject).not_to include(:logs_api_path)
|
||||
expect(subject).not_to include(:enable_advanced_logs_querying)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with developer access' do
|
||||
before do
|
||||
project.add_developer(user)
|
||||
end
|
||||
|
||||
it 'exposes logs keys' do
|
||||
expect(subject).to include(:logs_path)
|
||||
expect(subject).to include(:logs_api_path)
|
||||
expect(subject).to include(:enable_advanced_logs_querying)
|
||||
end
|
||||
|
||||
it 'uses k8s api when ES is not available' do
|
||||
expect(subject[:logs_api_path]).to eq(k8s_project_logs_path(project, environment_name: environment.name, format: :json))
|
||||
end
|
||||
|
||||
it 'uses ES api when ES is available' do
|
||||
allow(environment).to receive(:elastic_stack_available?).and_return(true)
|
||||
|
||||
expect(subject[:logs_api_path]).to eq(elasticsearch_project_logs_path(project, environment_name: environment.name, format: :json))
|
||||
end
|
||||
|
||||
context 'with feature flag disabled' do
|
||||
before do
|
||||
stub_feature_flags(monitor_logging: false)
|
||||
end
|
||||
|
||||
it 'does not expose logs keys' do
|
||||
expect(subject).not_to include(:logs_path)
|
||||
expect(subject).not_to include(:logs_api_path)
|
||||
expect(subject).not_to include(:enable_advanced_logs_querying)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with deployment service ready' do
|
||||
before do
|
||||
allow(environment).to receive(:has_terminals?).and_return(true)
|
||||
|
|
169
yarn.lock
169
yarn.lock
|
@ -976,6 +976,11 @@
|
|||
exec-sh "^0.3.2"
|
||||
minimist "^1.2.0"
|
||||
|
||||
"@csstools/selector-specificity@^2.0.1":
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.0.1.tgz#b6b8d81780b9a9f6459f4bfe9226ac6aefaefe87"
|
||||
integrity sha512-aG20vknL4/YjQF9BSV7ts4EWm/yrjagAN7OWBNmlbEOUiu0llj4OGrFoOKK3g2vey4/p2omKCoHrWtPxSwV3HA==
|
||||
|
||||
"@discoveryjs/json-ext@^0.5.0":
|
||||
version "0.5.6"
|
||||
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f"
|
||||
|
@ -1034,14 +1039,14 @@
|
|||
resolved "https://registry.yarnpkg.com/@gitlab/favicon-overlay/-/favicon-overlay-2.0.0.tgz#2f32d0b6a4d5b8ac44e2927083d9ab478a78c984"
|
||||
integrity sha512-GNcORxXJ98LVGzOT9dDYKfbheqH6lNgPDD72lyXRnQIH7CjgGyos8i17aSBPq1f4s3zF3PyedFiAR4YEZbva2Q==
|
||||
|
||||
"@gitlab/stylelint-config@4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/stylelint-config/-/stylelint-config-4.0.0.tgz#d24646592908d92dce35aaa8e7bea66fd53e4160"
|
||||
integrity sha512-5avbb8XQLdnL/vdrxf9jvdPl/HPaXnI7Y/fArOHe1uMpgcBoBWUKmon15+lHJ4MgURsGuYSiM2FIgArDSylR4g==
|
||||
"@gitlab/stylelint-config@4.1.0":
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/stylelint-config/-/stylelint-config-4.1.0.tgz#bd431406c8f8725afba353652f08e42c3301a982"
|
||||
integrity sha512-WiTLRKoXutmAKR0z4Z/kuXiTAtblyA2XWX6vb2/NHhLd7oboKrxR8CiznSfw7SNxmYtqW/ripaQOdanR1fYMwA==
|
||||
dependencies:
|
||||
postcss-scss "4.0.3"
|
||||
postcss-scss "4.0.4"
|
||||
stylelint-declaration-strict-value "1.8.0"
|
||||
stylelint-scss "4.1.0"
|
||||
stylelint-scss "4.2.0"
|
||||
|
||||
"@gitlab/svgs@2.21.0":
|
||||
version "2.21.0"
|
||||
|
@ -3170,7 +3175,7 @@ braces@^2.3.1:
|
|||
split-string "^3.0.2"
|
||||
to-regex "^3.0.1"
|
||||
|
||||
braces@^3.0.1, braces@~3.0.2:
|
||||
braces@^3.0.2, braces@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
|
||||
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
|
||||
|
@ -4114,6 +4119,11 @@ css-color-names@0.0.4:
|
|||
resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0"
|
||||
integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=
|
||||
|
||||
css-functions-list@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/css-functions-list/-/css-functions-list-3.1.0.tgz#cf5b09f835ad91a00e5959bcfc627cd498e1321b"
|
||||
integrity sha512-/9lCvYZaUbBGvYUgYGFJ4dcYiyqdhSjG7IPVluoV8A1ILjkF7ilmhp1OGUz8n+nmBcu0RNrQAzgD8B6FJbrt2w==
|
||||
|
||||
css-loader@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-2.1.1.tgz#d8254f72e412bb2238bb44dd674ffbef497333ea"
|
||||
|
@ -4788,7 +4798,7 @@ debug@^3.1.0, debug@^3.2.6, debug@^3.2.7:
|
|||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4:
|
||||
debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
|
||||
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
|
||||
|
@ -6738,10 +6748,10 @@ html-escaper@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.0.tgz#71e87f931de3fe09e56661ab9a29aadec707b491"
|
||||
integrity sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==
|
||||
|
||||
html-tags@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140"
|
||||
integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==
|
||||
html-tags@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.2.0.tgz#dbb3518d20b726524e4dd43de397eb0a95726961"
|
||||
integrity sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==
|
||||
|
||||
html-void-elements@^2.0.0:
|
||||
version "2.0.1"
|
||||
|
@ -8117,10 +8127,10 @@ kleur@^4.0.3:
|
|||
resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.4.tgz#8c202987d7e577766d039a8cd461934c01cda04d"
|
||||
integrity sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==
|
||||
|
||||
known-css-properties@^0.24.0:
|
||||
version "0.24.0"
|
||||
resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.24.0.tgz#19aefd85003ae5698a5560d2b55135bf5432155c"
|
||||
integrity sha512-RTSoaUAfLvpR357vWzAz/50Q/BmHfmE6ETSWfutT0AJiw10e6CmcdYRQJlLRd95B53D0Y2aD1jSxD3V3ySF+PA==
|
||||
known-css-properties@^0.25.0:
|
||||
version "0.25.0"
|
||||
resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.25.0.tgz#6ebc4d4b412f602e5cfbeb4086bd544e34c0a776"
|
||||
integrity sha512-b0/9J1O9Jcyik1GC6KC42hJ41jKwdO/Mq8Mdo5sYN+IuRTXs2YFHZC3kZSx6ueusqa95x3wLYe/ytKjbAfGixA==
|
||||
|
||||
latest-version@^5.0.0:
|
||||
version "5.1.0"
|
||||
|
@ -9090,13 +9100,13 @@ micromatch@^3.1.10, micromatch@^3.1.4:
|
|||
snapdragon "^0.8.1"
|
||||
to-regex "^3.0.2"
|
||||
|
||||
micromatch@^4.0.2, micromatch@^4.0.4:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
|
||||
integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
|
||||
micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5:
|
||||
version "4.0.5"
|
||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
|
||||
integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
|
||||
dependencies:
|
||||
braces "^3.0.1"
|
||||
picomatch "^2.2.3"
|
||||
braces "^3.0.2"
|
||||
picomatch "^2.3.1"
|
||||
|
||||
miller-rabin@^4.0.0:
|
||||
version "4.0.1"
|
||||
|
@ -9366,10 +9376,10 @@ multicast-dns@^7.2.4:
|
|||
dns-packet "^5.2.2"
|
||||
thunky "^1.0.2"
|
||||
|
||||
nanoid@^3.1.30:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c"
|
||||
integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==
|
||||
nanoid@^3.3.4:
|
||||
version "3.3.4"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
|
||||
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
|
||||
|
||||
nanomatch@^1.2.9:
|
||||
version "1.2.13"
|
||||
|
@ -9549,11 +9559,6 @@ normalize-path@^3.0.0, normalize-path@~3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
||||
|
||||
normalize-selector@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-selector/-/normalize-selector-0.2.0.tgz#d0b145eb691189c63a78d201dc4fdb1293ef0c03"
|
||||
integrity sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=
|
||||
|
||||
normalize-url@^4.1.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129"
|
||||
|
@ -10056,10 +10061,10 @@ picocolors@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
||||
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
|
||||
|
||||
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
|
||||
integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
|
||||
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
|
||||
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
|
||||
|
||||
pify@^2.0.0:
|
||||
version "2.3.0"
|
||||
|
@ -10176,15 +10181,15 @@ postcss-safe-parser@^6.0.0:
|
|||
resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz#bb4c29894171a94bc5c996b9a30317ef402adaa1"
|
||||
integrity sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==
|
||||
|
||||
postcss-scss@4.0.3:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-4.0.3.tgz#36c23c19a804274e722e83a54d20b838ab4767ac"
|
||||
integrity sha512-j4KxzWovfdHsyxwl1BxkUal/O4uirvHgdzMKS1aWJBAV0qh2qj5qAZqpeBfVUYGWv+4iK9Az7SPyZ4fyNju1uA==
|
||||
postcss-scss@4.0.4:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-4.0.4.tgz#aa8f60e19ee18259bc193db9e4b96edfce3f3b1f"
|
||||
integrity sha512-aBBbVyzA8b3hUL0MGrpydxxXKXFZc5Eqva0Q3V9qsBOLEMsjb6w49WfpsoWzpEgcqJGW4t7Rio8WXVU9Gd8vWg==
|
||||
|
||||
postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.6, postcss-selector-parser@^6.0.9:
|
||||
version "6.0.9"
|
||||
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz#ee71c3b9ff63d9cd130838876c13a2ec1a992b2f"
|
||||
integrity sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ==
|
||||
postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.6, postcss-selector-parser@^6.0.9:
|
||||
version "6.0.10"
|
||||
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d"
|
||||
integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==
|
||||
dependencies:
|
||||
cssesc "^3.0.0"
|
||||
util-deprecate "^1.0.2"
|
||||
|
@ -10199,14 +10204,14 @@ postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
|
|||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
|
||||
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
|
||||
|
||||
postcss@8.4.5, postcss@^8.2.1, postcss@^8.4.5:
|
||||
version "8.4.5"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95"
|
||||
integrity sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==
|
||||
postcss@8.4.14, postcss@^8.2.1, postcss@^8.4.14:
|
||||
version "8.4.14"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.14.tgz#ee9274d5622b4858c1007a74d76e42e56fd21caf"
|
||||
integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==
|
||||
dependencies:
|
||||
nanoid "^3.1.30"
|
||||
nanoid "^3.3.4"
|
||||
picocolors "^1.0.0"
|
||||
source-map-js "^1.0.1"
|
||||
source-map-js "^1.0.2"
|
||||
|
||||
postcss@^7.0.14, postcss@^7.0.5, postcss@^7.0.6:
|
||||
version "7.0.39"
|
||||
|
@ -11406,10 +11411,10 @@ sigmund@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590"
|
||||
integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=
|
||||
|
||||
signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3:
|
||||
version "3.0.6"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af"
|
||||
integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==
|
||||
signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7:
|
||||
version "3.0.7"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
|
||||
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
|
||||
|
||||
sirv@^1.0.7:
|
||||
version "1.0.11"
|
||||
|
@ -11502,7 +11507,7 @@ source-list-map@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085"
|
||||
integrity sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==
|
||||
|
||||
"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1:
|
||||
"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
|
||||
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
|
||||
|
@ -11600,11 +11605,6 @@ spdy@^4.0.2:
|
|||
select-hose "^2.0.0"
|
||||
spdy-transport "^3.0.0"
|
||||
|
||||
specificity@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/specificity/-/specificity-0.4.1.tgz#aab5e645012db08ba182e151165738d00887b019"
|
||||
integrity sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==
|
||||
|
||||
split-string@^3.0.1, split-string@^3.0.2:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2"
|
||||
|
@ -11846,10 +11846,10 @@ stylelint-declaration-strict-value@1.8.0:
|
|||
css-values "^0.1.0"
|
||||
shortcss "^0.1.3"
|
||||
|
||||
stylelint-scss@4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/stylelint-scss/-/stylelint-scss-4.1.0.tgz#39b808696f8152081163d970449257ff80b5c041"
|
||||
integrity sha512-BNYTo7MMamhFOlcaAWp2dMpjg6hPyM/FFqfDIYzmYVLMmQJqc8lWRIiTqP4UX5bresj9Vo0dKC6odSh43VP2NA==
|
||||
stylelint-scss@4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/stylelint-scss/-/stylelint-scss-4.2.0.tgz#e25fd390ee38a7e89fcfaec2a8f9dce2ec6ddee8"
|
||||
integrity sha512-HHHMVKJJ5RM9pPIbgJ/XA67h9H0407G68Rm69H4fzFbFkyDMcTV1Byep3qdze5+fJ3c0U7mJrbj6S0Fg072uZA==
|
||||
dependencies:
|
||||
lodash "^4.17.21"
|
||||
postcss-media-query-parser "^0.2.3"
|
||||
|
@ -11857,15 +11857,17 @@ stylelint-scss@4.1.0:
|
|||
postcss-selector-parser "^6.0.6"
|
||||
postcss-value-parser "^4.1.0"
|
||||
|
||||
stylelint@^14.3.0:
|
||||
version "14.3.0"
|
||||
resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-14.3.0.tgz#26b62730da7b3dc320021fc469d80048d7b77ebe"
|
||||
integrity sha512-PZXSwtJe4f4qBPWBwAbHL0M0Qjrv8iHN+cLpUNsffaVMS3YzpDDRI73+2lsqLAYfQEzxRwpll6BDKImREbpHWA==
|
||||
stylelint@^14.9.1:
|
||||
version "14.9.1"
|
||||
resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-14.9.1.tgz#6494ed38f148b1e75b402d678a3b6a8aae86dfda"
|
||||
integrity sha512-RdAkJdPiLqHawCSnu21nE27MjNXaVd4WcOHA4vK5GtIGjScfhNnaOuWR2wWdfKFAvcWQPOYe311iveiVKSmwsA==
|
||||
dependencies:
|
||||
"@csstools/selector-specificity" "^2.0.1"
|
||||
balanced-match "^2.0.0"
|
||||
colord "^2.9.2"
|
||||
cosmiconfig "^7.0.1"
|
||||
debug "^4.3.3"
|
||||
css-functions-list "^3.1.0"
|
||||
debug "^4.3.4"
|
||||
execall "^2.0.0"
|
||||
fast-glob "^3.2.11"
|
||||
fastest-levenshtein "^1.0.12"
|
||||
|
@ -11874,26 +11876,24 @@ stylelint@^14.3.0:
|
|||
global-modules "^2.0.0"
|
||||
globby "^11.1.0"
|
||||
globjoin "^0.1.4"
|
||||
html-tags "^3.1.0"
|
||||
html-tags "^3.2.0"
|
||||
ignore "^5.2.0"
|
||||
import-lazy "^4.0.0"
|
||||
imurmurhash "^0.1.4"
|
||||
is-plain-object "^5.0.0"
|
||||
known-css-properties "^0.24.0"
|
||||
known-css-properties "^0.25.0"
|
||||
mathml-tag-names "^2.1.3"
|
||||
meow "^9.0.0"
|
||||
micromatch "^4.0.4"
|
||||
micromatch "^4.0.5"
|
||||
normalize-path "^3.0.0"
|
||||
normalize-selector "^0.2.0"
|
||||
picocolors "^1.0.0"
|
||||
postcss "^8.4.5"
|
||||
postcss "^8.4.14"
|
||||
postcss-media-query-parser "^0.2.3"
|
||||
postcss-resolve-nested-selector "^0.1.1"
|
||||
postcss-safe-parser "^6.0.0"
|
||||
postcss-selector-parser "^6.0.9"
|
||||
postcss-selector-parser "^6.0.10"
|
||||
postcss-value-parser "^4.2.0"
|
||||
resolve-from "^5.0.0"
|
||||
specificity "^0.4.1"
|
||||
string-width "^4.2.3"
|
||||
strip-ansi "^6.0.1"
|
||||
style-search "^0.1.0"
|
||||
|
@ -11901,7 +11901,7 @@ stylelint@^14.3.0:
|
|||
svg-tags "^1.0.0"
|
||||
table "^6.8.0"
|
||||
v8-compile-cache "^2.3.0"
|
||||
write-file-atomic "^4.0.0"
|
||||
write-file-atomic "^4.0.1"
|
||||
|
||||
stylis@^4.0.10:
|
||||
version "4.0.10"
|
||||
|
@ -12382,11 +12382,6 @@ typedarray-to-buffer@^3.1.5:
|
|||
dependencies:
|
||||
is-typedarray "^1.0.0"
|
||||
|
||||
typedarray-to-buffer@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-4.0.0.tgz#cdd2933c61dd3f5f02eda5d012d441f95bfeb50a"
|
||||
integrity sha512-6dOYeZfS3O9RtRD1caom0sMxgK59b27+IwoNy8RDPsmslSGOyU+mpTamlaIW7aNKi90ZQZ9DFaZL3YRoiSCULQ==
|
||||
|
||||
typedarray@^0.0.6:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
|
@ -13311,15 +13306,13 @@ write-file-atomic@^3.0.0:
|
|||
signal-exit "^3.0.2"
|
||||
typedarray-to-buffer "^3.1.5"
|
||||
|
||||
write-file-atomic@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.0.tgz#0eff5dc687d3e22535ca3fca8558124645a4b053"
|
||||
integrity sha512-JhcWoKffJNF7ivO9yflBhc7tn3wKnokMUfWpBriM9yCXj4ePQnRPcWglBkkg1AHC8nsW/EfxwwhqsLtOy59djA==
|
||||
write-file-atomic@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.1.tgz#9faa33a964c1c85ff6f849b80b42a88c2c537c8f"
|
||||
integrity sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==
|
||||
dependencies:
|
||||
imurmurhash "^0.1.4"
|
||||
is-typedarray "^1.0.0"
|
||||
signal-exit "^3.0.2"
|
||||
typedarray-to-buffer "^4.0.0"
|
||||
signal-exit "^3.0.7"
|
||||
|
||||
"ws@^5.2.0 || ^6.0.0 || ^7.0.0", ws@^7.2.3, ws@^7.3.1:
|
||||
version "7.5.5"
|
||||
|
|
Loading…
Reference in New Issue