Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
a8704bd33c
commit
3172281335
|
@ -99,7 +99,7 @@ In which enterprise tier should this feature go? See https://about.gitlab.com/ha
|
|||
<!-- Label reminders - you should have one of each of the following labels.
|
||||
Use the following resources to find the appropriate labels:
|
||||
- https://gitlab.com/gitlab-org/gitlab/-/labels
|
||||
- https://about.gitlab.com/handbook/product/product-categories/features/
|
||||
- https://about.gitlab.com/handbook/product/categories/features/
|
||||
-->
|
||||
/label ~devops:: ~group: ~Category:
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
<!--- Use the following resources to find the appropriate labels:
|
||||
- https://gitlab.com/gitlab-org/gitlab/-/labels
|
||||
- https://about.gitlab.com/handbook/product/product-categories/features/
|
||||
- https://about.gitlab.com/handbook/product/categories/features/
|
||||
|
||||
Consider adding related issues and epics to this issue. You can also reference the Feature Proposal Template (https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/issue_templates/Feature%20proposal.md) for additional details to consider adding to this issue. Additionally, as a data oriented organization, when your feature exits planning breakdown, consider adding the `What does success look like, and how can we measure that?` section.
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ We generally recommend events be tracked using a [structured event](https://docs
|
|||
<!-- Label reminders - you should have one of each of the following labels.
|
||||
Use the following resources to find the appropriate labels:
|
||||
- https://gitlab.com/gitlab-org/gitlab/-/labels
|
||||
- https://about.gitlab.com/handbook/product/product-categories/features/
|
||||
- https://about.gitlab.com/handbook/product/categories/features/
|
||||
-->
|
||||
/label ~devops:: ~group: ~Category:
|
||||
/label ~"snowplow tracking events"
|
||||
|
|
4
Gemfile
4
Gemfile
|
@ -372,7 +372,7 @@ group :development, :test do
|
|||
gem 'spring', '~> 2.1.0'
|
||||
gem 'spring-commands-rspec', '~> 1.0.4'
|
||||
|
||||
gem 'gitlab-styles', '~> 5.2.0', require: false
|
||||
gem 'gitlab-styles', '~> 5.3.0', require: false
|
||||
|
||||
gem 'scss_lint', '~> 0.59.0', require: false
|
||||
gem 'haml_lint', '~> 0.36.0', require: false
|
||||
|
@ -430,7 +430,7 @@ end
|
|||
gem 'octokit', '~> 4.15'
|
||||
|
||||
# https://gitlab.com/gitlab-org/gitlab/issues/207207
|
||||
gem 'gitlab-mail_room', '~> 0.0.7', require: 'mail_room'
|
||||
gem 'gitlab-mail_room', '~> 0.0.8', require: 'mail_room'
|
||||
|
||||
gem 'email_reply_trimmer', '~> 0.1'
|
||||
gem 'html2text'
|
||||
|
|
|
@ -446,7 +446,7 @@ GEM
|
|||
opentracing (~> 0.4)
|
||||
redis (> 3.0.0, < 5.0.0)
|
||||
gitlab-license (1.0.0)
|
||||
gitlab-mail_room (0.0.7)
|
||||
gitlab-mail_room (0.0.8)
|
||||
gitlab-markup (1.7.1)
|
||||
gitlab-net-dns (0.9.1)
|
||||
gitlab-pg_query (1.3.0)
|
||||
|
@ -457,7 +457,7 @@ GEM
|
|||
gitlab-puma (>= 2.7, < 5)
|
||||
gitlab-sidekiq-fetcher (0.5.2)
|
||||
sidekiq (~> 5)
|
||||
gitlab-styles (5.2.0)
|
||||
gitlab-styles (5.3.0)
|
||||
rubocop (~> 0.89.1)
|
||||
rubocop-gitlab-security (~> 0.1.0)
|
||||
rubocop-performance (~> 1.8.1)
|
||||
|
@ -1361,14 +1361,14 @@ DEPENDENCIES
|
|||
gitlab-fog-azure-rm (~> 1.0)
|
||||
gitlab-labkit (= 0.13.3)
|
||||
gitlab-license (~> 1.0)
|
||||
gitlab-mail_room (~> 0.0.7)
|
||||
gitlab-mail_room (~> 0.0.8)
|
||||
gitlab-markup (~> 1.7.1)
|
||||
gitlab-net-dns (~> 0.9.1)
|
||||
gitlab-pg_query (~> 1.3)
|
||||
gitlab-puma (~> 4.3.3.gitlab.2)
|
||||
gitlab-puma_worker_killer (~> 0.1.1.gitlab.1)
|
||||
gitlab-sidekiq-fetcher (= 0.5.2)
|
||||
gitlab-styles (~> 5.2.0)
|
||||
gitlab-styles (~> 5.3.0)
|
||||
gitlab_chronic_duration (~> 0.10.6.2)
|
||||
gitlab_omniauth-ldap (~> 2.1.1)
|
||||
gon (~> 6.2)
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
GlTabs,
|
||||
GlTab,
|
||||
GlBadge,
|
||||
GlAlert,
|
||||
} from '@gitlab/ui';
|
||||
import { sprintf, __ } from '../../../locale';
|
||||
import CiIcon from '../../../vue_shared/components/ci_icon.vue';
|
||||
|
@ -26,6 +27,7 @@ export default {
|
|||
GlTabs,
|
||||
GlTab,
|
||||
GlBadge,
|
||||
GlAlert,
|
||||
},
|
||||
directives: {
|
||||
SafeHtml,
|
||||
|
@ -89,11 +91,16 @@ export default {
|
|||
:can-set-ci="true"
|
||||
class="mb-auto mt-auto"
|
||||
/>
|
||||
<div v-else-if="latestPipeline.yamlError" class="bs-callout bs-callout-danger">
|
||||
<gl-alert
|
||||
v-else-if="latestPipeline.yamlError"
|
||||
variant="danger"
|
||||
:dismissible="false"
|
||||
class="gl-mt-5"
|
||||
>
|
||||
<p class="gl-mb-0">{{ __('Found errors in your .gitlab-ci.yml:') }}</p>
|
||||
<p class="gl-mb-0 break-word">{{ latestPipeline.yamlError }}</p>
|
||||
<p v-safe-html="ciLintText" class="gl-mb-0"></p>
|
||||
</div>
|
||||
</gl-alert>
|
||||
<gl-tabs v-else>
|
||||
<gl-tab :active="!pipelineFailed">
|
||||
<template #title>
|
||||
|
|
|
@ -150,7 +150,7 @@ export default {
|
|||
// Dispatch event which updates open/close state, shared among the issue show page
|
||||
document.dispatchEvent(new CustomEvent('issuable_vue_app:change', payload));
|
||||
})
|
||||
.catch(() => createFlash({ message: __('Update failed. Please try again.') }))
|
||||
.catch(() => createFlash({ message: __('Error occurred while updating the issue status') }))
|
||||
.finally(() => {
|
||||
this.toggleStateButtonLoading(false);
|
||||
});
|
||||
|
@ -192,22 +192,19 @@ export default {
|
|||
|
||||
<template>
|
||||
<div class="detail-page-header-actions">
|
||||
<gl-dropdown class="gl-display-block gl-display-sm-none!" block :text="dropdownText">
|
||||
<gl-dropdown-item
|
||||
v-if="showToggleIssueStateButton"
|
||||
:disabled="isToggleStateButtonLoading"
|
||||
@click="toggleIssueState"
|
||||
>
|
||||
<gl-dropdown
|
||||
class="gl-display-block gl-display-sm-none!"
|
||||
block
|
||||
:text="dropdownText"
|
||||
:loading="isToggleStateButtonLoading"
|
||||
>
|
||||
<gl-dropdown-item v-if="showToggleIssueStateButton" @click="toggleIssueState">
|
||||
{{ buttonText }}
|
||||
</gl-dropdown-item>
|
||||
<gl-dropdown-item v-if="canCreateIssue" :href="newIssuePath">
|
||||
{{ newIssueTypeText }}
|
||||
</gl-dropdown-item>
|
||||
<gl-dropdown-item
|
||||
v-if="canPromoteToEpic"
|
||||
:disabled="isToggleStateButtonLoading"
|
||||
@click="promoteToEpic"
|
||||
>
|
||||
<gl-dropdown-item v-if="canPromoteToEpic" @click="promoteToEpic">
|
||||
{{ __('Promote to epic') }}
|
||||
</gl-dropdown-item>
|
||||
<gl-dropdown-item v-if="!isIssueAuthor" :href="reportAbusePath">
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import { s__ } from '~/locale';
|
||||
|
||||
export default {
|
||||
sample: {
|
||||
text: s__('ProjectTemplates|Sample GitLab Project'),
|
||||
icon: '.template-option .icon-sample',
|
||||
},
|
||||
rails: {
|
||||
text: s__('ProjectTemplates|Ruby on Rails'),
|
||||
icon: '.template-option .icon-rails',
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
import { s__ } from '~/locale';
|
||||
|
||||
export default {
|
||||
basic: {
|
||||
text: s__('ProjectTemplates|Basic'),
|
||||
icon: '.template-option .icon-basic',
|
||||
},
|
||||
serenity_valley: {
|
||||
text: s__('ProjectTemplates|Serenity Valley'),
|
||||
icon: '.template-option .icon-serenity_valley',
|
||||
},
|
||||
};
|
|
@ -1,6 +1,5 @@
|
|||
import $ from 'jquery';
|
||||
import DEFAULT_PROJECT_TEMPLATES from 'ee_else_ce/projects/default_project_templates';
|
||||
import DEFAULT_SAMPLE_DATA_TEMPLATES from '~/projects/default_sample_data_templates';
|
||||
import { addSelectOnFocusBehaviour } from '../lib/utils/common_utils';
|
||||
import {
|
||||
convertToTitleCase,
|
||||
|
@ -150,8 +149,7 @@ const bindEvents = () => {
|
|||
$selectedIcon.empty();
|
||||
const value = $(this).val();
|
||||
|
||||
const selectedTemplate =
|
||||
DEFAULT_PROJECT_TEMPLATES[value] || DEFAULT_SAMPLE_DATA_TEMPLATES[value];
|
||||
const selectedTemplate = DEFAULT_PROJECT_TEMPLATES[value];
|
||||
$selectedTemplateText.text(selectedTemplate.text);
|
||||
$(selectedTemplate.icon)
|
||||
.clone()
|
||||
|
|
|
@ -30,8 +30,9 @@
|
|||
}
|
||||
|
||||
//// Copied from roadmaps.scss - adapted for on-call schedules
|
||||
$header-item-height: 60px;
|
||||
$details-cell-width: px-to-rem(150px);
|
||||
$header-item-height: 72px;
|
||||
$item-height: 40px;
|
||||
$details-cell-width: 150px;
|
||||
$timeline-cell-height: 32px;
|
||||
$timeline-cell-width: 180px;
|
||||
$border-style: 1px solid var(--gray-100, $gray-100);
|
||||
|
@ -40,7 +41,6 @@ $gradient-gray: rgba(255, 255, 255, 0.001);
|
|||
$scroll-top-gradient: linear-gradient(to bottom, $gradient-dark-gray 0%, $gradient-gray 100%);
|
||||
$scroll-bottom-gradient: linear-gradient(to bottom, $gradient-gray 0%, $gradient-dark-gray 100%);
|
||||
$column-right-gradient: linear-gradient(to right, $gradient-dark-gray 0%, $gradient-gray 100%);
|
||||
$epic-details-cell-width: 150px;
|
||||
|
||||
.schedule-shell {
|
||||
@include gl-relative;
|
||||
|
@ -55,7 +55,6 @@ $epic-details-cell-width: 150px;
|
|||
|
||||
.timeline-section {
|
||||
@include gl-sticky;
|
||||
position: -webkit-sticky;
|
||||
@include gl-top-0;
|
||||
z-index: 20;
|
||||
|
||||
|
@ -69,27 +68,15 @@ $epic-details-cell-width: 150px;
|
|||
|
||||
.timeline-header-blank {
|
||||
@include gl-sticky;
|
||||
position: -webkit-sticky;
|
||||
@include gl-top-0;
|
||||
@include gl-left-0;
|
||||
width: $details-cell-width;
|
||||
z-index: 2;
|
||||
|
||||
&::after {
|
||||
height: $header-item-height;
|
||||
@include gl-content-empty;
|
||||
@include gl-absolute;
|
||||
@include gl-top-0;
|
||||
right: -$grid-size;
|
||||
width: $grid-size;
|
||||
@include gl-pointer-events-none;
|
||||
background: $column-right-gradient;
|
||||
}
|
||||
}
|
||||
|
||||
.timeline-header-item {
|
||||
// container size minus left panel width divided by 2 week timeframes
|
||||
width: calc((100% - #{$epic-details-cell-width}) / 2);
|
||||
width: calc((100% - #{$details-cell-width}) / 2);
|
||||
|
||||
&:last-of-type .item-label {
|
||||
@include gl-border-r-0;
|
||||
|
@ -110,7 +97,8 @@ $epic-details-cell-width: 150px;
|
|||
}
|
||||
|
||||
.item-label {
|
||||
padding: $gl-padding-8 $gl-padding;
|
||||
@include gl-py-4;
|
||||
@include gl-pl-7;
|
||||
border-right: $border-style;
|
||||
border-bottom: $border-style;
|
||||
}
|
||||
|
@ -124,19 +112,72 @@ $epic-details-cell-width: 150px;
|
|||
@include gl-flex-basis-0;
|
||||
|
||||
text-align: center;
|
||||
font-size: $code-font-size;
|
||||
line-height: 1.5;
|
||||
@include gl-font-base;
|
||||
padding: 2px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.current-day-indicator-header {
|
||||
@include gl-absolute;
|
||||
@include gl-bottom-0;
|
||||
height: $gl-vert-padding;
|
||||
width: $gl-vert-padding;
|
||||
height: $grid-size;
|
||||
width: $grid-size;
|
||||
background-color: var(--red-500, $red-500);
|
||||
border-radius: 50%;
|
||||
transform: translateX(-3px);
|
||||
@include gl-rounded-full;
|
||||
transform: translate(-50%, 50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.timeline-section .timeline-header-blank,
|
||||
.list-section .details-cell {
|
||||
&::after {
|
||||
@include gl-h-full;
|
||||
@include gl-content-empty;
|
||||
@include gl-absolute;
|
||||
@include gl-top-0;
|
||||
right: -$grid-size;
|
||||
width: $grid-size;
|
||||
@include gl-pointer-events-none;
|
||||
background: $column-right-gradient;
|
||||
}
|
||||
}
|
||||
|
||||
.details-cell,
|
||||
.timeline-cell {
|
||||
@include float-left;
|
||||
height: $item-height;
|
||||
border-bottom: $border-style;
|
||||
}
|
||||
|
||||
.details-cell {
|
||||
@include gl-sticky;
|
||||
@include gl-left-0;
|
||||
width: $details-cell-width;
|
||||
@include gl-font-base;
|
||||
background-color: var(--white, $white);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.timeline-cell {
|
||||
@include gl-relative;
|
||||
// width: $timeline-cell-width;
|
||||
// container size minus left panel width divided by 2 week timeframes
|
||||
width: calc((100% - #{$details-cell-width}) / 2);
|
||||
@include gl-bg-transparent;
|
||||
border-right: $border-style;
|
||||
|
||||
&:last-child {
|
||||
@include gl-border-r-0;
|
||||
}
|
||||
|
||||
.current-day-indicator {
|
||||
@include gl-absolute;
|
||||
top: -1px;
|
||||
width: $gl-spacing-scale-1;
|
||||
height: calc(100% + 1px);
|
||||
background-color: var(--red-500, $red-500);
|
||||
@include gl-pointer-events-none;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Profiles::KeysController < Profiles::ApplicationController
|
||||
skip_before_action :authenticate_user!, only: [:get_keys]
|
||||
|
||||
feature_category :users
|
||||
|
||||
def index
|
||||
|
@ -35,25 +33,6 @@ class Profiles::KeysController < Profiles::ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
# Get all keys of a user(params[:username]) in a text format
|
||||
# Helpful for sysadmins to put in respective servers
|
||||
def get_keys
|
||||
if params[:username].present?
|
||||
begin
|
||||
user = UserFinder.new(params[:username]).find_by_username
|
||||
if user.present?
|
||||
render plain: user.all_ssh_keys.join("\n")
|
||||
else
|
||||
render_404
|
||||
end
|
||||
rescue => e
|
||||
render html: e.message
|
||||
end
|
||||
else
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def key_params
|
||||
|
|
|
@ -40,7 +40,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
|
|||
push_frontend_feature_flag(:default_merge_ref_for_diffs, @project)
|
||||
push_frontend_feature_flag(:core_security_mr_widget, @project, default_enabled: true)
|
||||
push_frontend_feature_flag(:core_security_mr_widget_counts, @project)
|
||||
push_frontend_feature_flag(:core_security_mr_widget_downloads, @project)
|
||||
push_frontend_feature_flag(:core_security_mr_widget_downloads, @project, default_enabled: true)
|
||||
push_frontend_feature_flag(:remove_resolve_note, @project, default_enabled: true)
|
||||
push_frontend_feature_flag(:test_failure_history, @project)
|
||||
push_frontend_feature_flag(:diffs_gradual_load, @project)
|
||||
|
|
|
@ -41,6 +41,12 @@ class UsersController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
# Get all keys of a user(params[:username]) in a text format
|
||||
# Helpful for sysadmins to put in respective servers
|
||||
def ssh_keys
|
||||
render plain: user.all_ssh_keys.join("\n")
|
||||
end
|
||||
|
||||
def activity
|
||||
respond_to do |format|
|
||||
format.html { render 'show' }
|
||||
|
|
|
@ -80,9 +80,9 @@ module IconsHelper
|
|||
|
||||
def boolean_to_icon(value)
|
||||
if value
|
||||
sprite_icon('check', css_class: 'cgreen')
|
||||
sprite_icon('check', css_class: 'gl-text-green-500')
|
||||
else
|
||||
sprite_icon('power', css_class: 'clgray')
|
||||
sprite_icon('power', css_class: 'gl-text-gray-500')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -722,6 +722,7 @@ class User < ApplicationRecord
|
|||
u.name = 'GitLab Security Bot'
|
||||
u.website_url = Gitlab::Routing.url_helpers.help_page_url('user/application_security/security_bot/index.md')
|
||||
u.avatar = bot_avatar(image: 'security-bot.png')
|
||||
u.confirmed_at = Time.zone.now
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -25,6 +25,10 @@ class BasePolicy < DeclarativePolicy::Base
|
|||
with_options scope: :user, score: 0
|
||||
condition(:support_bot) { @user&.support_bot? }
|
||||
|
||||
desc "User is security bot"
|
||||
with_options scope: :user, score: 0
|
||||
condition(:security_bot) { @user&.security_bot? }
|
||||
|
||||
desc "User email is unconfirmed or user account is locked"
|
||||
with_options scope: :user, score: 0
|
||||
condition(:inactive) { @user&.confirmation_required_on_sign_in? || @user&.access_locked? }
|
||||
|
|
|
@ -49,6 +49,10 @@ module PolicyActor
|
|||
false
|
||||
end
|
||||
|
||||
def security_bot?
|
||||
false
|
||||
end
|
||||
|
||||
def deactivated?
|
||||
false
|
||||
end
|
||||
|
|
|
@ -48,7 +48,7 @@ class GlobalPolicy < BasePolicy
|
|||
prevent :use_slash_commands
|
||||
end
|
||||
|
||||
rule { blocked | (internal & ~migration_bot) }.policy do
|
||||
rule { blocked | (internal & ~migration_bot & ~security_bot) }.policy do
|
||||
prevent :access_git
|
||||
end
|
||||
|
||||
|
|
|
@ -75,3 +75,5 @@ class PipelineSerializer < BaseSerializer
|
|||
]
|
||||
end
|
||||
end
|
||||
|
||||
PipelineSerializer.prepend_if_ee('EE::PipelineSerializer')
|
||||
|
|
|
@ -5,17 +5,11 @@
|
|||
%li.built-in-tab
|
||||
%a.nav-link.active{ href: "#built-in", data: { toggle: 'tab'} }
|
||||
= _('Built-in')
|
||||
%span.badge.badge-pill= Gitlab::ProjectTemplate.all.count
|
||||
%li.sample-data-templates-tab
|
||||
%a.nav-link{ href: "#sample-data-templates", data: { toggle: 'tab'} }
|
||||
= _('Sample Data')
|
||||
%span.badge.badge-pill= Gitlab::SampleDataTemplate.all.count
|
||||
%span.badge.badge-pill= Gitlab::SampleDataTemplate.all.count + Gitlab::ProjectTemplate.all.count
|
||||
|
||||
.tab-content
|
||||
.project-templates-buttons.import-buttons.tab-pane.active#built-in
|
||||
= render partial: 'projects/project_templates/template', collection: Gitlab::ProjectTemplate.all
|
||||
.project-templates-buttons.import-buttons.tab-pane#sample-data-templates
|
||||
= render partial: 'projects/project_templates/template', collection: Gitlab::SampleDataTemplate.all
|
||||
= render partial: 'projects/project_templates/template', collection: Gitlab::SampleDataTemplate.all + Gitlab::ProjectTemplate.all
|
||||
|
||||
.project-fields-form
|
||||
= render 'projects/project_templates/project_fields_form'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
%table.table.b-table.gl-table.mt-3{ role: 'table', 'aria-busy': false, 'aria-colcount': 4 }
|
||||
%table.table.b-table.gl-table{ role: 'table', 'aria-busy': false, 'aria-colcount': 4 }
|
||||
%colgroup
|
||||
%col
|
||||
%col
|
||||
|
@ -15,11 +15,10 @@
|
|||
- integrations.each do |integration|
|
||||
- activated_label = (integration.activated? ? s_("ProjectService|%{service_title}: status on") : s_("ProjectService|%{service_title}: status off")) % { service_title: integration.title }
|
||||
%tr{ role: 'row' }
|
||||
%td{ role: 'cell', 'aria-colindex': 1, 'aria-label': activated_label }
|
||||
%td{ role: 'cell', 'aria-colindex': 1, 'aria-label': activated_label, title: activated_label }
|
||||
= boolean_to_icon integration.operating?
|
||||
%td{ role: 'cell', 'aria-colindex': 2 }
|
||||
= link_to scoped_edit_integration_path(integration), { data: { qa_selector: "#{integration.to_param}_link" } } do
|
||||
%strong= integration.title
|
||||
= link_to integration.title, scoped_edit_integration_path(integration), class: 'gl-font-weight-bold', data: { qa_selector: "#{integration.to_param}_link" }
|
||||
%td.d-none.d-sm-table-cell{ role: 'cell', 'aria-colindex': 3 }
|
||||
= integration.description
|
||||
%td{ role: 'cell', 'aria-colindex': 4 }
|
||||
|
|
|
@ -15,6 +15,7 @@ class PurgeDependencyProxyCacheWorker
|
|||
return unless valid?
|
||||
|
||||
@group.dependency_proxy_blobs.destroy_all # rubocop:disable Cop/DestroyAll
|
||||
@group.dependency_proxy_manifests.destroy_all # rubocop:disable Cop/DestroyAll
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Delete manifests when purging the dependency proxy using the API
|
||||
merge_request: 49056
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Update ide pipeline alert to use gitlab ui
|
||||
merge_request: 49634
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Allow downloading of security reports directly from merge request page
|
||||
merge_request: 49572
|
||||
author:
|
||||
type: added
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add issue header mobile dropdown loading state
|
||||
merge_request: 49734
|
||||
author:
|
||||
type: added
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Merge 'Sample Data' and 'Built-in' tabs on Project Templates page
|
||||
merge_request: 49374
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Use GitLab UI styles on Integrations page
|
||||
merge_request: 47478
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Move profiles/keys#get_keys to users#ssh_keys
|
||||
merge_request: 48991
|
||||
author: Takuya Noguchi
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Upgrade mailroom to v0.0.8
|
||||
merge_request: 49834
|
||||
author:
|
||||
type: fixed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Improve the performance of the diff change access check
|
||||
merge_request: 49803
|
||||
author:
|
||||
type: performance
|
|
@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/273418
|
|||
milestone: '13.7'
|
||||
type: development
|
||||
group: group::static analysis
|
||||
default_enabled: false
|
||||
default_enabled: true
|
||||
|
|
|
@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/288827
|
|||
milestone: '13.7'
|
||||
type: development
|
||||
group: group::code review
|
||||
default_enabled: false
|
||||
default_enabled: true
|
||||
|
|
|
@ -55,7 +55,7 @@ end
|
|||
|
||||
constraints(::Constraints::UserUrlConstrainer.new) do
|
||||
# Get all SSH keys of user
|
||||
get ':username.keys' => 'profiles/keys#get_keys', constraints: { username: Gitlab::PathRegex.root_namespace_route_regex }
|
||||
get ':username.keys' => 'users#ssh_keys', constraints: { username: Gitlab::PathRegex.root_namespace_route_regex }
|
||||
|
||||
# Get all GPG keys of user
|
||||
get ':username.gpg' => 'profiles/gpg_keys#get_keys', constraints: { username: Gitlab::PathRegex.root_namespace_route_regex }
|
||||
|
|
|
@ -11,7 +11,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11631) in GitLab 12.10.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/273655) to [GitLab Core](https://about.gitlab.com/pricing/) in GitLab 13.6.
|
||||
|
||||
Deletes the cached blobs for a group. This endpoint requires group admin access.
|
||||
Deletes the cached manifests and blobs for a group. This endpoint requires group admin access.
|
||||
|
||||
WARNING:
|
||||
[A bug exists](https://gitlab.com/gitlab-org/gitlab/-/issues/277161) for this API.
|
||||
|
|
|
@ -29,8 +29,8 @@ This page is a development guide for application secrets.
|
|||
## Warning: Before you add a new secret to application secrets
|
||||
|
||||
Before you add a new secret to [`config/initializers/01_secret_token.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/initializers/01_secret_token.rb),
|
||||
make sure you also update Omnibus GitLab or updates will fail. Omnibus is responsible for writing the `secrets.yml` file.
|
||||
If Omnibus doesn't know about a secret, Rails will attempt to write to the file, but this will fail because Rails doesn't have write access.
|
||||
make sure you also update Omnibus GitLab or updates fail. Omnibus is responsible for writing the `secrets.yml` file.
|
||||
If Omnibus doesn't know about a secret, Rails attempts to write to the file, but this fails because Rails doesn't have write access.
|
||||
The same rules apply to Cloud Native GitLab charts, you must update the charts at first.
|
||||
In case you need the secret to have same value on each node (which is usually the case) you need to make sure it's configured for all
|
||||
GitLab.com environments prior to changing this file.
|
||||
|
@ -44,5 +44,5 @@ GitLab.com environments prior to changing this file.
|
|||
|
||||
## Further iteration
|
||||
|
||||
We might deprecate/remove this automatic secret generation '01_secret_token.rb' in the future.
|
||||
Please see [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/222690) for more information.
|
||||
We may either deprecate or remove this automatic secret generation `01_secret_token.rb` in the future.
|
||||
Please see [issue 222690](https://gitlab.com/gitlab-org/gitlab/-/issues/222690) for more information.
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
As [Werner Vogels](https://twitter.com/Werner), the CTO at Amazon Web Services, famously put it, **Everything fails, all the time**.
|
||||
|
||||
As a developer, it's as important to consider the failure modes in which your software will operate as much as normal operation. Doing so can mean the difference between a minor hiccup leading to a scattering of `500` errors experienced by a tiny fraction of users and a full site outage that affects all users for an extended period.
|
||||
As a developer, it's as important to consider the failure modes in which your software may operate as much as normal operation. Doing so can mean the difference between a minor hiccup leading to a scattering of `500` errors experienced by a tiny fraction of users, and a full site outage that affects all users for an extended period.
|
||||
|
||||
To paraphrase [Tolstoy](https://en.wikipedia.org/wiki/Anna_Karenina_principle), _all happy servers are alike, but all failing servers are failing in their own way_. Luckily, there are ways we can attempt to simulate these failure modes, and the chaos endpoints are tools for assisting in this process.
|
||||
|
||||
|
@ -40,17 +40,17 @@ Replace `secret` with your own secret token.
|
|||
|
||||
## Invoking chaos
|
||||
|
||||
Once you have enabled the chaos endpoints and restarted the application, you can start testing using the endpoints.
|
||||
After you have enabled the chaos endpoints and restarted the application, you can start testing using the endpoints.
|
||||
|
||||
By default, when invoking a chaos endpoint, the web worker process which receives the request will handle it. This means, for example, that if the Kill
|
||||
operation is invoked, the Puma or Unicorn worker process handling the request will be killed. To test these operations in Sidekiq, the `async` parameter on
|
||||
each endpoint can be set to `true`. This will run the chaos process in a Sidekiq worker.
|
||||
By default, when invoking a chaos endpoint, the web worker process which receives the request handles it. This means, for example, that if the Kill
|
||||
operation is invoked, the Puma or Unicorn worker process handling the request is killed. To test these operations in Sidekiq, the `async` parameter on
|
||||
each endpoint can be set to `true`. This runs the chaos process in a Sidekiq worker.
|
||||
|
||||
## Memory leaks
|
||||
|
||||
To simulate a memory leak in your application, use the `/-/chaos/leakmem` endpoint.
|
||||
|
||||
The memory is not retained after the request finishes. After the request has completed, the Ruby garbage collector will attempt to recover the memory.
|
||||
The memory is not retained after the request finishes. After the request has completed, the Ruby garbage collector attempts to recover the memory.
|
||||
|
||||
```plaintext
|
||||
GET /-/chaos/leakmem
|
||||
|
@ -85,7 +85,7 @@ GET /-/chaos/cpu_spin?duration_s=50&async=true
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
| ------------ | ------- | -------- | --------------------------------------------------------------------- |
|
||||
| `duration_s` | integer | no | Duration, in seconds, that the core will be used. Defaults to 30s |
|
||||
| `duration_s` | integer | no | Duration, in seconds, that the core is used. Defaults to 30s |
|
||||
| `async` | boolean | no | Set to true to consume CPU in a Sidekiq background worker process |
|
||||
|
||||
```shell
|
||||
|
@ -110,7 +110,7 @@ GET /-/chaos/db_spin?duration_s=50&async=true
|
|||
| Attribute | Type | Required | Description |
|
||||
| ------------ | ------- | -------- | --------------------------------------------------------------------------- |
|
||||
| `interval_s` | float | no | Interval, in seconds, for every DB request. Defaults to 1s |
|
||||
| `duration_s` | integer | no | Duration, in seconds, that the core will be used. Defaults to 30s |
|
||||
| `duration_s` | integer | no | Duration, in seconds, that the core is used. Defaults to 30s |
|
||||
| `async` | boolean | no | Set to true to perform the operation in a Sidekiq background worker process |
|
||||
|
||||
```shell
|
||||
|
@ -120,9 +120,9 @@ curl "http://localhost:3000/-/chaos/db_spin?interval_s=1&duration_s=60&token=sec
|
|||
|
||||
## Sleep
|
||||
|
||||
This endpoint is similar to the CPU Spin endpoint but simulates off-processor activity, such as network calls to backend services. It will sleep for a given duration_s.
|
||||
This endpoint is similar to the CPU Spin endpoint but simulates off-processor activity, such as network calls to backend services. It sleeps for a given `duration_s`.
|
||||
|
||||
As with the CPU Spin endpoint, this may lead to your request timing out if duration_s exceeds the configured limit.
|
||||
As with the CPU Spin endpoint, this may lead to your request timing out if `duration_s` exceeds the configured limit.
|
||||
|
||||
```plaintext
|
||||
GET /-/chaos/sleep
|
||||
|
@ -132,7 +132,7 @@ GET /-/chaos/sleep?duration_s=50&async=true
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
| ------------ | ------- | -------- | ---------------------------------------------------------------------- |
|
||||
| `duration_s` | integer | no | Duration, in seconds, that the request will sleep for. Defaults to 30s |
|
||||
| `duration_s` | integer | no | Duration, in seconds, that the request sleeps for. Defaults to 30s |
|
||||
| `async` | boolean | no | Set to true to sleep in a Sidekiq background worker process |
|
||||
|
||||
```shell
|
||||
|
@ -142,7 +142,7 @@ curl "http://localhost:3000/-/chaos/sleep?duration_s=60&token=secret"
|
|||
|
||||
## Kill
|
||||
|
||||
This endpoint will simulate the unexpected death of a worker process using a `kill` signal.
|
||||
This endpoint simulates the unexpected death of a worker process using a `kill` signal.
|
||||
|
||||
Because this endpoint uses the `KILL` signal, the worker isn't given an
|
||||
opportunity to cleanup or shutdown.
|
||||
|
|
|
@ -147,7 +147,7 @@ Keep the following in mind when submitting merge requests:
|
|||
- If the code quality is found to not meet GitLab’s standards, the merge request reviewer will
|
||||
provide guidance and refer the author to our:
|
||||
- [Documentation](../documentation/styleguide/index.md) style guide.
|
||||
- Code style guides.
|
||||
- [Code style guides](style_guides.md).
|
||||
- Sometimes style guides will be followed but the code will lack structural integrity, or the
|
||||
reviewer will have reservations about the code’s overall quality. When there is a reservation,
|
||||
the reviewer will inform the author and provide some guidance.
|
||||
|
|
|
@ -97,6 +97,32 @@ To that end, we encourage creation of new RuboCop rules in the codebase.
|
|||
When creating a new cop that could be applied to multiple applications, we encourage you
|
||||
to add it to our [GitLab Styles](https://gitlab.com/gitlab-org/gitlab-styles) gem.
|
||||
|
||||
### Resolving RuboCop exceptions
|
||||
|
||||
When the number of RuboCop exceptions exceed the default [`exclude-limit` of 15](https://docs.rubocop.org/rubocop/1.2/usage/basic_usage.html#command-line-flags),
|
||||
we may want to resolve exceptions over multiple commits. To minimize confusion,
|
||||
we should track our progress through the exception list.
|
||||
|
||||
When auto-generating the `.rubocop_todo.yml` exception list for a particular Cop,
|
||||
and more than 15 files are affected, we should add the exception list to
|
||||
a different file, `.rubocop_manual_todo.yml`.
|
||||
|
||||
This ensures that our list isn't mistakenly removed by another auto generation of
|
||||
the `.rubocop_todo.yml`. This also allows us greater visibility into the exceptions
|
||||
which are currently being resolved.
|
||||
|
||||
One way to generate the initial list is to run the todo auto generation,
|
||||
with `exclude limit` set to a high number.
|
||||
|
||||
```shell
|
||||
bundle exec rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit=10000
|
||||
```
|
||||
|
||||
You can then move the list from the freshly generated `.rubocop_todo.yml` for the Cop being actively
|
||||
resolved and place it in the `.rubocop_manual_todo.yml`. In this scenario, do not commit auto generated
|
||||
changes to the `.rubocop_todo.yml` as an `exclude limit` that is higher than 15 will make the
|
||||
`.rubocop_todo.yml` hard to parse.
|
||||
|
||||
## Database migrations
|
||||
|
||||
See the dedicated [Database Migrations Style Guide](../migration_style_guide.md).
|
||||
|
|
|
@ -625,6 +625,58 @@ methods: {
|
|||
},
|
||||
```
|
||||
|
||||
#### Pagination and optimistic updates
|
||||
|
||||
When Apollo caches paginated data client-side, it includes `pageInfo` variables in the cache key.
|
||||
If you wanted to optimistically update that data, you'd have to provide `pageInfo` variables
|
||||
when interacting with the cache via [`.readQuery()`](https://www.apollographql.com/docs/react/v2/api/apollo-client/#ApolloClient.readQuery)
|
||||
or [`.writeQuery()`](https://www.apollographql.com/docs/react/v2/api/apollo-client/#ApolloClient.writeQuery).
|
||||
This can be tedious and counter-intuitive.
|
||||
|
||||
To make it easier to deal with cached paginated queries, Apollo provides the `@connection` directive.
|
||||
The directive accepts a `key` parameter that will be used as a static key when caching the data.
|
||||
You'd then be able to retrieve the data without providing any pagination-specific variables.
|
||||
|
||||
Here's an example of a query using the `@connection` directive:
|
||||
|
||||
```graphql
|
||||
#import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
|
||||
|
||||
query DastSiteProfiles($fullPath: ID!, $after: String, $before: String, $first: Int, $last: Int) {
|
||||
project(fullPath: $fullPath) {
|
||||
siteProfiles: dastSiteProfiles(after: $after, before: $before, first: $first, last: $last)
|
||||
@connection(key: "dastSiteProfiles") {
|
||||
pageInfo {
|
||||
...PageInfo
|
||||
}
|
||||
edges {
|
||||
cursor
|
||||
node {
|
||||
id
|
||||
# ...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In this example, Apollo will store the data with the stable `dastSiteProfiles` cache key.
|
||||
|
||||
To retrieve that data from the cache, you'd then only need to provide the `$fullPath` variable,
|
||||
omitting pagination-specific variables like `after` or `before`:
|
||||
|
||||
```javascript
|
||||
const data = store.readQuery({
|
||||
query: dastSiteProfilesQuery,
|
||||
variables: {
|
||||
fullPath: 'namespace/project',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Read more about the `@connection` directive in [Apollo's documentation](https://www.apollographql.com/docs/react/v2/caching/cache-interaction/#the-connection-directive).
|
||||
|
||||
### Managing performance
|
||||
|
||||
The Apollo client will batch queries by default. This means that if you have 3 queries defined,
|
||||
|
|
|
@ -50,28 +50,28 @@ called `Gitlab::GithubImport::AdvanceStageWorker`.
|
|||
|
||||
### 1. RepositoryImportWorker
|
||||
|
||||
This worker will kick off the import process by simply scheduling a job for the
|
||||
This worker starts the import process by scheduling a job for the
|
||||
next worker.
|
||||
|
||||
### 2. Stage::ImportRepositoryWorker
|
||||
|
||||
This worker will import the repository and wiki, scheduling the next stage when
|
||||
This worker imports the repository and wiki, scheduling the next stage when
|
||||
done.
|
||||
|
||||
### 3. Stage::ImportBaseDataWorker
|
||||
|
||||
This worker will import base data such as labels, milestones, and releases. This
|
||||
work is done in a single thread since it can be performed fast enough that we
|
||||
This worker imports base data such as labels, milestones, and releases. This
|
||||
work is done in a single thread because it can be performed fast enough that we
|
||||
don't need to perform this work in parallel.
|
||||
|
||||
### 4. Stage::ImportPullRequestsWorker
|
||||
|
||||
This worker will import all pull requests. For every pull request a job for the
|
||||
This worker imports all pull requests. For every pull request a job for the
|
||||
`Gitlab::GithubImport::ImportPullRequestWorker` worker is scheduled.
|
||||
|
||||
### 5. Stage::ImportIssuesAndDiffNotesWorker
|
||||
|
||||
This worker will import all issues and pull request comments. For every issue, we
|
||||
This worker imports all issues and pull request comments. For every issue, we
|
||||
schedule a job for the `Gitlab::GithubImport::ImportIssueWorker` worker. For
|
||||
pull request comments, we instead schedule jobs for the
|
||||
`Gitlab::GithubImport::DiffNoteImporter` worker.
|
||||
|
@ -91,14 +91,14 @@ This worker imports regular comments for both issues and pull requests. For
|
|||
every comment, we schedule a job for the
|
||||
`Gitlab::GithubImport::ImportNoteWorker` worker.
|
||||
|
||||
Regular comments have to be imported at the end since the GitHub API used
|
||||
Regular comments have to be imported at the end because the GitHub API used
|
||||
returns comments for both issues and pull requests. This means we have to wait
|
||||
for all issues and pull requests to be imported before we can import regular
|
||||
comments.
|
||||
|
||||
### 7. Stage::FinishImportWorker
|
||||
|
||||
This worker will wrap up the import process by performing some housekeeping
|
||||
This worker completes the import process by performing some housekeeping
|
||||
(such as flushing any caches) and by marking the import as completed.
|
||||
|
||||
## Advancing stages
|
||||
|
@ -113,22 +113,22 @@ The first approach should only be used by workers that perform all their work in
|
|||
a single thread, while `AdvanceStageWorker` should be used for everything else.
|
||||
|
||||
The way `AdvanceStageWorker` works is fairly simple. When scheduling a job it
|
||||
will be given a project ID, a list of Redis keys, and the name of the next
|
||||
is given a project ID, a list of Redis keys, and the name of the next
|
||||
stage. The Redis keys (produced by `Gitlab::JobWaiter`) are used to check if the
|
||||
currently running stage has been completed or not. If the stage has not yet been
|
||||
completed `AdvanceStageWorker` will reschedule itself. Once a stage finishes
|
||||
`AdvanceStageworker` will refresh the import JID (more on this below) and
|
||||
completed `AdvanceStageWorker` reschedules itself. After a stage finishes
|
||||
`AdvanceStageworker` refreshes the import JID (more on this below) and
|
||||
schedule the worker of the next stage.
|
||||
|
||||
To reduce the number of `AdvanceStageWorker` jobs scheduled this worker will
|
||||
briefly wait for jobs to complete before deciding what the next action should
|
||||
be. For small projects, this may slow down the import process a bit, but it will
|
||||
also reduce pressure on the system as a whole.
|
||||
To reduce the number of `AdvanceStageWorker` jobs scheduled this worker
|
||||
briefly waits for jobs to complete before deciding what the next action should
|
||||
be. For small projects, this may slow down the import process a bit, but it
|
||||
also reduces pressure on the system as a whole.
|
||||
|
||||
## Refreshing import JIDs
|
||||
|
||||
GitLab includes a worker called `Gitlab::Import::StuckProjectImportJobsWorker`
|
||||
that will periodically run and mark project imports as failed if they have been
|
||||
that periodically runs and marks project imports as failed if they have been
|
||||
running for more than 15 hours. For GitHub projects, this poses a bit of a
|
||||
problem: importing large projects could take several hours depending on how
|
||||
often we hit the GitHub rate limit (more on this below), but we don't want
|
||||
|
@ -151,7 +151,7 @@ because we need the Email address of users in order to map them to GitLab users.
|
|||
|
||||
We handle this by doing the following:
|
||||
|
||||
1. Once we hit the rate limit all jobs will automatically reschedule themselves
|
||||
1. After we hit the rate limit all jobs automatically reschedule themselves
|
||||
in such a way that they are not executed until the rate limit has been reset.
|
||||
1. We cache the mapping of GitHub users to GitLab users in Redis.
|
||||
|
||||
|
@ -164,7 +164,7 @@ perform:
|
|||
|
||||
1. One API call to get the user's Email address.
|
||||
1. Two database queries to see if a corresponding GitLab user exists. One query
|
||||
will try to find the user based on the GitHub user ID, while the second query
|
||||
tries to find the user based on the GitHub user ID, while the second query
|
||||
is used to find the user using their GitHub Email address.
|
||||
|
||||
Because this process is quite expensive we cache the result of these lookups in
|
||||
|
@ -186,11 +186,11 @@ positive lookup, we refresh the TTL automatically. The TTL of false lookups is
|
|||
never refreshed.
|
||||
|
||||
Because of this caching layer, it's possible newly registered GitLab accounts
|
||||
won't be linked to their corresponding GitHub accounts. This, however, will sort
|
||||
itself out once the cached keys expire.
|
||||
aren't linked to their corresponding GitHub accounts. This, however, is resolved
|
||||
after the cached keys expire.
|
||||
|
||||
The user cache lookup is shared across projects. This means that the more
|
||||
projects get imported the fewer GitHub API calls will be needed.
|
||||
The user cache lookup is shared across projects. This means that the greater the number of
|
||||
projects that are imported, fewer GitHub API calls are needed.
|
||||
|
||||
The code for this resides in:
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ This method ignores all the errors silently (including the ones related to `GITA
|
|||
|
||||
A convenient script, [`bin/import-project`](https://gitlab.com/gitlab-org/quality/performance/blob/master/bin/import-project), is provided with [performance](https://gitlab.com/gitlab-org/quality/performance) project to import the Project tarball into a GitLab environment via API from the terminal.
|
||||
|
||||
Note that to use the script, it will require some preparation if you haven't done so already:
|
||||
Note that to use the script, it requires some preparation if you haven't done so already:
|
||||
|
||||
1. First, set up [`Ruby`](https://www.ruby-lang.org/en/documentation/installation/) and [`Ruby Bundler`](https://bundler.io) if they aren't already available on the machine.
|
||||
1. Next, install the required Ruby Gems via Bundler with `bundle install`.
|
||||
|
@ -40,7 +40,7 @@ For details how to use `bin/import-project`, run:
|
|||
bin/import-project --help
|
||||
```
|
||||
|
||||
The process should take up to 15 minutes for the project to import fully. The script will keep checking periodically for the status and exit once import has completed.
|
||||
The process should take up to 15 minutes for the project to import fully. The script checks the status periodically and exits after the import has completed.
|
||||
|
||||
### Importing via GitHub
|
||||
|
||||
|
@ -49,7 +49,7 @@ There is also an option to [import the project via GitHub](../user/project/impor
|
|||
1. Create the group `qa-perf-testing`
|
||||
1. Import the GitLab FOSS repository that's [mirrored on GitHub](https://github.com/gitlabhq/gitlabhq) into the group via the UI.
|
||||
|
||||
This method will take longer to import than the other methods and will depend on several factors. It's recommended to use the other methods.
|
||||
This method takes longer to import than the other methods and depends on several factors. It's recommended to use the other methods.
|
||||
|
||||
### Importing via a Rake task
|
||||
|
||||
|
@ -94,7 +94,7 @@ The `namespace_path` does not exist.
|
|||
For example, one of the groups or subgroups is mistyped or missing
|
||||
or you've specified the project name in the path.
|
||||
|
||||
The task will only create the project.
|
||||
The task only creates the project.
|
||||
If you want to import it to a new group or subgroup then create it first.
|
||||
|
||||
##### `Exception: No such file or directory @ rb_sysopen - (filename)`
|
||||
|
@ -118,8 +118,8 @@ with '-', end in '.git' or end in '.atom'
|
|||
|
||||
The project name specified in `project_path` is not valid for one of the specified reasons.
|
||||
|
||||
Only put the project name in `project_path`. If, for example, you put a path of subgroups in there
|
||||
it will fail with this error as `/` is not a valid character in a project name.
|
||||
Only put the project name in `project_path`. For example, if you provide a path of subgroups
|
||||
it fails with this error as `/` is not a valid character in a project name.
|
||||
|
||||
##### `Name has already been taken and Path has already been taken`
|
||||
|
||||
|
@ -190,7 +190,7 @@ For Performance testing, we should:
|
|||
- Count the number of executed SQL queries during the restore.
|
||||
- Observe the number of GC cycles happening.
|
||||
|
||||
You can use this snippet: `https://gitlab.com/gitlab-org/gitlab/snippets/1924954` (must be logged in), which will restore the project, and measure the execution time of `Project::TreeRestorer`, number of SQL queries and number of GC cycles happening.
|
||||
You can use this snippet: `https://gitlab.com/gitlab-org/gitlab/snippets/1924954` (must be logged in), which restores the project, and measures the execution time of `Project::TreeRestorer`, number of SQL queries and number of GC cycles happening.
|
||||
|
||||
You can execute the script from the `gdk/gitlab` directory like this:
|
||||
|
||||
|
@ -200,7 +200,7 @@ bundle exec rails r /path_to_sript/script.rb project_name /path_to_extracted_pr
|
|||
|
||||
## Troubleshooting
|
||||
|
||||
In this section we'll detail any known issues we've seen when trying to import a project and how to manage them.
|
||||
This section details known issues we've seen when trying to import a project and how to manage them.
|
||||
|
||||
### Gitaly calls error when importing
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ Additionally, the pattern that is currently used to update the project statistic
|
|||
(the callback) doesn't scale adequately. It is currently one of the largest
|
||||
[database queries transactions on production](https://gitlab.com/gitlab-org/gitlab/-/issues/29070)
|
||||
that takes the most time overall. We can't add one more query to it as
|
||||
it will increase the transaction's length.
|
||||
it increases the transaction's length.
|
||||
|
||||
Because of all of the above, we can't apply the same pattern to store
|
||||
and update the namespaces statistics, as the `namespaces` table is one
|
||||
|
@ -137,12 +137,12 @@ WHERE namespace_id IN (
|
|||
|
||||
Even though this approach would make aggregating much easier, it has some major downsides:
|
||||
|
||||
- We'd have to migrate **all namespaces** by adding and filling a new column. Because of the size of the table, dealing with time/cost will not be great. The background migration will take approximately `153h`, see <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/29772>.
|
||||
- We'd have to migrate **all namespaces** by adding and filling a new column. Because of the size of the table, dealing with time/cost would be significant. The background migration would take approximately `153h`, see <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/29772>.
|
||||
- Background migration has to be shipped one release before, delaying the functionality by another milestone.
|
||||
|
||||
### Attempt E (final): Update the namespace storage statistics in async way
|
||||
|
||||
This approach consists of keep using the incremental statistics updates we currently already have,
|
||||
This approach consists of continuing to use the incremental statistics updates we already have,
|
||||
but we refresh them through Sidekiq jobs and in different transactions:
|
||||
|
||||
1. Create a second table (`namespace_aggregation_schedules`) with two columns `id` and `namespace_id`.
|
||||
|
|
|
@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
# Query Count Limits
|
||||
|
||||
Each controller or API endpoint is allowed to execute up to 100 SQL queries and
|
||||
in test environments we'll raise an error when this threshold is exceeded.
|
||||
in test environments we raise an error when this threshold is exceeded.
|
||||
|
||||
## Solving Failing Tests
|
||||
|
||||
|
@ -20,18 +20,18 @@ solutions to this problem:
|
|||
You should only resort to whitelisting when an existing controller or endpoint
|
||||
is to blame as in this case reducing the number of SQL queries can take a lot of
|
||||
effort. Newly added controllers and endpoints are not allowed to execute more
|
||||
than 100 SQL queries and no exceptions will be made for this rule. _If_ a large
|
||||
than 100 SQL queries and no exceptions are made for this rule. _If_ a large
|
||||
number of SQL queries is necessary to perform certain work it's best to have
|
||||
this work performed by Sidekiq instead of doing this directly in a web request.
|
||||
|
||||
## Whitelisting
|
||||
|
||||
In the event that you _have_ to whitelist a controller you'll first need to
|
||||
In the event that you _have_ to whitelist a controller you must first
|
||||
create an issue. This issue should (preferably in the title) mention the
|
||||
controller or endpoint and include the appropriate labels (`database`,
|
||||
`performance`, and at least a team specific label such as `Discussion`).
|
||||
|
||||
Once the issue has been created you can whitelist the code in question. For
|
||||
After the issue has been created you can whitelist the code in question. For
|
||||
Rails controllers it's best to create a `before_action` hook that runs as early
|
||||
as possible. The called method in turn should call
|
||||
`Gitlab::QueryLimiting.whitelist('issue URL here')`. For example:
|
||||
|
|
|
@ -19,7 +19,7 @@ The measuring module is a tool that allows to measure a service's execution, and
|
|||
- RSS memory usage
|
||||
- Server worker ID
|
||||
|
||||
The measuring module will log these measurements into a structured log called [`service_measurement.log`](../administration/logs.md#service_measurementlog),
|
||||
The measuring module logs these measurements into a structured log called [`service_measurement.log`](../administration/logs.md#service_measurementlog),
|
||||
as a single entry for each service execution.
|
||||
|
||||
For GitLab.com, `service_measurement.log` is ingested in Elasticsearch and Kibana as part of our monitoring solution.
|
||||
|
@ -43,7 +43,7 @@ DummyService.prepend(Measurable)
|
|||
|
||||
In case when you are prepending a module from the `EE` namespace with EE features, you need to prepend Measurable after prepending the `EE` module.
|
||||
|
||||
This way, `Measurable` will be at the bottom of the ancestor chain, in order to measure execution of `EE` features as well:
|
||||
This way, `Measurable` is at the bottom of the ancestor chain, in order to measure execution of `EE` features as well:
|
||||
|
||||
```ruby
|
||||
class DummyService
|
||||
|
@ -69,7 +69,7 @@ def extra_attributes_for_measurement
|
|||
end
|
||||
```
|
||||
|
||||
After the measurement module is injected in the service, it will be behind a generic feature flag.
|
||||
After the measurement module is injected in the service, it is behind a generic feature flag.
|
||||
To actually use it, you need to enable measuring for the desired service by enabling the feature flag.
|
||||
|
||||
### Enabling measurement using feature flags
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 3.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
|
@ -127,6 +127,7 @@ with this approach, however, and there is a
|
|||
|
||||
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/4393) in GitLab Core 13.5.
|
||||
> - Made [available in all tiers](https://gitlab.com/gitlab-org/gitlab/-/issues/273205) in 13.6.
|
||||
> - Report download dropdown [added](https://gitlab.com/gitlab-org/gitlab/-/issues/273418) in 13.7.
|
||||
> - It's [deployed behind a feature flag](../feature_flags.md), enabled by default.
|
||||
> - It's enabled on GitLab.com.
|
||||
> - It can be enabled or disabled for a single project.
|
||||
|
@ -137,9 +138,10 @@ WARNING:
|
|||
This feature might not be available to you. Check the **version history** note above for details.
|
||||
|
||||
Merge requests which have run security scans let you know that the generated
|
||||
reports are available to download.
|
||||
reports are available to download. To download a report, click on the
|
||||
**Download results** dropdown, and select the desired report.
|
||||
|
||||
![Security widget](img/security_widget_v13_6.png)
|
||||
![Security widget](img/security_widget_v13_7.png)
|
||||
|
||||
## Interacting with the vulnerabilities
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 48 KiB |
Binary file not shown.
After Width: | Height: | Size: 99 KiB |
|
@ -18,6 +18,8 @@ container registry images of a project without having a user and a password.
|
|||
|
||||
Deploy tokens can be managed by [maintainers only](../../permissions.md).
|
||||
|
||||
Deploy tokens cannot be used with the GitLab API.
|
||||
|
||||
If you have a key pair, you might want to use [deploy keys](../../../ssh/README.md#deploy-keys)
|
||||
instead.
|
||||
|
||||
|
@ -36,7 +38,7 @@ project. Alternatively, you can also create [group-scoped deploy tokens](#group-
|
|||
1. Save the deploy token somewhere safe. After you leave or refresh
|
||||
the page, **you won't be able to access it again**.
|
||||
|
||||
![Personal access tokens page](img/deploy_tokens.png)
|
||||
![Personal access tokens page](img/deploy_tokens_ui.png)
|
||||
|
||||
## Deploy token expiration
|
||||
|
||||
|
|
|
@ -72,8 +72,8 @@ the following table.
|
|||
|
||||
| Scope | Description |
|
||||
| ------------------ | ----------- |
|
||||
| `api` | Grants complete read/write access to the scoped project API. |
|
||||
| `read_api` | Grants read access to the scoped project API. |
|
||||
| `api` | Grants complete read/write access to the scoped project API, including the Package Registry](../../packages/package_registry/index.md). |
|
||||
| `read_api` | Grants read access to the scoped project API, including the [Package Registry](../../packages/package_registry/index.md). |
|
||||
| `read_registry` | Allows read-access (pull) to [container registry](../../packages/container_registry/index.md) images if a project is private and authorization is required. |
|
||||
| `write_registry` | Allows write-access (push) to [container registry](../../packages/container_registry/index.md). |
|
||||
| `read_repository` | Allows read-only access (pull) to the repository. |
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
stage: Create
|
||||
group: Static Site Editor
|
||||
group: Editor
|
||||
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
|
||||
type: reference, how-to
|
||||
description: "The static site editor enables users to edit content on static websites without prior knowledge of the underlying templating language, site architecture or Git commands."
|
||||
|
@ -11,6 +11,7 @@ description: "The static site editor enables users to edit content on static web
|
|||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28758) in GitLab 12.10.
|
||||
> - WYSIWYG editor [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214559) in GitLab 13.0.
|
||||
> - Non-Markdown content blocks uneditable on the WYSIWYG mode [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216836) in GitLab 13.3.
|
||||
> - Formatting Markdown [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49052) in GitLab 13.7.
|
||||
|
||||
Static Site Editor (SSE) enables users to edit content on static websites without
|
||||
prior knowledge of the underlying templating language, site architecture, or
|
||||
|
@ -58,7 +59,8 @@ performs automatically in the background:
|
|||
|
||||
1. Creates a new branch.
|
||||
1. Commits their changes.
|
||||
1. Fixes formatting according to the [Handbook Markdown Style Guide](https://about.gitlab.com/handbook/markdown-guide/) style guide and add them through another commit.
|
||||
1. Fixes formatting according to the [Handbook Markdown Style Guide](https://about.gitlab.com/handbook/markdown-guide/)
|
||||
style guide and add them through another commit.
|
||||
1. Opens a merge request against the default branch.
|
||||
|
||||
The editor can then navigate to the merge request to assign it to a colleague for review.
|
||||
|
|
|
@ -17,7 +17,7 @@ module Gitlab
|
|||
|
||||
file_paths = []
|
||||
|
||||
if ::Feature.enabled?(:diff_check_with_paths_changed_rpc, project)
|
||||
if ::Feature.enabled?(:diff_check_with_paths_changed_rpc, project, default_enabled: true)
|
||||
paths = project.repository.find_changed_paths(commits.map(&:sha))
|
||||
paths.each do |path|
|
||||
file_paths.concat([path.path])
|
||||
|
|
|
@ -40,30 +40,30 @@ module Gitlab
|
|||
# TODO: Review child inheritance of this table (see: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41699#note_430928221)
|
||||
def localized_templates_table
|
||||
[
|
||||
ProjectTemplate.new('rails', 'Ruby on Rails', _('Includes an MVC structure, Gemfile, Rakefile, along with many others, to help you get started.'), 'https://gitlab.com/gitlab-org/project-templates/rails', 'illustrations/logos/rails.svg'),
|
||||
ProjectTemplate.new('spring', 'Spring', _('Includes an MVC structure, mvnw and pom.xml to help you get started.'), 'https://gitlab.com/gitlab-org/project-templates/spring', 'illustrations/logos/spring.svg'),
|
||||
ProjectTemplate.new('express', 'NodeJS Express', _('Includes an MVC structure to help you get started.'), 'https://gitlab.com/gitlab-org/project-templates/express', 'illustrations/logos/express.svg'),
|
||||
ProjectTemplate.new('iosswift', 'iOS (Swift)', _('A ready-to-go template for use with iOS Swift apps.'), 'https://gitlab.com/gitlab-org/project-templates/iosswift', 'illustrations/logos/swift.svg'),
|
||||
ProjectTemplate.new('rails', 'Ruby on Rails', _('Includes an MVC structure, Gemfile, Rakefile, along with many others, to help you get started'), 'https://gitlab.com/gitlab-org/project-templates/rails', 'illustrations/logos/rails.svg'),
|
||||
ProjectTemplate.new('spring', 'Spring', _('Includes an MVC structure, mvnw and pom.xml to help you get started'), 'https://gitlab.com/gitlab-org/project-templates/spring', 'illustrations/logos/spring.svg'),
|
||||
ProjectTemplate.new('express', 'NodeJS Express', _('Includes an MVC structure to help you get started'), 'https://gitlab.com/gitlab-org/project-templates/express', 'illustrations/logos/express.svg'),
|
||||
ProjectTemplate.new('iosswift', 'iOS (Swift)', _('A ready-to-go template for use with iOS Swift apps'), 'https://gitlab.com/gitlab-org/project-templates/iosswift', 'illustrations/logos/swift.svg'),
|
||||
ProjectTemplate.new('dotnetcore', '.NET Core', _('A .NET Core console application template, customizable for any .NET Core project'), 'https://gitlab.com/gitlab-org/project-templates/dotnetcore', 'illustrations/logos/dotnet.svg'),
|
||||
ProjectTemplate.new('android', 'Android', _('A ready-to-go template for use with Android apps.'), 'https://gitlab.com/gitlab-org/project-templates/android', 'illustrations/logos/android.svg'),
|
||||
ProjectTemplate.new('gomicro', 'Go Micro', _('Go Micro is a framework for micro service development.'), 'https://gitlab.com/gitlab-org/project-templates/go-micro', 'illustrations/logos/gomicro.svg'),
|
||||
ProjectTemplate.new('gatsby', 'Pages/Gatsby', _('Everything you need to create a GitLab Pages site using Gatsby.'), 'https://gitlab.com/pages/gatsby'),
|
||||
ProjectTemplate.new('hugo', 'Pages/Hugo', _('Everything you need to create a GitLab Pages site using Hugo.'), 'https://gitlab.com/pages/hugo', 'illustrations/logos/hugo.svg'),
|
||||
ProjectTemplate.new('jekyll', 'Pages/Jekyll', _('Everything you need to create a GitLab Pages site using Jekyll.'), 'https://gitlab.com/pages/jekyll', 'illustrations/logos/jekyll.svg'),
|
||||
ProjectTemplate.new('plainhtml', 'Pages/Plain HTML', _('Everything you need to create a GitLab Pages site using plain HTML.'), 'https://gitlab.com/pages/plain-html'),
|
||||
ProjectTemplate.new('gitbook', 'Pages/GitBook', _('Everything you need to create a GitLab Pages site using GitBook.'), 'https://gitlab.com/pages/gitbook', 'illustrations/logos/gitbook.svg'),
|
||||
ProjectTemplate.new('hexo', 'Pages/Hexo', _('Everything you need to create a GitLab Pages site using Hexo.'), 'https://gitlab.com/pages/hexo', 'illustrations/logos/hexo.svg'),
|
||||
ProjectTemplate.new('android', 'Android', _('A ready-to-go template for use with Android apps'), 'https://gitlab.com/gitlab-org/project-templates/android', 'illustrations/logos/android.svg'),
|
||||
ProjectTemplate.new('gomicro', 'Go Micro', _('Go Micro is a framework for micro service development'), 'https://gitlab.com/gitlab-org/project-templates/go-micro', 'illustrations/logos/gomicro.svg'),
|
||||
ProjectTemplate.new('gatsby', 'Pages/Gatsby', _('Everything you need to create a GitLab Pages site using Gatsby'), 'https://gitlab.com/pages/gatsby'),
|
||||
ProjectTemplate.new('hugo', 'Pages/Hugo', _('Everything you need to create a GitLab Pages site using Hugo'), 'https://gitlab.com/pages/hugo', 'illustrations/logos/hugo.svg'),
|
||||
ProjectTemplate.new('jekyll', 'Pages/Jekyll', _('Everything you need to create a GitLab Pages site using Jekyll'), 'https://gitlab.com/pages/jekyll', 'illustrations/logos/jekyll.svg'),
|
||||
ProjectTemplate.new('plainhtml', 'Pages/Plain HTML', _('Everything you need to create a GitLab Pages site using plain HTML'), 'https://gitlab.com/pages/plain-html'),
|
||||
ProjectTemplate.new('gitbook', 'Pages/GitBook', _('Everything you need to create a GitLab Pages site using GitBook'), 'https://gitlab.com/pages/gitbook', 'illustrations/logos/gitbook.svg'),
|
||||
ProjectTemplate.new('hexo', 'Pages/Hexo', _('Everything you need to create a GitLab Pages site using Hexo'), 'https://gitlab.com/pages/hexo', 'illustrations/logos/hexo.svg'),
|
||||
ProjectTemplate.new('sse_middleman', 'Static Site Editor/Middleman', _('Middleman project with Static Site Editor support'), 'https://gitlab.com/gitlab-org/project-templates/static-site-editor-middleman', 'illustrations/logos/middleman.svg'),
|
||||
ProjectTemplate.new('gitpod_spring_petclinic', 'Gitpod/Spring Petclinic', _('A Gitpod configured Webapplication in Spring and Java'), 'https://gitlab.com/gitlab-org/project-templates/gitpod-spring-petclinic', 'illustrations/logos/gitpod.svg'),
|
||||
ProjectTemplate.new('nfhugo', 'Netlify/Hugo', _('A Hugo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features.'), 'https://gitlab.com/pages/nfhugo', 'illustrations/logos/netlify.svg'),
|
||||
ProjectTemplate.new('nfjekyll', 'Netlify/Jekyll', _('A Jekyll site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features.'), 'https://gitlab.com/pages/nfjekyll', 'illustrations/logos/netlify.svg'),
|
||||
ProjectTemplate.new('nfplainhtml', 'Netlify/Plain HTML', _('A plain HTML site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features.'), 'https://gitlab.com/pages/nfplain-html', 'illustrations/logos/netlify.svg'),
|
||||
ProjectTemplate.new('nfgitbook', 'Netlify/GitBook', _('A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features.'), 'https://gitlab.com/pages/nfgitbook', 'illustrations/logos/netlify.svg'),
|
||||
ProjectTemplate.new('nfhexo', 'Netlify/Hexo', _('A Hexo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features.'), 'https://gitlab.com/pages/nfhexo', 'illustrations/logos/netlify.svg'),
|
||||
ProjectTemplate.new('salesforcedx', 'SalesforceDX', _('A project boilerplate for Salesforce App development with Salesforce Developer tools.'), 'https://gitlab.com/gitlab-org/project-templates/salesforcedx'),
|
||||
ProjectTemplate.new('nfhugo', 'Netlify/Hugo', _('A Hugo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features'), 'https://gitlab.com/pages/nfhugo', 'illustrations/logos/netlify.svg'),
|
||||
ProjectTemplate.new('nfjekyll', 'Netlify/Jekyll', _('A Jekyll site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features'), 'https://gitlab.com/pages/nfjekyll', 'illustrations/logos/netlify.svg'),
|
||||
ProjectTemplate.new('nfplainhtml', 'Netlify/Plain HTML', _('A plain HTML site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features'), 'https://gitlab.com/pages/nfplain-html', 'illustrations/logos/netlify.svg'),
|
||||
ProjectTemplate.new('nfgitbook', 'Netlify/GitBook', _('A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features'), 'https://gitlab.com/pages/nfgitbook', 'illustrations/logos/netlify.svg'),
|
||||
ProjectTemplate.new('nfhexo', 'Netlify/Hexo', _('A Hexo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features'), 'https://gitlab.com/pages/nfhexo', 'illustrations/logos/netlify.svg'),
|
||||
ProjectTemplate.new('salesforcedx', 'SalesforceDX', _('A project boilerplate for Salesforce App development with Salesforce Developer tools'), 'https://gitlab.com/gitlab-org/project-templates/salesforcedx'),
|
||||
ProjectTemplate.new('serverless_framework', 'Serverless Framework/JS', _('A basic page and serverless function that uses AWS Lambda, AWS API Gateway, and GitLab Pages'), 'https://gitlab.com/gitlab-org/project-templates/serverless-framework', 'illustrations/logos/serverless_framework.svg'),
|
||||
ProjectTemplate.new('jsonnet', 'Jsonnet for Dynamic Child Pipelines', _('An example showing how to use Jsonnet with GitLab dynamic child pipelines'), 'https://gitlab.com/gitlab-org/project-templates/jsonnet'),
|
||||
ProjectTemplate.new('cluster_management', 'GitLab Cluster Management', _('An example project for managing Kubernetes clusters integrated with GitLab.'), 'https://gitlab.com/gitlab-org/project-templates/cluster-management')
|
||||
ProjectTemplate.new('cluster_management', 'GitLab Cluster Management', _('An example project for managing Kubernetes clusters integrated with GitLab'), 'https://gitlab.com/gitlab-org/project-templates/cluster-management')
|
||||
].freeze
|
||||
end
|
||||
|
||||
|
|
|
@ -5,8 +5,7 @@ module Gitlab
|
|||
class << self
|
||||
def localized_templates_table
|
||||
[
|
||||
SampleDataTemplate.new('basic', 'Basic', _('Basic Sample Data template with Issues, Merge Requests and Milestones.'), 'https://gitlab.com/gitlab-org/sample-data-templates/basic'),
|
||||
SampleDataTemplate.new('serenity_valley', 'Serenity Valley', _('Serenity Valley Sample Data template.'), 'https://gitlab.com/gitlab-org/sample-data-templates/serenity-valley')
|
||||
SampleDataTemplate.new('sample', 'Sample GitLab Project', _('Get started with a project that follows best practices for setting up GitLab for your own organization, including sample Issues, Merge Requests, and Milestones'), 'https://gitlab.com/gitlab-org/sample-data-templates/sample-gitlab-project')
|
||||
].freeze
|
||||
end
|
||||
|
||||
|
|
|
@ -1196,19 +1196,19 @@ msgstr ""
|
|||
msgid "A CI/CD pipeline must run and be successful before merge."
|
||||
msgstr ""
|
||||
|
||||
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
|
||||
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
|
||||
msgstr ""
|
||||
|
||||
msgid "A Gitpod configured Webapplication in Spring and Java"
|
||||
msgstr ""
|
||||
|
||||
msgid "A Hexo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
|
||||
msgid "A Hexo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
|
||||
msgstr ""
|
||||
|
||||
msgid "A Hugo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
|
||||
msgid "A Hugo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
|
||||
msgstr ""
|
||||
|
||||
msgid "A Jekyll site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
|
||||
msgid "A Jekyll site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
|
||||
msgstr ""
|
||||
|
||||
msgid "A Let's Encrypt SSL certificate can not be obtained until your domain is verified."
|
||||
|
@ -1277,13 +1277,13 @@ msgstr ""
|
|||
msgid "A non-confidential epic cannot be assigned to a confidential parent epic"
|
||||
msgstr ""
|
||||
|
||||
msgid "A plain HTML site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
|
||||
msgid "A plain HTML site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
|
||||
msgstr ""
|
||||
|
||||
msgid "A platform value can be web, mob or app."
|
||||
msgstr ""
|
||||
|
||||
msgid "A project boilerplate for Salesforce App development with Salesforce Developer tools."
|
||||
msgid "A project boilerplate for Salesforce App development with Salesforce Developer tools"
|
||||
msgstr ""
|
||||
|
||||
msgid "A project containing issues for each audit inquiry in the HIPAA Audit Protocol published by the U.S. Department of Health & Human Services"
|
||||
|
@ -1292,10 +1292,10 @@ msgstr ""
|
|||
msgid "A project is where you house your files (repository), plan your work (issues), and publish your documentation (wiki), %{among_other_things_link}."
|
||||
msgstr ""
|
||||
|
||||
msgid "A ready-to-go template for use with Android apps."
|
||||
msgid "A ready-to-go template for use with Android apps"
|
||||
msgstr ""
|
||||
|
||||
msgid "A ready-to-go template for use with iOS Swift apps."
|
||||
msgid "A ready-to-go template for use with iOS Swift apps"
|
||||
msgstr ""
|
||||
|
||||
msgid "A regular expression that will be used to find the test coverage output in the job log. Leave blank to disable"
|
||||
|
@ -3333,7 +3333,7 @@ msgstr ""
|
|||
msgid "An error ocurred while loading your content. Please try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "An example project for managing Kubernetes clusters integrated with GitLab."
|
||||
msgid "An example project for managing Kubernetes clusters integrated with GitLab"
|
||||
msgstr ""
|
||||
|
||||
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
|
||||
|
@ -4364,9 +4364,6 @@ msgstr ""
|
|||
msgid "Based on"
|
||||
msgstr ""
|
||||
|
||||
msgid "Basic Sample Data template with Issues, Merge Requests and Milestones."
|
||||
msgstr ""
|
||||
|
||||
msgid "Be careful. Changing the project's namespace can have unintended side effects."
|
||||
msgstr ""
|
||||
|
||||
|
@ -11304,22 +11301,22 @@ msgstr ""
|
|||
msgid "Everything on your to-do list is marked as done."
|
||||
msgstr ""
|
||||
|
||||
msgid "Everything you need to create a GitLab Pages site using Gatsby."
|
||||
msgid "Everything you need to create a GitLab Pages site using Gatsby"
|
||||
msgstr ""
|
||||
|
||||
msgid "Everything you need to create a GitLab Pages site using GitBook."
|
||||
msgid "Everything you need to create a GitLab Pages site using GitBook"
|
||||
msgstr ""
|
||||
|
||||
msgid "Everything you need to create a GitLab Pages site using Hexo."
|
||||
msgid "Everything you need to create a GitLab Pages site using Hexo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Everything you need to create a GitLab Pages site using Hugo."
|
||||
msgid "Everything you need to create a GitLab Pages site using Hugo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Everything you need to create a GitLab Pages site using Jekyll."
|
||||
msgid "Everything you need to create a GitLab Pages site using Jekyll"
|
||||
msgstr ""
|
||||
|
||||
msgid "Everything you need to create a GitLab Pages site using plain HTML."
|
||||
msgid "Everything you need to create a GitLab Pages site using plain HTML"
|
||||
msgstr ""
|
||||
|
||||
msgid "Evidence collection"
|
||||
|
@ -12845,6 +12842,9 @@ msgstr ""
|
|||
msgid "Get started"
|
||||
msgstr ""
|
||||
|
||||
msgid "Get started with a project that follows best practices for setting up GitLab for your own organization, including sample Issues, Merge Requests, and Milestones"
|
||||
msgstr ""
|
||||
|
||||
msgid "Get started with error tracking"
|
||||
msgstr ""
|
||||
|
||||
|
@ -13142,7 +13142,7 @@ msgstr ""
|
|||
msgid "Go Back"
|
||||
msgstr ""
|
||||
|
||||
msgid "Go Micro is a framework for micro service development."
|
||||
msgid "Go Micro is a framework for micro service development"
|
||||
msgstr ""
|
||||
|
||||
msgid "Go back"
|
||||
|
@ -14662,13 +14662,13 @@ msgstr ""
|
|||
msgid "Includes LFS objects. It can be overridden per group, or per project. 0 for unlimited."
|
||||
msgstr ""
|
||||
|
||||
msgid "Includes an MVC structure to help you get started."
|
||||
msgid "Includes an MVC structure to help you get started"
|
||||
msgstr ""
|
||||
|
||||
msgid "Includes an MVC structure, Gemfile, Rakefile, along with many others, to help you get started."
|
||||
msgid "Includes an MVC structure, Gemfile, Rakefile, along with many others, to help you get started"
|
||||
msgstr ""
|
||||
|
||||
msgid "Includes an MVC structure, mvnw and pom.xml to help you get started."
|
||||
msgid "Includes an MVC structure, mvnw and pom.xml to help you get started"
|
||||
msgstr ""
|
||||
|
||||
msgid "Incoming email"
|
||||
|
@ -21889,9 +21889,6 @@ msgstr ""
|
|||
msgid "ProjectTemplates|Android"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectTemplates|Basic"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectTemplates|GitLab Cluster Management"
|
||||
msgstr ""
|
||||
|
||||
|
@ -21946,7 +21943,7 @@ msgstr ""
|
|||
msgid "ProjectTemplates|SalesforceDX"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectTemplates|Serenity Valley"
|
||||
msgid "ProjectTemplates|Sample GitLab Project"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectTemplates|Serverless Framework/JS"
|
||||
|
@ -23980,9 +23977,6 @@ msgstr ""
|
|||
msgid "SSL Verification:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Sample Data"
|
||||
msgstr ""
|
||||
|
||||
msgid "Satisfied"
|
||||
msgstr ""
|
||||
|
||||
|
@ -24919,9 +24913,6 @@ msgstr ""
|
|||
msgid "September"
|
||||
msgstr ""
|
||||
|
||||
msgid "Serenity Valley Sample Data template."
|
||||
msgstr ""
|
||||
|
||||
msgid "SeriesFinalConjunction|and"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ module QA
|
|||
module Settings
|
||||
class Integrations < QA::Page::Base
|
||||
view 'app/views/shared/integrations/_index.html.haml' do
|
||||
element :prometheus_link, '{ data: { qa_selector: "#{integration.to_param' # rubocop:disable QA/ElementWithPattern
|
||||
element :jira_link, '{ data: { qa_selector: "#{integration.to_param' # rubocop:disable QA/ElementWithPattern
|
||||
element :prometheus_link, 'data: { qa_selector: "#{integration.to_param' # rubocop:disable QA/ElementWithPattern
|
||||
element :jira_link, 'data: { qa_selector: "#{integration.to_param' # rubocop:disable QA/ElementWithPattern
|
||||
end
|
||||
|
||||
def click_on_prometheus_integration
|
||||
|
|
|
@ -20,108 +20,4 @@ RSpec.describe Profiles::KeysController do
|
|||
expect(Key.last.expires_at).to be_like_time(expires_at)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#get_keys" do
|
||||
describe "non existent user" do
|
||||
it "does not generally work" do
|
||||
get :get_keys, params: { username: 'not-existent' }
|
||||
|
||||
expect(response).not_to be_successful
|
||||
end
|
||||
end
|
||||
|
||||
describe "user with no keys" do
|
||||
it "does generally work" do
|
||||
get :get_keys, params: { username: user.username }
|
||||
|
||||
expect(response).to be_successful
|
||||
end
|
||||
|
||||
it "renders all keys separated with a new line" do
|
||||
get :get_keys, params: { username: user.username }
|
||||
|
||||
expect(response.body).to eq("")
|
||||
end
|
||||
it "responds with text/plain content type" do
|
||||
get :get_keys, params: { username: user.username }
|
||||
expect(response.media_type).to eq("text/plain")
|
||||
end
|
||||
end
|
||||
|
||||
describe "user with keys" do
|
||||
let!(:key) { create(:key, user: user) }
|
||||
let!(:another_key) { create(:another_key, user: user) }
|
||||
let!(:deploy_key) { create(:deploy_key, user: user) }
|
||||
|
||||
describe "while signed in" do
|
||||
before do
|
||||
sign_in(user)
|
||||
end
|
||||
|
||||
it "does generally work" do
|
||||
get :get_keys, params: { username: user.username }
|
||||
|
||||
expect(response).to be_successful
|
||||
end
|
||||
|
||||
it "renders all non deploy keys separated with a new line" do
|
||||
get :get_keys, params: { username: user.username }
|
||||
|
||||
expect(response.body).not_to eq('')
|
||||
expect(response.body).to eq(user.all_ssh_keys.join("\n"))
|
||||
|
||||
expect(response.body).to include(key.key.sub(' dummy@gitlab.com', ''))
|
||||
expect(response.body).to include(another_key.key.sub(' dummy@gitlab.com', ''))
|
||||
|
||||
expect(response.body).not_to include(deploy_key.key)
|
||||
end
|
||||
|
||||
it "does not render the comment of the key" do
|
||||
get :get_keys, params: { username: user.username }
|
||||
expect(response.body).not_to match(/dummy@gitlab.com/)
|
||||
end
|
||||
|
||||
it "responds with text/plain content type" do
|
||||
get :get_keys, params: { username: user.username }
|
||||
|
||||
expect(response.media_type).to eq("text/plain")
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when logged out' do
|
||||
before do
|
||||
sign_out(user)
|
||||
end
|
||||
|
||||
it "still does generally work" do
|
||||
get :get_keys, params: { username: user.username }
|
||||
|
||||
expect(response).to be_successful
|
||||
end
|
||||
|
||||
it "renders all non deploy keys separated with a new line" do
|
||||
get :get_keys, params: { username: user.username }
|
||||
|
||||
expect(response.body).not_to eq('')
|
||||
expect(response.body).to eq(user.all_ssh_keys.join("\n"))
|
||||
|
||||
expect(response.body).to include(key.key.sub(' dummy@gitlab.com', ''))
|
||||
expect(response.body).to include(another_key.key.sub(' dummy@gitlab.com', ''))
|
||||
|
||||
expect(response.body).not_to include(deploy_key.key)
|
||||
end
|
||||
|
||||
it "does not render the comment of the key" do
|
||||
get :get_keys, params: { username: user.username }
|
||||
expect(response.body).not_to match(/dummy@gitlab.com/)
|
||||
end
|
||||
|
||||
it "responds with text/plain content type" do
|
||||
get :get_keys, params: { username: user.username }
|
||||
|
||||
expect(response.media_type).to eq("text/plain")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -221,6 +221,111 @@ RSpec.describe UsersController do
|
|||
end
|
||||
end
|
||||
|
||||
describe "#ssh_keys" do
|
||||
describe "non existent user" do
|
||||
it "does not generally work" do
|
||||
get :ssh_keys, params: { username: 'not-existent' }
|
||||
|
||||
expect(response).not_to be_successful
|
||||
end
|
||||
end
|
||||
|
||||
describe "user with no keys" do
|
||||
it "does generally work" do
|
||||
get :ssh_keys, params: { username: user.username }
|
||||
|
||||
expect(response).to be_successful
|
||||
end
|
||||
|
||||
it "renders all keys separated with a new line" do
|
||||
get :ssh_keys, params: { username: user.username }
|
||||
|
||||
expect(response.body).to eq("")
|
||||
end
|
||||
|
||||
it "responds with text/plain content type" do
|
||||
get :ssh_keys, params: { username: user.username }
|
||||
expect(response.content_type).to eq("text/plain")
|
||||
end
|
||||
end
|
||||
|
||||
describe "user with keys" do
|
||||
let!(:key) { create(:key, user: user) }
|
||||
let!(:another_key) { create(:another_key, user: user) }
|
||||
let!(:deploy_key) { create(:deploy_key, user: user) }
|
||||
|
||||
describe "while signed in" do
|
||||
before do
|
||||
sign_in(user)
|
||||
end
|
||||
|
||||
it "does generally work" do
|
||||
get :ssh_keys, params: { username: user.username }
|
||||
|
||||
expect(response).to be_successful
|
||||
end
|
||||
|
||||
it "renders all non deploy keys separated with a new line" do
|
||||
get :ssh_keys, params: { username: user.username }
|
||||
|
||||
expect(response.body).not_to eq('')
|
||||
expect(response.body).to eq(user.all_ssh_keys.join("\n"))
|
||||
|
||||
expect(response.body).to include(key.key.sub(' dummy@gitlab.com', ''))
|
||||
expect(response.body).to include(another_key.key.sub(' dummy@gitlab.com', ''))
|
||||
|
||||
expect(response.body).not_to include(deploy_key.key)
|
||||
end
|
||||
|
||||
it "does not render the comment of the key" do
|
||||
get :ssh_keys, params: { username: user.username }
|
||||
expect(response.body).not_to match(/dummy@gitlab.com/)
|
||||
end
|
||||
|
||||
it "responds with text/plain content type" do
|
||||
get :ssh_keys, params: { username: user.username }
|
||||
|
||||
expect(response.content_type).to eq("text/plain")
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when logged out' do
|
||||
before do
|
||||
sign_out(user)
|
||||
end
|
||||
|
||||
it "still does generally work" do
|
||||
get :ssh_keys, params: { username: user.username }
|
||||
|
||||
expect(response).to be_successful
|
||||
end
|
||||
|
||||
it "renders all non deploy keys separated with a new line" do
|
||||
get :ssh_keys, params: { username: user.username }
|
||||
|
||||
expect(response.body).not_to eq('')
|
||||
expect(response.body).to eq(user.all_ssh_keys.join("\n"))
|
||||
|
||||
expect(response.body).to include(key.key.sub(' dummy@gitlab.com', ''))
|
||||
expect(response.body).to include(another_key.key.sub(' dummy@gitlab.com', ''))
|
||||
|
||||
expect(response.body).not_to include(deploy_key.key)
|
||||
end
|
||||
|
||||
it "does not render the comment of the key" do
|
||||
get :ssh_keys, params: { username: user.username }
|
||||
expect(response.body).not_to match(/dummy@gitlab.com/)
|
||||
end
|
||||
|
||||
it "responds with text/plain content type" do
|
||||
get :ssh_keys, params: { username: user.username }
|
||||
|
||||
expect(response.content_type).to eq("text/plain")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #calendar' do
|
||||
context 'for user' do
|
||||
let(:project) { create(:project) }
|
||||
|
|
|
@ -47,6 +47,10 @@ FactoryBot.define do
|
|||
user_type { :migration_bot }
|
||||
end
|
||||
|
||||
trait :security_bot do
|
||||
user_type { :security_bot }
|
||||
end
|
||||
|
||||
trait :external do
|
||||
external { true }
|
||||
end
|
||||
|
|
|
@ -34,7 +34,7 @@ RSpec.describe 'Project' do
|
|||
end
|
||||
|
||||
context 'create with sample data template' do
|
||||
it_behaves_like 'creates from template', Gitlab::SampleDataTemplate.find(:basic), '.sample-data-templates-tab'
|
||||
it_behaves_like 'creates from template', Gitlab::SampleDataTemplate.find(:sample)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -6,8 +6,7 @@ RSpec.describe Gitlab::SampleDataTemplate do
|
|||
describe '.all' do
|
||||
it 'returns all templates' do
|
||||
expected = %w[
|
||||
basic
|
||||
serenity_valley
|
||||
sample
|
||||
]
|
||||
|
||||
expect(described_class.all).to be_an(Array)
|
||||
|
@ -19,7 +18,7 @@ RSpec.describe Gitlab::SampleDataTemplate do
|
|||
subject { described_class.find(query) }
|
||||
|
||||
context 'when there is a match' do
|
||||
let(:query) { :basic }
|
||||
let(:query) { :sample }
|
||||
|
||||
it { is_expected.to be_a(described_class) }
|
||||
end
|
||||
|
|
|
@ -7,6 +7,8 @@ RSpec.describe GlobalPolicy do
|
|||
|
||||
let_it_be(:project_bot) { create(:user, :project_bot) }
|
||||
let_it_be(:migration_bot) { create(:user, :migration_bot) }
|
||||
let_it_be(:security_bot) { create(:user, :security_bot) }
|
||||
|
||||
let(:current_user) { create(:user) }
|
||||
let(:user) { create(:user) }
|
||||
|
||||
|
@ -223,6 +225,12 @@ RSpec.describe GlobalPolicy do
|
|||
it { is_expected.not_to be_allowed(:access_api) }
|
||||
end
|
||||
|
||||
context 'security bot' do
|
||||
let(:current_user) { security_bot }
|
||||
|
||||
it { is_expected.not_to be_allowed(:access_api) }
|
||||
end
|
||||
|
||||
context 'user blocked pending approval' do
|
||||
before do
|
||||
current_user.block_pending_approval
|
||||
|
@ -353,6 +361,12 @@ RSpec.describe GlobalPolicy do
|
|||
it { is_expected.to be_allowed(:access_git) }
|
||||
end
|
||||
|
||||
context 'security bot' do
|
||||
let(:current_user) { security_bot }
|
||||
|
||||
it { is_expected.to be_allowed(:access_git) }
|
||||
end
|
||||
|
||||
describe 'deactivated user' do
|
||||
before do
|
||||
current_user.deactivate
|
||||
|
@ -513,6 +527,12 @@ RSpec.describe GlobalPolicy do
|
|||
it { is_expected.not_to be_allowed(:log_in) }
|
||||
end
|
||||
|
||||
context 'security bot' do
|
||||
let(:current_user) { security_bot }
|
||||
|
||||
it { is_expected.not_to be_allowed(:log_in) }
|
||||
end
|
||||
|
||||
context 'user blocked pending approval' do
|
||||
before do
|
||||
current_user.block_pending_approval
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
# user GET /users/:username/
|
||||
# user GET /:username
|
||||
# user_ssh_keys GET /:username.keys
|
||||
# user_groups GET /users/:username/groups(.:format)
|
||||
# user_projects GET /users/:username/projects(.:format)
|
||||
# user_contributed_projects GET /users/:username/contributed(.:format)
|
||||
|
@ -32,6 +33,13 @@ RSpec.describe UsersController, "routing" do
|
|||
expect(get("/users/User/snippets")).to route_to('users#snippets', username: 'User')
|
||||
end
|
||||
|
||||
# get all the ssh-keys of a user
|
||||
it "to #ssh_keys" do
|
||||
allow_any_instance_of(::Constraints::UserUrlConstrainer).to receive(:matches?).and_return(true)
|
||||
|
||||
expect(get("/User.keys")).to route_to('users#ssh_keys', username: 'User')
|
||||
end
|
||||
|
||||
it "to #calendar" do
|
||||
expect(get("/users/User/calendar")).to route_to('users#calendar', username: 'User')
|
||||
end
|
||||
|
@ -171,12 +179,6 @@ RSpec.describe Profiles::KeysController, "routing" do
|
|||
it "to #destroy" do
|
||||
expect(delete("/profile/keys/1")).to route_to('profiles/keys#destroy', id: '1')
|
||||
end
|
||||
|
||||
it "to #get_keys" do
|
||||
allow_any_instance_of(::Constraints::UserUrlConstrainer).to receive(:matches?).and_return(true)
|
||||
|
||||
expect(get("/foo.keys")).to route_to('profiles/keys#get_keys', username: 'foo')
|
||||
end
|
||||
end
|
||||
|
||||
# keys GET /gpg_keys gpg_keys#index
|
||||
|
|
|
@ -242,15 +242,39 @@ module TestEnv
|
|||
|
||||
def setup_workhorse
|
||||
start = Time.now
|
||||
return if skip_compile_workhorse?
|
||||
|
||||
puts "\n==> Setting up GitLab Workhorse..."
|
||||
|
||||
FileUtils.rm_rf(workhorse_dir)
|
||||
Gitlab::SetupHelper::Workhorse.compile_into(workhorse_dir)
|
||||
Gitlab::SetupHelper::Workhorse.create_configuration(workhorse_dir, nil)
|
||||
|
||||
File.write(workhorse_tree_file, workhorse_tree) if workhorse_source_clean?
|
||||
|
||||
puts " GitLab Workhorse set up in #{Time.now - start} seconds...\n"
|
||||
end
|
||||
|
||||
def skip_compile_workhorse?
|
||||
File.directory?(workhorse_dir) &&
|
||||
workhorse_source_clean? &&
|
||||
File.exist?(workhorse_tree_file) &&
|
||||
workhorse_tree == File.read(workhorse_tree_file)
|
||||
end
|
||||
|
||||
def workhorse_source_clean?
|
||||
out = IO.popen(%w[git status --porcelain workhorse], &:read)
|
||||
$?.success? && out.empty?
|
||||
end
|
||||
|
||||
def workhorse_tree
|
||||
IO.popen(%w[git rev-parse HEAD:workhorse], &:read)
|
||||
end
|
||||
|
||||
def workhorse_tree_file
|
||||
File.join(workhorse_dir, 'WORKHORSE_TREE')
|
||||
end
|
||||
|
||||
def workhorse_dir
|
||||
@workhorse_path ||= File.join('tmp', 'tests', 'gitlab-workhorse')
|
||||
end
|
||||
|
|
|
@ -6,6 +6,7 @@ RSpec.describe PurgeDependencyProxyCacheWorker do
|
|||
let_it_be(:user) { create(:admin) }
|
||||
let_it_be(:blob) { create(:dependency_proxy_blob )}
|
||||
let_it_be(:group, reload: true) { blob.group }
|
||||
let_it_be(:manifest) { create(:dependency_proxy_manifest, group: group )}
|
||||
let_it_be(:group_id) { group.id }
|
||||
|
||||
subject { described_class.new.perform(user.id, group_id) }
|
||||
|
@ -17,8 +18,9 @@ RSpec.describe PurgeDependencyProxyCacheWorker do
|
|||
|
||||
describe '#perform' do
|
||||
shared_examples 'returns nil' do
|
||||
it 'returns nil' do
|
||||
it 'returns nil', :aggregate_failures do
|
||||
expect { subject }.not_to change { group.dependency_proxy_blobs.size }
|
||||
expect { subject }.not_to change { group.dependency_proxy_manifests.size }
|
||||
expect(subject).to be_nil
|
||||
end
|
||||
end
|
||||
|
@ -27,12 +29,14 @@ RSpec.describe PurgeDependencyProxyCacheWorker do
|
|||
include_examples 'an idempotent worker' do
|
||||
let(:job_args) { [user.id, group_id] }
|
||||
|
||||
it 'deletes the blobs and returns ok' do
|
||||
it 'deletes the blobs and returns ok', :aggregate_failures do
|
||||
expect(group.dependency_proxy_blobs.size).to eq(1)
|
||||
expect(group.dependency_proxy_manifests.size).to eq(1)
|
||||
|
||||
subject
|
||||
|
||||
expect(group.dependency_proxy_blobs.size).to eq(0)
|
||||
expect(group.dependency_proxy_manifests.size).to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue