Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
c21064ccfd
commit
7f59234892
|
@ -164,7 +164,7 @@
|
|||
- "vendor/assets/**/*"
|
||||
- ".gitlab/ci/**/*"
|
||||
- ".{eslintignore,gitattributes,nvmrc,prettierrc,stylelintrc,yamllint}"
|
||||
- ".{codeclimate,eslintrc,gitlab-ci,haml-lint,haml-lint_todo,rubocop,rubocop_todo,scss-lint}.yml"
|
||||
- ".{codeclimate,eslintrc,gitlab-ci,haml-lint,haml-lint_todo,rubocop,rubocop_todo,rubocop_manual_todo,scss-lint}.yml"
|
||||
- "*_VERSION"
|
||||
- "Gemfile{,.lock}"
|
||||
- "Rakefile"
|
||||
|
@ -186,7 +186,7 @@
|
|||
- "vendor/assets/**/*"
|
||||
- ".gitlab/ci/**/*"
|
||||
- ".{eslintignore,gitattributes,nvmrc,prettierrc,stylelintrc,yamllint}"
|
||||
- ".{codeclimate,eslintrc,gitlab-ci,haml-lint,haml-lint_todo,rubocop,rubocop_todo,scss-lint}.yml"
|
||||
- ".{codeclimate,eslintrc,gitlab-ci,haml-lint,haml-lint_todo,rubocop,rubocop_todo,rubocop_manual_todo,scss-lint}.yml"
|
||||
- "*_VERSION"
|
||||
- "Gemfile{,.lock}"
|
||||
- "Rakefile"
|
||||
|
@ -210,7 +210,7 @@
|
|||
- "vendor/assets/**/*"
|
||||
- ".gitlab/ci/**/*"
|
||||
- ".{eslintignore,gitattributes,nvmrc,prettierrc,stylelintrc,yamllint}"
|
||||
- ".{codeclimate,eslintrc,gitlab-ci,haml-lint,haml-lint_todo,rubocop,rubocop_todo,scss-lint}.yml"
|
||||
- ".{codeclimate,eslintrc,gitlab-ci,haml-lint,haml-lint_todo,rubocop,rubocop_todo,rubocop_manual_todo,scss-lint}.yml"
|
||||
- "*_VERSION"
|
||||
- "Gemfile{,.lock}"
|
||||
- "Rakefile"
|
||||
|
@ -231,7 +231,7 @@
|
|||
- "vendor/assets/**/*"
|
||||
- ".gitlab/ci/**/*"
|
||||
- ".{eslintignore,gitattributes,nvmrc,prettierrc,stylelintrc,yamllint}"
|
||||
- ".{codeclimate,eslintrc,gitlab-ci,haml-lint,haml-lint_todo,rubocop,rubocop_todo,scss-lint}.yml"
|
||||
- ".{codeclimate,eslintrc,gitlab-ci,haml-lint,haml-lint_todo,rubocop,rubocop_todo,rubocop_manual_todo,scss-lint}.yml"
|
||||
- "*_VERSION"
|
||||
- "Gemfile{,.lock}"
|
||||
- "Rakefile"
|
||||
|
|
|
@ -43,8 +43,6 @@ Graphql/IDType:
|
|||
|
||||
Graphql/ResolverType:
|
||||
Exclude:
|
||||
- 'app/graphql/resolvers/assigned_merge_requests_resolver.rb'
|
||||
- 'app/graphql/resolvers/authored_merge_requests_resolver.rb'
|
||||
- 'app/graphql/resolvers/base_resolver.rb'
|
||||
- 'app/graphql/resolvers/ci/pipeline_stages_resolver.rb'
|
||||
- 'app/graphql/resolvers/commit_pipelines_resolver.rb'
|
||||
|
@ -61,7 +59,6 @@ Graphql/ResolverType:
|
|||
- 'app/graphql/resolvers/project_pipelines_resolver.rb'
|
||||
- 'app/graphql/resolvers/projects/snippets_resolver.rb'
|
||||
- 'app/graphql/resolvers/snippets_resolver.rb'
|
||||
- 'app/graphql/resolvers/user_merge_requests_resolver.rb'
|
||||
- 'app/graphql/resolvers/users/group_count_resolver.rb'
|
||||
- 'app/graphql/resolvers/users/snippets_resolver.rb'
|
||||
- 'ee/app/graphql/resolvers/ci/jobs_resolver.rb'
|
||||
|
|
|
@ -1 +1 @@
|
|||
8.53.0
|
||||
8.54.0
|
||||
|
|
|
@ -84,6 +84,14 @@ export default {
|
|||
}
|
||||
return {};
|
||||
},
|
||||
showDiscussions() {
|
||||
return typeof this.issuable.userDiscussionsCount === 'number';
|
||||
},
|
||||
showIssuableMeta() {
|
||||
return Boolean(
|
||||
this.hasSlotContents('status') || this.showDiscussions || this.issuable.assignees,
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
hasSlotContents(slotName) {
|
||||
|
@ -166,6 +174,7 @@ export default {
|
|||
<span class="author">{{ author.name }}</span>
|
||||
</gl-link>
|
||||
</span>
|
||||
<slot name="timeframe"></slot>
|
||||
|
||||
<gl-label
|
||||
v-for="(label, index) in labels"
|
||||
|
@ -181,10 +190,26 @@ export default {
|
|||
</div>
|
||||
</div>
|
||||
<div class="issuable-meta">
|
||||
<ul v-if="hasSlotContents('status') || issuable.assignees" class="controls">
|
||||
<ul v-if="showIssuableMeta" class="controls">
|
||||
<li v-if="hasSlotContents('status')" class="issuable-status">
|
||||
<slot name="status"></slot>
|
||||
</li>
|
||||
<li
|
||||
v-if="showDiscussions"
|
||||
data-testid="issuable-discussions"
|
||||
class="issuable-comments gl-display-none gl-display-sm-block"
|
||||
>
|
||||
<gl-link
|
||||
v-gl-tooltip:tooltipcontainer.top
|
||||
:title="__('Comments')"
|
||||
:href="`${issuable.webUrl}#notes`"
|
||||
:class="{ 'no-comments': !issuable.userDiscussionsCount }"
|
||||
class="gl-reset-color!"
|
||||
>
|
||||
<gl-icon name="comments" />
|
||||
{{ issuable.userDiscussionsCount }}
|
||||
</gl-link>
|
||||
</li>
|
||||
<li v-if="assignees.length" class="gl-display-flex">
|
||||
<issuable-assignees
|
||||
:assignees="issuable.assignees"
|
||||
|
|
|
@ -269,6 +269,9 @@ export default {
|
|||
<template #author>
|
||||
<slot name="author" :author="issuable.author"></slot>
|
||||
</template>
|
||||
<template #timeframe>
|
||||
<slot name="timeframe" :issuable="issuable"></slot>
|
||||
</template>
|
||||
<template #status>
|
||||
<slot name="status" :issuable="issuable"></slot>
|
||||
</template>
|
||||
|
|
|
@ -24,5 +24,5 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<gl-link :href="path" :class="cssClass" class="btn">{{ text }}</gl-link>
|
||||
<gl-link :href="path" :class="cssClass" class="btn gl-button">{{ text }}</gl-link>
|
||||
</template>
|
||||
|
|
|
@ -61,7 +61,6 @@ export default {
|
|||
<gl-dropdown
|
||||
v-if="hasMultipleActions"
|
||||
v-gl-tooltip="selectedAction.tooltip"
|
||||
class="gl-button-deprecated-adapter"
|
||||
:text="selectedAction.text"
|
||||
:split-href="selectedAction.href"
|
||||
:variant="variant"
|
||||
|
|
|
@ -75,6 +75,11 @@ export default {
|
|||
type: String,
|
||||
required: true,
|
||||
},
|
||||
suggestionsListClass: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
let selectedSortOption = this.sortOptions[0]?.sortDirection?.descending;
|
||||
|
@ -315,6 +320,7 @@ export default {
|
|||
:placeholder="searchInputPlaceholder"
|
||||
:available-tokens="tokens"
|
||||
:history-items="filteredRecentSearches"
|
||||
:suggestions-list-class="suggestionsListClass"
|
||||
class="flex-grow-1"
|
||||
@history-item-selected="handleHistoryItemSelected"
|
||||
@clear-history="handleClearHistory"
|
||||
|
|
|
@ -169,7 +169,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="d-inline-block gl-ml-3">
|
||||
<div class="gl-sm-ml-3">
|
||||
<actions-button
|
||||
:actions="actions"
|
||||
:selected-key="selection"
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
.tree-controls {
|
||||
margin-bottom: 10px;
|
||||
|
||||
.btn,
|
||||
.btn:not(.dropdown-toggle-split),
|
||||
.dropdown,
|
||||
.btn-group {
|
||||
width: 100%;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Resolvers
|
||||
class AssignedMergeRequestsResolver < UserMergeRequestsResolver
|
||||
class AssignedMergeRequestsResolver < UserMergeRequestsResolverBase
|
||||
type ::Types::MergeRequestType.connection_type, null: true
|
||||
accept_author
|
||||
|
||||
def user_role
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Resolvers
|
||||
class AuthoredMergeRequestsResolver < UserMergeRequestsResolver
|
||||
class AuthoredMergeRequestsResolver < UserMergeRequestsResolverBase
|
||||
type ::Types::MergeRequestType.connection_type, null: true
|
||||
accept_assignee
|
||||
|
||||
def user_role
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Resolvers
|
||||
class UserMergeRequestsResolver < MergeRequestsResolver
|
||||
class UserMergeRequestsResolverBase < MergeRequestsResolver
|
||||
include ResolvesProject
|
||||
|
||||
argument :project_path, GraphQL::STRING_TYPE,
|
|
@ -46,10 +46,10 @@ module Types
|
|||
resolver: Resolvers::UserStarredProjectsResolver
|
||||
|
||||
# Merge request field: MRs can be either authored or assigned:
|
||||
field :authored_merge_requests, Types::MergeRequestType.connection_type, null: true,
|
||||
field :authored_merge_requests,
|
||||
resolver: Resolvers::AuthoredMergeRequestsResolver,
|
||||
description: 'Merge Requests authored by the user'
|
||||
field :assigned_merge_requests, Types::MergeRequestType.connection_type, null: true,
|
||||
field :assigned_merge_requests,
|
||||
resolver: Resolvers::AssignedMergeRequestsResolver,
|
||||
description: 'Merge Requests assigned to the user'
|
||||
|
||||
|
|
|
@ -54,9 +54,6 @@ module Ci
|
|||
|
||||
raise "Unknown store type: #{store}" unless STORE_TYPES.key?(store)
|
||||
|
||||
# Can't memoize this because the feature flag may alter this
|
||||
return fog_store_class.new if store == :fog
|
||||
|
||||
STORE_TYPES[store].new
|
||||
end
|
||||
|
||||
|
@ -86,14 +83,6 @@ module Ci
|
|||
def metadata_attributes
|
||||
attribute_names - %w[raw_data]
|
||||
end
|
||||
|
||||
def fog_store_class
|
||||
if Feature.enabled?(:ci_trace_new_fog_store, default_enabled: true)
|
||||
Ci::BuildTraceChunks::Fog
|
||||
else
|
||||
Ci::BuildTraceChunks::LegacyFog
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def data
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Ci
|
||||
module BuildTraceChunks
|
||||
class LegacyFog
|
||||
def available?
|
||||
object_store.enabled
|
||||
end
|
||||
|
||||
def data(model)
|
||||
connection.get_object(bucket_name, key(model))[:body]
|
||||
rescue Excon::Error::NotFound
|
||||
# If the object does not exist in the object storage, this method returns nil.
|
||||
end
|
||||
|
||||
def set_data(model, new_data)
|
||||
connection.put_object(bucket_name, key(model), new_data)
|
||||
end
|
||||
|
||||
def append_data(model, new_data, offset)
|
||||
if offset > 0
|
||||
truncated_data = data(model).to_s.byteslice(0, offset)
|
||||
new_data = truncated_data + new_data
|
||||
end
|
||||
|
||||
set_data(model, new_data)
|
||||
new_data.bytesize
|
||||
end
|
||||
|
||||
def size(model)
|
||||
data(model).to_s.bytesize
|
||||
end
|
||||
|
||||
def delete_data(model)
|
||||
delete_keys([[model.build_id, model.chunk_index]])
|
||||
end
|
||||
|
||||
def keys(relation)
|
||||
return [] unless available?
|
||||
|
||||
relation.pluck(:build_id, :chunk_index)
|
||||
end
|
||||
|
||||
def delete_keys(keys)
|
||||
keys.each do |key|
|
||||
connection.delete_object(bucket_name, key_raw(*key))
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def key(model)
|
||||
key_raw(model.build_id, model.chunk_index)
|
||||
end
|
||||
|
||||
def key_raw(build_id, chunk_index)
|
||||
"tmp/builds/#{build_id.to_i}/chunks/#{chunk_index.to_i}.log"
|
||||
end
|
||||
|
||||
def bucket_name
|
||||
return unless available?
|
||||
|
||||
object_store.remote_directory
|
||||
end
|
||||
|
||||
def connection
|
||||
return unless available?
|
||||
|
||||
@connection ||= ::Fog::Storage.new(object_store.connection.to_hash.deep_symbolize_keys)
|
||||
end
|
||||
|
||||
def object_store
|
||||
Gitlab.config.artifacts.object_store
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,5 +2,5 @@
|
|||
- add_page_specific_style 'page_bundles/signup'
|
||||
|
||||
.signup-page
|
||||
= render 'devise/shared/signup_box'
|
||||
= render 'devise/shared/signup_box', url: registration_path(resource_name), button_text: _('Register'), show_omniauth_providers: omniauth_enabled? && button_based_providers_enabled?
|
||||
= render 'devise/shared/sign_in_link'
|
||||
|
|
|
@ -2,37 +2,36 @@
|
|||
- max_username_length = 255
|
||||
- min_username_length = 2
|
||||
.gl-mb-3.gl-p-4.gl-border-gray-100.gl-border-1.gl-border-solid.gl-rounded-base
|
||||
= form_for(resource, as: "new_#{resource_name}", url: registration_path(resource_name), html: { class: "new_new_user gl-show-field-errors", "aria-live" => "assertive" }) do |f|
|
||||
= form_for(resource, as: "new_#{resource_name}", url: url, html: { class: 'new_user gl-show-field-errors', 'aria-live' => 'assertive' }) do |f|
|
||||
.devise-errors
|
||||
= render "devise/shared/error_messages", resource: resource
|
||||
= render 'devise/shared/error_messages', resource: resource
|
||||
- if Feature.enabled?(:invisible_captcha)
|
||||
= invisible_captcha
|
||||
.name.form-row
|
||||
.col.form-group
|
||||
= f.label :first_name, _('First name'), for: 'new_user_first_name', class: 'label-bold'
|
||||
= f.text_field :first_name, class: 'form-control top js-block-emoji js-validate-length', :data => { :max_length => max_first_name_length, :max_length_message => _("First name is too long (maximum is %{max_length} characters).") % { max_length: max_first_name_length }, :qa_selector => 'new_user_first_name_field' }, required: true, title: _("This field is required.")
|
||||
= f.text_field :first_name, class: 'form-control top js-block-emoji js-validate-length', :data => { :max_length => max_first_name_length, :max_length_message => s_('SignUp|First name is too long (maximum is %{max_length} characters).') % { max_length: max_first_name_length }, :qa_selector => 'new_user_first_name_field' }, required: true, title: _('This field is required.')
|
||||
.col.form-group
|
||||
= f.label :last_name, _('Last name'), for: 'new_user_last_name', class: 'label-bold'
|
||||
= f.text_field :last_name, class: "form-control top js-block-emoji js-validate-length", :data => { :max_length => max_last_name_length, :max_length_message => _("Last name is too long (maximum is %{max_length} characters).") % { max_length: max_last_name_length }, :qa_selector => 'new_user_last_name_field' }, required: true, title: _("This field is required.")
|
||||
= f.text_field :last_name, class: 'form-control top js-block-emoji js-validate-length', :data => { :max_length => max_last_name_length, :max_length_message => s_('SignUp|Last name is too long (maximum is %{max_length} characters).') % { max_length: max_last_name_length }, :qa_selector => 'new_user_last_name_field' }, required: true, title: _('This field is required.')
|
||||
.username.form-group
|
||||
= f.label :username, class: 'label-bold'
|
||||
= f.text_field :username, class: "form-control middle js-block-emoji js-validate-length js-validate-username", :data => { :min_length => min_username_length, :min_length_message => s_("SignUp|Username is too short (minimum is %{min_length} characters).") % { min_length: min_username_length }, :max_length => max_username_length, :max_length_message => s_("SignUp|Username is too long (maximum is %{max_length} characters).") % { max_length: max_username_length }, :qa_selector => 'new_user_username_field' }, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _("Please create a username with only alphanumeric characters.")
|
||||
= f.text_field :username, class: 'form-control middle js-block-emoji js-validate-length js-validate-username', :data => { :api_path => suggestion_path, :min_length => min_username_length, :min_length_message => s_('SignUp|Username is too short (minimum is %{min_length} characters).') % { min_length: min_username_length }, :max_length => max_username_length, :max_length_message => s_('SignUp|Username is too long (maximum is %{max_length} characters).') % { max_length: max_username_length }, :qa_selector => 'new_user_username_field' }, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _('Please create a username with only alphanumeric characters.')
|
||||
%p.validation-error.gl-text-red-500.gl-field-error-ignore.gl-mt-2.field-validation.hide= _('Username is already taken.')
|
||||
%p.validation-success.gl-text-green-600.gl-field-error-ignore.gl-mt-2.field-validation.hide= _('Username is available.')
|
||||
%p.validation-pending.gl-field-error-ignore.gl-mt-2.field-validation.hide= _('Checking username availability...')
|
||||
.form-group
|
||||
= f.label :email, class: 'label-bold'
|
||||
= f.email_field :email, value: @invite_email, class: "form-control middle", data: { qa_selector: 'new_user_email_field' }, required: true, title: _("Please provide a valid email address.")
|
||||
= f.email_field :email, value: @invite_email, class: 'form-control middle', data: { qa_selector: 'new_user_email_field' }, required: true, title: _('Please provide a valid email address.')
|
||||
.form-group.append-bottom-20#password-strength
|
||||
= f.label :password, class: 'label-bold'
|
||||
= f.password_field :password, class: "form-control bottom", data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: _("Minimum length is %{minimum_password_length} characters.") % { minimum_password_length: @minimum_password_length }
|
||||
%p.gl-field-hint.text-secondary= _('Minimum length is %{minimum_password_length} characters') % { minimum_password_length: @minimum_password_length }
|
||||
= f.password_field :password, class: 'form-control bottom', data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length }
|
||||
%p.gl-field-hint.text-secondary= s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length }
|
||||
%div
|
||||
- if show_recaptcha_sign_up?
|
||||
= recaptcha_tags
|
||||
.submit-container
|
||||
= f.submit _("Register"), class: "btn gl-button btn-success", data: { qa_selector: 'new_user_register_button' }
|
||||
= f.submit button_text, class: 'btn gl-button btn-success', data: { qa_selector: 'new_user_register_button' }
|
||||
= render 'devise/shared/terms_of_service_notice'
|
||||
- if omniauth_enabled? && button_based_providers_enabled?
|
||||
- if show_omniauth_providers
|
||||
= render 'devise/shared/signup_omniauth_providers'
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
= link_to project_find_file_path(@project, @ref), class: 'btn shortcuts-find-file', rel: 'nofollow' do
|
||||
= link_to project_find_file_path(@project, @ref), class: 'gl-button btn shortcuts-find-file', rel: 'nofollow' do
|
||||
= _('Find file')
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
- dropdown_class = local_assigns.fetch(:dropdown_class, '')
|
||||
|
||||
.git-clone-holder.js-git-clone-holder
|
||||
%a#clone-dropdown.btn.btn-primary.clone-dropdown-btn.qa-clone-dropdown{ href: '#', data: { toggle: 'dropdown' } }
|
||||
%a#clone-dropdown.gl-button.btn.btn-primary.clone-dropdown-btn.qa-clone-dropdown{ href: '#', data: { toggle: 'dropdown' } }
|
||||
%span.gl-mr-2.js-clone-dropdown-label
|
||||
= _('Clone')
|
||||
= sprite_icon("chevron-down", css_class: "icon")
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
- if !project.empty_repo? && can?(current_user, :download_code, project)
|
||||
- archive_prefix = "#{project.path}-#{ref.tr('/', '-')}"
|
||||
.project-action-button.dropdown.inline>
|
||||
%button.btn.has-tooltip{ title: s_('DownloadSource|Download'), 'data-toggle' => 'dropdown', 'aria-label' => s_('DownloadSource|Download'), 'data-display' => 'static', data: { qa_selector: 'download_source_code_button' } }
|
||||
%button.gl-button.btn.has-tooltip{ title: s_('DownloadSource|Download'), 'data-toggle' => 'dropdown', 'aria-label' => s_('DownloadSource|Download'), 'data-display' => 'static', data: { qa_selector: 'download_source_code_button' } }
|
||||
= sprite_icon('download')
|
||||
%span.sr-only= _('Select Archive Format')
|
||||
= sprite_icon("chevron-down")
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
%a.btn.btn-default{ href: xcode_uri_to_repo(@project) }
|
||||
%a.gl-button.btn.btn-default{ href: xcode_uri_to_repo(@project) }
|
||||
= _("Open in Xcode")
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
= render 'shared/web_ide_button', blob: nil
|
||||
|
||||
- if show_xcode_link?(@project)
|
||||
.project-action-button.project-xcode.inline<
|
||||
.project-action-button.project-xcode<
|
||||
= render "projects/buttons/xcode_link"
|
||||
|
||||
= render 'projects/buttons/download', project: @project, ref: @ref
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: 'MR Analytics: Fix chart tooltip covering filter dropdown'
|
||||
merge_request: 47274
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Update Workhorse version to 8.54.0
|
||||
merge_request: 47625
|
||||
author:
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Update button styles in project tree header
|
||||
merge_request: 47562
|
||||
author:
|
||||
type: other
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: Make the Merge Train process flow more resilient by always refreshing merge
|
||||
requests from beginning
|
||||
merge_request: 46768
|
||||
author:
|
||||
type: fixed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Remove ci_trace_new_fog_store feature flag
|
||||
merge_request: 47522
|
||||
author:
|
||||
type: changed
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: ci_always_refresh_merge_requests_from_beginning
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/45232
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/268215
|
||||
milestone: '13.5'
|
||||
type: development
|
||||
group: group::continuous integration
|
||||
default_enabled: false
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: ci_trace_new_fog_store
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46209
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/273405
|
||||
milestone: '13.6'
|
||||
type: development
|
||||
group: group::testing
|
||||
default_enabled: true
|
|
@ -33,6 +33,7 @@ Example response:
|
|||
[
|
||||
{
|
||||
"id" : 1,
|
||||
"name": "board1",
|
||||
"project": {
|
||||
"id": 5,
|
||||
"name": "Diaspora Project Site",
|
||||
|
|
|
@ -52,8 +52,23 @@ and blocked, go to **Admin Area > Overview > Dashboard** and select **Users stat
|
|||
in the **Users** section. For more details, see
|
||||
[Users statistics](../../user/admin_area/index.md#users-statistics).
|
||||
|
||||
NOTE: **Note:**
|
||||
If you have LDAP integration enabled, anyone in the configured domain can sign up for a GitLab account. This can result in an unexpected bill at time of renewal. Consider [disabling new signups](../../user/admin_area/settings/sign_up_restrictions.md) and managing new users manually instead.
|
||||
### Tips for managing users and subscription seats
|
||||
|
||||
Managing the number of users against the number of subscription seats can be a challenge:
|
||||
|
||||
- If LDAP integration is enabled, anyone in the configured domain can sign up for a GitLab account.
|
||||
This can result in an unexpected bill at time of renewal.
|
||||
- If sign-up is enabled on your instance, anyone who can access the instance can sign up for an
|
||||
account.
|
||||
|
||||
GitLab has several features which can help you manage the number of users:
|
||||
|
||||
- Enable the [**Require administrator approval for new sign ups**](../../user/admin_area/settings/sign_up_restrictions.md#require-administrator-approval-for-new-sign-ups)
|
||||
option.
|
||||
- Enable the [User cap](../../user/admin_area/settings/sign_up_restrictions.md#user-cap)
|
||||
option. **Available in GitLab 13.6 and later**.
|
||||
- [Disable new sign-ups](../../user/admin_area/settings/sign_up_restrictions.md), and instead manage new
|
||||
users manually.
|
||||
|
||||
## Obtain a subscription
|
||||
|
||||
|
|
|
@ -46,6 +46,14 @@ To enforce confirmation of the email address used for new sign ups:
|
|||
1. Go to **Admin Area > Settings > General** and expand **Sign-up restrictions**.
|
||||
1. Select the **Enable email restrictions for sign ups** checkbox, then select **Save changes**.
|
||||
|
||||
## User cap **(CORE ONLY)**
|
||||
|
||||
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/4315) in GitLab 13.6.
|
||||
|
||||
When the number of users reaches the user cap, any user who is added or requests access must be
|
||||
[approved](../approving_users.md#approving-a-user) by an administrator before they can start using
|
||||
their account.
|
||||
|
||||
## Soft email confirmation
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/47003) in GitLab 12.2.
|
||||
|
|
|
@ -543,6 +543,12 @@ msgstr ""
|
|||
msgid "%{issuesSize} with a limit of %{maxIssueCount}"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{labelStart}Actual response:%{labelEnd} %{headers}"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{labelStart}Assert:%{labelEnd} %{assertion}"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{labelStart}Class:%{labelEnd} %{class}"
|
||||
msgstr ""
|
||||
|
||||
|
@ -558,9 +564,6 @@ msgstr ""
|
|||
msgid "%{labelStart}File:%{labelEnd} %{file}"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{labelStart}Headers:%{labelEnd} %{headers}"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{labelStart}Image:%{labelEnd} %{image}"
|
||||
msgstr ""
|
||||
|
||||
|
@ -576,13 +579,13 @@ msgstr ""
|
|||
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{labelStart}Sent request:%{labelEnd} %{headers}"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{labelStart}Status:%{labelEnd} %{status}"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{labelStart}URL:%{labelEnd} %{url}"
|
||||
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{label_for_message} unavailable"
|
||||
|
@ -9457,9 +9460,33 @@ msgstr ""
|
|||
msgid "DevopsAdoption|Add new segment"
|
||||
msgstr ""
|
||||
|
||||
msgid "DevopsAdoption|Approvals"
|
||||
msgstr ""
|
||||
|
||||
msgid "DevopsAdoption|Deploys"
|
||||
msgstr ""
|
||||
|
||||
msgid "DevopsAdoption|DevOps adoption uses segments to track adoption across key features. Segments are a way to track multiple related projects and groups at once. For example, you could create a segment for the engineering department or a particular product team."
|
||||
msgstr ""
|
||||
|
||||
msgid "DevopsAdoption|Issues"
|
||||
msgstr ""
|
||||
|
||||
msgid "DevopsAdoption|MRs"
|
||||
msgstr ""
|
||||
|
||||
msgid "DevopsAdoption|Pipelines"
|
||||
msgstr ""
|
||||
|
||||
msgid "DevopsAdoption|Runners"
|
||||
msgstr ""
|
||||
|
||||
msgid "DevopsAdoption|Scanning"
|
||||
msgstr ""
|
||||
|
||||
msgid "DevopsAdoption|Segment"
|
||||
msgstr ""
|
||||
|
||||
msgid "DevopsReport|Adoption"
|
||||
msgstr ""
|
||||
|
||||
|
@ -11950,9 +11977,6 @@ msgstr ""
|
|||
msgid "First name"
|
||||
msgstr ""
|
||||
|
||||
msgid "First name is too long (maximum is %{max_length} characters)."
|
||||
msgstr ""
|
||||
|
||||
msgid "First seen"
|
||||
msgstr ""
|
||||
|
||||
|
@ -15697,9 +15721,6 @@ msgstr ""
|
|||
msgid "Last name"
|
||||
msgstr ""
|
||||
|
||||
msgid "Last name is too long (maximum is %{max_length} characters)."
|
||||
msgstr ""
|
||||
|
||||
msgid "Last reply by"
|
||||
msgstr ""
|
||||
|
||||
|
@ -17572,12 +17593,6 @@ msgstr ""
|
|||
msgid "Minimum interval in days"
|
||||
msgstr ""
|
||||
|
||||
msgid "Minimum length is %{minimum_password_length} characters"
|
||||
msgstr ""
|
||||
|
||||
msgid "Minimum length is %{minimum_password_length} characters."
|
||||
msgstr ""
|
||||
|
||||
msgid "Minimum password length (number of characters)"
|
||||
msgstr ""
|
||||
|
||||
|
@ -22414,9 +22429,6 @@ msgstr ""
|
|||
msgid "Remediations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Remember me"
|
||||
msgstr ""
|
||||
|
||||
msgid "Remind later"
|
||||
msgstr ""
|
||||
|
||||
|
@ -24984,10 +24996,13 @@ msgstr ""
|
|||
msgid "Sign-up restrictions"
|
||||
msgstr ""
|
||||
|
||||
msgid "SignUp|First Name is too long (maximum is %{max_length} characters)."
|
||||
msgid "SignUp|First name is too long (maximum is %{max_length} characters)."
|
||||
msgstr ""
|
||||
|
||||
msgid "SignUp|Last Name is too long (maximum is %{max_length} characters)."
|
||||
msgid "SignUp|Last name is too long (maximum is %{max_length} characters)."
|
||||
msgstr ""
|
||||
|
||||
msgid "SignUp|Minimum length is %{minimum_password_length} characters."
|
||||
msgstr ""
|
||||
|
||||
msgid "SignUp|Username is too long (maximum is %{max_length} characters)."
|
||||
|
@ -30051,6 +30066,12 @@ msgstr ""
|
|||
msgid "Vulnerability|Activity"
|
||||
msgstr ""
|
||||
|
||||
msgid "Vulnerability|Actual received response is the one received when this fault was detected"
|
||||
msgstr ""
|
||||
|
||||
msgid "Vulnerability|Additional Info"
|
||||
msgstr ""
|
||||
|
||||
msgid "Vulnerability|Class"
|
||||
msgstr ""
|
||||
|
||||
|
@ -30099,10 +30120,7 @@ msgstr ""
|
|||
msgid "Vulnerability|Project"
|
||||
msgstr ""
|
||||
|
||||
msgid "Vulnerability|Request"
|
||||
msgstr ""
|
||||
|
||||
msgid "Vulnerability|Response"
|
||||
msgid "Vulnerability|Request/Response"
|
||||
msgstr ""
|
||||
|
||||
msgid "Vulnerability|Scanner"
|
||||
|
@ -30117,6 +30135,9 @@ msgstr ""
|
|||
msgid "Vulnerability|Status"
|
||||
msgstr ""
|
||||
|
||||
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
|
||||
msgstr ""
|
||||
|
||||
msgid "Wait for the file to load to copy its contents"
|
||||
msgstr ""
|
||||
|
||||
|
@ -31627,6 +31648,9 @@ msgstr ""
|
|||
msgid "ciReport|: Loading resulted in an error"
|
||||
msgstr ""
|
||||
|
||||
msgid "ciReport|API Fuzzing"
|
||||
msgstr ""
|
||||
|
||||
msgid "ciReport|All projects"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
"@babel/preset-env": "^7.10.1",
|
||||
"@gitlab/at.js": "1.5.5",
|
||||
"@gitlab/svgs": "1.175.0",
|
||||
"@gitlab/ui": "23.6.1",
|
||||
"@gitlab/ui": "23.8.0",
|
||||
"@gitlab/visual-review-tools": "1.6.1",
|
||||
"@rails/actioncable": "^6.0.3-3",
|
||||
"@rails/ujs": "^6.0.3-2",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { shallowMount } from '@vue/test-utils';
|
||||
import { GlLink, GlLabel, GlFormCheckbox } from '@gitlab/ui';
|
||||
import { GlLink, GlLabel, GlIcon, GlFormCheckbox } from '@gitlab/ui';
|
||||
|
||||
import IssuableItem from '~/issuable_list/components/issuable_item.vue';
|
||||
import IssuableAssignees from '~/vue_shared/components/issue/issue_assignees.vue';
|
||||
|
@ -12,6 +12,7 @@ const createComponent = ({ issuableSymbol = '#', issuable = mockIssuable, slots
|
|||
issuableSymbol,
|
||||
issuable,
|
||||
enableLabelPermalinks: true,
|
||||
showDiscussions: true,
|
||||
showCheckbox: false,
|
||||
},
|
||||
slots,
|
||||
|
@ -142,6 +143,31 @@ describe('IssuableItem', () => {
|
|||
expect(wrapper.vm.updatedAt).toContain('ago');
|
||||
});
|
||||
});
|
||||
|
||||
describe('showDiscussions', () => {
|
||||
it.each`
|
||||
userDiscussionsCount | returnValue
|
||||
${0} | ${true}
|
||||
${1} | ${true}
|
||||
${undefined} | ${false}
|
||||
${null} | ${false}
|
||||
`(
|
||||
'returns $returnValue when issuable.userDiscussionsCount is $userDiscussionsCount',
|
||||
({ userDiscussionsCount, returnValue }) => {
|
||||
const wrapperWithDiscussions = createComponent({
|
||||
issuableSymbol: '#',
|
||||
issuable: {
|
||||
...mockIssuable,
|
||||
userDiscussionsCount,
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapperWithDiscussions.vm.showDiscussions).toBe(returnValue);
|
||||
|
||||
wrapperWithDiscussions.destroy();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('methods', () => {
|
||||
|
@ -299,6 +325,24 @@ describe('IssuableItem', () => {
|
|||
wrapperWithAuthorSlot.destroy();
|
||||
});
|
||||
|
||||
it('renders timeframe via slot', () => {
|
||||
const wrapperWithTimeframeSlot = createComponent({
|
||||
issuableSymbol: '#',
|
||||
issuable: mockIssuable,
|
||||
slots: {
|
||||
timeframe: `
|
||||
<b class="js-timeframe">Jan 1, 2020 - Mar 31, 2020</b>
|
||||
`,
|
||||
},
|
||||
});
|
||||
const timeframeEl = wrapperWithTimeframeSlot.find('.js-timeframe');
|
||||
|
||||
expect(timeframeEl.exists()).toBe(true);
|
||||
expect(timeframeEl.text()).toBe('Jan 1, 2020 - Mar 31, 2020');
|
||||
|
||||
wrapperWithTimeframeSlot.destroy();
|
||||
});
|
||||
|
||||
it('renders gl-label component for each label present within `issuable` prop', () => {
|
||||
const labelsEl = wrapper.findAll(GlLabel);
|
||||
|
||||
|
@ -332,6 +376,18 @@ describe('IssuableItem', () => {
|
|||
wrapperWithStatusSlot.destroy();
|
||||
});
|
||||
|
||||
it('renders discussions count', () => {
|
||||
const discussionsEl = wrapper.find('[data-testid="issuable-discussions"]');
|
||||
|
||||
expect(discussionsEl.exists()).toBe(true);
|
||||
expect(discussionsEl.find(GlLink).attributes()).toMatchObject({
|
||||
title: 'Comments',
|
||||
href: `${mockIssuable.webUrl}#notes`,
|
||||
});
|
||||
expect(discussionsEl.find(GlIcon).props('name')).toBe('comments');
|
||||
expect(discussionsEl.find(GlLink).text()).toContain('2');
|
||||
});
|
||||
|
||||
it('renders issuable-assignees component', () => {
|
||||
const assigneesEl = wrapper.find(IssuableAssignees);
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ export const mockIssuable = {
|
|||
nodes: mockLabels,
|
||||
},
|
||||
assignees: [mockAuthor],
|
||||
userDiscussionsCount: 2,
|
||||
};
|
||||
|
||||
export const mockIssuables = [
|
||||
|
|
|
@ -45,6 +45,7 @@ function createComponent(options = {}) {
|
|||
provide: {
|
||||
portalName: 'fake target',
|
||||
alignSuggestions: function fakeAlignSuggestions() {},
|
||||
suggestionsListClass: 'custom-class',
|
||||
},
|
||||
stubs,
|
||||
});
|
||||
|
|
|
@ -45,6 +45,7 @@ function createComponent(options = {}) {
|
|||
provide: {
|
||||
portalName: 'fake target',
|
||||
alignSuggestions: function fakeAlignSuggestions() {},
|
||||
suggestionsListClass: 'custom-class',
|
||||
},
|
||||
stubs,
|
||||
});
|
||||
|
|
|
@ -50,6 +50,7 @@ function createComponent(options = {}) {
|
|||
provide: {
|
||||
portalName: 'fake target',
|
||||
alignSuggestions: function fakeAlignSuggestions() {},
|
||||
suggestionsListClass: 'custom-class',
|
||||
},
|
||||
stubs,
|
||||
});
|
||||
|
|
|
@ -48,6 +48,7 @@ function createComponent(options = {}) {
|
|||
provide: {
|
||||
portalName: 'fake target',
|
||||
alignSuggestions: function fakeAlignSuggestions() {},
|
||||
suggestionsListClass: 'custom-class',
|
||||
},
|
||||
stubs,
|
||||
});
|
||||
|
|
|
@ -135,30 +135,14 @@ RSpec.describe Ci::BuildTraceChunk, :clean_gitlab_redis_shared_state do
|
|||
context 'when data_store is fog' do
|
||||
let(:data_store) { :fog }
|
||||
|
||||
context 'when legacy Fog is enabled' do
|
||||
before do
|
||||
stub_feature_flags(ci_trace_new_fog_store: false)
|
||||
build_trace_chunk.send(:unsafe_set_data!, +'Sample data in fog')
|
||||
end
|
||||
|
||||
it { is_expected.to eq('Sample data in fog') }
|
||||
|
||||
it 'returns a LegacyFog store' do
|
||||
expect(described_class.get_store_class(data_store)).to be_a(Ci::BuildTraceChunks::LegacyFog)
|
||||
end
|
||||
before do
|
||||
build_trace_chunk.send(:unsafe_set_data!, +'Sample data in fog')
|
||||
end
|
||||
|
||||
context 'when new Fog is enabled' do
|
||||
before do
|
||||
stub_feature_flags(ci_trace_new_fog_store: true)
|
||||
build_trace_chunk.send(:unsafe_set_data!, +'Sample data in fog')
|
||||
end
|
||||
it { is_expected.to eq('Sample data in fog') }
|
||||
|
||||
it { is_expected.to eq('Sample data in fog') }
|
||||
|
||||
it 'returns a new Fog store' do
|
||||
expect(described_class.get_store_class(data_store)).to be_a(Ci::BuildTraceChunks::Fog)
|
||||
end
|
||||
it 'returns a new Fog store' do
|
||||
expect(described_class.get_store_class(data_store)).to be_a(Ci::BuildTraceChunks::Fog)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,164 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Ci::BuildTraceChunks::LegacyFog do
|
||||
let(:data_store) { described_class.new }
|
||||
|
||||
before do
|
||||
stub_artifacts_object_storage
|
||||
end
|
||||
|
||||
describe '#available?' do
|
||||
subject { data_store.available? }
|
||||
|
||||
context 'when object storage is enabled' do
|
||||
it { is_expected.to be_truthy }
|
||||
end
|
||||
|
||||
context 'when object storage is disabled' do
|
||||
before do
|
||||
stub_artifacts_object_storage(enabled: false)
|
||||
end
|
||||
|
||||
it { is_expected.to be_falsy }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#data' do
|
||||
subject { data_store.data(model) }
|
||||
|
||||
context 'when data exists' do
|
||||
let(:model) { create(:ci_build_trace_chunk, :fog_with_data, initial_data: 'sample data in fog') }
|
||||
|
||||
it 'returns the data' do
|
||||
is_expected.to eq('sample data in fog')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when data does not exist' do
|
||||
let(:model) { create(:ci_build_trace_chunk, :fog_without_data) }
|
||||
|
||||
it 'returns nil' do
|
||||
expect(data_store.data(model)).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#set_data' do
|
||||
let(:new_data) { 'abc123' }
|
||||
|
||||
context 'when data exists' do
|
||||
let(:model) { create(:ci_build_trace_chunk, :fog_with_data, initial_data: 'sample data in fog') }
|
||||
|
||||
it 'overwrites data' do
|
||||
expect(data_store.data(model)).to eq('sample data in fog')
|
||||
|
||||
data_store.set_data(model, new_data)
|
||||
|
||||
expect(data_store.data(model)).to eq new_data
|
||||
end
|
||||
end
|
||||
|
||||
context 'when data does not exist' do
|
||||
let(:model) { create(:ci_build_trace_chunk, :fog_without_data) }
|
||||
|
||||
it 'sets new data' do
|
||||
expect(data_store.data(model)).to be_nil
|
||||
|
||||
data_store.set_data(model, new_data)
|
||||
|
||||
expect(data_store.data(model)).to eq new_data
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#delete_data' do
|
||||
subject { data_store.delete_data(model) }
|
||||
|
||||
context 'when data exists' do
|
||||
let(:model) { create(:ci_build_trace_chunk, :fog_with_data, initial_data: 'sample data in fog') }
|
||||
|
||||
it 'deletes data' do
|
||||
expect(data_store.data(model)).to eq('sample data in fog')
|
||||
|
||||
subject
|
||||
|
||||
expect(data_store.data(model)).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when data does not exist' do
|
||||
let(:model) { create(:ci_build_trace_chunk, :fog_without_data) }
|
||||
|
||||
it 'does nothing' do
|
||||
expect(data_store.data(model)).to be_nil
|
||||
|
||||
subject
|
||||
|
||||
expect(data_store.data(model)).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#size' do
|
||||
context 'when data exists' do
|
||||
let(:model) { create(:ci_build_trace_chunk, :fog_with_data, initial_data: 'üabcd') }
|
||||
|
||||
it 'returns data bytesize correctly' do
|
||||
expect(data_store.size(model)).to eq 6
|
||||
end
|
||||
end
|
||||
|
||||
context 'when data does not exist' do
|
||||
let(:model) { create(:ci_build_trace_chunk, :fog_without_data) }
|
||||
|
||||
it 'returns zero' do
|
||||
expect(data_store.size(model)).to be_zero
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#keys' do
|
||||
subject { data_store.keys(relation) }
|
||||
|
||||
let(:build) { create(:ci_build) }
|
||||
let(:relation) { build.trace_chunks }
|
||||
|
||||
before do
|
||||
create(:ci_build_trace_chunk, :fog_with_data, chunk_index: 0, build: build)
|
||||
create(:ci_build_trace_chunk, :fog_with_data, chunk_index: 1, build: build)
|
||||
end
|
||||
|
||||
it 'returns keys' do
|
||||
is_expected.to eq([[build.id, 0], [build.id, 1]])
|
||||
end
|
||||
end
|
||||
|
||||
describe '#delete_keys' do
|
||||
subject { data_store.delete_keys(keys) }
|
||||
|
||||
let(:build) { create(:ci_build) }
|
||||
let(:relation) { build.trace_chunks }
|
||||
let(:keys) { data_store.keys(relation) }
|
||||
|
||||
before do
|
||||
create(:ci_build_trace_chunk, :fog_with_data, chunk_index: 0, build: build)
|
||||
create(:ci_build_trace_chunk, :fog_with_data, chunk_index: 1, build: build)
|
||||
end
|
||||
|
||||
it 'deletes multiple data' do
|
||||
::Fog::Storage.new(JobArtifactUploader.object_store_credentials).tap do |connection|
|
||||
expect(connection.get_object('artifacts', "tmp/builds/#{build.id}/chunks/0.log")[:body]).to be_present
|
||||
expect(connection.get_object('artifacts', "tmp/builds/#{build.id}/chunks/1.log")[:body]).to be_present
|
||||
end
|
||||
|
||||
subject
|
||||
|
||||
::Fog::Storage.new(JobArtifactUploader.object_store_credentials).tap do |connection|
|
||||
expect { connection.get_object('artifacts', "tmp/builds/#{build.id}/chunks/0.log")[:body] }.to raise_error(Excon::Error::NotFound)
|
||||
expect { connection.get_object('artifacts', "tmp/builds/#{build.id}/chunks/1.log")[:body] }.to raise_error(Excon::Error::NotFound)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -866,10 +866,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.175.0.tgz#734f341784af1cd1d62d160a17bcdfb61ff7b04d"
|
||||
integrity sha512-gXpc87TGSXIzfAr4QER1Qw1v3P47pBO6BXkma52blgwXVmcFNe3nhQzqsqt66wKNzrIrk3lAcB4GUyPHbPVXpg==
|
||||
|
||||
"@gitlab/ui@23.6.1":
|
||||
version "23.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-23.6.1.tgz#3b94945166c756a26c9598501ebef0997a3961e7"
|
||||
integrity sha512-jOEhJUTQmdsV4XEHqY+ray+GHAMa35CsddPFtKjiD8y1YiJFzXES7tVqQr/hXzSAWbBWfxSO1Rvp55+UnCGz5g==
|
||||
"@gitlab/ui@23.8.0":
|
||||
version "23.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-23.8.0.tgz#fe1807877c191e9e38b476d2cdfc4261facbb36b"
|
||||
integrity sha512-5CF2jU/d5EX5a1qLHzJujYOTaCze1ZvE9ovK1TbhJ7Va1O0SKB/N53XT8iPOb4MwOzj/zBWDOdsIs+xXxCeOcg==
|
||||
dependencies:
|
||||
"@babel/standalone" "^7.0.0"
|
||||
"@gitlab/vue-toasted" "^1.3.0"
|
||||
|
|
Loading…
Reference in New Issue