Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-09-25 12:09:24 +00:00
parent 9c3a433b31
commit 7a3aca2b5b
53 changed files with 711 additions and 580 deletions

View File

@ -24,6 +24,7 @@ RSpec/FilePath:
- 'spec/benchmarks/banzai_benchmark.rb'
- 'spec/docs_screenshots/container_registry_docs.rb'
- 'spec/docs_screenshots/wiki_docs.rb'
- 'spec/initializers/gitlab_http_spec.rb'
- 'spec/lib/error_tracking/sentry_client/event_spec.rb'
- 'spec/lib/gitlab/import_export/import_export_spec.rb'
- 'spec/lib/gitlab/mail_room/mail_room_spec.rb'

View File

@ -1 +1 @@
0fed39f4d44b51ff5dfa20e6dc4a1a940a5a6b38
531d5205acec6b5160d862ea687c157c07cbcff1

View File

@ -253,7 +253,7 @@ gem 'rainbow', '~> 3.0'
gem 'ruby-progressbar', '~> 1.10'
# Linear-time regex library for untrusted regular expressions
gem 're2', '2.1.2'
gem 're2', '2.1.3'
# Misc
@ -349,6 +349,7 @@ gem 'sentry-sidekiq', '~> 5.8.0'
gem 'pg_query', '~> 4.2.3'
gem 'gitlab-schema-validation', path: 'gems/gitlab-schema-validation'
gem 'gitlab-http', path: 'gems/gitlab-http'
gem 'premailer-rails', '~> 1.10.3'

View File

@ -490,16 +490,16 @@
{"name":"rbtree","version":"0.4.6","platform":"ruby","checksum":"14eea4469b24fd2472542e5f3eb105d6344c8ccf36f0b56d55fdcfeb4e0f10fc"},
{"name":"rchardet","version":"1.8.0","platform":"ruby","checksum":"693acd5253d5ade81a51940697955f6dd4bb2f0d245bda76a8e23deec70a52c7"},
{"name":"rdoc","version":"6.3.2","platform":"ruby","checksum":"def4a720235c27d56c176ae73555e647eb04ea58a8bbaa927f8f9f79de7805a6"},
{"name":"re2","version":"2.1.2","platform":"aarch64-linux","checksum":"dbd87fb2432f17734cfb948d38cb0d138335228d31c4316719c75ac0a976731f"},
{"name":"re2","version":"2.1.2","platform":"arm-linux","checksum":"4c0d903508bc0d82f27d09c84498e0fdc6ab87ef418bea884d711b85f7fca62f"},
{"name":"re2","version":"2.1.2","platform":"arm64-darwin","checksum":"39bb8a44a4afbd2d3f2e07d531d223728f7c4b83946bc55e8ce6aae8c2c34579"},
{"name":"re2","version":"2.1.2","platform":"ruby","checksum":"06bd25bf566dda720cbc607ceecb65ed16871427fbcb3e5239c300ec796fee9c"},
{"name":"re2","version":"2.1.2","platform":"x64-mingw-ucrt","checksum":"a1ad9cda576dae6020664c7578d7e43d2062ca21e5e945aea125f539944ee713"},
{"name":"re2","version":"2.1.2","platform":"x64-mingw32","checksum":"804fc9bafc6590e3e75d27d289546d7223b51bf3e46e9d81ee89cf5168c1a9be"},
{"name":"re2","version":"2.1.2","platform":"x86-linux","checksum":"6a048f8a1511a5481f7a386045e67ecbb221a856d2987b33a231efb5e17250bc"},
{"name":"re2","version":"2.1.2","platform":"x86-mingw32","checksum":"8e0e9d0f3166ff3000ffa38a05c9e5275ba431f2abce494fa7600033206ce108"},
{"name":"re2","version":"2.1.2","platform":"x86_64-darwin","checksum":"6b41f328b551173e58eb04320c70295de143b5aeb38c78122aa623a4308bc472"},
{"name":"re2","version":"2.1.2","platform":"x86_64-linux","checksum":"e082a1db722b7da3adc9e1f9d8681cba80a2d1176c54ae741443965ce277e6af"},
{"name":"re2","version":"2.1.3","platform":"aarch64-linux","checksum":"27316bb47cfc0f28cfd1626426120e1c55ca8420a64c9e966f8feb1c911eae2a"},
{"name":"re2","version":"2.1.3","platform":"arm-linux","checksum":"81ffdd76b202f24461b4868abed96c994e2106e57970004b841499da983f688c"},
{"name":"re2","version":"2.1.3","platform":"arm64-darwin","checksum":"86d553e85779943a353865cbfdd89156c0411b92a1c7fe6abf1024135d53190e"},
{"name":"re2","version":"2.1.3","platform":"ruby","checksum":"03a30b53002ab66b66fa2d4500c82ec0866020c22e11c23516f660ce43cfae8f"},
{"name":"re2","version":"2.1.3","platform":"x64-mingw-ucrt","checksum":"be0277c15bef6f38a2f9805aca798de4a31f6319cb1790ff6683112cb89721da"},
{"name":"re2","version":"2.1.3","platform":"x64-mingw32","checksum":"cadba41d90f2186507c97593084b8f951c9c3ee7ecb2be02f3497aa9c5cdaadb"},
{"name":"re2","version":"2.1.3","platform":"x86-linux","checksum":"ad54cafdaf40310cf3aab485697b997718c573d6a780f802c3faab7a38119623"},
{"name":"re2","version":"2.1.3","platform":"x86-mingw32","checksum":"6bfa3c1c119b485375688a9c90c0b8cfc03991495c2e4d50accb6bbcd406c186"},
{"name":"re2","version":"2.1.3","platform":"x86_64-darwin","checksum":"513b12c5b7536c65e80ddb2a7eee0dbbefea534d6352e9470040016c547f90a5"},
{"name":"re2","version":"2.1.3","platform":"x86_64-linux","checksum":"73a2e20fc1dc7b2773d2862ec061e545f6820643486c0d69e3ad40de19ce5c0b"},
{"name":"recaptcha","version":"5.12.3","platform":"ruby","checksum":"37d1894add9e70a54d0c6c7f0ecbeedffbfa7d075acfbd4c509818dfdebdb7ee"},
{"name":"recursive-open-struct","version":"1.1.3","platform":"ruby","checksum":"a3538a72552fcebcd0ada657bdff313641a4a5fbc482c08cfb9a65acb1c9de5a"},
{"name":"redcarpet","version":"3.6.0","platform":"ruby","checksum":"8ad1889c0355ff4c47174af14edd06d62f45a326da1da6e8a121d59bdcd2e9e9"},

View File

@ -23,6 +23,16 @@ PATH
error_tracking_open_api (1.0.0)
typhoeus (~> 1.0, >= 1.0.1)
PATH
remote: gems/gitlab-http
specs:
gitlab-http (0.1.0)
activesupport (~> 7.0.6)
httparty (~> 0.21.0)
ipaddress (~> 0.8.3)
nokogiri (~> 1.15.4)
railties (~> 7.0.6)
PATH
remote: gems/gitlab-rspec
specs:
@ -1288,7 +1298,7 @@ GEM
rbtree (0.4.6)
rchardet (1.8.0)
rdoc (6.3.2)
re2 (2.1.2)
re2 (2.1.3)
mini_portile2 (~> 2.8.4)
recaptcha (5.12.3)
json
@ -1812,6 +1822,7 @@ DEPENDENCIES
gitlab-dangerfiles (~> 4.0.0)
gitlab-experiment (~> 0.8.0)
gitlab-fog-azure-rm (~> 1.8.0)
gitlab-http!
gitlab-labkit (~> 0.34.0)
gitlab-license (~> 2.3)
gitlab-mail_room (~> 0.0.23)
@ -1954,7 +1965,7 @@ DEPENDENCIES
rainbow (~> 3.0)
rbtrace (~> 0.4)
rdoc (~> 6.3.2)
re2 (= 2.1.2)
re2 (= 2.1.3)
recaptcha (~> 5.12)
redis (~> 4.8.0)
redis-actionpack (~> 5.3.0)

View File

