Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
012ed4e4f6
commit
cc1e91be1c
2
Gemfile
2
Gemfile
|
@ -347,7 +347,7 @@ gem 'warning', '~> 1.3.0'
|
|||
group :development do
|
||||
gem 'lefthook', '~> 1.0.0', require: false
|
||||
gem 'rubocop'
|
||||
gem 'solargraph', '~> 0.44.3', require: false
|
||||
gem 'solargraph', '~> 0.45.0', require: false
|
||||
|
||||
gem 'letter_opener_web', '~> 2.0.0'
|
||||
|
||||
|
|
12
Gemfile.lock
12
Gemfile.lock
|
@ -310,7 +310,7 @@ GEM
|
|||
devise (~> 4.0)
|
||||
railties (< 7.1)
|
||||
rotp (~> 6.0)
|
||||
diff-lcs (1.4.4)
|
||||
diff-lcs (1.5.0)
|
||||
diff_match_patch (0.1.0)
|
||||
diffy (3.3.0)
|
||||
discordrb-webhooks (3.4.2)
|
||||
|
@ -744,7 +744,7 @@ GEM
|
|||
grpc (~> 1.0)
|
||||
knapsack (1.21.1)
|
||||
rake
|
||||
kramdown (2.3.1)
|
||||
kramdown (2.3.2)
|
||||
rexml
|
||||
kramdown-parser-gfm (1.1.0)
|
||||
kramdown (~> 2.0)
|
||||
|
@ -838,7 +838,7 @@ GEM
|
|||
netrc (0.11.0)
|
||||
nio4r (2.5.8)
|
||||
no_proxy_fix (0.1.2)
|
||||
nokogiri (1.13.6)
|
||||
nokogiri (1.13.7)
|
||||
mini_portile2 (~> 2.8.0)
|
||||
racc (~> 1.4)
|
||||
notiffany (0.1.3)
|
||||
|
@ -1172,7 +1172,7 @@ GEM
|
|||
rubocop-ast (>= 0.6.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 1.4.0, < 2.0)
|
||||
rubocop-ast (1.18.0)
|
||||
rubocop-ast (1.19.1)
|
||||
parser (>= 3.1.1.0)
|
||||
rubocop-gitlab-security (0.1.1)
|
||||
rubocop (>= 0.51)
|
||||
|
@ -1281,7 +1281,7 @@ GEM
|
|||
slack-messenger (2.3.4)
|
||||
snowplow-tracker (0.6.1)
|
||||
contracts (~> 0.7, <= 0.11)
|
||||
solargraph (0.44.3)
|
||||
solargraph (0.45.0)
|
||||
backport (~> 1.2)
|
||||
benchmark
|
||||
bundler (>= 1.17.2)
|
||||
|
@ -1730,7 +1730,7 @@ DEPENDENCIES
|
|||
simplecov-lcov (~> 0.8.0)
|
||||
slack-messenger (~> 2.3.4)
|
||||
snowplow-tracker (~> 0.6.1)
|
||||
solargraph (~> 0.44.3)
|
||||
solargraph (~> 0.45.0)
|
||||
spamcheck (~> 0.1.0)
|
||||
spring (~> 2.1.0)
|
||||
spring-commands-rspec (~> 1.0.4)
|
||||
|
|
|
@ -367,6 +367,7 @@ export default {
|
|||
:img-alt="avatarUrlTitle(assignee)"
|
||||
:img-src="avatarUrl(assignee)"
|
||||
:img-size="24"
|
||||
img-css-classes="avatar gl-mr-0!"
|
||||
class="js-no-trigger"
|
||||
tooltip-placement="bottom"
|
||||
>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { KeyMod, KeyCode } from 'monaco-editor';
|
||||
import { debounce } from 'lodash';
|
||||
import { BLOB_PREVIEW_ERROR } from '~/blob_edit/constants';
|
||||
import createFlash from '~/flash';
|
||||
|
@ -158,8 +159,8 @@ export class EditorMarkdownPreviewExtension {
|
|||
if (instance.getAction(EXTENSION_MARKDOWN_PREVIEW_ACTION_ID)) return;
|
||||
const actionBasis = {
|
||||
keybindings: [
|
||||
// eslint-disable-next-line no-bitwise,no-undef
|
||||
monaco.KeyMod.chord(monaco.KeyMod.CtrlCmd | monaco.KeyMod.Shift | monaco.KeyCode.KEY_P),
|
||||
// eslint-disable-next-line no-bitwise
|
||||
KeyMod.chord(KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_P),
|
||||
],
|
||||
contextMenuGroupId: 'navigation',
|
||||
contextMenuOrder: 1.5,
|
||||
|
|
|
@ -27,8 +27,8 @@ export default function initLinkedResources() {
|
|||
render: (createElement) =>
|
||||
createElement('resource-links-block', {
|
||||
props: {
|
||||
issuableId,
|
||||
helpPath,
|
||||
issuableId: parseInt(issuableId, 10),
|
||||
canAddResourceLinks: parseBoolean(canAddResourceLinks),
|
||||
},
|
||||
}),
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import { editor } from 'monaco-editor';
|
||||
import { Sortable } from 'sortablejs';
|
||||
import simulateDrag from './simulate_drag';
|
||||
import simulateInput from './simulate_input';
|
||||
|
||||
// Export to global space for rspec to use
|
||||
window.localMonaco = editor;
|
||||
window.simulateDrag = simulateDrag;
|
||||
window.simulateInput = simulateInput;
|
||||
window.Sortable = Sortable;
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
### Widget Extensions
|
||||
|
||||
#### Telemetry
|
||||
|
||||
Telemetry is enabled by default in all widget extensions.
|
||||
|
||||
However, telemetry events are not reported until they have been marked as a "known event" with a Metric Dictionary.
|
||||
|
||||
If telemetry metrics are desired when adding a widget extension, it is important to also create known events.
|
||||
|
||||
The following steps are needed to generate these known events for a single widget:
|
||||
|
||||
1. Widgets should be named `Widget${CamelName}`.
|
||||
- For example: a widget for "Test Reports" should be `WidgetTestReports`
|
||||
1. "Compute" the widget name slug by converting the `${CamelName}` to lower-, snake-case.
|
||||
- The above example would be `test_reports`
|
||||
1. Add the new widget name slug to `lib/gitlab/usage_data_counters/merge_request_widget_extension_counter.rb` in the `WIDGETS` list.
|
||||
1. Ensure the GDK is running (`gdk start`)
|
||||
1. Generate known events on the command line with the following command. Replace `test_reports` with your appropriate name slug.
|
||||
```
|
||||
bundle exec rails generate gitlab:usage_metric_definition \
|
||||
counts.code_review.i_merge_request_widget_test_reports_count_view \
|
||||
counts.code_review.i_merge_request_widget_test_reports_count_full_report_clicked \
|
||||
counts.code_review.i_merge_request_widget_test_reports_count_expand \
|
||||
counts.code_review.i_merge_request_widget_test_reports_count_expand_success \
|
||||
counts.code_review.i_merge_request_widget_test_reports_count_expand_warning \
|
||||
counts.code_review.i_merge_request_widget_test_reports_count_expand_failed \
|
||||
--dir=all
|
||||
```
|
||||
1. Modify each newly generated file so that they match the existing files for MR Widget Extension telemetry.
|
||||
- You can find existing examples by doing a glob search like so: `metrics/**/*_i_code_review_merge_request_widget_*`
|
||||
- Roughly-speaking, each file should have these values:
|
||||
1. `description` = A plain English description of this value. Please see existing widget extension telemetry files for examples.
|
||||
1. `product_section` = `dev`
|
||||
1. `product_stage` = `create`
|
||||
1. `product_group` = `code_review`
|
||||
1. `product_category` = `code_review`
|
||||
1. `introduced_by_url` = `'[your MR]'`
|
||||
1. `options.events` = (the event in the command from above that generated this file, like `i_code_review_merge_request_widget_test_reports_count_view`)
|
||||
- This is how the telemetry events are linked to "metrics" so this is probably one of the more important values
|
||||
1. `data_source` = `redis`
|
||||
1. `data_category` = `optional`
|
||||
1. Repeat steps 5 and 6 for the HLL metrics. Replace `test_reports` with your appropriate name slug.
|
||||
```
|
||||
bundle exec rails generate gitlab:usage_metric_definition:redis_hll code_review \
|
||||
i_code_review_merge_request_widget_test_reports_view \
|
||||
i_code_review_merge_request_widget_test_reports_full_report_clicked \
|
||||
i_code_review_merge_request_widget_test_reports_expand \
|
||||
i_code_review_merge_request_widget_test_reports_expand_success \
|
||||
i_code_review_merge_request_widget_test_reports_expand_warning \
|
||||
i_code_review_merge_request_widget_test_reports_expand_failed \
|
||||
--class_name=RedisHLLMetric
|
||||
```
|
||||
- In step 6 for HLL, change the `data_source` to `redis_hll`.
|
||||
1. Add each of the HLL metrics to `lib/gitlab/usage_data_counters/known_events/code_review_events.yml`
|
||||
1. `name` = [the event]
|
||||
1. `redis_slot` = `code_review`
|
||||
1. `category` = `code_review`
|
||||
1. `aggregation` = `weekly`
|
||||
1. Add each event to the appropriate aggregates in `config/metrics/aggregates/code_review.yml`
|
||||
|
||||
##### New Events
|
||||
|
||||
If you are adding a new event to our known events, it will need to be included in `lib/gitlab/usage_data_counters/merge_request_widget_extension_counter.rb`. Update the list of `KNOWN_EVENTS` with the new event(s).
|
|
@ -576,10 +576,10 @@ span.idiff {
|
|||
}
|
||||
}
|
||||
|
||||
// *:nth-of-type(1n+5) - makes sure we do not render elements 5+ right away when
|
||||
// *:nth-of-type(1n+30) - makes sure we do not render elements 30+ right away when
|
||||
// viewing a file. Even though the HTML is injected in the DOM, as long as we do
|
||||
// not render those elements, the browser doesn't need to spend resources
|
||||
// calculating and repainting what's hidden.
|
||||
.file-holder [data-loading] .file-content *:nth-of-type(1n+5) {
|
||||
.file-holder [data-loading] .file-content *:nth-of-type(1n+30) {
|
||||
@include gl-display-none;
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ class Profiles::PersonalAccessTokensController < Profiles::ApplicationController
|
|||
end
|
||||
|
||||
def active_personal_access_tokens
|
||||
tokens = finder(state: 'active', sort: 'expires_at_asc').execute
|
||||
tokens = finder(state: 'active', sort: 'expires_at_asc_id_desc').execute
|
||||
|
||||
if Feature.enabled?('access_token_pagination')
|
||||
tokens = tokens.page(page)
|
||||
|
|
|
@ -102,6 +102,7 @@ module Ci
|
|||
has_one :chat_data, class_name: 'Ci::PipelineChatData'
|
||||
|
||||
has_many :triggered_pipelines, through: :sourced_pipelines, source: :pipeline
|
||||
# Only includes direct and not nested children
|
||||
has_many :child_pipelines, -> { merge(Ci::Sources::Pipeline.same_project) }, through: :sourced_pipelines, source: :pipeline
|
||||
has_one :triggered_by_pipeline, through: :source_pipeline, source: :source_pipeline
|
||||
has_one :parent_pipeline, -> { merge(Ci::Sources::Pipeline.same_project) }, through: :source_pipeline, source: :source_pipeline
|
||||
|
@ -592,26 +593,20 @@ module Ci
|
|||
canceled? && auto_canceled_by_id?
|
||||
end
|
||||
|
||||
def cancel_running(retries: 1)
|
||||
preloaded_relations = [:project, :pipeline, :deployment, :taggings]
|
||||
# Cancel a pipelines cancelable jobs and optionally it's child pipelines cancelable jobs
|
||||
# retries - # of times to retry if errors
|
||||
# cascade_to_children - if true cancels all related child pipelines for parent child pipelines
|
||||
# auto_canceled_by_pipeline_id - store the pipeline_id of the pipeline that triggered cancellation
|
||||
# execute_async - if true cancel the children asyncronously
|
||||
def cancel_running(retries: 1, cascade_to_children: true, auto_canceled_by_pipeline_id: nil, execute_async: true)
|
||||
update(auto_canceled_by_id: auto_canceled_by_pipeline_id) if auto_canceled_by_pipeline_id
|
||||
|
||||
retry_lock(cancelable_statuses, retries, name: 'ci_pipeline_cancel_running') do |cancelables|
|
||||
cancelables.find_in_batches do |batch|
|
||||
Preloaders::CommitStatusPreloader.new(batch).execute(preloaded_relations)
|
||||
cancel_jobs(cancelable_statuses, retries: retries, auto_canceled_by_pipeline_id: auto_canceled_by_pipeline_id)
|
||||
|
||||
batch.each do |job|
|
||||
yield(job) if block_given?
|
||||
job.cancel
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def auto_cancel_running(pipeline, retries: 1)
|
||||
update(auto_canceled_by: pipeline)
|
||||
|
||||
cancel_running(retries: retries) do |job|
|
||||
job.auto_canceled_by = pipeline
|
||||
if cascade_to_children && project.cascade_cancel_pipelines_enabled?
|
||||
# cancel any bridges that could spin up new child pipelines
|
||||
cancel_jobs(bridges_in_self_and_descendants.cancelable, retries: retries, auto_canceled_by_pipeline_id: auto_canceled_by_pipeline_id)
|
||||
cancel_children(auto_canceled_by_pipeline_id: auto_canceled_by_pipeline_id, execute_async: execute_async)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -953,6 +948,10 @@ module Ci
|
|||
Ci::Build.latest.where(pipeline: self_and_descendants)
|
||||
end
|
||||
|
||||
def bridges_in_self_and_descendants
|
||||
Ci::Bridge.latest.where(pipeline: self_and_descendants)
|
||||
end
|
||||
|
||||
def environments_in_self_and_descendants(deployment_status: nil)
|
||||
# We limit to 100 unique environments for application safety.
|
||||
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/340781#note_699114700
|
||||
|
@ -986,6 +985,11 @@ module Ci
|
|||
object_hierarchy(project_condition: :same).base_and_descendants
|
||||
end
|
||||
|
||||
# With only parent-child pipelines
|
||||
def all_child_pipelines
|
||||
object_hierarchy(project_condition: :same).descendants
|
||||
end
|
||||
|
||||
def self_and_descendants_complete?
|
||||
self_and_descendants.all?(&:complete?)
|
||||
end
|
||||
|
@ -1323,6 +1327,42 @@ module Ci
|
|||
|
||||
private
|
||||
|
||||
def cancel_jobs(jobs, retries: 1, auto_canceled_by_pipeline_id: nil)
|
||||
retry_lock(jobs, retries, name: 'ci_pipeline_cancel_running') do |statuses|
|
||||
preloaded_relations = [:project, :pipeline, :deployment, :taggings]
|
||||
|
||||
statuses.find_in_batches do |status_batch|
|
||||
relation = CommitStatus.where(id: status_batch)
|
||||
Preloaders::CommitStatusPreloader.new(relation).execute(preloaded_relations)
|
||||
|
||||
relation.each do |job|
|
||||
job.auto_canceled_by_id = auto_canceled_by_pipeline_id if auto_canceled_by_pipeline_id
|
||||
job.cancel
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# For parent child-pipelines only (not multi-project)
|
||||
def cancel_children(auto_canceled_by_pipeline_id: nil, execute_async: true)
|
||||
all_child_pipelines.each do |child_pipeline|
|
||||
if execute_async
|
||||
::Ci::CancelPipelineWorker.perform_async(
|
||||
child_pipeline.id,
|
||||
auto_canceled_by_pipeline_id
|
||||
)
|
||||
else
|
||||
child_pipeline.cancel_running(
|
||||
# cascade_to_children is false because we iterate through children
|
||||
# we also cancel bridges prior to prevent more children
|
||||
cascade_to_children: false,
|
||||
execute_async: execute_async,
|
||||
auto_canceled_by_pipeline_id: auto_canceled_by_pipeline_id
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def add_message(severity, content)
|
||||
messages.build(severity: severity, content: content)
|
||||
end
|
||||
|
|
|
@ -33,6 +33,7 @@ class PersonalAccessToken < ApplicationRecord
|
|||
scope :preload_users, -> { preload(:user) }
|
||||
scope :order_expires_at_asc, -> { reorder(expires_at: :asc) }
|
||||
scope :order_expires_at_desc, -> { reorder(expires_at: :desc) }
|
||||
scope :order_expires_at_asc_id_desc, -> { reorder(expires_at: :asc, id: :desc) }
|
||||
scope :project_access_token, -> { includes(:user).where(user: { user_type: :project_bot }) }
|
||||
scope :owner_is_human, -> { includes(:user).where(user: { user_type: :human }) }
|
||||
|
||||
|
@ -77,7 +78,8 @@ class PersonalAccessToken < ApplicationRecord
|
|||
super.merge(
|
||||
{
|
||||
'expires_at_asc' => -> { order_expires_at_asc },
|
||||
'expires_at_desc' => -> { order_expires_at_desc }
|
||||
'expires_at_desc' => -> { order_expires_at_desc },
|
||||
'expires_at_asc_id_desc' => -> { order_expires_at_asc_id_desc }
|
||||
}
|
||||
)
|
||||
end
|
||||
|
|
|
@ -1041,6 +1041,13 @@ class Project < ApplicationRecord
|
|||
def emails_enabled?
|
||||
!emails_disabled?
|
||||
end
|
||||
|
||||
def cascade_cancel_pipelines_enabled?
|
||||
strong_memoize(:cascade_cancel_pipelines_enabled) do
|
||||
Feature.enabled?(:ci_parent_pipeline_cancels_children, self)
|
||||
end
|
||||
end
|
||||
|
||||
override :lfs_enabled?
|
||||
def lfs_enabled?
|
||||
return namespace.lfs_enabled? if self[:lfs_enabled].nil?
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# rubocop: disable Gitlab/NamespacedClass
|
||||
class GroupAccessTokenEntity < API::Entities::PersonalAccessToken
|
||||
include Gitlab::Routing
|
||||
|
||||
expose :revoke_path do |token, options|
|
||||
group = options.fetch(:group)
|
||||
|
||||
next unless group
|
||||
|
||||
revoke_group_settings_access_token_path(
|
||||
id: token,
|
||||
group_id: group.path)
|
||||
end
|
||||
|
||||
expose :access_level do |token, options|
|
||||
group = options.fetch(:group)
|
||||
|
||||
next unless group
|
||||
next unless token.user
|
||||
|
||||
group.member(token.user)&.access_level
|
||||
end
|
||||
end
|
||||
# rubocop: enable Gitlab/NamespacedClass
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# rubocop: disable Gitlab/NamespacedClass
|
||||
class GroupAccessTokenSerializer < BaseSerializer
|
||||
entity GroupAccessTokenEntity
|
||||
end
|
||||
# rubocop: enable Gitlab/NamespacedClass
|
|
@ -0,0 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# rubocop: disable Gitlab/NamespacedClass
|
||||
class PersonalAccessTokenEntity < API::Entities::PersonalAccessToken
|
||||
include Gitlab::Routing
|
||||
|
||||
expose :revoke_path do |token, options|
|
||||
revoke_profile_personal_access_token_path(token)
|
||||
end
|
||||
end
|
||||
# rubocop: enable Gitlab/NamespacedClass
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# rubocop: disable Gitlab/NamespacedClass
|
||||
class PersonalAccessTokenSerializer < BaseSerializer
|
||||
entity PersonalAccessTokenEntity
|
||||
end
|
||||
# rubocop: enable Gitlab/NamespacedClass
|
|
@ -0,0 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# rubocop: disable Gitlab/NamespacedClass
|
||||
class ProjectAccessTokenEntity < API::Entities::PersonalAccessToken
|
||||
include Gitlab::Routing
|
||||
|
||||
expose :revoke_path do |token, options|
|
||||
project = options.fetch(:project)
|
||||
|
||||
next unless project
|
||||
|
||||
revoke_namespace_project_settings_access_token_path(
|
||||
id: token,
|
||||
namespace_id: project.namespace.path,
|
||||
project_id: project.path)
|
||||
end
|
||||
|
||||
expose :access_level do |token, options|
|
||||
project = options.fetch(:project)
|
||||
|
||||
next unless project
|
||||
next unless token.user
|
||||
|
||||
project.member(token.user)&.access_level
|
||||
end
|
||||
end
|
||||
# rubocop: enable Gitlab/NamespacedClass
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# rubocop: disable Gitlab/NamespacedClass
|
||||
class ProjectAccessTokenSerializer < BaseSerializer
|
||||
entity ProjectAccessTokenEntity
|
||||
end
|
||||
# rubocop: enable Gitlab/NamespacedClass
|
|
@ -7,7 +7,7 @@ module Ci
|
|||
|
||||
Ci::ExpirePipelineCacheService.new.execute(pipeline, delete: true)
|
||||
|
||||
pipeline.cancel_running if pipeline.cancelable?
|
||||
pipeline.cancel_running(cascade_to_children: true, execute_async: false) if pipeline.cancelable?
|
||||
|
||||
# The pipeline, the builds, job and pipeline artifacts all get destroyed here.
|
||||
# Ci::Pipeline#destroy triggers fast destroy on job_artifacts and
|
||||
|
|
|
@ -2109,6 +2109,15 @@
|
|||
:weight: 2
|
||||
:idempotent: false
|
||||
:tags: []
|
||||
- :name: ci_cancel_pipeline
|
||||
:worker_name: Ci::CancelPipelineWorker
|
||||
:feature_category: :continuous_integration
|
||||
:has_external_dependencies: false
|
||||
:urgency: :high
|
||||
:resource_boundary: :unknown
|
||||
:weight: 1
|
||||
:idempotent: true
|
||||
:tags: []
|
||||
- :name: ci_delete_objects
|
||||
:worker_name: Ci::DeleteObjectsWorker
|
||||
:feature_category: :continuous_integration
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Ci
|
||||
class CancelPipelineWorker
|
||||
include ApplicationWorker
|
||||
|
||||
# lots of updates to ci_builds
|
||||
data_consistency :always
|
||||
feature_category :continuous_integration
|
||||
idempotent!
|
||||
deduplicate :until_executed
|
||||
urgency :high
|
||||
|
||||
def perform(pipeline_id, auto_canceled_by_pipeline_id)
|
||||
::Ci::Pipeline.find_by_id(pipeline_id).try do |pipeline|
|
||||
pipeline.cancel_running(
|
||||
# cascade_to_children is false because we iterate through children
|
||||
# we also cancel bridges prior to prevent more children
|
||||
cascade_to_children: false,
|
||||
auto_canceled_by_pipeline_id: auto_canceled_by_pipeline_id
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: ci_parent_pipeline_cancels_children
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82149
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/354528
|
||||
milestone: '15.3'
|
||||
type: development
|
||||
group: group::pipeline execution
|
||||
default_enabled: false
|
|
@ -80,6 +80,12 @@
|
|||
- 'i_code_review_user_create_note_in_ipynb_diff'
|
||||
- 'i_code_review_user_create_note_in_ipynb_diff_mr'
|
||||
- 'i_code_review_user_create_note_in_ipynb_diff_commit'
|
||||
- 'i_code_review_merge_request_widget_test_summary_view'
|
||||
- 'i_code_review_merge_request_widget_test_summary_full_report_clicked'
|
||||
- 'i_code_review_merge_request_widget_test_summary_expand'
|
||||
- 'i_code_review_merge_request_widget_test_summary_expand_success'
|
||||
- 'i_code_review_merge_request_widget_test_summary_expand_warning'
|
||||
- 'i_code_review_merge_request_widget_test_summary_expand_failed'
|
||||
- name: code_review_category_monthly_active_users
|
||||
operator: OR
|
||||
source: redis
|
||||
|
@ -148,6 +154,12 @@
|
|||
- 'i_code_review_user_create_note_in_ipynb_diff'
|
||||
- 'i_code_review_user_create_note_in_ipynb_diff_mr'
|
||||
- 'i_code_review_user_create_note_in_ipynb_diff_commit'
|
||||
- 'i_code_review_merge_request_widget_test_summary_view'
|
||||
- 'i_code_review_merge_request_widget_test_summary_full_report_clicked'
|
||||
- 'i_code_review_merge_request_widget_test_summary_expand'
|
||||
- 'i_code_review_merge_request_widget_test_summary_expand_success'
|
||||
- 'i_code_review_merge_request_widget_test_summary_expand_warning'
|
||||
- 'i_code_review_merge_request_widget_test_summary_expand_failed'
|
||||
- name: code_review_extension_category_monthly_active_users
|
||||
operator: OR
|
||||
source: redis
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
key_path: redis_hll_counters.code_review.i_code_review_merge_request_widget_test_summary_view_monthly
|
||||
description: The count of unique users (monthly) who were able to see the Test Summary widget extension
|
||||
product_section: dev
|
||||
product_stage: create
|
||||
product_group: code_review
|
||||
product_category: code_review
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.2"
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
|
||||
time_frame: 28d
|
||||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- i_code_review_merge_request_widget_test_summary_view
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
key_path: redis_hll_counters.code_review.i_code_review_merge_request_widget_test_summary_full_report_clicked_monthly
|
||||
description: The count of unique users (monthly) who clicked the Full Report button on the Test Summary widget extension
|
||||
product_section: dev
|
||||
product_stage: create
|
||||
product_group: code_review
|
||||
product_category: code_review
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.2"
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
|
||||
time_frame: 28d
|
||||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- i_code_review_merge_request_widget_test_summary_full_report_clicked
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
key_path: redis_hll_counters.code_review.i_code_review_merge_request_widget_test_summary_expand_monthly
|
||||
description: The count of unique users (monthly) who expanded the Test Summary widget extension
|
||||
product_section: dev
|
||||
product_stage: create
|
||||
product_group: code_review
|
||||
product_category: code_review
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.2"
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
|
||||
time_frame: 28d
|
||||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- i_code_review_merge_request_widget_test_summary_expand
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
key_path: redis_hll_counters.code_review.i_code_review_merge_request_widget_test_summary_expand_success_monthly
|
||||
description: The count of unique users (monthly) who expanded the Test Summary widget extension while it is in its Success state
|
||||
product_section: dev
|
||||
product_stage: create
|
||||
product_group: code_review
|
||||
product_category: code_review
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.2"
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
|
||||
time_frame: 28d
|
||||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- i_code_review_merge_request_widget_test_summary_expand_success
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
key_path: redis_hll_counters.code_review.i_code_review_merge_request_widget_test_summary_expand_warning_monthly
|
||||
description: The count of unique users (monthly) who expanded the Test Summary widget extension while it is in its Warning state
|
||||
product_section: dev
|
||||
product_stage: create
|
||||
product_group: code_review
|
||||
product_category: code_review
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.2"
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
|
||||
time_frame: 28d
|
||||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- i_code_review_merge_request_widget_test_summary_expand_warning
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
key_path: redis_hll_counters.code_review.i_code_review_merge_request_widget_test_summary_expand_failed_monthly
|
||||
description: The count of unique users (monthly) who expanded the Test Summary widget extension while it is in its Failed state
|
||||
product_section: dev
|
||||
product_stage: create
|
||||
product_group: code_review
|
||||
product_category: code_review
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.2"
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
|
||||
time_frame: 28d
|
||||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- i_code_review_merge_request_widget_test_summary_expand_failed
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
key_path: redis_hll_counters.code_review.i_code_review_merge_request_widget_test_summary_view_weekly
|
||||
description: The count of unique users (weekly) who were able to see the Test Summary widget extension
|
||||
product_section: dev
|
||||
product_stage: create
|
||||
product_group: code_review
|
||||
product_category: code_review
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.2"
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
|
||||
time_frame: 7d
|
||||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- i_code_review_merge_request_widget_test_summary_view
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
key_path: redis_hll_counters.code_review.i_code_review_merge_request_widget_test_summary_full_report_clicked_weekly
|
||||
description: The count of unique users (weekly) who clicked the Full Report button on the Test Summary widget extension
|
||||
product_section: dev
|
||||
product_stage: create
|
||||
product_group: code_review
|
||||
product_category: code_review
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.2"
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
|
||||
time_frame: 7d
|
||||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- i_code_review_merge_request_widget_test_summary_full_report_clicked
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
key_path: redis_hll_counters.code_review.i_code_review_merge_request_widget_test_summary_expand_weekly
|
||||
description: The count of unique users (weekly) who expanded the Test Summary widget extension
|
||||
product_section: dev
|
||||
product_stage: create
|
||||
product_group: code_review
|
||||
product_category: code_review
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.2"
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
|
||||
time_frame: 7d
|
||||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- i_code_review_merge_request_widget_test_summary_expand
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
key_path: redis_hll_counters.code_review.i_code_review_merge_request_widget_test_summary_expand_success_weekly
|
||||
description: The count of unique users (weekly) who expanded the Test Summary widget extension while it is in its Success state
|
||||
product_section: dev
|
||||
product_stage: create
|
||||
product_group: code_review
|
||||
product_category: code_review
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.2"
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
|
||||
time_frame: 7d
|
||||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- i_code_review_merge_request_widget_test_summary_expand_success
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
key_path: redis_hll_counters.code_review.i_code_review_merge_request_widget_test_summary_expand_warning_weekly
|
||||
description: The count of unique users (weekly) who expanded the Test Summary widget extension while it is in its Warning state
|
||||
product_section: dev
|
||||
product_stage: create
|
||||
product_group: code_review
|
||||
product_category: code_review
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.2"
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
|
||||
time_frame: 7d
|
||||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- i_code_review_merge_request_widget_test_summary_expand_warning
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
key_path: redis_hll_counters.code_review.i_code_review_merge_request_widget_test_summary_expand_failed_weekly
|
||||
description: The count of unique users (weekly) who expanded the Test Summary widget extension while it is in its Failed state
|
||||
product_section: dev
|
||||
product_stage: create
|
||||
product_group: code_review
|
||||
product_category: code_review
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.2"
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
|
||||
time_frame: 7d
|
||||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- i_code_review_merge_request_widget_test_summary_expand_failed
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
key_path: counts.i_code_review_merge_request_widget_test_summary_count_view
|
||||
description: Total number of times the Test Summary widget extension was viewed (rendered to the screen)
|
||||
product_section: dev
|
||||
product_stage: create
|
||||
product_group: code_review
|
||||
product_category: code_review
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.2"
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
|
||||
time_frame: all
|
||||
data_source: redis
|
||||
data_category: optional
|
||||
options:
|
||||
events:
|
||||
- i_code_review_merge_request_widget_test_summary_count_view
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
key_path: counts.i_code_review_merge_request_widget_test_summary_count_full_report_clicked
|
||||
description: Total number of times the Test Summary widget extension Full Report button was clicked
|
||||
product_section: dev
|
||||
product_stage: create
|
||||
product_group: code_review
|
||||
product_category: code_review
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.2"
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
|
||||
time_frame: all
|
||||
data_source: redis
|
||||
data_category: optional
|
||||
options:
|
||||
events:
|
||||
- i_code_review_merge_request_widget_test_summary_count_full_report_clicked
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
key_path: counts.i_code_review_merge_request_widget_test_summary_count_expand
|
||||
description: Total number of times the Test Summary widget extension was expanded (in any state)
|
||||
product_section: dev
|
||||
product_stage: create
|
||||
product_group: code_review
|
||||
product_category: code_review
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.2"
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
|
||||
time_frame: all
|
||||
data_source: redis
|
||||
data_category: optional
|
||||
options:
|
||||
events:
|
||||
- i_code_review_merge_request_widget_test_summary_count_expand
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
key_path: counts.i_code_review_merge_request_widget_test_summary_count_expand_success
|
||||
description: Total number of times the Test Summary widget extension was expanded (while in its Success state)
|
||||
product_section: dev
|
||||
product_stage: create
|
||||
product_group: code_review
|
||||
product_category: code_review
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.2"
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
|
||||
time_frame: all
|
||||
data_source: redis
|
||||
data_category: optional
|
||||
options:
|
||||
events:
|
||||
- i_code_review_merge_request_widget_test_summary_count_expand_success
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
key_path: counts.i_code_review_merge_request_widget_test_summary_count_expand_warning
|
||||
description: Total number of times the Test Summary widget extension was expanded (while in its Warning state)
|
||||
product_section: dev
|
||||
product_stage: create
|
||||
product_group: code_review
|
||||
product_category: code_review
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.2"
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
|
||||
time_frame: all
|
||||
data_source: redis
|
||||
data_category: optional
|
||||
options:
|
||||
events:
|
||||
- i_code_review_merge_request_widget_test_summary_count_expand_warning
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
key_path: counts.i_code_review_merge_request_widget_test_summary_count_expand_failed
|
||||
description: Total number of times the Test Summary widget extension was expanded (while in its Failed state)
|
||||
product_section: dev
|
||||
product_stage: create
|
||||
product_group: code_review
|
||||
product_category: code_review
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.2"
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
|
||||
time_frame: all
|
||||
data_source: redis
|
||||
data_category: optional
|
||||
options:
|
||||
events:
|
||||
- i_code_review_merge_request_widget_test_summary_count_expand_failed
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
|
@ -87,6 +87,8 @@
|
|||
- 2
|
||||
- - ci_batch_reset_minutes
|
||||
- 1
|
||||
- - ci_cancel_pipeline
|
||||
- 1
|
||||
- - ci_delete_objects
|
||||
- 1
|
||||
- - ci_job_artifacts_expire_project_build_artifacts
|
||||
|
|
|
@ -473,9 +473,7 @@ module.exports = {
|
|||
new VueLoaderPlugin(),
|
||||
|
||||
// automatically configure monaco editor web workers
|
||||
new MonacoWebpackPlugin({
|
||||
globalAPI: true,
|
||||
}),
|
||||
new MonacoWebpackPlugin(),
|
||||
|
||||
new GraphqlKnownOperationsPlugin({ filename: 'graphql_known_operations.yml' }),
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
# Error: gitlab.VersionTextSingleLine
|
||||
#
|
||||
# Verifies that single-item version notes don't have a hyphen.
|
||||
#
|
||||
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
|
||||
extends: existence
|
||||
message: 'Version text with only a single item must not start with a hyphen.'
|
||||
link: https://docs.gitlab.com/ee/development/documentation/versions.html#add-a-version-history-item
|
||||
level: error
|
||||
scope: raw
|
||||
raw:
|
||||
- '(\r|\n|\r\n){2}(> - .*)(\r|\n|\r\n){2}'
|
|
@ -36,11 +36,6 @@ Users with at least the Owner role for a group can add event streaming destinati
|
|||
- When the destination list is not empty, select **{plus}** to show the section for adding destinations.
|
||||
1. Enter the destination URL to add and select **Add**.
|
||||
|
||||
Event streaming is enabled if:
|
||||
|
||||
- No warning is shown.
|
||||
- The added endpoint is displayed in the UI.
|
||||
|
||||
### Use the API
|
||||
|
||||
To enable event streaming and add a destination, users with at least the Owner role for a group must use the
|
||||
|
@ -120,11 +115,6 @@ Users with at least the Owner role for a group can delete event streaming destin
|
|||
1. On the main area, select **Streams** tab.
|
||||
1. Select **{remove}** at the right side of each item.
|
||||
|
||||
The external streaming destination is deleted when:
|
||||
|
||||
- No warning is shown.
|
||||
- The deleted endpoint is not displayed in the UI.
|
||||
|
||||
### Use the API
|
||||
|
||||
Delete an event streaming destination by specifying an ID. Get the required ID by
|
||||
|
@ -237,11 +227,6 @@ Users with at least the Owner role for a group can add event streaming destinati
|
|||
[relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/361925).
|
||||
1. Select **Save** to update the endpoint.
|
||||
|
||||
Event streaming is updated if:
|
||||
|
||||
- The returned `errors` object is empty.
|
||||
- The API responds with `200 OK`.
|
||||
|
||||
### Deleting custom HTTP headers
|
||||
|
||||
Deleting custom HTTP headers with the API or GitLab UI.
|
||||
|
@ -281,11 +266,6 @@ Users with at least the Owner role for a group can delete event streaming destin
|
|||
1. Select **{remove}** at the right side of the header.
|
||||
1. Select **Save** to update the endpoint.
|
||||
|
||||
Event streaming is updated if:
|
||||
|
||||
- The returned `errors` object is empty.
|
||||
- The API responds with `200 OK`.
|
||||
|
||||
### List all custom headers
|
||||
|
||||
List all custom HTTP headers with the API or GitLab UI.
|
||||
|
|
|
@ -53,7 +53,7 @@ The package files are permanently deleted.
|
|||
|
||||
## Cleanup policy
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/346153) in GitLab 15.2.
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/346153) in GitLab 15.2.
|
||||
|
||||
Depending on the number of packages to remove, the process of manually deleting the packages can take a long time to finish.
|
||||
A cleanup policy defines a set of rules that, applied to a project, defines which package files you can automatically delete.
|
||||
|
|
|
@ -149,6 +149,7 @@ module.exports = (path, options = {}) => {
|
|||
'fault',
|
||||
'dateformat',
|
||||
'lowlight',
|
||||
'vscode-languageserver-types',
|
||||
...gfmParserDependencies,
|
||||
];
|
||||
|
||||
|
|
|
@ -40,7 +40,13 @@ module Gitlab
|
|||
::Ci::Pipeline
|
||||
.id_in(pipeline_ids)
|
||||
.with_only_interruptible_builds
|
||||
.each { |cancelable| cancelable.auto_cancel_running(pipeline) }
|
||||
.each do |cancelable_pipeline|
|
||||
# cascade_to_children not needed because we iterate through descendants here
|
||||
cancelable_pipeline.cancel_running(
|
||||
auto_canceled_by_pipeline_id: pipeline.id,
|
||||
cascade_to_children: false
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -167,15 +167,13 @@ module Gitlab
|
|||
end
|
||||
|
||||
def init_prometheus_metrics(max_heap_fragmentation)
|
||||
default_labels = { pid: worker_id }
|
||||
|
||||
@heap_frag_limit = Gitlab::Metrics.gauge(
|
||||
:gitlab_memwd_heap_frag_limit,
|
||||
'The configured limit for how fragmented the Ruby heap is allowed to be',
|
||||
default_labels
|
||||
'The configured limit for how fragmented the Ruby heap is allowed to be'
|
||||
)
|
||||
@heap_frag_limit.set({}, max_heap_fragmentation)
|
||||
|
||||
default_labels = { pid: worker_id }
|
||||
@heap_frag_violations = Gitlab::Metrics.counter(
|
||||
:gitlab_memwd_heap_frag_violations_total,
|
||||
'Total number of times heap fragmentation in a Ruby process exceeded its allowed maximum',
|
||||
|
|
|
@ -12,7 +12,6 @@ module Gitlab
|
|||
# Error information from the previous try is in the payload for
|
||||
# displaying in the Sidekiq UI, but is very confusing in logs!
|
||||
job = job.except(
|
||||
'error_backtrace', 'error_class', 'error_message',
|
||||
'exception.backtrace', 'exception.class', 'exception.message', 'exception.sql'
|
||||
)
|
||||
|
||||
|
|
|
@ -16,7 +16,8 @@ module Gitlab
|
|||
DesignsCounter,
|
||||
KubernetesAgentCounter,
|
||||
DiffsCounter,
|
||||
ServiceUsageDataCounter
|
||||
ServiceUsageDataCounter,
|
||||
MergeRequestWidgetExtensionCounter
|
||||
].freeze
|
||||
|
||||
UsageDataCounterError = Class.new(StandardError)
|
||||
|
|
|
@ -299,3 +299,29 @@
|
|||
redis_slot: code_review
|
||||
category: code_review
|
||||
aggregation: weekly
|
||||
# MR Widget Extensions
|
||||
## Test Summary
|
||||
- name: i_code_review_merge_request_widget_test_summary_view
|
||||
redis_slot: code_review
|
||||
category: code_review
|
||||
aggregation: weekly
|
||||
- name: i_code_review_merge_request_widget_test_summary_full_report_clicked
|
||||
redis_slot: code_review
|
||||
category: code_review
|
||||
aggregation: weekly
|
||||
- name: i_code_review_merge_request_widget_test_summary_expand
|
||||
redis_slot: code_review
|
||||
category: code_review
|
||||
aggregation: weekly
|
||||
- name: i_code_review_merge_request_widget_test_summary_expand_success
|
||||
redis_slot: code_review
|
||||
category: code_review
|
||||
aggregation: weekly
|
||||
- name: i_code_review_merge_request_widget_test_summary_expand_warning
|
||||
redis_slot: code_review
|
||||
category: code_review
|
||||
aggregation: weekly
|
||||
- name: i_code_review_merge_request_widget_test_summary_expand_failed
|
||||
redis_slot: code_review
|
||||
category: code_review
|
||||
aggregation: weekly
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module UsageDataCounters
|
||||
class MergeRequestWidgetExtensionCounter < BaseCounter
|
||||
KNOWN_EVENTS = %w[view full_report_clicked expand expand_success expand_warning expand_failed].freeze
|
||||
PREFIX = 'i_code_review_merge_request_widget'
|
||||
WIDGETS = %w[test_summary].freeze
|
||||
|
||||
class << self
|
||||
private
|
||||
|
||||
def known_events
|
||||
self::WIDGETS.product(self::KNOWN_EVENTS).map { |name_parts| name_parts.join('_count_') }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -5364,9 +5364,18 @@ msgstr ""
|
|||
msgid "AuditStreams|Setup streaming for audit events"
|
||||
msgstr ""
|
||||
|
||||
msgid "AuditStreams|Stream added successfully"
|
||||
msgstr ""
|
||||
|
||||
msgid "AuditStreams|Stream count icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "AuditStreams|Stream deleted successfully"
|
||||
msgstr ""
|
||||
|
||||
msgid "AuditStreams|Stream updated successfully"
|
||||
msgstr ""
|
||||
|
||||
msgid "AuditStreams|Streams"
|
||||
msgstr ""
|
||||
|
||||
|
@ -23489,6 +23498,9 @@ msgstr ""
|
|||
msgid "LinkedResources|Cancel"
|
||||
msgstr ""
|
||||
|
||||
msgid "LinkedResources|Error deleting the linked resource for the incident: %{error}"
|
||||
msgstr ""
|
||||
|
||||
msgid "LinkedResources|Fetching linked resources"
|
||||
msgstr ""
|
||||
|
||||
|
@ -23504,6 +23516,9 @@ msgstr ""
|
|||
msgid "LinkedResources|Remove"
|
||||
msgstr ""
|
||||
|
||||
msgid "LinkedResources|Something went wrong while deleting the linked resource for the incident."
|
||||
msgstr ""
|
||||
|
||||
msgid "LinkedResources|Something went wrong while fetching linked resources for the incident."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -140,9 +140,9 @@
|
|||
"mermaid": "^9.1.1",
|
||||
"micromatch": "^4.0.5",
|
||||
"minimatch": "^3.0.4",
|
||||
"monaco-editor": "^0.25.2",
|
||||
"monaco-editor-webpack-plugin": "^4.0.0",
|
||||
"monaco-yaml": "^2.5.1",
|
||||
"monaco-editor": "^0.28.0",
|
||||
"monaco-editor-webpack-plugin": "^4.2.0",
|
||||
"monaco-yaml": "3.0.0",
|
||||
"mousetrap": "1.6.5",
|
||||
"papaparse": "^5.3.1",
|
||||
"patch-package": "^6.4.7",
|
||||
|
|
16
security.txt
16
security.txt
|
@ -1,6 +1,16 @@
|
|||
Contact: security@gitlab.com
|
||||
# Preferred disclosure is via HackerOne
|
||||
Contact: https://hackerone.com/gitlab/
|
||||
# Additional disclosure processes are available in our handbook:
|
||||
Contact: https://about.gitlab.com/security/disclosure/
|
||||
|
||||
Policy: https://hackerone.com/gitlab/
|
||||
|
||||
Acknowledgments: https://hackerone.com/gitlab/
|
||||
Acknowledgments: https://about.gitlab.com/security/vulnerability-acknowledgements/
|
||||
|
||||
Canonical: https://gitlab.com/gitlab-org/gitlab/-/blob/master/security.txt
|
||||
|
||||
Preferred-Languages: en
|
||||
Canonical: https://about.gitlab.com/security/disclosure/
|
||||
Policy: https://hackerone.com/gitlab
|
||||
Hiring: https://about.gitlab.com/jobs/
|
||||
|
||||
Expires: 2023-07-31T00:00:00Z
|
||||
|
|
|
@ -87,6 +87,38 @@ RSpec.describe Profiles::PersonalAccessTokensController do
|
|||
end
|
||||
end
|
||||
|
||||
context "tokens returned are ordered" do
|
||||
let(:expires_1_day_from_now) { 1.day.from_now.to_date }
|
||||
let(:expires_2_day_from_now) { 2.days.from_now.to_date }
|
||||
|
||||
before do
|
||||
create(:personal_access_token, user: user, name: "Token1", expires_at: expires_1_day_from_now)
|
||||
create(:personal_access_token, user: user, name: "Token2", expires_at: expires_2_day_from_now)
|
||||
end
|
||||
|
||||
it "orders token list ascending on expires_at" do
|
||||
get :index
|
||||
|
||||
first_token = assigns(:active_personal_access_tokens).first.as_json
|
||||
expect(first_token[:name]).to eq("Token1")
|
||||
expect(first_token[:expires_at]).to eq(expires_1_day_from_now.strftime("%Y-%m-%d"))
|
||||
end
|
||||
|
||||
it "orders tokens on id in case token has same expires_at" do
|
||||
create(:personal_access_token, user: user, name: "Token3", expires_at: expires_1_day_from_now)
|
||||
|
||||
get :index
|
||||
|
||||
first_token = assigns(:active_personal_access_tokens).first.as_json
|
||||
expect(first_token[:name]).to eq("Token3")
|
||||
expect(first_token[:expires_at]).to eq(expires_1_day_from_now.strftime("%Y-%m-%d"))
|
||||
|
||||
second_token = assigns(:active_personal_access_tokens).second.as_json
|
||||
expect(second_token[:name]).to eq("Token1")
|
||||
expect(second_token[:expires_at]).to eq(expires_1_day_from_now.strftime("%Y-%m-%d"))
|
||||
end
|
||||
end
|
||||
|
||||
context "access_token_pagination feature flag is disabled" do
|
||||
before do
|
||||
stub_feature_flags(access_token_pagination: false)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe 'a maintainer edits files on a source-branch of an MR from a fork', :js, :sidekiq_might_not_need_inline do
|
||||
include Spec::Support::Helpers::Features::SourceEditorSpecHelpers
|
||||
include ProjectForksHelper
|
||||
let(:user) { create(:user, username: 'the-maintainer') }
|
||||
let(:target_project) { create(:project, :public, :repository) }
|
||||
|
@ -40,12 +41,13 @@ RSpec.describe 'a maintainer edits files on a source-branch of an MR from a fork
|
|||
end
|
||||
|
||||
it 'allows committing to the source branch' do
|
||||
execute_script("monaco.editor.getModels()[0].setValue('Updated the readme')")
|
||||
content = 'Updated the readme'
|
||||
editor_set_value(content)
|
||||
|
||||
click_button 'Commit changes'
|
||||
wait_for_requests
|
||||
|
||||
expect(page).to have_content('Your changes have been successfully committed')
|
||||
expect(page).to have_content('Updated the readme')
|
||||
expect(page).to have_content(content)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe 'Editing file blob', :js do
|
||||
include Spec::Support::Helpers::Features::SourceEditorSpecHelpers
|
||||
include TreeHelper
|
||||
include BlobSpecHelpers
|
||||
|
||||
|
@ -42,7 +43,7 @@ RSpec.describe 'Editing file blob', :js do
|
|||
|
||||
def fill_editor(content: 'class NextFeature\\nend\\n')
|
||||
wait_for_requests
|
||||
execute_script("monaco.editor.getModels()[0].setValue('#{content}')")
|
||||
editor_set_value(content)
|
||||
end
|
||||
|
||||
context 'from MR diff' do
|
||||
|
@ -98,10 +99,8 @@ RSpec.describe 'Editing file blob', :js do
|
|||
click_link 'Preview changes'
|
||||
wait_for_requests
|
||||
|
||||
old_line_count = page.all('.line_holder.old').size
|
||||
new_line_count = page.all('.line_holder.new').size
|
||||
|
||||
expect(old_line_count).to be > 0
|
||||
expect(new_line_count).to be > 0
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,6 +26,7 @@ RSpec.describe 'CI Lint', :js do
|
|||
shared_examples 'validates the YAML' do
|
||||
before do
|
||||
click_on 'Validate'
|
||||
scroll_to(page.find('[data-testid="ci-lint-status"]'))
|
||||
end
|
||||
|
||||
context 'YAML is correct' do
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe 'Projects > Files > User creates files', :js do
|
||||
include Spec::Support::Helpers::Features::SourceEditorSpecHelpers
|
||||
include BlobSpecHelpers
|
||||
|
||||
let(:fork_message) do
|
||||
|
@ -89,8 +90,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do
|
|||
end
|
||||
|
||||
it 'creates and commit a new file' do
|
||||
find('#editor')
|
||||
execute_script("monaco.editor.getModels()[0].setValue('*.rbca')")
|
||||
editor_set_value('*.rbca')
|
||||
fill_in(:file_name, with: 'not_a_file.md')
|
||||
fill_in(:commit_message, with: 'New commit message', visible: true)
|
||||
click_button('Commit changes')
|
||||
|
@ -107,8 +107,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do
|
|||
it 'creates and commit a new file with new lines at the end of file' do
|
||||
set_default_button('edit')
|
||||
|
||||
find('#editor')
|
||||
execute_script('monaco.editor.getModels()[0].setValue("Sample\n\n\n")')
|
||||
editor_set_value('Sample\n\n\n')
|
||||
fill_in(:file_name, with: 'not_a_file.md')
|
||||
fill_in(:commit_message, with: 'New commit message', visible: true)
|
||||
click_button('Commit changes')
|
||||
|
@ -119,8 +118,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do
|
|||
|
||||
click_link('Edit')
|
||||
|
||||
find('#editor')
|
||||
expect(evaluate_script('monaco.editor.getModels()[0].getValue()')).to eq("Sample\n\n\n")
|
||||
expect(find('.monaco-editor')).to have_content('Sample\n\n\n')
|
||||
end
|
||||
|
||||
it 'creates and commit a new file with a directory name' do
|
||||
|
@ -128,8 +126,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do
|
|||
|
||||
expect(page).to have_selector('.file-editor')
|
||||
|
||||
find('#editor')
|
||||
execute_script("monaco.editor.getModels()[0].setValue('*.rbca')")
|
||||
editor_set_value('*.rbca')
|
||||
fill_in(:commit_message, with: 'New commit message', visible: true)
|
||||
click_button('Commit changes')
|
||||
|
||||
|
@ -143,8 +140,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do
|
|||
it 'creates and commit a new file specifying a new branch' do
|
||||
expect(page).to have_selector('.file-editor')
|
||||
|
||||
find('#editor')
|
||||
execute_script("monaco.editor.getModels()[0].setValue('*.rbca')")
|
||||
editor_set_value('*.rbca')
|
||||
fill_in(:file_name, with: 'not_a_file.md')
|
||||
fill_in(:commit_message, with: 'New commit message', visible: true)
|
||||
fill_in(:branch_name, with: 'new_branch_name', visible: true)
|
||||
|
@ -178,8 +174,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do
|
|||
it 'creates and commit new file in forked project' do
|
||||
expect(page).to have_selector('.file-editor')
|
||||
|
||||
find('#editor')
|
||||
execute_script("monaco.editor.getModels()[0].setValue('*.rbca')")
|
||||
editor_set_value('*.rbca')
|
||||
|
||||
fill_in(:file_name, with: 'not_a_file.md')
|
||||
fill_in(:commit_message, with: 'New commit message', visible: true)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe 'Projects > Files > User edits files', :js do
|
||||
include Spec::Support::Helpers::Features::SourceEditorSpecHelpers
|
||||
include ProjectForksHelper
|
||||
include BlobSpecHelpers
|
||||
|
||||
|
@ -50,10 +51,9 @@ RSpec.describe 'Projects > Files > User edits files', :js do
|
|||
click_link_or_button('Edit')
|
||||
find('.file-editor', match: :first)
|
||||
|
||||
find('#editor')
|
||||
set_editor_value('*.rbca')
|
||||
editor_set_value('*.rbca')
|
||||
|
||||
expect(editor_value).to eq('*.rbca')
|
||||
expect(find('.monaco-editor')).to have_content('*.rbca')
|
||||
end
|
||||
|
||||
it 'does not show the edit link if a file is binary' do
|
||||
|
@ -72,8 +72,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do
|
|||
click_link_or_button('Edit')
|
||||
find('.file-editor', match: :first)
|
||||
|
||||
find('#editor')
|
||||
set_editor_value('*.rbca')
|
||||
editor_set_value('*.rbca')
|
||||
fill_in(:commit_message, with: 'New commit message', visible: true)
|
||||
click_button('Commit changes')
|
||||
|
||||
|
@ -91,8 +90,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do
|
|||
|
||||
find('.file-editor', match: :first)
|
||||
|
||||
find('#editor')
|
||||
set_editor_value('*.rbca')
|
||||
editor_set_value('*.rbca')
|
||||
fill_in(:commit_message, with: 'New commit message', visible: true)
|
||||
fill_in(:branch_name, with: 'new_branch_name', visible: true)
|
||||
click_button('Commit changes')
|
||||
|
@ -110,8 +108,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do
|
|||
click_link_or_button('Edit')
|
||||
find('.file-editor', match: :first)
|
||||
|
||||
find('#editor')
|
||||
set_editor_value('*.rbca')
|
||||
editor_set_value('*.rbca')
|
||||
click_link('Preview changes')
|
||||
|
||||
expect(page).to have_css('.line_holder.new')
|
||||
|
@ -156,10 +153,9 @@ RSpec.describe 'Projects > Files > User edits files', :js do
|
|||
|
||||
find('.file-editor', match: :first)
|
||||
|
||||
find('#editor')
|
||||
set_editor_value('*.rbca')
|
||||
editor_set_value('*.rbca')
|
||||
|
||||
expect(editor_value).to eq('*.rbca')
|
||||
expect(find('.monaco-editor')).to have_content('*.rbca')
|
||||
end
|
||||
|
||||
it 'opens the Web IDE in a forked project', :sidekiq_might_not_need_inline do
|
||||
|
@ -187,8 +183,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do
|
|||
|
||||
find('.file-editor', match: :first)
|
||||
|
||||
find('#editor')
|
||||
set_editor_value('*.rbca')
|
||||
editor_set_value('*.rbca')
|
||||
fill_in(:commit_message, with: 'New commit message', visible: true)
|
||||
click_button('Commit changes')
|
||||
|
||||
|
@ -216,8 +211,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do
|
|||
|
||||
expect(page).not_to have_link('Fork')
|
||||
|
||||
find('#editor')
|
||||
set_editor_value('*.rbca')
|
||||
editor_set_value('*.rbca')
|
||||
fill_in(:commit_message, with: 'Another commit', visible: true)
|
||||
click_button('Commit changes')
|
||||
|
||||
|
|
|
@ -15,4 +15,3 @@ jest.mock('monaco-editor/esm/vs/language/typescript/tsMode');
|
|||
jest.mock('monaco-yaml/lib/esm/yamlMode');
|
||||
|
||||
export * from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
export default global.monaco;
|
||||
|
|
|
@ -267,7 +267,6 @@ describe('Base editor', () => {
|
|||
let editorEl2;
|
||||
let inst1;
|
||||
let inst2;
|
||||
const readOnlyIndex = '78'; // readOnly option has the internal index of 78 in the editor's options
|
||||
|
||||
beforeEach(() => {
|
||||
setHTMLFixture('<div id="editor1"></div><div id="editor2"></div>');
|
||||
|
@ -331,10 +330,10 @@ describe('Base editor', () => {
|
|||
});
|
||||
|
||||
inst1 = editor.createInstance(inst1Args);
|
||||
expect(inst1.getOption(readOnlyIndex)).toBe(true);
|
||||
expect(inst1.getRawOptions().readOnly).toBe(true);
|
||||
|
||||
inst2 = editor.createInstance(inst2Args);
|
||||
expect(inst2.getOption(readOnlyIndex)).toBe(true);
|
||||
expect(inst2.getRawOptions().readOnly).toBe(true);
|
||||
});
|
||||
|
||||
it('allows overriding editor options on the instance level', () => {
|
||||
|
@ -346,7 +345,7 @@ describe('Base editor', () => {
|
|||
readOnly: false,
|
||||
});
|
||||
|
||||
expect(inst1.getOption(readOnlyIndex)).toBe(false);
|
||||
expect(inst1.getRawOptions().readOnly).toBe(false);
|
||||
});
|
||||
|
||||
it('disposes instances and relevant models independently from each other', () => {
|
||||
|
|
|
@ -70,7 +70,6 @@ class CustomEnvironment extends JSDOMEnvironment {
|
|||
//
|
||||
// Monaco-related environment variables
|
||||
//
|
||||
this.global.MonacoEnvironment = { globalAPI: true };
|
||||
Object.defineProperty(this.global, 'matchMedia', {
|
||||
writable: true,
|
||||
value: (query) => ({
|
||||
|
|
|
@ -145,8 +145,7 @@ describe('RepoEditor', () => {
|
|||
jest.clearAllMocks();
|
||||
// create a new model each time, otherwise tests conflict with each other
|
||||
// because of same model being used in multiple tests
|
||||
// eslint-disable-next-line no-undef
|
||||
monaco.editor.getModels().forEach((model) => model.dispose());
|
||||
monacoEditor.getModels().forEach((model) => model.dispose());
|
||||
wrapper.destroy();
|
||||
wrapper = null;
|
||||
});
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* global monaco */
|
||||
|
||||
import { editor as monacoEditor } from 'monaco-editor';
|
||||
import setWindowLocation from 'helpers/set_window_location_helper';
|
||||
import { TEST_HOST } from 'helpers/test_constants';
|
||||
import { initIde } from '~/ide';
|
||||
|
@ -20,7 +19,7 @@ export default (container, { isRepoEmpty = false, path = '', mrId = '' } = {}) =
|
|||
const vm = initIde(el, { extendStore });
|
||||
|
||||
// We need to dispose of editor Singleton things or tests will bump into eachother
|
||||
vm.$on('destroy', () => monaco.editor.getModels().forEach((model) => model.dispose()));
|
||||
vm.$on('destroy', () => monacoEditor.getModels().forEach((model) => model.dispose()));
|
||||
|
||||
return vm;
|
||||
};
|
||||
|
|
|
@ -26,6 +26,8 @@ RSpec.describe Gitlab::Memory::Watchdog, :aggregate_failures, :prometheus do
|
|||
allow(logger).to receive(:info)
|
||||
|
||||
allow(Gitlab::Metrics::Memory).to receive(:gc_heap_fragmentation).and_return(fragmentation)
|
||||
|
||||
allow(::Prometheus::PidProvider).to receive(:worker_id).and_return('worker_1')
|
||||
end
|
||||
|
||||
after do
|
||||
|
@ -37,7 +39,7 @@ RSpec.describe Gitlab::Memory::Watchdog, :aggregate_failures, :prometheus do
|
|||
let(:max_strikes) { 0 }
|
||||
|
||||
it 'sets the heap fragmentation limit gauge' do
|
||||
allow(Gitlab::Metrics).to receive(:gauge).and_return(heap_frag_limit_gauge)
|
||||
allow(Gitlab::Metrics).to receive(:gauge).with(anything, anything).and_return(heap_frag_limit_gauge)
|
||||
|
||||
expect(heap_frag_limit_gauge).to receive(:set).with({}, max_heap_fragmentation)
|
||||
end
|
||||
|
@ -86,11 +88,12 @@ RSpec.describe Gitlab::Memory::Watchdog, :aggregate_failures, :prometheus do
|
|||
let(:fragmentation) { max_heap_fragmentation + 0.1 }
|
||||
|
||||
before do
|
||||
expected_labels = { pid: 'worker_1' }
|
||||
allow(Gitlab::Metrics).to receive(:counter)
|
||||
.with(:gitlab_memwd_heap_frag_violations_total, anything, anything)
|
||||
.with(:gitlab_memwd_heap_frag_violations_total, anything, expected_labels)
|
||||
.and_return(heap_frag_violations_counter)
|
||||
allow(Gitlab::Metrics).to receive(:counter)
|
||||
.with(:gitlab_memwd_heap_frag_violations_handled_total, anything, anything)
|
||||
.with(:gitlab_memwd_heap_frag_violations_handled_total, anything, expected_labels)
|
||||
.and_return(heap_frag_violations_handled_counter)
|
||||
allow(heap_frag_violations_counter).to receive(:increment)
|
||||
allow(heap_frag_violations_handled_counter).to receive(:increment)
|
||||
|
@ -146,7 +149,6 @@ RSpec.describe Gitlab::Memory::Watchdog, :aggregate_failures, :prometheus do
|
|||
end
|
||||
|
||||
it 'logs the event' do
|
||||
expect(::Prometheus::PidProvider).to receive(:worker_id).at_least(:once).and_return('worker_1')
|
||||
expect(Gitlab::Metrics::System).to receive(:memory_usage_rss).at_least(:once).and_return(1024)
|
||||
expect(logger).to receive(:warn).with({
|
||||
message: 'heap fragmentation limit exceeded',
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::UsageDataCounters::MergeRequestWidgetExtensionCounter do
|
||||
it_behaves_like 'a redis usage counter', 'Widget Extension', :test_summary_count_expand
|
||||
|
||||
it_behaves_like 'a redis usage counter with totals', :i_code_review_merge_request_widget, test_summary_count_expand: 5
|
||||
end
|
|
@ -2920,7 +2920,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
|
|||
end
|
||||
|
||||
describe '#cancel_running' do
|
||||
subject(:latest_status) { pipeline.statuses.pluck(:status) }
|
||||
let(:latest_status) { pipeline.statuses.pluck(:status) }
|
||||
|
||||
let_it_be(:pipeline) { create(:ci_empty_pipeline, :created) }
|
||||
|
||||
|
@ -2963,6 +2963,32 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with bridge jobs' do
|
||||
before do
|
||||
create(:ci_bridge, :created, pipeline: pipeline)
|
||||
|
||||
pipeline.cancel_running
|
||||
end
|
||||
|
||||
it 'bridges are canceled' do
|
||||
expect(pipeline.bridges.first.status).to eq 'canceled'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when pipeline is not cancelable' do
|
||||
before do
|
||||
create(:ci_build, :canceled, stage_idx: 0, pipeline: pipeline)
|
||||
|
||||
pipeline.cancel_running
|
||||
end
|
||||
|
||||
it 'does not send cancel signal to cancel self' do
|
||||
expect(pipeline).not_to receive(:cancel_self_only)
|
||||
|
||||
pipeline.cancel_running
|
||||
end
|
||||
end
|
||||
|
||||
context 'preloading relations' do
|
||||
let(:pipeline1) { create(:ci_empty_pipeline, :created) }
|
||||
let(:pipeline2) { create(:ci_empty_pipeline, :created) }
|
||||
|
@ -2994,37 +3020,257 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when the first try cannot get an exclusive lock' do
|
||||
let(:retries) { 1 }
|
||||
shared_examples 'retries' do
|
||||
context 'when the first try cannot get an exclusive lock' do
|
||||
let(:retries) { 1 }
|
||||
|
||||
subject(:cancel_running) { pipeline.cancel_running(retries: retries) }
|
||||
subject { pipeline.cancel_running(retries: retries) }
|
||||
|
||||
before do
|
||||
build = create(:ci_build, :running, pipeline: pipeline)
|
||||
before do
|
||||
create(:ci_build, :running, pipeline: pipeline)
|
||||
|
||||
allow(pipeline.cancelable_statuses).to receive(:find_in_batches).and_yield([build])
|
||||
stub_first_cancel_call_fails
|
||||
end
|
||||
|
||||
call_count = 0
|
||||
allow(build).to receive(:cancel).and_wrap_original do |original, *args|
|
||||
call_count >= retries ? raise(ActiveRecord::StaleObjectError) : original.call(*args)
|
||||
it 'retries again and cancels the build' do
|
||||
subject
|
||||
|
||||
call_count += 1
|
||||
expect(latest_status).to contain_exactly('canceled')
|
||||
end
|
||||
|
||||
context 'when the retries parameter is 0' do
|
||||
let(:retries) { 0 }
|
||||
|
||||
it 'raises error' do
|
||||
expect { subject }.to raise_error(ActiveRecord::StaleObjectError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'retries again and cancels the build' do
|
||||
cancel_running
|
||||
def stub_first_cancel_call_fails
|
||||
call_count = 0
|
||||
|
||||
expect(latest_status).to contain_exactly('canceled')
|
||||
allow_next_found_instance_of(Ci::Build) do |build|
|
||||
allow(build).to receive(:cancel).and_wrap_original do |original, *args| # rubocop:disable RSpec/AnyInstanceOf
|
||||
call_count >= retries ? raise(ActiveRecord::StaleObjectError) : original.call(*args)
|
||||
|
||||
call_count += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with retries' do
|
||||
context 'when feature ci_parent_pipeline_cancels_children is disabled' do
|
||||
before do
|
||||
stub_feature_flags(ci_parent_pipeline_cancels_children: false)
|
||||
end
|
||||
|
||||
it_behaves_like 'retries'
|
||||
end
|
||||
|
||||
context 'when the retries parameter is 0' do
|
||||
let(:retries) { 0 }
|
||||
context 'when feature ci_parent_pipeline_cancels_children is enabled' do
|
||||
it_behaves_like 'retries'
|
||||
end
|
||||
end
|
||||
|
||||
it 'raises error' do
|
||||
expect do
|
||||
context 'when auto canceled' do
|
||||
let!(:canceled_by) { create(:ci_empty_pipeline) }
|
||||
|
||||
before do
|
||||
create(:ci_build, :running, pipeline: pipeline)
|
||||
|
||||
pipeline.cancel_running(auto_canceled_by_pipeline_id: canceled_by.id)
|
||||
end
|
||||
|
||||
it 'sets auto cancel' do
|
||||
jobs_canceled_by = pipeline.statuses.map { |s| s.auto_canceled_by.id }
|
||||
|
||||
expect(jobs_canceled_by).to contain_exactly(canceled_by.id)
|
||||
expect(pipeline.auto_canceled_by.id).to eq(canceled_by.id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are child pipelines', :sidekiq_inline do
|
||||
let_it_be(:child_pipeline) { create(:ci_empty_pipeline, :created, child_of: pipeline) }
|
||||
|
||||
before do
|
||||
project.clear_memoization(:cascade_cancel_pipelines_enabled)
|
||||
|
||||
pipeline.reload
|
||||
end
|
||||
|
||||
context 'when cascade_to_children is true' do
|
||||
let(:cascade_to_children) { true }
|
||||
let(:canceled_by) { nil }
|
||||
let(:execute_async) { true }
|
||||
|
||||
let(:params) do
|
||||
{
|
||||
cascade_to_children: cascade_to_children,
|
||||
execute_async: execute_async
|
||||
}.tap do |p|
|
||||
p.merge!(auto_canceled_by_pipeline_id: canceled_by.id) if canceled_by
|
||||
end
|
||||
end
|
||||
|
||||
subject(:cancel_running) { pipeline.cancel_running(**params) }
|
||||
|
||||
context 'when cancelable child pipeline builds' do
|
||||
before do
|
||||
create(:ci_build, :created, pipeline: child_pipeline)
|
||||
create(:ci_build, :running, pipeline: child_pipeline)
|
||||
end
|
||||
|
||||
it 'cancels child builds' do
|
||||
cancel_running
|
||||
end.to raise_error(ActiveRecord::StaleObjectError)
|
||||
|
||||
latest_status_for_child = child_pipeline.statuses.pluck(:status)
|
||||
expect(latest_status_for_child).to eq %w(canceled canceled)
|
||||
expect(latest_status).to eq %w(canceled)
|
||||
end
|
||||
|
||||
it 'cancels bridges' do
|
||||
create(:ci_bridge, :created, pipeline: pipeline)
|
||||
create(:ci_bridge, :created, pipeline: child_pipeline)
|
||||
|
||||
cancel_running
|
||||
|
||||
expect(pipeline.bridges.reload.first.status).to eq 'canceled'
|
||||
expect(child_pipeline.bridges.reload.first.status).to eq 'canceled'
|
||||
end
|
||||
|
||||
context 'with nested child pipelines' do
|
||||
let!(:nested_child_pipeline) { create(:ci_empty_pipeline, :created, child_of: child_pipeline) }
|
||||
let!(:nested_child_pipeline_build) { create(:ci_build, :created, pipeline: nested_child_pipeline) }
|
||||
|
||||
it 'cancels them' do
|
||||
cancel_running
|
||||
|
||||
expect(nested_child_pipeline.reload.status).to eq 'canceled'
|
||||
expect(nested_child_pipeline_build.reload.status).to eq 'canceled'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when auto canceled' do
|
||||
let(:canceled_by) { create(:ci_empty_pipeline) }
|
||||
|
||||
it 'sets auto cancel' do
|
||||
cancel_running
|
||||
|
||||
pipeline.reload
|
||||
|
||||
jobs_canceled_by_ids = pipeline.statuses.map(&:auto_canceled_by_id)
|
||||
child_pipelines_canceled_by_ids = pipeline.child_pipelines.map(&:auto_canceled_by_id)
|
||||
child_pipelines_jobs_canceled_by_ids = pipeline.child_pipelines.map(&:statuses).flatten.map(&:auto_canceled_by_id)
|
||||
|
||||
expect(jobs_canceled_by_ids).to contain_exactly(canceled_by.id)
|
||||
expect(pipeline.auto_canceled_by_id).to eq(canceled_by.id)
|
||||
expect(child_pipelines_canceled_by_ids).to contain_exactly(canceled_by.id)
|
||||
expect(child_pipelines_jobs_canceled_by_ids).to contain_exactly(canceled_by.id, canceled_by.id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when execute_async is false' do
|
||||
let(:execute_async) { false }
|
||||
|
||||
it 'runs sync' do
|
||||
expect(::Ci::CancelPipelineWorker).not_to receive(:perform_async)
|
||||
|
||||
cancel_running
|
||||
end
|
||||
|
||||
it 'cancels children' do
|
||||
cancel_running
|
||||
|
||||
latest_status_for_child = child_pipeline.statuses.pluck(:status)
|
||||
expect(latest_status_for_child).to eq %w(canceled canceled)
|
||||
expect(latest_status).to eq %w(canceled)
|
||||
end
|
||||
|
||||
context 'with nested child pipelines' do
|
||||
let!(:nested_child_pipeline) { create(:ci_empty_pipeline, :created, child_of: child_pipeline) }
|
||||
let!(:nested_child_pipeline_build) { create(:ci_build, :created, pipeline: nested_child_pipeline) }
|
||||
|
||||
it 'cancels them' do
|
||||
cancel_running
|
||||
|
||||
expect(nested_child_pipeline.reload.status).to eq 'canceled'
|
||||
expect(nested_child_pipeline_build.reload.status).to eq 'canceled'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'does not cancel uncancelable child pipeline builds' do
|
||||
create(:ci_build, :failed, pipeline: child_pipeline)
|
||||
|
||||
cancel_running
|
||||
|
||||
latest_status_for_child = child_pipeline.statuses.pluck(:status)
|
||||
expect(latest_status_for_child).to eq %w(failed)
|
||||
expect(latest_status).to eq %w(canceled)
|
||||
end
|
||||
|
||||
context 'when feature ci_parent_pipeline_cancels_children is disabled' do
|
||||
before do
|
||||
stub_feature_flags(ci_parent_pipeline_cancels_children: false)
|
||||
end
|
||||
|
||||
it 'does not cancel child pipeline builds' do
|
||||
create(:ci_build, :created, pipeline: child_pipeline)
|
||||
create(:ci_build, :running, pipeline: child_pipeline)
|
||||
|
||||
cancel_running
|
||||
|
||||
latest_status_for_child = child_pipeline.statuses.pluck(:status)
|
||||
expect(latest_status_for_child).not_to include('canceled')
|
||||
expect(latest_status).to eq %w(canceled)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when cascade_to_children is false' do
|
||||
let(:cascade_to_children) { false }
|
||||
|
||||
subject(:cancel_running) { pipeline.cancel_running(cascade_to_children: cascade_to_children) }
|
||||
|
||||
it 'does not cancel cancelable child pipeline builds' do
|
||||
create(:ci_build, :created, pipeline: child_pipeline)
|
||||
create(:ci_build, :running, pipeline: child_pipeline)
|
||||
|
||||
cancel_running
|
||||
|
||||
latest_status_for_child = child_pipeline.statuses.pluck(:status)
|
||||
expect(latest_status_for_child).to eq %w(created running)
|
||||
expect(latest_status).to eq %w(canceled)
|
||||
end
|
||||
|
||||
it 'does not cancel uncancelable child pipeline builds' do
|
||||
create(:ci_build, :failed, pipeline: child_pipeline)
|
||||
|
||||
cancel_running
|
||||
|
||||
latest_status_for_child = child_pipeline.statuses.pluck(:status)
|
||||
expect(latest_status_for_child).to eq %w(failed)
|
||||
expect(latest_status).to eq %w(canceled)
|
||||
end
|
||||
|
||||
context 'when feature ci_parent_pipeline_cancels_children is disabled' do
|
||||
before do
|
||||
stub_feature_flags(ci_parent_pipeline_cancels_children: false)
|
||||
end
|
||||
|
||||
it 'cancels parent but not children pipeline builds' do
|
||||
create(:ci_build, :created, pipeline: child_pipeline)
|
||||
create(:ci_build, :running, pipeline: child_pipeline)
|
||||
|
||||
cancel_running
|
||||
|
||||
latest_status_for_child = child_pipeline.statuses.pluck(:status)
|
||||
expect(latest_status_for_child).not_to include('canceled')
|
||||
expect(latest_status).to eq %w(canceled)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -251,7 +251,7 @@ RSpec.describe PersonalAccessToken do
|
|||
|
||||
describe '.simple_sorts' do
|
||||
it 'includes overridden keys' do
|
||||
expect(described_class.simple_sorts.keys).to include(*%w(expires_at_asc expires_at_desc))
|
||||
expect(described_class.simple_sorts.keys).to include(*%w(expires_at_asc expires_at_desc expires_at_asc_id_desc))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -270,5 +270,13 @@ RSpec.describe PersonalAccessToken do
|
|||
expect(described_class.order_expires_at_desc).to match [later_token, earlier_token]
|
||||
end
|
||||
end
|
||||
|
||||
describe '.order_expires_at_asc_id_desc' do
|
||||
let_it_be(:earlier_token_2) { create(:personal_access_token, expires_at: 2.days.ago) }
|
||||
|
||||
it 'returns ordered list in combination of expires_at ascending and id descending' do
|
||||
expect(described_class.order_expires_at_asc_id_desc).to eq [earlier_token_2, earlier_token, later_token]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1792,9 +1792,10 @@ RSpec.describe User do
|
|||
|
||||
describe '#generate_password' do
|
||||
it 'does not generate password by default' do
|
||||
user = create(:user, password: 'abcdefghe')
|
||||
password = User.random_password
|
||||
user = create(:user, password: password)
|
||||
|
||||
expect(user.password).to eq('abcdefghe')
|
||||
expect(user.password).to eq(password)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -5997,8 +5998,9 @@ RSpec.describe User do
|
|||
end
|
||||
|
||||
context 'user with a bcrypt password hash' do
|
||||
# Plaintext password 'eiFubohV6iro'
|
||||
let(:encrypted_password) { '$2a$10$xLTxCKOa75IU4RQGqqOrTuZOgZdJEzfSzjG6ZSEi/C31TB/yLZYpi' }
|
||||
# Manually set a 'known' encrypted password
|
||||
let(:password) { User.random_password }
|
||||
let(:encrypted_password) { Devise::Encryptor.digest(User, password) }
|
||||
let(:user) { create(:user, encrypted_password: encrypted_password) }
|
||||
|
||||
shared_examples 'not re-encrypting with PBKDF2' do
|
||||
|
@ -6010,7 +6012,9 @@ RSpec.describe User do
|
|||
end
|
||||
|
||||
context 'using the wrong password' do
|
||||
# password 'WRONG PASSWORD' will not match the bcrypt hash
|
||||
let(:password) { 'WRONG PASSWORD' }
|
||||
let(:encrypted_password) { Devise::Encryptor.digest(User, User.random_password) }
|
||||
|
||||
it { is_expected.to be_falsey }
|
||||
it_behaves_like 'not re-encrypting with PBKDF2'
|
||||
|
@ -6026,8 +6030,6 @@ RSpec.describe User do
|
|||
end
|
||||
|
||||
context 'using the correct password' do
|
||||
let(:password) { 'eiFubohV6iro' }
|
||||
|
||||
it { is_expected.to be_truthy }
|
||||
|
||||
it 'validates the password and re-encrypts with PBKDF2' do
|
||||
|
@ -6061,8 +6063,11 @@ RSpec.describe User do
|
|||
end
|
||||
|
||||
context 'user with password hash that is neither PBKDF2 nor BCrypt' do
|
||||
let(:user) { create(:user, encrypted_password: '$argon2i$v=19$m=512,t=4,p=2$eM+ZMyYkpDRGaI3xXmuNcQ$c5DeJg3eb5dskVt1mDdxfw') }
|
||||
let(:password) { 'password' }
|
||||
# Manually calculated User.random_password
|
||||
let(:password) { "gg_w215TmVXGWSt7RJKXwYTVz886f6SDM3zvzztaJf2mX9ttUE8gRkNJSbWyWRLqxz4LFzxBekPe75ydDcGauE9wqg-acKMRT-WpSYjTm1Rdx-tnssE7CQByJcnxwWNH" }
|
||||
# Created with https://argon2.online/ using 'aaaaaaaa' as the salt
|
||||
let(:encrypted_password) { "$argon2i$v=19$m=512,t=4,p=2$YWFhYWFhYWE$PvJscKO5XRlevcgRReUg6w" }
|
||||
let(:user) { create(:user, encrypted_password: encrypted_password) }
|
||||
|
||||
it { is_expected.to be_falsey }
|
||||
|
||||
|
@ -6079,7 +6084,7 @@ RSpec.describe User do
|
|||
# These entire test section can be removed once the :pbkdf2_password_encryption feature flag is removed.
|
||||
describe '#password=' do
|
||||
let(:user) { create(:user) }
|
||||
let(:password) { 'Oot5iechahqu' }
|
||||
let(:password) { User.random_password }
|
||||
|
||||
def compare_bcrypt_password(user, password)
|
||||
Devise::Encryptor.compare(User, user.encrypted_password, password)
|
||||
|
|
|
@ -18,10 +18,10 @@ RSpec.describe ProjectHookPresenter do
|
|||
end
|
||||
|
||||
describe '#logs_retry_path' do
|
||||
subject { web_hook.present.logs_details_path(web_hook_log) }
|
||||
subject { web_hook.present.logs_retry_path(web_hook_log) }
|
||||
|
||||
let(:expected_path) do
|
||||
"/#{project.namespace.path}/#{project.name}/-/hooks/#{web_hook.id}/hook_logs/#{web_hook_log.id}"
|
||||
"/#{project.namespace.path}/#{project.name}/-/hooks/#{web_hook.id}/hook_logs/#{web_hook_log.id}/retry"
|
||||
end
|
||||
|
||||
it { is_expected.to eq(expected_path) }
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe GroupAccessTokenEntity do
|
||||
let_it_be(:group) { create(:group) }
|
||||
let_it_be(:bot) { create(:user, :project_bot) }
|
||||
let_it_be(:token) { create(:personal_access_token, user: bot) }
|
||||
|
||||
subject(:json) { described_class.new(token, group: group).as_json }
|
||||
|
||||
context 'when bot is a member of the group' do
|
||||
before do
|
||||
group.add_developer(bot)
|
||||
end
|
||||
|
||||
it 'has the correct attributes' do
|
||||
expected_revoke_path = Gitlab::Routing.url_helpers
|
||||
.revoke_group_settings_access_token_path(
|
||||
{ id: token,
|
||||
group_id: group.path })
|
||||
|
||||
expect(json).to(
|
||||
include(
|
||||
id: token.id,
|
||||
name: token.name,
|
||||
scopes: token.scopes,
|
||||
user_id: token.user_id,
|
||||
revoke_path: expected_revoke_path,
|
||||
access_level: ::Gitlab::Access::DEVELOPER
|
||||
))
|
||||
|
||||
expect(json).not_to include(:token)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when bot is unrelated to the group' do
|
||||
it 'has the correct attributes' do
|
||||
expected_revoke_path = Gitlab::Routing.url_helpers
|
||||
.revoke_group_settings_access_token_path(
|
||||
{ id: token,
|
||||
group_id: group.path })
|
||||
|
||||
expect(json).to(
|
||||
include(
|
||||
id: token.id,
|
||||
name: token.name,
|
||||
scopes: token.scopes,
|
||||
user_id: token.user_id,
|
||||
revoke_path: expected_revoke_path,
|
||||
access_level: nil
|
||||
))
|
||||
|
||||
expect(json).not_to include(:token)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,28 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe GroupAccessTokenSerializer do
|
||||
let_it_be(:group) { create(:group) }
|
||||
let_it_be(:bot) { create(:user, :project_bot) }
|
||||
|
||||
subject(:serializer) { described_class.new }
|
||||
|
||||
before do
|
||||
group.add_developer(bot)
|
||||
end
|
||||
|
||||
describe '#represent' do
|
||||
it 'can render a single token' do
|
||||
token = create(:personal_access_token, user: bot)
|
||||
|
||||
expect(serializer.represent(token, group: group)).to be_kind_of(Hash)
|
||||
end
|
||||
|
||||
it 'can render a collection of tokens' do
|
||||
tokens = create_list(:personal_access_token, 2, user: bot)
|
||||
|
||||
expect(serializer.represent(tokens, group: group)).to be_kind_of(Array)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe PersonalAccessTokenEntity do
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:token) { create(:personal_access_token, user: user) }
|
||||
|
||||
subject(:json) { described_class.new(token).as_json }
|
||||
|
||||
it 'has the correct attributes' do
|
||||
expected_revoke_path = Gitlab::Routing.url_helpers
|
||||
.revoke_profile_personal_access_token_path(
|
||||
{ id: token })
|
||||
|
||||
expect(json).to(
|
||||
include(
|
||||
id: token.id,
|
||||
name: token.name,
|
||||
scopes: token.scopes,
|
||||
user_id: token.user_id,
|
||||
revoke_path: expected_revoke_path
|
||||
))
|
||||
|
||||
expect(json).not_to include(:token)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe PersonalAccessTokenSerializer do
|
||||
subject(:serializer) { described_class.new }
|
||||
|
||||
describe '#represent' do
|
||||
it 'can render a single token' do
|
||||
token = create(:personal_access_token)
|
||||
|
||||
expect(serializer.represent(token)).to be_kind_of(Hash)
|
||||
end
|
||||
|
||||
it 'can render a collection of tokens' do
|
||||
tokens = create_list(:personal_access_token, 2)
|
||||
|
||||
expect(serializer.represent(tokens)).to be_kind_of(Array)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,61 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe ProjectAccessTokenEntity do
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:bot) { create(:user, :project_bot) }
|
||||
let_it_be(:token) { create(:personal_access_token, user: bot) }
|
||||
|
||||
subject(:json) { described_class.new(token, project: project).as_json }
|
||||
|
||||
context 'when bot is a member of the project' do
|
||||
before do
|
||||
project.add_developer(bot)
|
||||
end
|
||||
|
||||
it 'has the correct attributes' do
|
||||
expected_revoke_path = Gitlab::Routing.url_helpers
|
||||
.revoke_namespace_project_settings_access_token_path(
|
||||
{ id: token,
|
||||
namespace_id: project.namespace.path,
|
||||
project_id: project.path })
|
||||
|
||||
expect(json).to(
|
||||
include(
|
||||
id: token.id,
|
||||
name: token.name,
|
||||
scopes: token.scopes,
|
||||
user_id: token.user_id,
|
||||
revoke_path: expected_revoke_path,
|
||||
access_level: ::Gitlab::Access::DEVELOPER
|
||||
))
|
||||
|
||||
expect(json).not_to include(:token)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when bot is unrelated to the project' do
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
it 'has the correct attributes' do
|
||||
expected_revoke_path = Gitlab::Routing.url_helpers
|
||||
.revoke_namespace_project_settings_access_token_path(
|
||||
{ id: token,
|
||||
namespace_id: project.namespace.path,
|
||||
project_id: project.path })
|
||||
|
||||
expect(json).to(
|
||||
include(
|
||||
id: token.id,
|
||||
name: token.name,
|
||||
scopes: token.scopes,
|
||||
user_id: token.user_id,
|
||||
revoke_path: expected_revoke_path,
|
||||
access_level: nil
|
||||
))
|
||||
|
||||
expect(json).not_to include(:token)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,28 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe ProjectAccessTokenSerializer do
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:bot) { create(:user, :project_bot) }
|
||||
|
||||
subject(:serializer) { described_class.new }
|
||||
|
||||
before do
|
||||
project.add_developer(bot)
|
||||
end
|
||||
|
||||
describe '#represent' do
|
||||
it 'can render a single token' do
|
||||
token = create(:personal_access_token, user: bot)
|
||||
|
||||
expect(serializer.represent(token, project: project)).to be_kind_of(Hash)
|
||||
end
|
||||
|
||||
it 'can render a collection of tokens' do
|
||||
tokens = create_list(:personal_access_token, 2, user: bot)
|
||||
|
||||
expect(serializer.represent(tokens, project: project)).to be_kind_of(Array)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -90,15 +90,23 @@ RSpec.describe ::Ci::DestroyPipelineService do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when pipeline is in cancelable state' do
|
||||
before do
|
||||
allow(pipeline).to receive(:cancelable?).and_return(true)
|
||||
end
|
||||
context 'when pipeline is in cancelable state', :sidekiq_inline do
|
||||
let!(:build) { create(:ci_build, :running, pipeline: pipeline) }
|
||||
let!(:child_pipeline) { create(:ci_pipeline, :running, child_of: pipeline) }
|
||||
let!(:child_build) { create(:ci_build, :running, pipeline: child_pipeline) }
|
||||
|
||||
it 'cancels the pipeline' do
|
||||
expect(pipeline).to receive(:cancel_running)
|
||||
it 'cancels the pipelines sync' do
|
||||
# turn off deletion for all instances of pipeline to allow for testing cancellation
|
||||
allow(pipeline).to receive_message_chain(:reset, :destroy!)
|
||||
allow_next_found_instance_of(Ci::Pipeline) { |p| allow(p).to receive_message_chain(:reset, :destroy!) }
|
||||
|
||||
# ensure cancellation happens sync so we accumulate minutes
|
||||
expect(::Ci::CancelPipelineWorker).not_to receive(:perform)
|
||||
|
||||
subject
|
||||
|
||||
expect(build.reload.status).to eq('canceled')
|
||||
expect(child_build.reload.status).to eq('canceled')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,12 +11,4 @@ module BlobSpecHelpers
|
|||
def unset_default_button
|
||||
set_default_button('')
|
||||
end
|
||||
|
||||
def editor_value
|
||||
evaluate_script('monaco.editor.getModels()[0].getValue()')
|
||||
end
|
||||
|
||||
def set_editor_value(value)
|
||||
execute_script("monaco.editor.getModels()[0].setValue('#{value}')")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,8 +12,7 @@ module Spec
|
|||
def editor_set_value(value)
|
||||
editor = find('.monaco-editor')
|
||||
uri = editor['data-uri']
|
||||
|
||||
execute_script("monaco.editor.getModel('#{uri}').setValue('#{escape_javascript(value)}')")
|
||||
execute_script("localMonaco.getModel('#{uri}').setValue('#{escape_javascript(value)}')")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Ci::CancelPipelineWorker, :aggregate_failures do
|
||||
let!(:pipeline) { create(:ci_pipeline, :running) }
|
||||
|
||||
describe '#perform' do
|
||||
subject(:perform) { described_class.new.perform(pipeline.id, pipeline.id) }
|
||||
|
||||
it 'calls cancel_running' do
|
||||
allow(::Ci::Pipeline).to receive(:find_by_id).and_return(pipeline)
|
||||
expect(pipeline).to receive(:cancel_running).with(
|
||||
auto_canceled_by_pipeline_id: pipeline.id,
|
||||
cascade_to_children: false
|
||||
)
|
||||
|
||||
perform
|
||||
end
|
||||
|
||||
context 'if pipeline is deleted' do
|
||||
subject(:perform) { described_class.new.perform(non_existing_record_id, non_existing_record_id) }
|
||||
|
||||
it 'does not error' do
|
||||
expect(pipeline).not_to receive(:cancel_running)
|
||||
|
||||
perform
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with builds and state transition side effects', :sidekiq_inline do
|
||||
let!(:build) { create(:ci_build, :running, pipeline: pipeline) }
|
||||
|
||||
it_behaves_like 'an idempotent worker', :sidekiq_inline do
|
||||
let(:job_args) { [pipeline.id, pipeline.id] }
|
||||
|
||||
it 'cancels the pipeline' do
|
||||
perform
|
||||
|
||||
pipeline.reload
|
||||
|
||||
expect(pipeline).to be_canceled
|
||||
expect(pipeline.builds.first).to be_canceled
|
||||
expect(pipeline.builds.first.auto_canceled_by_id).to eq pipeline.id
|
||||
expect(pipeline.auto_canceled_by_id).to eq pipeline.id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
184
yarn.lock
184
yarn.lock
|
@ -2576,13 +2576,6 @@ acorn@^8.0.4, acorn@^8.7.0:
|
|||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30"
|
||||
integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==
|
||||
|
||||
agent-base@4, agent-base@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
|
||||
integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==
|
||||
dependencies:
|
||||
es6-promisify "^5.0.0"
|
||||
|
||||
aggregate-error@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0"
|
||||
|
@ -4780,14 +4773,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9:
|
|||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@^3.1.0, debug@^3.2.6, debug@^3.2.7:
|
||||
debug@^3.2.6, debug@^3.2.7:
|
||||
version "3.2.7"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
|
||||
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
|
||||
|
@ -5331,23 +5317,11 @@ es-to-primitive@^1.2.1:
|
|||
is-date-object "^1.0.1"
|
||||
is-symbol "^1.0.2"
|
||||
|
||||
es6-promise@^4.0.3:
|
||||
version "4.2.8"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
|
||||
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
|
||||
|
||||
es6-promise@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.0.2.tgz#010d5858423a5f118979665f46486a95c6ee2bb6"
|
||||
integrity sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=
|
||||
|
||||
es6-promisify@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
|
||||
integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=
|
||||
dependencies:
|
||||
es6-promise "^4.0.3"
|
||||
|
||||
escalade@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
|
||||
|
@ -6845,14 +6819,6 @@ http-parser-js@>=0.5.1:
|
|||
resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9"
|
||||
integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==
|
||||
|
||||
http-proxy-agent@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405"
|
||||
integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==
|
||||
dependencies:
|
||||
agent-base "4"
|
||||
debug "3.1.0"
|
||||
|
||||
http-proxy-middleware@^2.0.3:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.4.tgz#03af0f4676d172ae775cb5c33f592f40e1a4e07a"
|
||||
|
@ -6887,14 +6853,6 @@ https-browserify@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
|
||||
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
|
||||
|
||||
https-proxy-agent@^2.2.3:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b"
|
||||
integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==
|
||||
dependencies:
|
||||
agent-base "^4.3.0"
|
||||
debug "^3.1.0"
|
||||
|
||||
human-signals@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
|
||||
|
@ -7961,7 +7919,7 @@ js-cookie@^3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
|
||||
|
||||
js-yaml@^3.13.1:
|
||||
js-yaml@^3.13.1, js-yaml@^3.14.1:
|
||||
version "3.14.1"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537"
|
||||
integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
|
||||
|
@ -8105,11 +8063,6 @@ json5@^2.1.2, json5@^2.2.1:
|
|||
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c"
|
||||
integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
|
||||
|
||||
jsonc-parser@^2.2.1, jsonc-parser@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.3.1.tgz#59549150b133f2efacca48fe9ce1ec0659af2342"
|
||||
integrity sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==
|
||||
|
||||
jsonc-parser@~3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22"
|
||||
|
@ -9397,24 +9350,26 @@ moment-mini@^2.24.0:
|
|||
resolved "https://registry.yarnpkg.com/moment-mini/-/moment-mini-2.24.0.tgz#fa68d98f7fe93ae65bf1262f6abb5fb6983d8d18"
|
||||
integrity sha512-9ARkWHBs+6YJIvrIp0Ik5tyTTtP9PoV0Ssu2Ocq5y9v8+NOOpWiRshAp8c4rZVWTOe+157on/5G+zj5pwIQFEQ==
|
||||
|
||||
monaco-editor-webpack-plugin@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-4.0.0.tgz#95be3f48f4220999b909266a9997727f0deab947"
|
||||
integrity sha512-4BT9XDRQXraMQjxEUjR+uuubRe3RIPkvVoGw8zwWG++s7wq6TAiXaSOMdkdS9TrjCREgSnygCOlVzY6MS8RPuA==
|
||||
monaco-editor-webpack-plugin@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-4.2.0.tgz#2be76cde9cca7bd8c3418503625990f86886927b"
|
||||
integrity sha512-/P3sFiEgBl+Y50he4mbknMhbLJVop5gBUZiPS86SuHUDOOnQiQ5rL1jU5lwt1XKAwMEkhwZbUwqaHxTPkb1Utw==
|
||||
dependencies:
|
||||
loader-utils "^2.0.0"
|
||||
|
||||
monaco-editor@^0.25.2:
|
||||
version "0.25.2"
|
||||
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.25.2.tgz#119e2b15bbd968a1a99c03cac9c329316d7c37e9"
|
||||
integrity sha512-5iylzSJevCnzJn9UVsW8yOZ3yHjmAs4TfvH3zsbftKiFKmHG0xirGN6DK9Kk04VSWxYCZZAIafYJoNJJMAU1KA==
|
||||
monaco-editor@^0.28.0:
|
||||
version "0.28.1"
|
||||
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.28.1.tgz#732788ff2172d59e6d436b206da8cac715413940"
|
||||
integrity sha512-P1vPqxB4B1ZFzTeR1ScggSp9/5NoQrLCq88fnlNUsuRAP1usEBN4TIpI2lw0AYIZNVIanHk0qwjze2uJwGOHUw==
|
||||
|
||||
monaco-yaml@^2.5.1:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/monaco-yaml/-/monaco-yaml-2.5.1.tgz#af9303a4aa6e3b94db62b8a8659362f31944590d"
|
||||
integrity sha512-U+zIAcwnQzlUgy6vdzFdNf5PToFzuz099FxYmUxIeen9GTiq6XYDX9mmXSR31mMrgiSaU5a2bGEyG4p2fbW/7A==
|
||||
monaco-yaml@3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/monaco-yaml/-/monaco-yaml-3.0.0.tgz#b3d59c3485bd5a161438072a8e5a8aaf74041dfd"
|
||||
integrity sha512-WkgdfjCj0L2VPPwPoiwc4l8+B78FyVpSsMoufEWqe3ukm8+WygKUtmtCFOFnehmMih6tSqhy4DUtoAhfnicyZA==
|
||||
dependencies:
|
||||
yaml-language-server "^0.11.1"
|
||||
"@types/json-schema" "^7.0.8"
|
||||
js-yaml "^3.14.1"
|
||||
yaml-ast-parser-custom-tags "^0.0.43"
|
||||
|
||||
mousetrap@1.6.5:
|
||||
version "1.6.5"
|
||||
|
@ -10301,11 +10256,6 @@ pretender@^3.4.3:
|
|||
fake-xml-http-request "^2.1.1"
|
||||
route-recognizer "^0.3.3"
|
||||
|
||||
prettier@2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4"
|
||||
integrity sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==
|
||||
|
||||
prettier@2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5"
|
||||
|
@ -10933,15 +10883,6 @@ repeat-string@^1.6.1:
|
|||
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
|
||||
integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc=
|
||||
|
||||
request-light@^0.2.4:
|
||||
version "0.2.5"
|
||||
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.2.5.tgz#38a3da7b2e56f7af8cbba57e8a94930ee2380746"
|
||||
integrity sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==
|
||||
dependencies:
|
||||
http-proxy-agent "^2.1.0"
|
||||
https-proxy-agent "^2.2.3"
|
||||
vscode-nls "^4.1.1"
|
||||
|
||||
request-promise-core@1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f"
|
||||
|
@ -12852,78 +12793,6 @@ vm-browserify@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.0.tgz#bd76d6a23323e2ca8ffa12028dc04559c75f9019"
|
||||
integrity sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==
|
||||
|
||||
vscode-json-languageservice@^3.6.0:
|
||||
version "3.9.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.9.1.tgz#f72b581f8cd2bd9b47445ccf8b0ddcde6aba7483"
|
||||
integrity sha512-oJkknkdCVitQ5XPSRa0weHjUxt8eSCptaL+MBQQlRsa6Nb8XnEY0S5wYnLUFHzEvKzwt01/LKk8LdOixWEXkNA==
|
||||
dependencies:
|
||||
jsonc-parser "^2.3.1"
|
||||
vscode-languageserver-textdocument "^1.0.1"
|
||||
vscode-languageserver-types "3.16.0-next.2"
|
||||
vscode-nls "^5.0.0"
|
||||
vscode-uri "^2.1.2"
|
||||
|
||||
vscode-jsonrpc@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz#a7bf74ef3254d0a0c272fab15c82128e378b3be9"
|
||||
integrity sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==
|
||||
|
||||
vscode-languageserver-protocol@3.14.1:
|
||||
version "3.14.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz#b8aab6afae2849c84a8983d39a1cf742417afe2f"
|
||||
integrity sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==
|
||||
dependencies:
|
||||
vscode-jsonrpc "^4.0.0"
|
||||
vscode-languageserver-types "3.14.0"
|
||||
|
||||
vscode-languageserver-textdocument@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz#178168e87efad6171b372add1dea34f53e5d330f"
|
||||
integrity sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==
|
||||
|
||||
vscode-languageserver-types@3.14.0:
|
||||
version "3.14.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz#d3b5952246d30e5241592b6dde8280e03942e743"
|
||||
integrity sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==
|
||||
|
||||
vscode-languageserver-types@3.16.0-next.2:
|
||||
version "3.16.0-next.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0-next.2.tgz#940bd15c992295a65eae8ab6b8568a1e8daa3083"
|
||||
integrity sha512-QjXB7CKIfFzKbiCJC4OWC8xUncLsxo19FzGVp/ADFvvi87PlmBSCAtZI5xwGjF5qE0xkLf0jjKUn3DzmpDP52Q==
|
||||
|
||||
vscode-languageserver-types@^3.15.1:
|
||||
version "3.15.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz#17be71d78d2f6236d414f0001ce1ef4d23e6b6de"
|
||||
integrity sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==
|
||||
|
||||
vscode-languageserver@^5.2.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz#0d2feddd33f92aadf5da32450df498d52f6f14eb"
|
||||
integrity sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==
|
||||
dependencies:
|
||||
vscode-languageserver-protocol "3.14.1"
|
||||
vscode-uri "^1.0.6"
|
||||
|
||||
vscode-nls@^4.1.1, vscode-nls@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.2.tgz#ca8bf8bb82a0987b32801f9fddfdd2fb9fd3c167"
|
||||
integrity sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==
|
||||
|
||||
vscode-nls@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.0.tgz#99f0da0bd9ea7cda44e565a74c54b1f2bc257840"
|
||||
integrity sha512-u0Lw+IYlgbEJFF6/qAqG2d1jQmJl0eyAGJHoAJqr2HT4M2BNuQYSEiSE75f52pXHSJm8AlTjnLLbBFPrdz2hpA==
|
||||
|
||||
vscode-uri@^1.0.6:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.8.tgz#9769aaececae4026fb6e22359cb38946580ded59"
|
||||
integrity sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==
|
||||
|
||||
vscode-uri@^2.1.1, vscode-uri@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.1.2.tgz#c8d40de93eb57af31f3c715dd650e2ca2c096f1c"
|
||||
integrity sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==
|
||||
|
||||
vue-apollo@^3.0.7:
|
||||
version "3.0.7"
|
||||
resolved "https://registry.yarnpkg.com/vue-apollo/-/vue-apollo-3.0.7.tgz#97a031d45641faa4888a6d5a7f71c40834359704"
|
||||
|
@ -13481,28 +13350,11 @@ yallist@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
|
||||
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
||||
|
||||
yaml-ast-parser-custom-tags@0.0.43:
|
||||
yaml-ast-parser-custom-tags@^0.0.43:
|
||||
version "0.0.43"
|
||||
resolved "https://registry.yarnpkg.com/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz#46968145ce4e24cb03c3312057f0f141b93a7d02"
|
||||
integrity sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==
|
||||
|
||||
yaml-language-server@^0.11.1:
|
||||
version "0.11.1"
|
||||
resolved "https://registry.yarnpkg.com/yaml-language-server/-/yaml-language-server-0.11.1.tgz#4ddc72eb9a6dd7dc41f31af2a8f5c72cce456cc9"
|
||||
integrity sha512-N3Tu3g4O6ZWV7W0LVsNk62DtKJDQkbnPZRDd7ntaAeEl8QkxL1vnMunI26uzDU4PwwG4tPJ8g/VRS6U+fVp/6A==
|
||||
dependencies:
|
||||
js-yaml "^3.13.1"
|
||||
jsonc-parser "^2.2.1"
|
||||
request-light "^0.2.4"
|
||||
vscode-json-languageservice "^3.6.0"
|
||||
vscode-languageserver "^5.2.1"
|
||||
vscode-languageserver-types "^3.15.1"
|
||||
vscode-nls "^4.1.2"
|
||||
vscode-uri "^2.1.1"
|
||||
yaml-ast-parser-custom-tags "0.0.43"
|
||||
optionalDependencies:
|
||||
prettier "2.0.5"
|
||||
|
||||
yaml@^1.10.0:
|
||||
version "1.10.2"
|
||||
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
|
||||
|
|
Loading…
Reference in New Issue