Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-12-11 18:09:57 +00:00
parent a8704bd33c
commit 3172281335
72 changed files with 538 additions and 340 deletions

View File

@ -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:

View File

@ -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.

View File

@ -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"

View File

@ -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'

View File

@ -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)

View File

@ -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>

View File

@ -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">

View File

@ -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',

View File

@ -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',
},
};

View File

@ -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()

View File

@ -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%);
}
}

View File

@ -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

View File

@ -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)

View File

@ -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' }

View File

@ -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

View File

@ -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

View File

@ -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? }

View File

@ -49,6 +49,10 @@ module PolicyActor
false
end
def security_bot?
false
end
def deactivated?
false
end

View File

@ -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

View File

@ -75,3 +75,5 @@ class PipelineSerializer < BaseSerializer
]
end
end
PipelineSerializer.prepend_if_ee('EE::PipelineSerializer')

View File

@ -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'

View File

@ -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 }

View File

@ -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

View File

@ -0,0 +1,5 @@
---
title: Delete manifests when purging the dependency proxy using the API
merge_request: 49056
author:
type: changed

View File

@ -0,0 +1,5 @@
---
title: Update ide pipeline alert to use gitlab ui
merge_request: 49634
author:
type: changed

View File

@ -0,0 +1,5 @@
---
title: Allow downloading of security reports directly from merge request page
merge_request: 49572
author:
type: added

View File

@ -0,0 +1,5 @@
---
title: Add issue header mobile dropdown loading state
merge_request: 49734
author:
type: added

View File

@ -0,0 +1,5 @@
---
title: Merge 'Sample Data' and 'Built-in' tabs on Project Templates page
merge_request: 49374
author:
type: changed

View File

@ -0,0 +1,5 @@
---
title: Use GitLab UI styles on Integrations page
merge_request: 47478
author:
type: changed

View File

@ -0,0 +1,5 @@
---
title: Move profiles/keys#get_keys to users#ssh_keys
merge_request: 48991
author: Takuya Noguchi
type: other

View File

@ -0,0 +1,5 @@
---
title: Upgrade mailroom to v0.0.8
merge_request: 49834
author:
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Improve the performance of the diff change access check
merge_request: 49803
author:
type: performance

View File

@ -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

View File

@ -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

View File

@ -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 }

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -147,7 +147,7 @@ Keep the following in mind when submitting merge requests:
- If the code quality is found to not meet GitLabs 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 codes overall quality. When there is a reservation,
the reviewer will inform the author and provide some guidance.

View File

@ -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).

View File

@ -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,

View File

@ -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:

View File

@ -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

View File

@ -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`.

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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. |

View File

@ -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.

View File

@ -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])

View File

@ -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

View File

@ -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

View File

@ -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 ""

View File

@ -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

View File

@ -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

View File

@ -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) }

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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