@ -0,0 +1,116 @@
<script>
import { GlTooltipDirective, GlLink, GlButton } from '@gitlab/ui';
import { __ } from '~/locale';
import SafeHtml from '~/vue_shared/directives/safe_html';
import defaultAvatarUrl from 'images/no_avatar.png';
import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
import getRefMixin from '../mixins/get_ref';
export default {
components: {
UserAvatarLink,
TimeagoTooltip,
GlButton,
GlLink,
UserAvatarImage,
},
directives: {
GlTooltip: GlTooltipDirective,
SafeHtml,
},
mixins: [getRefMixin],
props: {
commit: {
type: Object,
required: true,
},
},
data() {
return { showDescription: false };
},
computed: {
commitDescription() {
// Strip the newline at the beginning
return this.commit?.descriptionHtml?.replace(/^&#x000A;/, '');
},
},
methods: {
toggleShowDescription() {
this.showDescription = !this.showDescription;
},
},
defaultAvatarUrl,
safeHtmlConfig: {
ADD_TAGS: ['gl-emoji'],
},
i18n: {
toggleCommitDescription: __('Toggle commit description'),
authored: __('authored'),
},
};
</script>
<template>
<div class="well-segment commit gl-min-h-8 gl-p-5 gl-w-full gl-display-flex">
<user-avatar-link
v-if="commit.author"
:link-href="commit.author.webPath"
:img-src="commit.author.avatarUrl"
:img-size="32"
class="gl-my-2 gl-mr-4"
/>
<user-avatar-image
v-else
class="gl-my-2 gl-mr-4"
:img-src="commit.authorGravatar || $options.defaultAvatarUrl"
:size="32"
/>
<div
class="commit-detail flex-list gl-display-flex gl-justify-content-space-between gl-align-items-center gl-flex-grow-1 gl-min-w-0"
>
<div class="commit-content" data-qa-selector="commit_content">
<gl-link
v-safe-html:[$options.safeHtmlConfig]="commit.titleHtml"
:href="commit.webPath"
:class="{ 'gl-font-style-italic': !commit.message }"
class="commit-row-message item-title"
/>
<gl-button
v-if="commit.descriptionHtml"
v-gl-tooltip
:class="{ open: showDescription }"
:title="$options.i18n.toggleCommitDescription"
:aria-label="$options.i18n.toggleCommitDescription"
:selected="showDescription"
class="text-expander gl-vertical-align-bottom!"
icon="ellipsis_h"
@click="toggleShowDescription"
/>
<div class="committer">
<gl-link
v-if="commit.author"
:href="commit.author.webPath"
class="commit-author-link js-user-link"
>
{{ commit.author.name }}</gl-link
>
<template v-else>
{{ commit.authorName }}
</template>
{{ $options.i18n.authored }}
<timeago-tooltip :time="commit.authoredDate" tooltip-placement="bottom" />
</div>
<pre
v-if="commitDescription"
v-safe-html:[$options.safeHtmlConfig]="commitDescription"
:class="{ 'gl-display-block!': showDescription }"
class="commit-row-description gl-mb-3 gl-white-space-pre-line"
></pre>
</div>
<div class="gl-flex-grow-1"></div>
<slot></slot>
</div>
</div>
</template>

View File

@ -1,32 +1,26 @@
<script>
import { GlTooltipDirective, GlLink, GlButton, GlButtonGroup, GlLoadingIcon } from '@gitlab/ui';
import { GlTooltipDirective, GlButton, GlButtonGroup, GlLoadingIcon } from '@gitlab/ui';
import SafeHtml from '~/vue_shared/directives/safe_html';
import defaultAvatarUrl from 'images/no_avatar.png';
import pathLastCommitQuery from 'shared_queries/repository/path_last_commit.query.graphql';
import { sprintf, s__ } from '~/locale';
import CiBadgeLink from '~/vue_shared/components/ci_badge_link.vue';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
import SignatureBadge from '~/commit/components/signature_badge.vue';
import getRefMixin from '../mixins/get_ref';
import projectPathQuery from '../queries/project_path.query.graphql';
import eventHub from '../event_hub';
import { FORK_UPDATED_EVENT } from '../constants';
import CommitInfo from './commit_info.vue';
export default {
components: {
UserAvatarLink,
TimeagoTooltip,
CommitInfo,
ClipboardButton,
GlButton,
GlButtonGroup,
GlLink,
GlLoadingIcon,
UserAvatarImage,
SignatureBadge,
CiBadgeLink,
GlButtonGroup,
GlButton,
GlLoadingIcon,
},
directives: {
GlTooltip: GlTooltipDirective,
@ -80,13 +74,12 @@ export default {
return {
projectPath: '',
commit: null,
showDescription: false,
};
},
computed: {
statusTitle() {
return sprintf(s__('PipelineStatusTooltip|Pipeline: %{ciStatus}'), {
ciStatus: this.commit.pipeline.detailedStatus.text,
ciStatus: this.commit?.pipeline?.detailedStatus?.text,
});
},
isLoading() {
@ -95,10 +88,6 @@ export default {
showCommitId() {
return this.commit?.sha?.substr(0, 8);
},
commitDescription() {
// Strip the newline at the beginning
return this.commit?.descriptionHtml?.replace(/^&#x000A;/, '');
},
},
watch: {
currentPath() {
@ -112,112 +101,40 @@ export default {
eventHub.$off(FORK_UPDATED_EVENT, this.refetchLastCommit);
},
methods: {
toggleShowDescription() {
this.showDescription = !this.showDescription;
},
refetchLastCommit() {
this.$apollo.queries.commit.refetch();
},
},
defaultAvatarUrl,
safeHtmlConfig: {
ADD_TAGS: ['gl-emoji'],
},
};
</script>
<template>
<div class="well-segment commit gl-p-5 gl-w-full gl-display-flex">
<gl-loading-icon v-if="isLoading" size="lg" color="dark" class="m-auto" />
<template v-else-if="commit">
<user-avatar-link
v-if="commit.author"
:link-href="commit.author.webPath"
:img-src="commit.author.avatarUrl"
:img-size="32"
class="gl-my-2 gl-mr-4"
/>
<user-avatar-image
v-else
class="gl-my-2 gl-mr-4"
:img-src="commit.authorGravatar || $options.defaultAvatarUrl"
:size="32"
/>
<div
class="commit-detail flex-list gl-display-flex gl-justify-content-space-between gl-align-items-center gl-flex-grow-1 gl-min-w-0"
>
<div class="commit-content" data-qa-selector="commit_content">
<gl-link
v-safe-html:[$options.safeHtmlConfig]="commit.titleHtml"
:href="commit.webPath"
:class="{ 'font-italic': !commit.message }"
class="commit-row-message item-title"
/>
<gl-button
v-if="commit.descriptionHtml"
v-gl-tooltip
:class="{ open: showDescription }"
:title="__('Toggle commit description')"
:aria-label="__('Toggle commit description')"
:selected="showDescription"
class="text-expander gl-vertical-align-bottom!"
icon="ellipsis_h"
@click="toggleShowDescription"
/>
<div class="committer">
<gl-link
v-if="commit.author"
:href="commit.author.webPath"
class="commit-author-link js-user-link"
>
{{ commit.author.name }}</gl-link
>
<template v-else>
{{ commit.authorName }}
</template>
{{ s__('LastCommit|authored') }}
<timeago-tooltip :time="commit.authoredDate" tooltip-placement="bottom" />
</div>
<pre
v-if="commitDescription"
v-safe-html:[$options.safeHtmlConfig]="commitDescription"
:class="{ 'd-block': showDescription }"
class="commit-row-description gl-mb-3 gl-white-space-pre-line"
></pre>
</div>
<div class="gl-flex-grow-1"></div>
<div
class="commit-actions gl-display-flex gl-flex-align gl-align-items-center gl-flex-direction-row"
>
<signature-badge v-if="commit.signature" :signature="commit.signature" />
<div v-if="commit.pipeline" class="ci-status-link">
<ci-badge-link
:status="commit.pipeline.detailedStatus"
:details-path="commit.pipeline.detailedStatus.detailsPath"
:aria-label="statusTitle"
size="lg"
:show-text="false"
class="js-commit-pipeline"
/>
</div>
<gl-button-group class="gl-ml-4 js-commit-sha-group">
<gl-button label class="gl-font-monospace" data-testid="last-commit-id-label">{{
showCommitId
}}</gl-button>
<clipboard-button
:text="commit.sha"
:title="__('Copy commit SHA')"
class="input-group-text"
/>
</gl-button-group>
</div>
<gl-loading-icon v-if="isLoading" size="lg" color="dark" class="m-auto" />
<commit-info v-else-if="commit" :commit="commit">
<div
class="commit-actions gl-display-flex gl-flex-align gl-align-items-center gl-flex-direction-row"
>
<signature-badge v-if="commit.signature" :signature="commit.signature" />
<div v-if="commit.pipeline" class="ci-status-link">
<ci-badge-link
:status="commit.pipeline.detailedStatus"
:details-path="commit.pipeline.detailedStatus.detailsPath"
:aria-label="statusTitle"
size="lg"
:show-text="false"
class="js-commit-pipeline"
/>
</div>
</template>
</div>
<gl-button-group class="gl-ml-4 js-commit-sha-group">
<gl-button label class="gl-font-monospace" data-testid="last-commit-id-label">{{
showCommitId
}}</gl-button>
<clipboard-button
:text="commit.sha"
:title="__('Copy commit SHA')"
class="input-group-text"
/>
</gl-button-group>
</div>
</commit-info>
</template>
<style scoped>
.commit {
min-height: 4.75rem;
}
</style>

View File

@ -163,7 +163,7 @@ export default {
<div class="gl-flex-grow-1 gl-overflow-auto" data-testid="nav-container">
<div
id="super-sidebar-context-header"
class="gl-px-5 gl-pt-3 gl-pb-2 gl-m-0 gl-reset-line-height gl-font-sm super-sidebar-context-header"
class="gl-px-5 gl-pt-3 gl-pb-2 gl-m-0 gl-reset-line-height gl-font-weight-bold gl-font-sm super-sidebar-context-header"
>
{{ sidebarData.current_context_header }}
</div>

View File

@ -51,6 +51,7 @@ module ApplicationSettingImplementation
container_registry_token_expire_delay: 5,
container_registry_vendor: '',
container_registry_version: '',
container_registry_db_enabled: false,
custom_http_clone_url_root: nil,
decompress_archive_file_timeout: 210,
default_artifacts_expire_in: '30 days',

View File

@ -33,6 +33,10 @@ module Clusters
revoked: 1
}
def revoke!
update(status: :revoked)
end
def to_ability_name
:cluster
end

View File

@ -13,7 +13,7 @@ module Clusters
def execute
return error_no_permissions unless current_user.can?(:create_cluster, token.agent.project)
if token.update(status: token.class.statuses[:revoked])
if token.revoke!
log_activity_event(token)
ServiceResponse.success

View File

@ -1,4 +1,4 @@
= render Pajamas::CardComponent.new(body_options: { class: 'gl-py-0' }) do |c|
= render Pajamas::CardComponent.new(card_options: { class: 'gl-mb-5' }, body_options: { class: 'gl-py-0' }) do |c|
- c.with_header do
= _('Profile')
- c.with_body do

View File

@ -16,8 +16,6 @@ class MergeWorker # rubocop:disable Scalability/IdempotentWorker
deduplicate :until_executed, including_scheduled: true
def perform(merge_request_id, current_user_id, params)
params = params.with_indifferent_access
begin
current_user = User.find(current_user_id)
merge_request = MergeRequest.find(merge_request_id)
@ -25,6 +23,9 @@ class MergeWorker # rubocop:disable Scalability/IdempotentWorker
return
end
params = params.with_indifferent_access
params[:check_mergeability_retry_lease] = true unless params.has_key?(:check_mergeability_retry_lease)
MergeRequests::MergeService.new(project: merge_request.target_project, current_user: current_user, params: params)
.execute(merge_request)
end

View File

@ -36,13 +36,6 @@ module ActiveRecord
def aliased_types(name, fallback)
fallback
end
# Adds a compatible_table_definition method that
# returns the value passed in so that all of the
# versioned Migrations can always return super.
def compatible_table_definition(table)
table
end
end
end
end

View File

@ -0,0 +1,26 @@
# frozen_string_literal: true
# When including this gem, we also initialize the patch / override classes in the gem.
require 'gitlab-http'
Gitlab::HTTP_V2.configure do |config|
config.allowed_internal_uris = [
URI::HTTP.build(
scheme: Gitlab.config.gitlab.protocol,
host: Gitlab.config.gitlab.host,
port: Gitlab.config.gitlab.port
),
URI::Generic.build(
scheme: 'ssh',
host: Gitlab.config.gitlab_shell.ssh_host,
port: Gitlab.config.gitlab_shell.ssh_port
)
]
config.log_exception_proc = ->(exception, extra_info) do
Gitlab::ErrorTracking.log_exception(exception, extra_info)
end
config.silent_mode_log_info_proc = ->(message, http_method) do
Gitlab::SilentMode.log_info(message: message, outbound_http_request_method: http_method)
end
end

View File

@ -1,52 +0,0 @@
# frozen_string_literal: true
# This override allows passing `@hostname_override` to the SNI protocol,
# which is used to lookup the correct SSL certificate in the
# request handshake process.
#
# Given we've forced the HTTP request to be sent to the resolved
# IP address in a few scenarios (e.g.: `Gitlab::HTTP` through
# `Gitlab::UrlBlocker.validate!`), we need to provide the _original_
# hostname via SNI in order to have a clean connection setup.
#
# This is ultimately needed in order to avoid DNS rebinding attacks
# through HTTP requests.
#
class OpenSSL::SSL::SSLContext
attr_accessor :hostname_override
end
class OpenSSL::SSL::SSLSocket
module HostnameOverride
# rubocop: disable Gitlab/ModuleWithInstanceVariables
def hostname=(hostname)
super(@context.hostname_override || hostname)
end
def post_connection_check(hostname)
super(@context.hostname_override || hostname)
end
# rubocop: enable Gitlab/ModuleWithInstanceVariables
end
prepend HostnameOverride
end
class Net::HTTP
attr_accessor :hostname_override
SSL_IVNAMES << :@hostname_override
SSL_ATTRIBUTES << :hostname_override
module HostnameOverride
def addr_port
return super unless hostname_override
addr = hostname_override
default_port = use_ssl? ? Net::HTTP.https_default_port : Net::HTTP.http_default_port
default_port == port ? addr : "#{addr}:#{port}"
end
end
prepend HostnameOverride
end

View File

@ -1,39 +0,0 @@
# frozen_string_literal: true
# Monkey patch Net::HTTP to fix missing URL decoding for username and password in proxy settings
#
# See proposed upstream fix https://github.com/ruby/net-http/pull/5
# See Ruby-lang issue https://bugs.ruby-lang.org/issues/17542
# See issue on GitLab https://gitlab.com/gitlab-org/gitlab/-/issues/289836
require 'net/http'
# This file can be removed once Ruby 3.0 is no longer supported:
# https://gitlab.com/gitlab-org/gitlab/-/issues/396223
return if Gem::Version.new(Net::HTTP::VERSION) >= Gem::Version.new('0.2.0')
module Net
class HTTP < Protocol
def proxy_user
if environment_variable_is_multiuser_safe? && @proxy_from_env
user = proxy_uri&.user
CGI.unescape(user) unless user.nil?
else
@proxy_user
end
end
def proxy_pass
if environment_variable_is_multiuser_safe? && @proxy_from_env
pass = proxy_uri&.password
CGI.unescape(pass) unless pass.nil?
else
@proxy_pass
end
end
def environment_variable_is_multiuser_safe?
ENVIRONMENT_VARIABLE_IS_MULTIUSER_SAFE
end
end
end

View File

@ -1,48 +0,0 @@
# frozen_string_literal: true
module Net
class HTTPResponse
# rubocop: disable Cop/LineBreakAfterGuardClauses
# rubocop: disable Cop/LineBreakAroundConditionalBlock
# rubocop: disable Layout/EmptyLineAfterGuardClause
# rubocop: disable Style/AndOr
# rubocop: disable Style/CharacterLiteral
# rubocop: disable Style/InfiniteLoop
# Original method:
# https://github.com/ruby/ruby/blob/v2_7_5/lib/net/http/response.rb#L54-L69
#
# Our changes:
# - Pass along the `start_time` to `Gitlab::BufferedIo`, so we can raise a timeout
# if reading the headers takes too long.
# - Limit the regexes to avoid ReDoS attacks.
def self.each_response_header(sock)
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
key = value = nil
while true
line = sock.is_a?(Gitlab::BufferedIo) ? sock.readuntil("\n", true, start_time) : sock.readuntil("\n", true)
line = line.sub(/\s{0,10}\z/, '')
break if line.empty?
if line[0] == ?\s or line[0] == ?\t and value
# rubocop:disable Gitlab/NoCodeCoverageComment
# :nocov:
value << ' ' unless value.empty?
value << line.strip
# :nocov:
# rubocop:enable Gitlab/NoCodeCoverageComment
else
yield key, value if key
key, value = line.strip.split(/\s{0,10}:\s{0,10}/, 2)
raise Net::HTTPBadResponse, 'wrong header line format' if value.nil?
end
end
yield key, value if key
end
# rubocop: enable Cop/LineBreakAfterGuardClauses
# rubocop: enable Cop/LineBreakAroundConditionalBlock
# rubocop: enable Layout/EmptyLineAfterGuardClause
# rubocop: enable Style/AndOr
# rubocop: enable Style/CharacterLiteral
# rubocop: enable Style/InfiniteLoop
end
end

View File

@ -9,7 +9,7 @@ class AddAuthorizedScopesToSlackIntegration < Gitlab::Database::Migration[2.1]
end
create_table :slack_integrations_scopes do |t|
references :slack_api_scope,
t.references :slack_api_scope,
null: false,
index: false, # See composite index
foreign_key: {
@ -17,7 +17,7 @@ class AddAuthorizedScopesToSlackIntegration < Gitlab::Database::Migration[2.1]
on_delete: :cascade
}
references :slack_integration,
t.references :slack_integration,
null: false,
index: false, # see composite index
foreign_key: {

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
class AddContainerRegistryDbEnabledToApplicationSettings < Gitlab::Database::Migration[2.1]
enable_lock_retries!
def change
add_column :application_settings, :container_registry_db_enabled, :boolean, null: false, default: false
end
end

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
class AddLastAssignedUsersRefreshedAtToSubscriptionAddOnPurchases < Gitlab::Database::Migration[2.1]
enable_lock_retries!
def change
add_column(:subscription_add_on_purchases, :last_assigned_users_refreshed_at, :datetime_with_timezone)
end
end

View File

@ -0,0 +1,38 @@
# frozen_string_literal: true
class DropColumnsFromGeoNodeStatusTable < Gitlab::Database::Migration[2.1]
enable_lock_retries!
def up
remove_columns :geo_node_statuses,
:wikis_checksum_failed_count,
:wikis_checksum_mismatch_count,
:wikis_checksummed_count,
:wikis_failed_count,
:wikis_retrying_verification_count,
:wikis_synced_count,
:wikis_verification_failed_count,
:wikis_verified_count,
:design_repositories_count,
:design_repositories_synced_count,
:design_repositories_failed_count,
:design_repositories_registry_count
end
def down
change_table(:geo_node_statuses) do |t|
t.integer :wikis_checksum_failed_count
t.integer :wikis_checksum_mismatch_count
t.integer :wikis_checksummed_count
t.integer :wikis_failed_count
t.integer :wikis_retrying_verification_count
t.integer :wikis_synced_count
t.integer :wikis_verification_failed_count
t.integer :wikis_verified_count
t.integer :design_repositories_count
t.integer :design_repositories_synced_count
t.integer :design_repositories_failed_count
t.integer :design_repositories_registry_count
end
end
end

View File

@ -0,0 +1 @@
0e31f2b685b3d229816f7e330b54cf5cafb7abb71aa4489d88af768dfb3629fc

View File

@ -0,0 +1 @@
6f95154ad6b0a9417935a203cb666aea99e06eef22f32c110e1f0e3914c87778

View File

@ -0,0 +1 @@
821bf9cd2c93d34323edc587949a70779acdcc3f7866d7165ef3ebec2127ea0a

View File

@ -12052,6 +12052,7 @@ CREATE TABLE application_settings (
decompress_archive_file_timeout integer DEFAULT 210 NOT NULL,
search_rate_limit_allowlist text[] DEFAULT '{}'::text[] NOT NULL,
snowplow_database_collector_hostname text,
container_registry_db_enabled boolean DEFAULT false NOT NULL,
CONSTRAINT app_settings_container_reg_cleanup_tags_max_list_size_positive CHECK ((container_registry_cleanup_tags_service_max_list_size >= 0)),
CONSTRAINT app_settings_container_registry_pre_import_tags_rate_positive CHECK ((container_registry_pre_import_tags_rate >= (0)::numeric)),
CONSTRAINT app_settings_dep_proxy_ttl_policies_worker_capacity_positive CHECK ((dependency_proxy_ttl_group_policy_worker_capacity >= 0)),
@ -16602,8 +16603,6 @@ CREATE TABLE geo_node_statuses (
replication_slots_count integer,
replication_slots_used_count integer,
replication_slots_max_retained_wal_bytes bigint,
wikis_synced_count integer,
wikis_failed_count integer,
job_artifacts_count integer,
job_artifacts_synced_count integer,
job_artifacts_failed_count integer,
@ -16611,28 +16610,18 @@ CREATE TABLE geo_node_statuses (
revision character varying,
repositories_verified_count integer,
repositories_verification_failed_count integer,
wikis_verified_count integer,
wikis_verification_failed_count integer,
lfs_objects_synced_missing_on_primary_count integer,
job_artifacts_synced_missing_on_primary_count integer,
repositories_checksummed_count integer,
repositories_checksum_failed_count integer,
repositories_checksum_mismatch_count integer,
wikis_checksummed_count integer,
wikis_checksum_failed_count integer,
wikis_checksum_mismatch_count integer,
storage_configuration_digest bytea,
repositories_retrying_verification_count integer,
wikis_retrying_verification_count integer,
projects_count integer,
container_repositories_count integer,
container_repositories_synced_count integer,
container_repositories_failed_count integer,
container_repositories_registry_count integer,
design_repositories_count integer,
design_repositories_synced_count integer,
design_repositories_failed_count integer,
design_repositories_registry_count integer,
status jsonb DEFAULT '{}'::jsonb NOT NULL
);
@ -23650,6 +23639,7 @@ CREATE TABLE subscription_add_on_purchases (
quantity integer NOT NULL,
expires_on date NOT NULL,
purchase_xid text NOT NULL,
last_assigned_users_refreshed_at timestamp with time zone,
CONSTRAINT check_3313c4d200 CHECK ((char_length(purchase_xid) <= 255))
);

View File

@ -231,7 +231,8 @@ It is also possible to specify a [custom CI/CD configuration file for a specific
## Set CI/CD limits
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/352175) in GitLab 14.10.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/352175) in GitLab 14.10.
> - **Maximum number of active pipelines per project** setting [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/368195) in GitLab 16.0.
You can configure some [CI/CD limits](../../administration/instance_limits.md#cicd-limits)
from the Admin Area:
@ -243,7 +244,6 @@ from the Admin Area:
1. In the **CI/CD limits** section, you can set the following limits:
- **Maximum number of jobs in a single pipeline**
- **Total number of jobs in currently active pipelines**
- **Maximum number of active pipelines per project**
- **Maximum number of pipeline subscriptions to and from a project**
- **Maximum number of pipeline schedules**
- **Maximum number of DAG dependencies that a job can have**

View File

@ -315,9 +315,20 @@ If the artifacts were deleted successfully, a response with status `204 No Conte
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/223793) in GitLab 14.7 [with a flag](../administration/feature_flags.md) named `bulk_expire_project_artifacts`. Enabled by default on GitLab self-managed. Enabled on GitLab.com.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/350609) in GitLab 14.10.
Delete artifacts of a project that can be deleted.
Delete artifacts eligible for deletion in a project. By default, artifacts from
[the most recent successful pipeline of each ref](../ci/jobs/job_artifacts.md#keep-artifacts-from-most-recent-successful-jobs).
are not deleted.
By default, [artifacts from the most recent successful pipeline of each ref are kept](../ci/jobs/job_artifacts.md#keep-artifacts-from-most-recent-successful-jobs).
Requests to this endpoint set the expiry of all artifacts that
can be deleted to the current time. The files are then deleted from the system as part
of the regular cleanup of expired job artifacts. Job logs are never deleted.
The regular cleanup occurs asynchronously on a schedule, so there might be a short delay
before artifacts are deleted.
Prerequisite:
- You must have at least the Maintainer role for the project.
```plaintext
DELETE /projects/:id/artifacts
@ -333,8 +344,4 @@ Example request:
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/artifacts"
```
NOTE:
At least Maintainer role is required to delete artifacts.
Schedules a worker to update to the current time the expiry of all artifacts that can be deleted.
A response with status `202 Accepted` is returned.

View File

@ -20,11 +20,12 @@ module Net
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
key = value = nil
while true
line = if sock.is_a?(Gitlab::HTTP_V2::BufferedIo)
sock.readuntil("\n", true, start_time)
else
sock.readuntil("\n", true)
end
uses_buffered_io = sock.is_a?(Gitlab::HTTP_V2::BufferedIo)
# TODO: Gitlab::BufferedIo is temporarily used for an easy migration.
uses_buffered_io ||= sock.is_a?(Gitlab::BufferedIo) if defined?(Gitlab::BufferedIo)
line = uses_buffered_io ? sock.readuntil("\n", true, start_time) : sock.readuntil("\n", true)
line = line.sub(/\s{0,10}\z/, '')
break if line.empty?
if line[0] == ?\s or line[0] == ?\t and value

View File

@ -3,7 +3,7 @@
require 'spec_helper'
require 'net/http'
RSpec.describe 'Net::HTTP patch proxy user and password encoding' do
RSpec.describe 'Net::HTTP patch proxy user and password encoding', feature_category: :shared do
let(:net_http) { Net::HTTP.new('hostname.example') }
before do

View File

@ -76,12 +76,14 @@ module API
]
failure [
{ code: 400, message: 'Bad Request' },
{ code: 401, message: 'Unauthorized' },
{ code: 403, message: 'Forbidden' },
{ code: 404, message: 'Not Found' }
]
tags %w[npm_packages]
end
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true,
authenticate_non_public: true
get 'dist-tags', format: false, requirements: ::API::Helpers::Packages::Npm::NPM_ENDPOINT_REQUIREMENTS do
package_name = params[:package_name]
@ -186,6 +188,7 @@ module API
]
failure [
{ code: 400, message: 'Bad Request' },
{ code: 401, message: 'Unauthorized' },
{ code: 403, message: 'Forbidden' },
{ code: 404, message: 'Not Found' }
]
@ -194,7 +197,8 @@ module API
params do
use :package_name
end
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true,
authenticate_non_public: true
get '*package_name', format: false, requirements: ::API::Helpers::Packages::Npm::NPM_ENDPOINT_REQUIREMENTS do
package_name = params[:package_name]
available_packages =
@ -224,9 +228,7 @@ module API
).execute
if available_packages.any? && available_packages_to_user.empty?
forbidden! if current_user
not_found!('Packages')
current_user ? forbidden! : unauthorized!
end
available_packages = available_packages_to_user

View File

@ -102,8 +102,7 @@ module API
def group
group = find_group(params[:id])
not_found!('Group') unless can?(current_user, :read_group, group)
group
check_group_access(group)
end
strong_memoize_attr :group

View File

@ -10,6 +10,7 @@ module ContainerRegistry
REGISTRY_VERSION_HEADER = 'gitlab-container-registry-version'
REGISTRY_FEATURES_HEADER = 'gitlab-container-registry-features'
REGISTRY_TAG_DELETE_FEATURE = 'tag_delete'
REGISTRY_DB_ENABLED_HEADER = 'gitlab-container-registry-database-enabled'
DEFAULT_TAGS_PAGE_SIZE = 10000
@ -47,11 +48,13 @@ module ContainerRegistry
version = response.headers[REGISTRY_VERSION_HEADER]
features = response.headers.fetch(REGISTRY_FEATURES_HEADER, '')
db_enabled = response.headers.fetch(REGISTRY_DB_ENABLED_HEADER, '')
{
version: version,
features: features.split(',').map(&:strip),
vendor: version ? 'gitlab' : 'other'
vendor: version ? 'gitlab' : 'other',
db_enabled: ::Gitlab::Utils.to_boolean(db_enabled, default: false)
}
end

View File

@ -43,7 +43,7 @@ module Gitlab
end
end
t.instance_eval(&block) unless block.nil?
yield t unless block.nil?
end
end

View File

@ -27504,9 +27504,6 @@ msgstr ""
msgid "Last year"
msgstr ""
msgid "LastCommit|authored"
msgstr ""
msgid "LastPushEvent|You pushed to"
msgstr ""
@ -46691,9 +46688,6 @@ msgstr ""
msgid "TanukiBot|What is a fork?"
msgstr ""
msgid "Targe branch"
msgstr ""
msgid "Target"
msgstr ""

View File

@ -176,7 +176,7 @@
"mousetrap": "1.6.5",
"orderedmap": "^2.1.1",
"papaparse": "^5.3.1",
"patch-package": "^6.4.7",
"patch-package": "6.5.1",
"pdfjs-dist": "^2.16.105",
"pikaday": "^1.8.0",
"popper.js": "^1.16.1",

View File

@ -14,7 +14,7 @@ module QA
element :commit_message_field
end
base.view 'app/assets/javascripts/repository/components/last_commit.vue' do
base.view 'app/assets/javascripts/repository/components/commit_info.vue' do
element :commit_content
end

View File

@ -1,4 +1,4 @@
const { execSync } = require('child_process');
const { spawnSync } = require('child_process');
const chalk = require('chalk');
// check that fsevents is available if we're on macOS
@ -24,5 +24,7 @@ console.log(`${chalk.green('success')} Dependency postinstall check passed.`);
// Apply any patches to our packages
// See https://gitlab.com/gitlab-org/gitlab/-/issues/336138
execSync('node_modules/.bin/patch-package --error-on-fail');
console.log(`${chalk.green('success')} Packages successfully patched.`);
process.exitCode =
spawnSync('node_modules/.bin/patch-package', ['--error-on-fail', '--error-on-warn'], {
stdio: ['ignore', 'inherit', 'inherit'],
}).status ?? 1;

View File

@ -1,97 +1,48 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Repository last commit component renders commit widget 1`] = `
<div
class="commit gl-display-flex gl-p-5 gl-w-full well-segment"
<commit-info-stub
commit="[object Object]"
>
<user-avatar-link-stub
class="gl-mr-4 gl-my-2"
imgalt=""
imgcssclasses=""
imgcsswrapperclasses=""
imgsize="32"
imgsrc="https://test.com"
linkhref="/test"
popoveruserid=""
popoverusername=""
tooltipplacement="top"
tooltiptext=""
username=""
/>
<div
class="commit-detail flex-list gl-align-items-center gl-display-flex gl-flex-grow-1 gl-justify-content-space-between gl-min-w-0"
class="commit-actions gl-align-items-center gl-display-flex gl-flex-align gl-flex-direction-row"
>
<div
class="commit-content"
data-qa-selector="commit_content"
class="ci-status-link"
>
<gl-link-stub
class="commit-row-message item-title"
href="/commit/123"
>
Commit title
</gl-link-stub>
<div
class="committer"
>
<gl-link-stub
class="commit-author-link js-user-link"
href="/test"
>
Test
</gl-link-stub>
authored
<timeago-tooltip-stub
cssclass=""
datetimeformat="DATE_WITH_TIME_FORMAT"
time="2019-01-01"
tooltipplacement="bottom"
/>
</div>
<ci-badge-link-stub
aria-label="Pipeline: failed"
class="js-commit-pipeline"
details-path="https://test.com/pipeline"
size="lg"
status="[object Object]"
/>
</div>
<div
class="gl-flex-grow-1"
/>
<div
class="commit-actions gl-align-items-center gl-display-flex gl-flex-align gl-flex-direction-row"
<gl-button-group-stub
class="gl-ml-4 js-commit-sha-group"
>
<div
class="ci-status-link"
<gl-button-stub
buttontextclasses=""
category="primary"
class="gl-font-monospace"
data-testid="last-commit-id-label"
icon=""
label="true"
size="medium"
variant="default"
>
<ci-badge-link-stub
aria-label="Pipeline: failed"
class="js-commit-pipeline"
details-path="https://test.com/pipeline"
size="lg"
status="[object Object]"
/>
</div>
<gl-button-group-stub
class="gl-ml-4 js-commit-sha-group"
>
<gl-button-stub
buttontextclasses=""
category="primary"
class="gl-font-monospace"
data-testid="last-commit-id-label"
icon=""
label="true"
size="medium"
variant="default"
>
12345678
</gl-button-stub>
<clipboard-button-stub
category="secondary"
class="input-group-text"
size="medium"
text="123456789"
title="Copy commit SHA"
tooltipplacement="top"
variant="default"
/>
</gl-button-group-stub>
</div>
12345678
</gl-button-stub>
<clipboard-button-stub
category="secondary"
class="input-group-text"
size="medium"
text="123456789"
title="Copy commit SHA"
tooltipplacement="top"
variant="default"
/>
</gl-button-group-stub>
</div>
</div>
</commit-info-stub>
`;

View File

@ -0,0 +1,87 @@
import { nextTick } from 'vue';
import { GlButton } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import CommitInfo from '~/repository/components/commit_info.vue';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
let wrapper;
const commit = {
title: 'Commit title',
titleHtml: 'Commit title html',
message: 'Commit message',
authoredDate: '2019-01-01',
authorName: 'Test authorName',
author: { name: 'Test name', avatarUrl: 'https://test.com', webPath: '/test' },
};
const findTextExpander = () => wrapper.findComponent(GlButton);
const findUserLink = () => wrapper.findByText(commit.author.name);
const findUserAvatarLink = () => wrapper.findComponent(UserAvatarLink);
const findAuthorName = () => wrapper.findByText(`${commit.authorName} authored`);
const findCommitRowDescription = () => wrapper.find('pre');
const findTitleHtml = () => wrapper.findByText(commit.titleHtml);
const createComponent = async ({ commitMock = {} } = {}) => {
wrapper = shallowMountExtended(CommitInfo, {
propsData: { commit: { ...commit, ...commitMock } },
});
await nextTick();
};
describe('Repository last commit component', () => {
it('renders author info', () => {
createComponent();
expect(findUserLink().exists()).toBe(true);
expect(findUserAvatarLink().exists()).toBe(true);
});
it('hides author component when author does not exist', () => {
createComponent({ commitMock: { author: null } });
expect(findUserLink().exists()).toBe(false);
expect(findUserAvatarLink().exists()).toBe(false);
expect(findAuthorName().exists()).toBe(true);
});
it('does not render description expander when description is null', () => {
createComponent();
expect(findTextExpander().exists()).toBe(false);
expect(findCommitRowDescription().exists()).toBe(false);
});
describe('when the description is present', () => {
beforeEach(() => {
createComponent({ commitMock: { descriptionHtml: '&#x000A;Update ADOPTERS.md' } });
});
it('strips the first newline of the description', () => {
expect(findCommitRowDescription().html()).toBe(
'<pre class="commit-row-description gl-mb-3 gl-white-space-pre-line">Update ADOPTERS.md</pre>',
);
});
it('renders commit description collapsed by default', () => {
expect(findCommitRowDescription().classes('gl-display-block!')).toBe(false);
expect(findTextExpander().classes('open')).toBe(false);
expect(findTextExpander().props('selected')).toBe(false);
});
it('expands commit description when clicking expander', async () => {
findTextExpander().vm.$emit('click');
await nextTick();
expect(findCommitRowDescription().classes('gl-display-block!')).toBe(true);
expect(findTextExpander().classes('open')).toBe(true);
expect(findTextExpander().props('selected')).toBe(true);
});
});
it('sets correct CSS class if the commit message is empty', () => {
createComponent({ commitMock: { message: '' } });
expect(findTitleHtml().classes()).toContain('gl-font-style-italic');
});
});

View File

@ -1,29 +1,26 @@
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import { GlLoadingIcon } from '@gitlab/ui';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import LastCommit from '~/repository/components/last_commit.vue';
import CommitInfo from '~/repository/components/commit_info.vue';
import SignatureBadge from '~/commit/components/signature_badge.vue';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
import eventHub from '~/repository/event_hub';
import pathLastCommitQuery from 'shared_queries/repository/path_last_commit.query.graphql';
import { FORK_UPDATED_EVENT } from '~/repository/constants';
import { refMock } from '../mock_data';
let wrapper;
let commitData;
let mockResolver;
const findPipeline = () => wrapper.find('.js-commit-pipeline');
const findTextExpander = () => wrapper.find('.text-expander');
const findUserLink = () => wrapper.find('.js-user-link');
const findUserAvatarLink = () => wrapper.findComponent(UserAvatarLink);
const findLastCommitLabel = () => wrapper.findByTestId('last-commit-id-label');
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findCommitRowDescription = () => wrapper.find('.commit-row-description');
const findStatusBox = () => wrapper.findComponent(SignatureBadge);
const findItemTitle = () => wrapper.find('.item-title');
const findCommitInfo = () => wrapper.findComponent(CommitInfo);
const defaultPipelineEdges = [
{
@ -44,23 +41,7 @@ const defaultPipelineEdges = [
},
];
const defaultAuthor = {
__typename: 'UserCore',
id: 'gid://gitlab/User/1',
name: 'Test',
avatarUrl: 'https://test.com',
webPath: '/test',
};
const defaultMessage = 'Commit title';
const createCommitData = ({
pipelineEdges = defaultPipelineEdges,
author = defaultAuthor,
descriptionHtml = '',
signature = null,
message = defaultMessage,
}) => {
const createCommitData = ({ pipelineEdges = defaultPipelineEdges, signature = null }) => {
return {
data: {
project: {
@ -79,13 +60,19 @@ const createCommitData = ({
sha: '123456789',
title: 'Commit title',
titleHtml: 'Commit title',
descriptionHtml,
message,
descriptionHtml: '',
message: '',
webPath: '/commit/123',
authoredDate: '2019-01-01',
authorName: 'Test',
authorGravatar: 'https://test.com',
author,
author: {
__typename: 'UserCore',
id: 'gid://gitlab/User/1',
name: 'Test',
avatarUrl: 'https://test.com',
webPath: '/test',
},
signature,
pipelines: {
__typename: 'PipelineConnection',
@ -101,12 +88,13 @@ const createCommitData = ({
};
};
const createComponent = (data = {}) => {
const createComponent = async (data = {}) => {
Vue.use(VueApollo);
const currentPath = 'path';
mockResolver = jest.fn().mockResolvedValue(createCommitData(data));
commitData = createCommitData(data);
mockResolver = jest.fn().mockResolvedValue(commitData);
wrapper = shallowMountExtended(LastCommit, {
apolloProvider: createMockApollo([[pathLastCommitQuery, mockResolver]]),
@ -116,8 +104,13 @@ const createComponent = (data = {}) => {
SignatureBadge,
},
});
await waitForPromises();
await nextTick();
};
beforeEach(() => createComponent());
afterEach(() => {
mockResolver = null;
});
@ -137,17 +130,17 @@ describe('Repository last commit component', () => {
expect(findLoadingIcon().exists()).toBe(loading);
});
it('renders commit widget', async () => {
createComponent();
await waitForPromises();
it('renders a CommitInfo component', () => {
const commit = { ...commitData.project?.repository.paginatedTree.nodes[0].lastCommit };
expect(findCommitInfo().props().commit).toMatchObject(commit);
});
it('renders commit widget', () => {
expect(wrapper.element).toMatchSnapshot();
});
it('renders short commit ID', async () => {
createComponent();
await waitForPromises();
it('renders short commit ID', () => {
expect(findLastCommitLabel().text()).toBe('12345678');
});
@ -158,29 +151,10 @@ describe('Repository last commit component', () => {
expect(findPipeline().exists()).toBe(false);
});
it('renders pipeline components when pipeline exists', async () => {
createComponent();
await waitForPromises();
it('renders pipeline components when pipeline exists', () => {
expect(findPipeline().exists()).toBe(true);
});
it('hides author component when author does not exist', async () => {
createComponent({ author: null });
await waitForPromises();
expect(findUserLink().exists()).toBe(false);
expect(findUserAvatarLink().exists()).toBe(false);
});
it('does not render description expander when description is null', async () => {
createComponent();
await waitForPromises();
expect(findTextExpander().exists()).toBe(false);
expect(findCommitRowDescription().exists()).toBe(false);
});
describe('created', () => {
it('binds `epicsListScrolled` event listener via eventHub', () => {
jest.spyOn(eventHub, '$on').mockImplementation(() => {});
@ -200,32 +174,6 @@ describe('Repository last commit component', () => {
});
});
describe('when the description is present', () => {
beforeEach(async () => {
createComponent({ descriptionHtml: '&#x000A;Update ADOPTERS.md' });
await waitForPromises();
});
it('strips the first newline of the description', () => {
expect(findCommitRowDescription().html()).toBe(
'<pre class="commit-row-description gl-mb-3 gl-white-space-pre-line">Update ADOPTERS.md</pre>',
);
});
it('expands commit description when clicking expander', async () => {
expect(findCommitRowDescription().classes('d-block')).toBe(false);
expect(findTextExpander().classes('open')).toBe(false);
expect(findTextExpander().props('selected')).toBe(false);
findTextExpander().vm.$emit('click');
await nextTick();
expect(findCommitRowDescription().classes('d-block')).toBe(true);
expect(findTextExpander().classes('open')).toBe(true);
expect(findTextExpander().props('selected')).toBe(true);
});
});
it('renders the signature HTML as returned by the backend', async () => {
const signatureResponse = {
__typename: 'GpgSignature',
@ -241,11 +189,4 @@ describe('Repository last commit component', () => {
expect(findStatusBox().props()).toMatchObject({ signature: signatureResponse });
});
it('sets correct CSS class if the commit message is empty', async () => {
createComponent({ message: '' });
await waitForPromises();
expect(findItemTitle().classes()).toContain('font-italic');
});
});

View File

@ -0,0 +1,47 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::HTTP_V2, feature_category: :shared do
it 'handles log_exception_proc' do
expect(Gitlab::HTTP_V2::Client).to receive(:httparty_perform_request)
.and_raise(Net::ReadTimeout)
expect(Gitlab::ErrorTracking).to receive(:log_exception)
.with(Net::ReadTimeout, {})
expect { described_class.get('http://example.org') }.to raise_error(Net::ReadTimeout)
end
context 'when silent_mode_enabled is true' do
before do
stub_application_setting(silent_mode_enabled: true)
end
context 'when sending a POST request' do
it 'handles silent_mode_log_info_proc' do
expect(::Gitlab::AppJsonLogger).to receive(:info).with(
message: "Outbound HTTP request blocked",
outbound_http_request_method: 'Net::HTTP::Post',
silent_mode_enabled: true
)
expect { described_class.post('http://example.org', silent_mode_enabled: true) }.to raise_error(
Gitlab::HTTP_V2::SilentModeBlockedError
)
end
end
context 'when sending a GET request' do
before do
stub_request(:get, 'http://example.org').to_return(body: 'hello')
end
it 'does not raise an error' do
expect(::Gitlab::AppJsonLogger).not_to receive(:info)
expect(described_class.get('http://example.org', silent_mode_enabled: true).body).to eq('hello')
end
end
end
end

View File

@ -1,11 +1,11 @@
# frozen_string_literal: true
require 'fast_spec_helper'
require 'net/http'
# TODO: This spec file can be removed after fully migration to the gitlab-http gem.
# It's already covered in gems/gitlab-http/spec/gitlab/http_v2/net_http_patch_spec.rb
require_relative '../../config/initializers/net_http_patch'
require 'spec_helper'
RSpec.describe 'Net::HTTP patch proxy user and password encoding' do
RSpec.describe 'Net::HTTP patch proxy user and password encoding', feature_category: :shared do
let(:net_http) { Net::HTTP.new('hostname.example') }
before do

View File

@ -1,5 +1,8 @@
# frozen_string_literal: true
# TODO: This spec file can be removed after fully migration to the gitlab-http gem.
# It's already covered in gems/gitlab-http/spec/gitlab/http_v2/net_http_response_patch_spec.rb
require 'spec_helper'
RSpec.describe 'Net::HTTPResponse patch header read timeout', feature_category: :shared do

View File

@ -89,13 +89,14 @@ RSpec.describe ContainerRegistry::Client do
it_behaves_like 'handling timeouts'
end
shared_examples 'handling repository info' do
shared_examples 'handling registry info' do
context 'when the check is successful' do
context 'when using the GitLab container registry' do
before do
stub_registry_info(headers: {
'GitLab-Container-Registry-Version' => '2.9.1-gitlab',
'GitLab-Container-Registry-Features' => 'a,b,c'
'GitLab-Container-Registry-Features' => 'a,b,c',
'GitLab-Container-Registry-Database-Enabled' => 'true'
})
end
@ -106,6 +107,10 @@ RSpec.describe ContainerRegistry::Client do
it 'identifies version and features' do
expect(subject).to include(version: '2.9.1-gitlab', features: %w[a b c])
end
it 'identifies the registry DB as enabled' do
expect(subject).to include(db_enabled: true)
end
end
context 'when using a third-party container registry' do
@ -120,6 +125,10 @@ RSpec.describe ContainerRegistry::Client do
it 'does not identify version or features' do
expect(subject).to include(version: nil, features: [])
end
it 'does not identify the registry DB as enabled' do
expect(subject).to include(db_enabled: false)
end
end
end
@ -130,6 +139,16 @@ RSpec.describe ContainerRegistry::Client do
expect(subject).to eq({})
end
end
context 'when the check returns an unexpected value in the database enabled header' do
it 'does not identify the registry DB as enabled' do
stub_registry_info(headers: {
'GitLab-Container-Registry-Database-Enabled' => '123'
})
expect(subject).to include(db_enabled: false)
end
end
end
describe '#repository_manifest' do
@ -360,7 +379,7 @@ RSpec.describe ContainerRegistry::Client do
describe '#registry_info' do
subject { client.registry_info }
it_behaves_like 'handling repository info'
it_behaves_like 'handling registry info'
end
describe '.supports_tag_delete?' do
@ -446,7 +465,7 @@ RSpec.describe ContainerRegistry::Client do
stub_container_registry_config(enabled: true, api_url: registry_api_url, key: 'spec/fixtures/x509_certificate_pk.key')
end
it_behaves_like 'handling repository info'
it_behaves_like 'handling registry info'
end
def stub_upload(path, content, digest, status = 200)

View File

@ -95,6 +95,15 @@ RSpec.describe Clusters::AgentToken, feature_category: :deployment_management do
expect(agent_token.token).to start_with described_class::TOKEN_PREFIX
end
it 'is revoked on revoke!' do
agent_token = build(:cluster_agent_token, token_encrypted: nil)
agent_token.save!
agent_token.revoke!
expect(agent_token.active?).to be_falsey
end
end
describe '#to_ability_name' do

View File

@ -325,8 +325,13 @@ RSpec.describe API::GroupExport, feature_category: :importers do
end
context 'when bulk import is disabled' do
before do
stub_application_setting(bulk_import_enabled: false)
end
it_behaves_like '404 response' do
let(:request) { get api(path, user) }
let(:message) { '404 Not Found' }
let(:request) { post api(path, user) }
end
end
end

View File

@ -22,11 +22,11 @@ RSpec.describe API::NpmGroupPackages, feature_category: :package_registry do
where(:auth, :group_visibility, :project_visibility, :user_role, :expected_status) do
nil | :public | :public | nil | :ok
nil | :public | :internal | nil | :not_found
nil | :public | :private | nil | :not_found
nil | :internal | :internal | nil | :not_found
nil | :internal | :private | nil | :not_found
nil | :private | :private | nil | :not_found
nil | :public | :internal | nil | :unauthorized
nil | :public | :private | nil | :unauthorized
nil | :internal | :internal | nil | :unauthorized
nil | :internal | :private | nil | :unauthorized
nil | :private | :private | nil | :unauthorized
:oauth | :public | :public | :guest | :ok
:oauth | :public | :internal | :guest | :ok

View File

@ -708,6 +708,8 @@ RSpec.describe API::ProjectExport, :aggregate_failures, :clean_gitlab_redis_cach
describe 'POST /projects/:id/export_relations' do
it_behaves_like '404 response' do
let(:message) { '404 Not Found' }
subject(:request) { post api(path, user) }
end
end
@ -721,12 +723,16 @@ RSpec.describe API::ProjectExport, :aggregate_failures, :clean_gitlab_redis_cach
end
it_behaves_like '404 response' do
subject(:request) { post api(path, user) }
let(:message) { '404 Not Found' }
subject(:request) { get api(download_path, user) }
end
end
describe 'GET /projects/:id/export_relations/status' do
it_behaves_like '404 response' do
let(:message) { '404 Not Found' }
subject(:request) { get api(status_path, user) }
end
end
@ -758,11 +764,5 @@ RSpec.describe API::ProjectExport, :aggregate_failures, :clean_gitlab_redis_cach
end
end
end
context 'when bulk import is disabled' do
it_behaves_like '404 response' do
subject(:request) { get api(path, user) }
end
end
end
end

View File

@ -68,22 +68,22 @@ RSpec.shared_examples 'handling get metadata requests' do |scope: :project|
nil | :unscoped | false | :public | nil | :accept | :ok
nil | :non_existing | true | :public | nil | :redirect | :redirected
nil | :non_existing | false | :public | nil | :reject | :not_found
nil | :scoped_naming_convention | true | :private | nil | :reject | :not_found
nil | :scoped_naming_convention | false | :private | nil | :reject | :not_found
nil | :scoped_no_naming_convention | true | :private | nil | :reject | :not_found
nil | :scoped_no_naming_convention | false | :private | nil | :reject | :not_found
nil | :unscoped | true | :private | nil | :reject | :not_found
nil | :unscoped | false | :private | nil | :reject | :not_found
nil | :scoped_naming_convention | true | :private | nil | :reject | :unauthorized
nil | :scoped_naming_convention | false | :private | nil | :reject | :unauthorized
nil | :scoped_no_naming_convention | true | :private | nil | :reject | :unauthorized
nil | :scoped_no_naming_convention | false | :private | nil | :reject | :unauthorized
nil | :unscoped | true | :private | nil | :reject | :unauthorized
nil | :unscoped | false | :private | nil | :reject | :unauthorized
nil | :non_existing | true | :private | nil | :redirect | :redirected
nil | :non_existing | false | :private | nil | :reject | :not_found
nil | :scoped_naming_convention | true | :internal | nil | :reject | :not_found
nil | :scoped_naming_convention | false | :internal | nil | :reject | :not_found
nil | :scoped_no_naming_convention | true | :internal | nil | :reject | :not_found
nil | :scoped_no_naming_convention | false | :internal | nil | :reject | :not_found
nil | :unscoped | true | :internal | nil | :reject | :not_found
nil | :unscoped | false | :internal | nil | :reject | :not_found
nil | :non_existing | false | :private | nil | :reject | :unauthorized
nil | :scoped_naming_convention | true | :internal | nil | :reject | :unauthorized
nil | :scoped_naming_convention | false | :internal | nil | :reject | :unauthorized
nil | :scoped_no_naming_convention | true | :internal | nil | :reject | :unauthorized
nil | :scoped_no_naming_convention | false | :internal | nil | :reject | :unauthorized
nil | :unscoped | true | :internal | nil | :reject | :unauthorized
nil | :unscoped | false | :internal | nil | :reject | :unauthorized
nil | :non_existing | true | :internal | nil | :redirect | :redirected
nil | :non_existing | false | :internal | nil | :reject | :not_found
nil | :non_existing | false | :internal | nil | :reject | :unauthorized
:oauth | :scoped_naming_convention | true | :public | :guest | :accept | :ok
:oauth | :scoped_naming_convention | true | :public | :reporter | :accept | :ok
@ -280,11 +280,15 @@ RSpec.shared_examples 'handling get metadata requests' do |scope: :project|
end
end
if (scope == :group && params[:package_name_type] == :non_existing) &&
(!params[:request_forward] || (!params[:auth] && params[:request_forward] && params[:visibility] != :public))
if scope == :group && params[:package_name_type] == :non_existing && !params[:request_forward] && params[:auth]
status = :not_found
end
if scope == :group && params[:package_name_type] == :non_existing && params[:request_forward] && !params[:auth] && params[:visibility] != :public
example_name = 'reject metadata request'
status = :unauthorized
end
# Check the error message for :not_found
example_name = 'returning response status with error' if status == :not_found
@ -522,14 +526,14 @@ RSpec.shared_examples 'handling get dist tags requests' do |scope: :project|
nil | :scoped_no_naming_convention | :public | nil | :accept | :ok
nil | :unscoped | :public | nil | :accept | :ok
nil | :non_existing | :public | nil | :reject | :not_found
nil | :scoped_naming_convention | :private | nil | :reject | :not_found
nil | :scoped_no_naming_convention | :private | nil | :reject | :not_found
nil | :unscoped | :private | nil | :reject | :not_found
nil | :non_existing | :private | nil | :reject | :not_found
nil | :scoped_naming_convention | :internal | nil | :reject | :not_found
nil | :scoped_no_naming_convention | :internal | nil | :reject | :not_found
nil | :unscoped | :internal | nil | :reject | :not_found
nil | :non_existing | :internal | nil | :reject | :not_found
nil | :scoped_naming_convention | :private | nil | :reject | :unauthorized
nil | :scoped_no_naming_convention | :private | nil | :reject | :unauthorized
nil | :unscoped | :private | nil | :reject | :unauthorized
nil | :non_existing | :private | nil | :reject | :unauthorized
nil | :scoped_naming_convention | :internal | nil | :reject | :unauthorized
nil | :scoped_no_naming_convention | :internal | nil | :reject | :unauthorized
nil | :unscoped | :internal | nil | :reject | :unauthorized
nil | :non_existing | :internal | nil | :reject | :unauthorized
:oauth | :scoped_naming_convention | :public | :guest | :accept | :ok
:oauth | :scoped_naming_convention | :public | :reporter | :accept | :ok

View File

@ -48,4 +48,61 @@ RSpec.describe MergeWorker, feature_category: :source_code_management do
end
end
end
describe 'delegation to MergeRequests::MergeService' do
# Some ids that should be nonexistentn
let(:user_id) { -1 }
let(:merge_request_id) { -1 }
let(:params) { {} }
subject { described_class.new.perform(merge_request_id, user_id, params) }
context 'when user exists' do
let!(:user) { create(:user) }
let(:user_id) { user.id }
context 'and merge request exists' do
let!(:merge_request) { create(:merge_request, source_project: create(:project, :empty_repo)) }
let(:merge_request_id) { merge_request.id }
let(:user) { merge_request.author }
let(:merge_service_double) { instance_double(MergeRequests::MergeService) }
it 'delegates to MergeRequests::MergeService' do
expect(MergeRequests::MergeService).to receive(:new).with(
project: merge_request.target_project,
current_user: user,
params: { check_mergeability_retry_lease: true }
).and_return(merge_service_double)
expect(merge_service_double).to receive(:execute)
subject
end
context 'and check_mergeability_retry_lease is specified' do
let(:params) { { check_mergeability_retry_lease: false } }
it 'does not change the check_mergeability_retry_lease parameter' do
expect(MergeRequests::MergeService).to receive(:new).with(
project: merge_request.target_project,
current_user: user,
params: params
).and_return(merge_service_double)
expect(merge_service_double).to receive(:execute)
subject
end
end
end
it 'does not call MergeRequests::MergeService' do
expect(MergeRequests::MergeService).not_to receive(:new)
subject
end
end
it 'does not call MergeRequests::MergeService' do
expect(MergeRequests::MergeService).not_to receive(:new)
subject
end
end
end

View File

@ -3510,6 +3510,11 @@ asynckit@^0.4.0:
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
at-least-node@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
atob@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
@ -4184,9 +4189,9 @@ ci-info@^2.0.0:
integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==
ci-info@^3.2.0, ci-info@^3.3.0:
version "3.3.1"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.1.tgz#58331f6f472a25fe3a50a351ae3052936c2c7f32"
integrity sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==
version "3.8.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91"
integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==
cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
version "1.0.4"
@ -6859,14 +6864,15 @@ from2@^2.1.0:
inherits "^2.0.1"
readable-stream "^2.0.0"
fs-extra@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9"
integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==
fs-extra@^9.0.0:
version "9.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==
dependencies:
graceful-fs "^4.1.2"
jsonfile "^4.0.0"
universalify "^0.1.0"
at-least-node "^1.0.0"
graceful-fs "^4.2.0"
jsonfile "^6.0.1"
universalify "^2.0.0"
fs-minipass@^2.0.0:
version "2.0.0"
@ -7130,10 +7136,10 @@ gopd@^1.0.1:
dependencies:
get-intrinsic "^1.1.3"
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
version "4.2.10"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
version "4.2.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
graphemer@^1.4.0:
version "1.4.0"
@ -8687,10 +8693,12 @@ jsonc-parser@^3.0.0, jsonc-parser@~3.2.0:
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76"
integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
jsonfile@^6.0.1:
version "6.1.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
dependencies:
universalify "^2.0.0"
optionalDependencies:
graceful-fs "^4.1.6"
@ -10610,24 +10618,25 @@ pascalcase@^0.1.1:
resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=
patch-package@^6.4.7:
version "6.4.7"
resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.4.7.tgz#2282d53c397909a0d9ef92dae3fdeb558382b148"
integrity sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==
patch-package@6.5.1:
version "6.5.1"
resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.5.1.tgz#3e5d00c16997e6160291fee06a521c42ac99b621"
integrity sha512-I/4Zsalfhc6bphmJTlrLoOcAF87jcxko4q0qsv4bGcurbr8IskEOtdnt9iCmsQVGL1B+iUhSQqweyTLJfCF9rA==
dependencies:
"@yarnpkg/lockfile" "^1.1.0"
chalk "^2.4.2"
chalk "^4.1.2"
cross-spawn "^6.0.5"
find-yarn-workspace-root "^2.0.0"
fs-extra "^7.0.1"
fs-extra "^9.0.0"
is-ci "^2.0.0"
klaw-sync "^6.0.0"
minimist "^1.2.0"
minimist "^1.2.6"
open "^7.4.2"
rimraf "^2.6.3"
semver "^5.6.0"
slash "^2.0.0"
tmp "^0.0.33"
yaml "^1.10.2"
path-browserify@0.0.1:
version "0.0.1"
@ -11852,9 +11861,9 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0, semver@^6.3.1:
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
semver@^7.3.4, semver@^7.3.5, semver@^7.3.6, semver@^7.3.7, semver@^7.5.0:
version "7.5.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.0.tgz#ed8c5dc8efb6c629c88b23d41dc9bf40c1d96cd0"
integrity sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==
version "7.5.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
dependencies:
lru-cache "^6.0.0"
@ -13246,11 +13255,16 @@ unist-util-visit@^4.0.0:
unist-util-is "^5.0.0"
unist-util-visit-parents "^5.0.0"
universalify@^0.1.0, universalify@^0.1.2:
universalify@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
universalify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
unixify@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unixify/-/unixify-1.0.0.tgz#3a641c8c2ffbce4da683a5c70f03a462940c2090"
@ -14096,10 +14110,15 @@ yallist@^4.0.0:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yaml@^1.10.2:
version "1.10.2"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
yaml@^2.0.0, yaml@^2.0.0-10:
version "2.1.1"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.1.1.tgz#1e06fb4ca46e60d9da07e4f786ea370ed3c3cfec"
integrity sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw==
version "2.3.2"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.2.tgz#f522db4313c671a0ca963a75670f1c12ea909144"
integrity sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==
yargs-parser@^18.1.2:
version "18.1.3"