Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
4ab67d6529
commit
7f408a3831
47 changed files with 379 additions and 148 deletions
|
@ -137,7 +137,6 @@ linters:
|
|||
- Style/ParenthesesAroundCondition
|
||||
- Style/RedundantParentheses
|
||||
- Style/SelfAssignment
|
||||
- Style/Semicolon
|
||||
- Style/TernaryParentheses
|
||||
- Style/TrailingCommaInHashLiteral
|
||||
- Style/UnlessElse
|
||||
|
|
|
@ -1 +1 @@
|
|||
4ea88e921af65ba0577c40f8b54830c97adaa56c
|
||||
8752fc1097114316889560502579ddf477a20a2d
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<script>
|
||||
import { GlTooltipDirective, GlIcon, GlLink, GlSafeHtmlDirective } from '@gitlab/ui';
|
||||
import { ApolloMutation } from 'vue-apollo';
|
||||
import { __ } from '~/locale';
|
||||
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
|
||||
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
|
||||
|
@ -10,6 +11,9 @@ import { findNoteId, extractDesignNoteId } from '../../utils/design_management_u
|
|||
import DesignReplyForm from './design_reply_form.vue';
|
||||
|
||||
export default {
|
||||
i18n: {
|
||||
editCommentLabel: __('Edit comment'),
|
||||
},
|
||||
components: {
|
||||
UserAvatarLink,
|
||||
TimelineEntryItem,
|
||||
|
@ -113,7 +117,8 @@ export default {
|
|||
v-if="isEditButtonVisible"
|
||||
v-gl-tooltip
|
||||
type="button"
|
||||
:title="__('Edit comment')"
|
||||
:title="$options.i18n.editCommentLabel"
|
||||
:aria-label="$options.i18n.editCommentLabel"
|
||||
class="note-action-button js-note-edit btn btn-transparent qa-note-edit-button"
|
||||
@click="isEditing = true"
|
||||
>
|
||||
|
|
|
@ -68,6 +68,7 @@ export default {
|
|||
}"
|
||||
type="button"
|
||||
class="js-diff-notes-toggle"
|
||||
:aria-label="__('Show comments')"
|
||||
@click="toggleDiscussion({ discussionId: discussion.id })"
|
||||
>
|
||||
<gl-icon v-if="discussion.expanded" name="collapse" class="collapse-icon" />
|
||||
|
|
|
@ -122,6 +122,7 @@ export default {
|
|||
:disabled="!shouldToggleDiscussion"
|
||||
class="js-image-badge"
|
||||
type="button"
|
||||
:aria-label="__('Show comments')"
|
||||
@click="clickedToggle(discussion)"
|
||||
>
|
||||
<gl-icon v-if="showCommentIcon" name="image-comment-dark" :size="24" />
|
||||
|
|
|
@ -146,6 +146,7 @@ export default {
|
|||
type="button"
|
||||
class="add-diff-note note-button js-add-diff-note-button"
|
||||
:disabled="line.commentsDisabled"
|
||||
:aria-label="addCommentTooltip"
|
||||
@click="handleCommentButton"
|
||||
>
|
||||
<gl-icon :size="12" name="comment" />
|
||||
|
|
|
@ -195,6 +195,7 @@ export default {
|
|||
type="button"
|
||||
class="add-diff-note note-button js-add-diff-note-button qa-diff-comment"
|
||||
:disabled="line.left.commentsDisabled"
|
||||
:aria-label="addCommentTooltipLeft"
|
||||
@click="handleCommentButton(line.left)"
|
||||
>
|
||||
<gl-icon :size="12" name="comment" />
|
||||
|
@ -252,6 +253,7 @@ export default {
|
|||
type="button"
|
||||
class="add-diff-note note-button js-add-diff-note-button qa-diff-comment"
|
||||
:disabled="line.right.commentsDisabled"
|
||||
:aria-label="addCommentTooltipRight"
|
||||
@click="handleCommentButton(line.right)"
|
||||
>
|
||||
<gl-icon :size="12" name="comment" />
|
||||
|
|
|
@ -105,6 +105,7 @@ export default {
|
|||
}"
|
||||
type="button"
|
||||
class="gl-border-0 gl-border-b-2 gl-border-b-solid gl-flex-fill-1 gl-text-gray-300 gl-pt-3 gl-pb-3 gl-bg-transparent emoji-picker-category-tab"
|
||||
:aria-label="category.name"
|
||||
@click="scrollToCategory(category.name)"
|
||||
>
|
||||
<gl-icon :name="category.icon" :size="12" />
|
||||
|
|
|
@ -51,6 +51,7 @@ export default {
|
|||
v-gl-tooltip.hover
|
||||
class="gl-display-block gl-mb-4 mb-md-0 gl-w-full"
|
||||
:title="ignoreBtn.title"
|
||||
:aria-label="ignoreBtn.title"
|
||||
@click="$emit('update-issue-status', { errorId: error.id, status: ignoreBtn.status })"
|
||||
>
|
||||
<gl-icon class="gl-display-none d-md-inline gl-m-0" :name="ignoreBtn.icon" :size="12" />
|
||||
|
@ -62,6 +63,7 @@ export default {
|
|||
v-gl-tooltip.hover
|
||||
class="gl-display-block gl-mb-4 mb-md-0 gl-w-full"
|
||||
:title="resolveBtn.title"
|
||||
:aria-label="resolveBtn.title"
|
||||
@click="$emit('update-issue-status', { errorId: error.id, status: resolveBtn.status })"
|
||||
>
|
||||
<gl-icon class="gl-display-none d-md-inline gl-m-0" :name="resolveBtn.icon" :size="12" />
|
||||
|
|
|
@ -55,6 +55,7 @@ export default {
|
|||
:disabled="disabled"
|
||||
class="btn-scroll btn-transparent btn-blank"
|
||||
type="button"
|
||||
:aria-label="tooltipTitle"
|
||||
@click="clickedScroll"
|
||||
>
|
||||
<gl-icon :name="iconName" />
|
||||
|
|
|
@ -22,8 +22,8 @@ export const fetchBranches = ({ commit, dispatch, state }, query) => {
|
|||
.get(state.branchesEndpoint, {
|
||||
params: { search: query },
|
||||
})
|
||||
.then(({ data }) => {
|
||||
commit(types.RECEIVE_BRANCHES_SUCCESS, data.Branches || []);
|
||||
.then(({ data = [] }) => {
|
||||
commit(types.RECEIVE_BRANCHES_SUCCESS, data.Branches?.length ? data.Branches : data);
|
||||
})
|
||||
.catch(() => {
|
||||
createFlash({ message: PROJECT_BRANCHES_ERROR });
|
||||
|
|
|
@ -9,10 +9,13 @@ import {
|
|||
GlSkeletonLoader,
|
||||
GlTooltipDirective,
|
||||
} from '@gitlab/ui';
|
||||
|
||||
import { __ } from '~/locale';
|
||||
import { ANY_OPTION } from '../constants';
|
||||
|
||||
export default {
|
||||
i18n: {
|
||||
clearLabel: __('Clear'),
|
||||
},
|
||||
name: 'SearchableDropdown',
|
||||
components: {
|
||||
GlDropdown,
|
||||
|
@ -96,7 +99,8 @@ export default {
|
|||
v-gl-tooltip
|
||||
name="clear"
|
||||
category="tertiary"
|
||||
:title="__('Clear')"
|
||||
:title="$options.i18n.clearLabel"
|
||||
:aria-label="$options.i18n.clearLabel"
|
||||
class="gl-p-0! gl-mr-2"
|
||||
@keydown.enter.stop="resetDropdown"
|
||||
@click.stop="resetDropdown"
|
||||
|
|
|
@ -68,6 +68,7 @@ export default {
|
|||
category="primary"
|
||||
size="small"
|
||||
:title="buttonTitle"
|
||||
:aria-label="buttonTitle"
|
||||
:loading="isLoading"
|
||||
:disabled="isActionInProgress"
|
||||
:class="`inline gl-ml-2 ${containerClasses}`"
|
||||
|
|
|
@ -25,7 +25,7 @@ export default {
|
|||
</script>
|
||||
<template>
|
||||
<span>
|
||||
<gl-button ref="popoverTrigger" variant="link" icon="question" tabindex="0" />
|
||||
<gl-button ref="popoverTrigger" variant="link" icon="question" :aria-label="__('Help')" />
|
||||
<gl-popover :target="() => $refs.popoverTrigger.$el" v-bind="options">
|
||||
<template v-if="options.title" #title>
|
||||
<span v-safe-html="options.title"></span>
|
||||
|
|
|
@ -21,7 +21,11 @@ export default {
|
|||
};
|
||||
</script>
|
||||
<template>
|
||||
<button v-gl-tooltip="{ title: tooltip }" class="p-0 gl-display-flex toolbar-button">
|
||||
<button
|
||||
v-gl-tooltip="{ title: tooltip }"
|
||||
:aria-label="tooltip"
|
||||
class="p-0 gl-display-flex toolbar-button"
|
||||
>
|
||||
<gl-icon class="gl-mx-auto gl-align-self-center" :name="icon" />
|
||||
</button>
|
||||
</template>
|
||||
|
|
|
@ -13,7 +13,7 @@ module Packages
|
|||
return ::Packages::Package.none unless within_group
|
||||
return ::Packages::Package.none unless Ability.allowed?(user, :read_group, within_group)
|
||||
|
||||
projects = projects_visible_to_reporters(user, within_group.self_and_descendants.select(:id))
|
||||
projects = projects_visible_to_reporters(user, within_group: within_group)
|
||||
::Packages::Package.for_projects(projects.select(:id))
|
||||
end
|
||||
|
||||
|
@ -21,12 +21,16 @@ module Packages
|
|||
return ::Project.none unless within_group
|
||||
return ::Project.none unless Ability.allowed?(user, :read_group, within_group)
|
||||
|
||||
projects_visible_to_reporters(user, within_group.self_and_descendants.select(:id))
|
||||
projects_visible_to_reporters(user, within_group: within_group)
|
||||
end
|
||||
|
||||
def projects_visible_to_reporters(user, namespace_ids)
|
||||
::Project.in_namespace(namespace_ids)
|
||||
.public_or_visible_to_user(user, ::Gitlab::Access::REPORTER)
|
||||
def projects_visible_to_reporters(user, within_group:)
|
||||
if user.is_a?(DeployToken) && Feature.enabled?(:packages_finder_helper_deploy_token)
|
||||
user.accessible_projects
|
||||
else
|
||||
within_group.all_projects
|
||||
.public_or_visible_to_user(user, ::Gitlab::Access::REPORTER)
|
||||
end
|
||||
end
|
||||
|
||||
def package_type
|
||||
|
|
|
@ -76,7 +76,7 @@ module Packages
|
|||
|
||||
def group_level_improvements?
|
||||
strong_memoize(:group_level_improvements) do
|
||||
Feature.enabled?(:maven_packages_group_level_improvements)
|
||||
Feature.enabled?(:maven_packages_group_level_improvements, default_enabled: :yaml)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -137,14 +137,6 @@ module Issuable
|
|||
scope :references_project, -> { references(:project) }
|
||||
scope :non_archived, -> { join_project.where(projects: { archived: false }) }
|
||||
|
||||
scope :includes_for_bulk_update, -> do
|
||||
associations = %i[author assignees epic group labels metrics project source_project target_project].select do |association|
|
||||
reflect_on_association(association)
|
||||
end
|
||||
|
||||
includes(*associations)
|
||||
end
|
||||
|
||||
attr_mentionable :title, pipeline: :single_line
|
||||
attr_mentionable :description
|
||||
|
||||
|
|
|
@ -39,13 +39,11 @@ module Milestoneable
|
|||
private
|
||||
|
||||
def milestone_is_valid
|
||||
errors.add(:milestone_id, 'is invalid') if respond_to?(:milestone_id) && !milestone_available?
|
||||
errors.add(:milestone_id, 'is invalid') if respond_to?(:milestone_id) && milestone_id.present? && !milestone_available?
|
||||
end
|
||||
end
|
||||
|
||||
def milestone_available?
|
||||
return true if milestone_id.blank?
|
||||
|
||||
project_id == milestone&.project_id || project.ancestors_upto.compact.include?(milestone&.group)
|
||||
end
|
||||
|
||||
|
|
|
@ -138,7 +138,7 @@ class Packages::Package < ApplicationRecord
|
|||
after_commit :update_composer_cache, on: :destroy, if: -> { composer? }
|
||||
|
||||
def self.for_projects(projects)
|
||||
unless Feature.enabled?(:maven_packages_group_level_improvements)
|
||||
unless Feature.enabled?(:maven_packages_group_level_improvements, default_enabled: :yaml)
|
||||
return none unless projects.any?
|
||||
end
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ module Issuable
|
|||
set_update_params(type)
|
||||
items = update_issuables(type, ids)
|
||||
|
||||
response_success(payload: { count: items.size })
|
||||
response_success(payload: { count: items.count })
|
||||
rescue ArgumentError => e
|
||||
response_error(e.message, 422)
|
||||
end
|
||||
|
@ -59,17 +59,10 @@ module Issuable
|
|||
|
||||
def find_issuables(parent, model_class, ids)
|
||||
if parent.is_a?(Project)
|
||||
projects = parent
|
||||
model_class.id_in(ids).of_projects(parent)
|
||||
elsif parent.is_a?(Group)
|
||||
projects = parent.all_projects
|
||||
else
|
||||
return
|
||||
model_class.id_in(ids).of_projects(parent.all_projects)
|
||||
end
|
||||
|
||||
model_class
|
||||
.id_in(ids)
|
||||
.of_projects(projects)
|
||||
.includes_for_bulk_update
|
||||
end
|
||||
|
||||
def response_success(message: nil, payload: nil)
|
||||
|
|
|
@ -143,8 +143,12 @@ module MergeRequests
|
|||
merge_request, merge_request.project, current_user, old_reviewers)
|
||||
end
|
||||
|
||||
def create_pipeline_for(merge_request, user)
|
||||
MergeRequests::CreatePipelineService.new(project, user).execute(merge_request)
|
||||
def create_pipeline_for(merge_request, user, async: false)
|
||||
if async
|
||||
MergeRequests::CreatePipelineWorker.perform_async(project.id, user.id, merge_request.id)
|
||||
else
|
||||
MergeRequests::CreatePipelineService.new(project, user).execute(merge_request)
|
||||
end
|
||||
end
|
||||
|
||||
def abort_auto_merge(merge_request, reason)
|
||||
|
|
|
@ -162,9 +162,12 @@ module MergeRequests
|
|||
end
|
||||
|
||||
def refresh_pipelines_on_merge_requests(merge_request)
|
||||
create_pipeline_for(merge_request, current_user)
|
||||
|
||||
UpdateHeadPipelineForMergeRequestWorker.perform_async(merge_request.id)
|
||||
if Feature.enabled?(:code_review_async_pipeline_creation, project, default_enabled: :yaml)
|
||||
create_pipeline_for(merge_request, current_user, async: true)
|
||||
else
|
||||
create_pipeline_for(merge_request, current_user, async: false)
|
||||
UpdateHeadPipelineForMergeRequestWorker.perform_async(merge_request.id)
|
||||
end
|
||||
end
|
||||
|
||||
def abort_auto_merges(merge_request)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
-# We currently only support `alert`, `notice`, `success`, 'toast'
|
||||
- icons = {'alert' => 'error', 'notice' => 'information-o', 'success' => 'check-circle'};
|
||||
- icons = {'alert' => 'error', 'notice' => 'information-o', 'success' => 'check-circle'}
|
||||
.flash-container.flash-container-page.sticky{ data: { qa_selector: 'flash_container' } }
|
||||
- flash.each do |key, value|
|
||||
- if key == 'toast' && value
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
- modifier_key = client_js_flags[:isMac] ? '⌘' : s_('KeyboardKey|Ctrl+');
|
||||
- modifier_key = client_js_flags[:isMac] ? '⌘' : s_('KeyboardKey|Ctrl+')
|
||||
|
||||
.md-header-toolbar.active
|
||||
= markdown_toolbar_button({ icon: "bold",
|
||||
|
|
|
@ -1227,6 +1227,14 @@
|
|||
:weight: 4
|
||||
:idempotent:
|
||||
:tags: []
|
||||
- :name: pipeline_creation:merge_requests_create_pipeline
|
||||
:feature_category: :continuous_integration
|
||||
:has_external_dependencies:
|
||||
:urgency: :high
|
||||
:resource_boundary: :cpu
|
||||
:weight: 4
|
||||
:idempotent: true
|
||||
:tags: []
|
||||
- :name: pipeline_creation:run_pipeline_schedule
|
||||
:feature_category: :continuous_integration
|
||||
:has_external_dependencies:
|
||||
|
|
28
app/workers/merge_requests/create_pipeline_worker.rb
Normal file
28
app/workers/merge_requests/create_pipeline_worker.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module MergeRequests
|
||||
class CreatePipelineWorker
|
||||
include ApplicationWorker
|
||||
include PipelineQueue
|
||||
|
||||
queue_namespace :pipeline_creation
|
||||
feature_category :continuous_integration
|
||||
urgency :high
|
||||
worker_resource_boundary :cpu
|
||||
idempotent!
|
||||
|
||||
def perform(project_id, user_id, merge_request_id)
|
||||
project = Project.find_by_id(project_id)
|
||||
return unless project
|
||||
|
||||
user = User.find_by_id(user_id)
|
||||
return unless user
|
||||
|
||||
merge_request = MergeRequest.find_by_id(merge_request_id)
|
||||
return unless merge_request
|
||||
|
||||
MergeRequests::CreatePipelineService.new(project, user).execute(merge_request)
|
||||
merge_request.update_head_pipeline
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Optimize issuable updates
|
||||
merge_request: 58114
|
||||
author:
|
||||
type: performance
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Update gatsby project template to address the pipeline failure
|
||||
merge_request: 37410
|
||||
author: Takuya Noguchi
|
||||
type: fixed
|
5
changelogs/unreleased/326099-enabled-by-default.yml
Normal file
5
changelogs/unreleased/326099-enabled-by-default.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Reduce the number of SQL queries executed on Maven file API endpoints
|
||||
merge_request: 59136
|
||||
author:
|
||||
type: performance
|
5
changelogs/unreleased/327064-fix-revert-query.yml
Normal file
5
changelogs/unreleased/327064-fix-revert-query.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix revert commit query
|
||||
merge_request: 59356
|
||||
author:
|
||||
type: fixed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add aria labels to icon-only buttons
|
||||
merge_request: 59037
|
||||
author:
|
||||
type: fixed
|
5
changelogs/unreleased/move_pipeline_creation_async.yml
Normal file
5
changelogs/unreleased/move_pipeline_creation_async.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Create the pipelines asynchronously when refreshing merge requests
|
||||
merge_request: 58542
|
||||
author:
|
||||
type: performance
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: code_review_async_pipeline_creation
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58542
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/327559
|
||||
milestone: '13.11'
|
||||
type: development
|
||||
group: group::code review
|
||||
default_enabled: false
|
|
@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/326099
|
|||
milestone: '13.11'
|
||||
type: development
|
||||
group: group::package
|
||||
default_enabled: false
|
||||
default_enabled: true
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: packages_finder_helper_deploy_token
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58497
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/326808
|
||||
milestone: '13.11'
|
||||
type: development
|
||||
group: group::package
|
||||
default_enabled: false
|
|
@ -177,7 +177,7 @@ Find where your version sits in the upgrade path below, and upgrade GitLab
|
|||
accordingly, while also consulting the
|
||||
[version-specific upgrade instructions](#version-specific-upgrading-instructions):
|
||||
|
||||
`8.11.Z` -> `8.12.0` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` -> `13.0.14` -> `13.1.11` -> `13.5.4` - > [latest `13.Y.Z`](https://about.gitlab.com/releases/categories/releases/)
|
||||
`8.11.Z` -> `8.12.0` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` -> `13.0.14` -> `13.1.11` -> [latest `13.Y.Z`](https://about.gitlab.com/releases/categories/releases/)
|
||||
|
||||
The following table, while not exhaustive, shows some examples of the supported
|
||||
upgrade paths.
|
||||
|
|
|
@ -80,7 +80,7 @@ module API
|
|||
|
||||
def fetch_package(file_name:, project: nil, group: nil)
|
||||
order_by_package_file = false
|
||||
if Feature.enabled?(:maven_packages_group_level_improvements)
|
||||
if Feature.enabled?(:maven_packages_group_level_improvements, default_enabled: :yaml)
|
||||
order_by_package_file = file_name.include?(::Packages::Maven::Metadata.filename) &&
|
||||
!params[:path].include?(::Packages::Maven::FindOrCreatePackageService::SNAPSHOT_TERM)
|
||||
end
|
||||
|
|
|
@ -62,6 +62,7 @@ FactoryBot.define do
|
|||
project_key { nil }
|
||||
vulnerabilities_enabled { false }
|
||||
vulnerabilities_issuetype { nil }
|
||||
deployment_type { 'cloud' }
|
||||
end
|
||||
|
||||
before(:create) do |service, evaluator|
|
||||
|
@ -72,7 +73,7 @@ FactoryBot.define do
|
|||
jira_issue_transition_id: evaluator.jira_issue_transition_id,
|
||||
username: evaluator.username, password: evaluator.password, issues_enabled: evaluator.issues_enabled,
|
||||
project_key: evaluator.project_key, vulnerabilities_enabled: evaluator.vulnerabilities_enabled,
|
||||
vulnerabilities_issuetype: evaluator.vulnerabilities_issuetype
|
||||
vulnerabilities_issuetype: evaluator.vulnerabilities_issuetype, deployment_type: evaluator.deployment_type
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,7 +6,6 @@ RSpec.describe ::Packages::FinderHelper do
|
|||
describe '#packages_visible_to_user' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be_with_reload(:group) { create(:group) }
|
||||
let_it_be_with_reload(:project1) { create(:project, namespace: group) }
|
||||
let_it_be(:package1) { create(:package, project: project1) }
|
||||
|
@ -44,41 +43,87 @@ RSpec.describe ::Packages::FinderHelper do
|
|||
it { is_expected.to be_empty }
|
||||
end
|
||||
|
||||
where(:group_visibility, :subgroup_visibility, :project2_visibility, :user_role, :shared_example_name) do
|
||||
'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :maintainer | 'returning both packages'
|
||||
'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :developer | 'returning both packages'
|
||||
'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :guest | 'returning both packages'
|
||||
'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :anonymous | 'returning both packages'
|
||||
'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :maintainer | 'returning both packages'
|
||||
'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :developer | 'returning both packages'
|
||||
'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :guest | 'returning package1'
|
||||
'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :anonymous | 'returning package1'
|
||||
'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :maintainer | 'returning both packages'
|
||||
'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :developer | 'returning both packages'
|
||||
'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :guest | 'returning package1'
|
||||
'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :anonymous | 'returning package1'
|
||||
'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :maintainer | 'returning both packages'
|
||||
'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :developer | 'returning both packages'
|
||||
'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :guest | 'returning no packages'
|
||||
'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :anonymous | 'returning no packages'
|
||||
end
|
||||
context 'with a user' do
|
||||
let_it_be(:user) { create(:user) }
|
||||
|
||||
with_them do
|
||||
before do
|
||||
unless user_role == :anonymous
|
||||
group.send("add_#{user_role}", user)
|
||||
subgroup.send("add_#{user_role}", user)
|
||||
project1.send("add_#{user_role}", user)
|
||||
project2.send("add_#{user_role}", user)
|
||||
end
|
||||
|
||||
project2.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project2_visibility, false))
|
||||
subgroup.update!(visibility_level: Gitlab::VisibilityLevel.const_get(subgroup_visibility, false))
|
||||
project1.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility, false))
|
||||
group.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility, false))
|
||||
where(:group_visibility, :subgroup_visibility, :project2_visibility, :user_role, :shared_example_name) do
|
||||
'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :maintainer | 'returning both packages'
|
||||
'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :developer | 'returning both packages'
|
||||
'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :guest | 'returning both packages'
|
||||
'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :anonymous | 'returning both packages'
|
||||
'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :maintainer | 'returning both packages'
|
||||
'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :developer | 'returning both packages'
|
||||
'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :guest | 'returning package1'
|
||||
'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :anonymous | 'returning package1'
|
||||
'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :maintainer | 'returning both packages'
|
||||
'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :developer | 'returning both packages'
|
||||
'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :guest | 'returning package1'
|
||||
'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :anonymous | 'returning package1'
|
||||
'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :maintainer | 'returning both packages'
|
||||
'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :developer | 'returning both packages'
|
||||
'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :guest | 'returning no packages'
|
||||
'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :anonymous | 'returning no packages'
|
||||
end
|
||||
|
||||
it_behaves_like params[:shared_example_name]
|
||||
with_them do
|
||||
before do
|
||||
unless user_role == :anonymous
|
||||
group.send("add_#{user_role}", user)
|
||||
subgroup.send("add_#{user_role}", user)
|
||||
project1.send("add_#{user_role}", user)
|
||||
project2.send("add_#{user_role}", user)
|
||||
end
|
||||
|
||||
project2.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project2_visibility, false))
|
||||
subgroup.update!(visibility_level: Gitlab::VisibilityLevel.const_get(subgroup_visibility, false))
|
||||
project1.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility, false))
|
||||
group.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility, false))
|
||||
end
|
||||
|
||||
it_behaves_like params[:shared_example_name]
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a group deploy token' do
|
||||
let_it_be(:user) { create(:deploy_token, :group, read_package_registry: true) }
|
||||
let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: user, group: group) }
|
||||
|
||||
shared_examples 'handling all conditions' do
|
||||
where(:group_visibility, :subgroup_visibility, :project2_visibility, :shared_example_name) do
|
||||
'PUBLIC' | 'PUBLIC' | 'PUBLIC' | 'returning both packages'
|
||||
'PUBLIC' | 'PUBLIC' | 'PRIVATE' | 'returning both packages'
|
||||
'PUBLIC' | 'PRIVATE' | 'PRIVATE' | 'returning both packages'
|
||||
'PRIVATE' | 'PRIVATE' | 'PRIVATE' | 'returning both packages'
|
||||
end
|
||||
|
||||
with_them do
|
||||
before do
|
||||
project2.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project2_visibility, false))
|
||||
subgroup.update!(visibility_level: Gitlab::VisibilityLevel.const_get(subgroup_visibility, false))
|
||||
project1.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility, false))
|
||||
group.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility, false))
|
||||
end
|
||||
|
||||
it_behaves_like params[:shared_example_name]
|
||||
end
|
||||
end
|
||||
|
||||
context 'with packages_finder_helper_deploy_token enabled' do
|
||||
before do
|
||||
expect(group).not_to receive(:all_projects)
|
||||
end
|
||||
|
||||
it_behaves_like 'handling all conditions'
|
||||
end
|
||||
|
||||
context 'with packages_finder_helper_deploy_token disabled' do
|
||||
before do
|
||||
stub_feature_flags(packages_finder_helper_deploy_token: false)
|
||||
expect(group).to receive(:all_projects).and_call_original
|
||||
end
|
||||
|
||||
it_behaves_like 'handling all conditions'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -121,41 +166,87 @@ RSpec.describe ::Packages::FinderHelper do
|
|||
it { is_expected.to be_empty }
|
||||
end
|
||||
|
||||
where(:group_visibility, :subgroup_visibility, :project2_visibility, :user_role, :shared_example_name) do
|
||||
'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :maintainer | 'returning both projects'
|
||||
'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :developer | 'returning both projects'
|
||||
'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :guest | 'returning both projects'
|
||||
'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :anonymous | 'returning both projects'
|
||||
'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :maintainer | 'returning both projects'
|
||||
'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :developer | 'returning both projects'
|
||||
'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :guest | 'returning project1'
|
||||
'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :anonymous | 'returning project1'
|
||||
'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :maintainer | 'returning both projects'
|
||||
'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :developer | 'returning both projects'
|
||||
'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :guest | 'returning project1'
|
||||
'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :anonymous | 'returning project1'
|
||||
'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :maintainer | 'returning both projects'
|
||||
'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :developer | 'returning both projects'
|
||||
'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :guest | 'returning no project'
|
||||
'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :anonymous | 'returning no project'
|
||||
end
|
||||
context 'with a user' do
|
||||
let_it_be(:user) { create(:user) }
|
||||
|
||||
with_them do
|
||||
before do
|
||||
unless user_role == :anonymous
|
||||
group.send("add_#{user_role}", user)
|
||||
subgroup.send("add_#{user_role}", user)
|
||||
project1.send("add_#{user_role}", user)
|
||||
project2.send("add_#{user_role}", user)
|
||||
end
|
||||
|
||||
project2.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project2_visibility, false))
|
||||
subgroup.update!(visibility_level: Gitlab::VisibilityLevel.const_get(subgroup_visibility, false))
|
||||
project1.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility, false))
|
||||
group.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility, false))
|
||||
where(:group_visibility, :subgroup_visibility, :project2_visibility, :user_role, :shared_example_name) do
|
||||
'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :maintainer | 'returning both projects'
|
||||
'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :developer | 'returning both projects'
|
||||
'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :guest | 'returning both projects'
|
||||
'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :anonymous | 'returning both projects'
|
||||
'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :maintainer | 'returning both projects'
|
||||
'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :developer | 'returning both projects'
|
||||
'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :guest | 'returning project1'
|
||||
'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :anonymous | 'returning project1'
|
||||
'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :maintainer | 'returning both projects'
|
||||
'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :developer | 'returning both projects'
|
||||
'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :guest | 'returning project1'
|
||||
'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :anonymous | 'returning project1'
|
||||
'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :maintainer | 'returning both projects'
|
||||
'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :developer | 'returning both projects'
|
||||
'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :guest | 'returning no project'
|
||||
'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :anonymous | 'returning no project'
|
||||
end
|
||||
|
||||
it_behaves_like params[:shared_example_name]
|
||||
with_them do
|
||||
before do
|
||||
unless user_role == :anonymous
|
||||
group.send("add_#{user_role}", user)
|
||||
subgroup.send("add_#{user_role}", user)
|
||||
project1.send("add_#{user_role}", user)
|
||||
project2.send("add_#{user_role}", user)
|
||||
end
|
||||
|
||||
project2.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project2_visibility, false))
|
||||
subgroup.update!(visibility_level: Gitlab::VisibilityLevel.const_get(subgroup_visibility, false))
|
||||
project1.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility, false))
|
||||
group.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility, false))
|
||||
end
|
||||
|
||||
it_behaves_like params[:shared_example_name]
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a group deploy token' do
|
||||
let_it_be(:user) { create(:deploy_token, :group, read_package_registry: true) }
|
||||
let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: user, group: group) }
|
||||
|
||||
shared_examples 'handling all conditions' do
|
||||
where(:group_visibility, :subgroup_visibility, :project2_visibility, :shared_example_name) do
|
||||
'PUBLIC' | 'PUBLIC' | 'PUBLIC' | 'returning both projects'
|
||||
'PUBLIC' | 'PUBLIC' | 'PRIVATE' | 'returning both projects'
|
||||
'PUBLIC' | 'PRIVATE' | 'PRIVATE' | 'returning both projects'
|
||||
'PRIVATE' | 'PRIVATE' | 'PRIVATE' | 'returning both projects'
|
||||
end
|
||||
|
||||
with_them do
|
||||
before do
|
||||
project2.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project2_visibility, false))
|
||||
subgroup.update!(visibility_level: Gitlab::VisibilityLevel.const_get(subgroup_visibility, false))
|
||||
project1.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility, false))
|
||||
group.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility, false))
|
||||
end
|
||||
|
||||
it_behaves_like params[:shared_example_name]
|
||||
end
|
||||
end
|
||||
|
||||
context 'with packages_finder_helper_deploy_token enabled' do
|
||||
before do
|
||||
expect(group).not_to receive(:all_projects)
|
||||
end
|
||||
|
||||
it_behaves_like 'handling all conditions'
|
||||
end
|
||||
|
||||
context 'with packages_finder_helper_deploy_token disabled' do
|
||||
before do
|
||||
stub_feature_flags(packages_finder_helper_deploy_token: false)
|
||||
expect(group).to receive(:all_projects).and_call_original
|
||||
end
|
||||
|
||||
it_behaves_like 'handling all conditions'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -34,7 +34,6 @@ describe('HelpPopover', () => {
|
|||
icon: 'question',
|
||||
variant: 'link',
|
||||
});
|
||||
expect(findQuestionButton().attributes().tabindex).toBe('0');
|
||||
});
|
||||
|
||||
it('renders popover that uses the question button as target', () => {
|
||||
|
|
|
@ -65,23 +65,6 @@ RSpec.describe Issuable do
|
|||
it { expect(issuable_class).to respond_to(:opened) }
|
||||
it { expect(issuable_class).to respond_to(:closed) }
|
||||
it { expect(issuable_class).to respond_to(:assigned) }
|
||||
|
||||
describe '.includes_for_bulk_update' do
|
||||
before do
|
||||
stub_const('Example', Class.new(ActiveRecord::Base))
|
||||
|
||||
Example.class_eval do
|
||||
include Issuable # adds :labels and :metrics, among others
|
||||
|
||||
belongs_to :author
|
||||
has_many :assignees
|
||||
end
|
||||
end
|
||||
|
||||
it 'includes available associations' do
|
||||
expect(Example.includes_for_bulk_update.includes_values).to eq([:author, :assignees, :labels, :metrics])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'author_name' do
|
||||
|
|
|
@ -50,13 +50,13 @@ RSpec.describe Milestoneable do
|
|||
it 'returns true with a milestone from the issue project' do
|
||||
milestone = create(:milestone, project: project)
|
||||
|
||||
expect(build_milestoneable(milestone.id).milestone_available?).to be(true)
|
||||
expect(build_milestoneable(milestone.id).milestone_available?).to be_truthy
|
||||
end
|
||||
|
||||
it 'returns true with a milestone from the issue project group' do
|
||||
milestone = create(:milestone, group: group)
|
||||
|
||||
expect(build_milestoneable(milestone.id).milestone_available?).to be(true)
|
||||
expect(build_milestoneable(milestone.id).milestone_available?).to be_truthy
|
||||
end
|
||||
|
||||
it 'returns true with a milestone from the the parent of the issue project group' do
|
||||
|
@ -64,23 +64,19 @@ RSpec.describe Milestoneable do
|
|||
group.update!(parent: parent)
|
||||
milestone = create(:milestone, group: parent)
|
||||
|
||||
expect(build_milestoneable(milestone.id).milestone_available?).to be(true)
|
||||
end
|
||||
|
||||
it 'returns true with a blank milestone' do
|
||||
expect(build_milestoneable('').milestone_available?).to be(true)
|
||||
expect(build_milestoneable(milestone.id).milestone_available?).to be_truthy
|
||||
end
|
||||
|
||||
it 'returns false with a milestone from another project' do
|
||||
milestone = create(:milestone)
|
||||
|
||||
expect(build_milestoneable(milestone.id).milestone_available?).to be(false)
|
||||
expect(build_milestoneable(milestone.id).milestone_available?).to be_falsey
|
||||
end
|
||||
|
||||
it 'returns false with a milestone from another group' do
|
||||
milestone = create(:milestone, group: create(:group))
|
||||
|
||||
expect(build_milestoneable(milestone.id).milestone_available?).to be(false)
|
||||
expect(build_milestoneable(milestone.id).milestone_available?).to be_falsey
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -387,7 +387,7 @@ RSpec.describe API::MavenPackages do
|
|||
|
||||
subject
|
||||
|
||||
status = Feature.enabled?(:maven_packages_group_level_improvements) ? :not_found : :forbidden
|
||||
status = Feature.enabled?(:maven_packages_group_level_improvements, default_enabled: :yaml) ? :not_found : :forbidden
|
||||
expect(response).to have_gitlab_http_status(status)
|
||||
end
|
||||
|
||||
|
|
|
@ -198,7 +198,7 @@ RSpec.describe MergeRequests::RefreshService do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'Pipelines for merge requests' do
|
||||
shared_examples 'Pipelines for merge requests' do
|
||||
before do
|
||||
stub_ci_pipeline_yaml_file(config)
|
||||
end
|
||||
|
@ -256,7 +256,7 @@ RSpec.describe MergeRequests::RefreshService do
|
|||
stub_feature_flags(ci_disallow_to_create_merge_request_pipelines_in_target_project: false)
|
||||
end
|
||||
|
||||
it 'creates detached merge request pipeline for fork merge request', :sidekiq_inline do
|
||||
it 'creates detached merge request pipeline for fork merge request' do
|
||||
expect { subject }
|
||||
.to change { @fork_merge_request.pipelines_for_merge_request.count }.by(1)
|
||||
|
||||
|
@ -364,6 +364,18 @@ RSpec.describe MergeRequests::RefreshService do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when the code_review_async_pipeline_creation feature flag is on', :sidekiq_inline do
|
||||
it_behaves_like 'Pipelines for merge requests'
|
||||
end
|
||||
|
||||
context 'when the code_review_async_pipeline_creation feature flag is off', :sidekiq_inline do
|
||||
before do
|
||||
stub_feature_flags(code_review_async_pipeline_creation: false)
|
||||
end
|
||||
|
||||
it_behaves_like 'Pipelines for merge requests'
|
||||
end
|
||||
|
||||
context 'push to origin repo source branch' do
|
||||
let(:refresh_service) { service.new(@project, @user) }
|
||||
let(:notification_service) { spy('notification_service') }
|
||||
|
|
61
spec/workers/merge_requests/create_pipeline_worker_spec.rb
Normal file
61
spec/workers/merge_requests/create_pipeline_worker_spec.rb
Normal file
|
@ -0,0 +1,61 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe MergeRequests::CreatePipelineWorker do
|
||||
subject(:worker) { described_class.new }
|
||||
|
||||
describe '#perform' do
|
||||
let(:user) { create(:user) }
|
||||
let(:project) { create(:project) }
|
||||
let(:merge_request) { create(:merge_request) }
|
||||
|
||||
context 'when the objects exist' do
|
||||
it 'calls the merge request create pipeline service and calls update head pipeline' do
|
||||
aggregate_failures do
|
||||
expect_next_instance_of(MergeRequests::CreatePipelineService, project, user) do |service|
|
||||
expect(service).to receive(:execute).with(merge_request)
|
||||
end
|
||||
|
||||
expect(MergeRequest).to receive(:find_by_id).with(merge_request.id).and_return(merge_request)
|
||||
expect(merge_request).to receive(:update_head_pipeline)
|
||||
|
||||
subject.perform(project.id, user.id, merge_request.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'when object does not exist' do
|
||||
it 'does not call the create pipeline service' do
|
||||
expect(MergeRequests::CreatePipelineService).not_to receive(:new)
|
||||
|
||||
expect { subject.perform(project.id, user.id, merge_request.id) }
|
||||
.not_to raise_exception
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the project does not exist' do
|
||||
before do
|
||||
project.destroy!
|
||||
end
|
||||
|
||||
it_behaves_like 'when object does not exist'
|
||||
end
|
||||
|
||||
context 'when the user does not exist' do
|
||||
before do
|
||||
user.destroy!
|
||||
end
|
||||
|
||||
it_behaves_like 'when object does not exist'
|
||||
end
|
||||
|
||||
context 'when the merge request does not exist' do
|
||||
before do
|
||||
merge_request.destroy!
|
||||
end
|
||||
|
||||
it_behaves_like 'when object does not exist'
|
||||
end
|
||||
end
|
||||
end
|
BIN
vendor/project_templates/gatsby.tar.gz
vendored
BIN
vendor/project_templates/gatsby.tar.gz
vendored
Binary file not shown.
Loading…
Reference in a new issue