Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-03-11 09:07:59 +00:00
parent 134681224f
commit 27ad9b4c89
22 changed files with 106 additions and 141 deletions

View File

@ -0,0 +1,13 @@
query getSecurityTrainingVulnerability($id: ID!) {
vulnerability(id: $id) {
id
identifiers {
externalType
}
securityTrainingUrls {
name
url
status
}
}
}

View File

@ -70,7 +70,9 @@ export default {
<template v-if="isCollapsed">
<slot name="header"></slot>
<gl-button
variant="link"
category="tertiary"
variant="confirm"
size="small"
data-testid="mr-collapsible-title"
:disabled="isLoading"
:class="{ 'border-0': isLoading }"
@ -81,7 +83,9 @@ export default {
</template>
<gl-button
v-else
variant="link"
category="tertiary"
variant="confirm"
size="small"
data-testid="mr-collapsible-title"
:disabled="isLoading"
:class="{ 'border-0': isLoading }"

View File

@ -1,8 +1,6 @@
import { __ } from '~/locale';
export const MERGE_DISABLED_TEXT = __(
'Merge blocked: all merge request dependencies must be merged or closed.',
);
export const MERGE_DISABLED_TEXT = __('You can only merge once the items above are resolved.');
export const MERGE_DISABLED_SKIPPED_PIPELINE_TEXT = __(
"Merge blocked: pipeline must succeed. It's waiting for a manual job to continue.",
);

View File

@ -111,9 +111,7 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
allow_tree_conflicts: display_merge_conflicts_in_diff?
)
if @merge_request.project.context_commits_enabled?
options[:context_commits] = @merge_request.recent_context_commits
end
options[:context_commits] = @merge_request.recent_context_commits
render json: DiffsSerializer.new(request).represent(diffs, options)
end

View File

@ -219,8 +219,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
end
def context_commits
return render_404 unless project.context_commits_enabled?
# Get commits from repository
# or from cache if already merged
commits = ContextCommitsFinder.new(project, @merge_request, { search: params[:search], limit: params[:limit], offset: params[:offset] }).execute

View File

@ -108,7 +108,9 @@ module Types
field :suggestion_commit_message, GraphQL::Types::String, null: true,
description: 'Commit message used to apply merge request suggestions.'
field :group, Types::GroupType, null: true,
# No, the quotes are not a typo. Used to get around circular dependencies.
# See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27536#note_871009675
field :group, 'Types::GroupType', null: true,
description: 'Group of the project.'
field :namespace, Types::NamespaceType, null: true,
description: 'Namespace of the project.'

View File

@ -18,7 +18,7 @@ module Types
null: true,
authorize: :read_project
field :group, Types::GroupType,
field :group, 'Types::GroupType',
description: 'Group this to-do item is associated with.',
null: true,
authorize: :read_group

View File

@ -44,31 +44,31 @@ class EventCollection
private
def project_events
relation_with_join_lateral('project_id', projects)
in_operator_optimized_relation('project_id', projects)
end
def group_events
in_operator_optimized_relation('group_id', groups)
end
def project_and_group_events
group_events = relation_with_join_lateral('group_id', groups)
Event.from_union([project_events, group_events]).recent
end
# This relation is built using JOIN LATERAL, producing faster queries than a
# regular LIMIT + OFFSET approach.
def relation_with_join_lateral(parent_column, parents)
parents_for_lateral = parents.select(:id).to_sql
def in_operator_optimized_relation(parent_column, parents)
scope = filtered_events
array_scope = parents.select(:id)
array_mapping_scope = -> (parent_id_expression) { Event.where(Event.arel_table[parent_column].eq(parent_id_expression)).reorder(id: :desc) }
finder_query = -> (id_expression) { Event.where(Event.arel_table[:id].eq(id_expression)) }
lateral = filtered_events
# Applying the limit here (before we filter (permissions) means we may get less than limit)
.limit(limit_for_join_lateral)
.where("events.#{parent_column} = parents_for_lateral.id") # rubocop:disable GitlabSecurity/SqlInjection
.to_sql
# The outer query does not need to re-apply the filters since the JOIN
# LATERAL body already takes care of this.
base_relation
.from("(#{parents_for_lateral}) parents_for_lateral")
.joins("JOIN LATERAL (#{lateral}) AS #{Event.table_name} ON true")
Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder
.new(
scope: scope,
array_scope: array_scope,
array_mapping_scope: array_mapping_scope,
finder_query: finder_query
)
.execute
end
def filtered_events
@ -85,16 +85,6 @@ class EventCollection
Event.unscoped.recent
end
def limit_for_join_lateral
# Applying the OFFSET on the inside of a JOIN LATERAL leads to incorrect
# results. To work around this we need to increase the inner limit for every
# page.
#
# This means that on page 1 we use LIMIT 20, and an outer OFFSET of 0. On
# page 2 we use LIMIT 40 and an outer OFFSET of 20.
@limit + @offset
end
def current_page
(@offset / @limit) + 1
end

View File

@ -1012,10 +1012,6 @@ class Project < ApplicationRecord
Feature.enabled?(:unlink_fork_network_upon_visibility_decrease, self, default_enabled: true)
end
def context_commits_enabled?
Feature.enabled?(:context_commits, self.group, default_enabled: :yaml)
end
# LFS and hashed repository storage are required for using Design Management.
def design_management_enabled?
lfs_enabled? && hashed_storage?(:repository)

View File

@ -23,7 +23,7 @@ class DiffsEntity < Grape::Entity
CommitEntity.represent(options[:commit], commit_options(options))
end
expose :context_commits, using: API::Entities::Commit, if: -> (diffs, options) { merge_request&.project&.context_commits_enabled? } do |diffs|
expose :context_commits, using: API::Entities::Commit do |diffs|
options[:context_commits]
end
@ -89,7 +89,7 @@ class DiffsEntity < Grape::Entity
project_blob_path(merge_request.project, merge_request.diff_head_sha)
end
expose :context_commits_diff, if: -> (_) { merge_request&.project&.context_commits_enabled? } do |diffs, options|
expose :context_commits_diff do |diffs, options|
next unless merge_request.context_commits_diff.commits_count > 0
ContextCommitsDiffEntity.represent(

View File

@ -22,7 +22,7 @@
- if context_commits.present?
%li.commit-header.js-commit-header
%span.font-weight-bold= n_("%d previously merged commit", "%d previously merged commits", context_commits.count) % context_commits.count
- if project.context_commits_enabled? && can_update_merge_request
- if can_update_merge_request
%button.gl-button.btn.btn-default.ml-3.add-review-item-modal-trigger{ type: "button", data: { context_commits_empty: 'false' } }
= _('Add/remove')
@ -40,7 +40,7 @@
.gl-alert-content
= n_('%s additional commit has been omitted to prevent performance issues.', '%s additional commits have been omitted to prevent performance issues.', hidden) % number_with_delimiter(hidden)
- if project.context_commits_enabled? && can_update_merge_request && context_commits&.empty?
- if can_update_merge_request && context_commits&.empty?
%button.gl-button.btn.btn-default.mt-3.add-review-item-modal-trigger{ type: "button", data: { context_commits_empty: 'true' } }
= _('Add previously merged commits')

View File

@ -5,7 +5,7 @@
= custom_icon ('illustration_no_commits')
%h4
= _('There are no commits yet.')
- if @project&.context_commits_enabled? && can_update_merge_request
- if can_update_merge_request
%p
= _('Push commits to the source branch or add previously merged commits to review them.')
%button.btn.gl-button.btn-confirm.add-review-item-modal-trigger{ type: "button", data: { commits_empty: 'true', context_commits_empty: 'true' } }
@ -14,5 +14,5 @@
%ol#commits-list.list-unstyled
= render "projects/commits/commits", merge_request: @merge_request
- if @project&.context_commits_enabled? && can_update_merge_request && @merge_request.iid
- if can_update_merge_request && @merge_request.iid
.add-review-item-modal-wrapper{ data: { context_commits_path: context_commits_project_json_merge_request_url(@merge_request&.project, @merge_request, :json), target_branch: @merge_request.target_branch, merge_request_iid: @merge_request.iid, project_id: @merge_request.project.id } }

View File

@ -1,8 +0,0 @@
---
name: context_commits
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23701
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/320757
milestone: '12.8'
type: development
group: group::code review
default_enabled: true

View File

@ -31,15 +31,7 @@ To seamlessly navigate among commits in a merge request:
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/29274) in GitLab 13.12 [with a flag](../../../administration/feature_flags.md) named `context_commits`. Enabled by default.
> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/320757) in GitLab 14.8.
WARNING:
This feature is in [beta](../../../policy/alpha-beta-support.md#beta-features)
and is [incomplete](https://gitlab.com/groups/gitlab-org/-/epics/1192).
FLAG:
On self-managed GitLab, by default this feature is available. To hide the feature,
ask an administrator to [disable the feature flag](../../../administration/feature_flags.md) named `context_commits`.
On GitLab.com, this feature is available.
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/320757) in GitLab 14.9. [Feature flag `context_commits`](https://gitlab.com/gitlab-org/gitlab/-/issues/320757) removed.
When reviewing a merge request, it helps to have more context about the changes
made. That includes unchanged lines in unchanged files, and previous commits

View File

@ -304,10 +304,6 @@ module API
end
get ':id/merge_requests/:merge_request_iid/context_commits', feature_category: :code_review, urgency: :high do
merge_request = find_merge_request_with_access(params[:merge_request_iid])
project = merge_request.project
not_found! unless project.context_commits_enabled?
context_commits =
paginate(merge_request.merge_request_context_commits).map(&:to_commit)
@ -328,9 +324,6 @@ module API
end
merge_request = find_merge_request_with_access(params[:merge_request_iid])
project = merge_request.project
not_found! unless project.context_commits_enabled?
authorize!(:update_merge_request, merge_request)
@ -351,9 +344,6 @@ module API
delete ':id/merge_requests/:merge_request_iid/context_commits', feature_category: :code_review do
commit_ids = params[:commits]
merge_request = find_merge_request_with_access(params[:merge_request_iid])
project = merge_request.project
not_found! unless project.context_commits_enabled?
authorize!(:destroy_merge_request, merge_request)
project = merge_request.target_project

View File

@ -9,6 +9,9 @@ require 'task_list/filter'
module Banzai
module Filter
class TaskListFilter < TaskList::Filter
def render_item_checkbox(item)
"<task-button></task-button>#{super}"
end
end
end
end

View File

@ -41056,9 +41056,6 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
msgid "Vulnerability|Secure Code Warrior"
msgstr ""
msgid "Vulnerability|Security Audit"
msgstr ""
@ -42156,6 +42153,9 @@ msgstr ""
msgid "You can only edit files when you are on a branch"
msgstr ""
msgid "You can only merge once the items above are resolved."
msgstr ""
msgid "You can only transfer the project to namespaces you manage."
msgstr ""

View File

@ -218,13 +218,13 @@
</ol>
<ul data-sourcepos="7:1-9:47" class="task-list" dir="auto">
<li data-sourcepos="7:1-7:47" class="task-list-item">
<input type="checkbox" class="task-list-item-checkbox" checked disabled> <span class="media-container audio-container"><audio src="https://gitlab.com/1.mp3" controls="true" data-setup="{}" data-title="Sample Audio"></audio><a href="https://gitlab.com/1.mp3" target="_blank" rel="nofollow noreferrer noopener" title="Download 'Sample Audio'">Sample Audio</a></span>
<task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> <span class="media-container audio-container"><audio src="https://gitlab.com/1.mp3" controls="true" data-setup="{}" data-title="Sample Audio"></audio><a href="https://gitlab.com/1.mp3" target="_blank" rel="nofollow noreferrer noopener" title="Download 'Sample Audio'">Sample Audio</a></span>
</li>
<li data-sourcepos="8:1-8:47" class="task-list-item">
<input type="checkbox" class="task-list-item-checkbox" checked disabled> <span class="media-container audio-container"><audio src="https://gitlab.com/2.mp3" controls="true" data-setup="{}" data-title="Sample Audio"></audio><a href="https://gitlab.com/2.mp3" target="_blank" rel="nofollow noreferrer noopener" title="Download 'Sample Audio'">Sample Audio</a></span>
<task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> <span class="media-container audio-container"><audio src="https://gitlab.com/2.mp3" controls="true" data-setup="{}" data-title="Sample Audio"></audio><a href="https://gitlab.com/2.mp3" target="_blank" rel="nofollow noreferrer noopener" title="Download 'Sample Audio'">Sample Audio</a></span>
</li>
<li data-sourcepos="9:1-9:47" class="task-list-item">
<input type="checkbox" class="task-list-item-checkbox" checked disabled> <span class="media-container video-container"><video src="https://gitlab.com/3.mp4" controls="true" data-setup="{}" data-title="Sample Video" width="400" preload="metadata"></video><a href="https://gitlab.com/3.mp4" target="_blank" rel="nofollow noreferrer noopener" title="Download 'Sample Video'">Sample Video</a></span>
<task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> <span class="media-container video-container"><video src="https://gitlab.com/3.mp4" controls="true" data-setup="{}" data-title="Sample Video" width="400" preload="metadata"></video><a href="https://gitlab.com/3.mp4" target="_blank" rel="nofollow noreferrer noopener" title="Download 'Sample Video'">Sample Video</a></span>
</li>
</ul>
@ -670,19 +670,19 @@
html: |-
<ol data-sourcepos="1:1-6:18" class="task-list" dir="auto">
<li data-sourcepos="1:1-1:12" class="task-list-item">
<input type="checkbox" class="task-list-item-checkbox" checked disabled> hello</li>
<task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> hello</li>
<li data-sourcepos="2:1-2:12" class="task-list-item">
<input type="checkbox" class="task-list-item-checkbox" checked disabled> world</li>
<task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> world</li>
<li data-sourcepos="3:1-6:18" class="task-list-item">
<input type="checkbox" class="task-list-item-checkbox" disabled> example
<task-button></task-button><input type="checkbox" class="task-list-item-checkbox" disabled> example
<ol data-sourcepos="4:4-6:18" class="task-list">
<li data-sourcepos="4:4-6:18" class="task-list-item">
<input type="checkbox" class="task-list-item-checkbox" disabled> of nested
<task-button></task-button><input type="checkbox" class="task-list-item-checkbox" disabled> of nested
<ol data-sourcepos="5:7-6:18" class="task-list">
<li data-sourcepos="5:7-5:22" class="task-list-item">
<input type="checkbox" class="task-list-item-checkbox" checked disabled> task list</li>
<task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> task list</li>
<li data-sourcepos="6:7-6:18" class="task-list-item">
<input type="checkbox" class="task-list-item-checkbox" disabled> items</li>
<task-button></task-button><input type="checkbox" class="task-list-item-checkbox" disabled> items</li>
</ol>
</li>
</ol>
@ -697,11 +697,11 @@
html: |-
<ol start="4893" data-sourcepos="1:1-3:17" class="task-list" dir="auto">
<li data-sourcepos="1:1-1:15" class="task-list-item">
<input type="checkbox" class="task-list-item-checkbox" checked disabled> hello</li>
<task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> hello</li>
<li data-sourcepos="2:1-2:15" class="task-list-item">
<input type="checkbox" class="task-list-item-checkbox" checked disabled> world</li>
<task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> world</li>
<li data-sourcepos="3:1-3:17" class="task-list-item">
<input type="checkbox" class="task-list-item-checkbox" disabled> example</li>
<task-button></task-button><input type="checkbox" class="task-list-item-checkbox" disabled> example</li>
</ol>
- name: reference_for_project_wiki
@ -810,19 +810,19 @@
html: |-
<ul data-sourcepos="1:1-6:15" class="task-list" dir="auto">
<li data-sourcepos="1:1-1:11" class="task-list-item">
<input type="checkbox" class="task-list-item-checkbox" checked disabled> hello</li>
<task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> hello</li>
<li data-sourcepos="2:1-2:11" class="task-list-item">
<input type="checkbox" class="task-list-item-checkbox" checked disabled> world</li>
<task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> world</li>
<li data-sourcepos="3:1-6:15" class="task-list-item">
<input type="checkbox" class="task-list-item-checkbox" disabled> example
<task-button></task-button><input type="checkbox" class="task-list-item-checkbox" disabled> example
<ul data-sourcepos="4:3-6:15" class="task-list">
<li data-sourcepos="4:3-6:15" class="task-list-item">
<input type="checkbox" class="task-list-item-checkbox" disabled> of nested
<task-button></task-button><input type="checkbox" class="task-list-item-checkbox" disabled> of nested
<ul data-sourcepos="5:5-6:15" class="task-list">
<li data-sourcepos="5:5-5:19" class="task-list-item">
<input type="checkbox" class="task-list-item-checkbox" checked disabled> task list</li>
<task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> task list</li>
<li data-sourcepos="6:5-6:15" class="task-list-item">
<input type="checkbox" class="task-list-item-checkbox" disabled> items</li>
<task-button></task-button><input type="checkbox" class="task-list-item-checkbox" disabled> items</li>
</ul>
</li>
</ul>

View File

@ -1,6 +1,10 @@
export const testProjectPath = 'foo/bar';
export const testProviderIds = [101, 102, 103];
export const testProviderName = ['Vendor Name 1', 'Vendor Name 2', 'Vendor Name 3'];
export const testTrainingUrls = [
'https://www.vendornameone.com/url',
'https://www.vendornametwo.com/url',
];
const createSecurityTrainingProviders = ({ providerOverrides = {} }) => [
{

View File

@ -0,0 +1,13 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Banzai::Filter::TaskListFilter do
include FilterSpecHelper
it 'adds `<task-button></task-button>` to every list item' do
doc = filter("<ul data-sourcepos=\"1:1-2:20\">\n<li data-sourcepos=\"1:1-1:20\">[ ] testing item 1</li>\n<li data-sourcepos=\"2:1-2:20\">[x] testing item 2</li>\n</ul>")
expect(doc.xpath('.//li//task-button').count).to eq(2)
end
end

View File

@ -71,9 +71,9 @@ RSpec.describe EventCollection do
end
it 'can paginate through events' do
events = described_class.new(projects, offset: 20).to_a
events = described_class.new(projects, limit: 5, offset: 15).to_a
expect(events.length).to eq(2)
expect(events.length).to eq(5)
end
it 'returns an empty Array when crossing the maximum page number' do
@ -124,6 +124,19 @@ RSpec.describe EventCollection do
expect(subject).to eq([event1])
end
context 'pagination through events' do
let_it_be(:project_events) { create_list(:event, 10, project: project) }
let_it_be(:group_events) { create_list(:event, 10, group: group, author: user) }
let(:subject) { described_class.new(projects, limit: 10, offset: 5, groups: groups).to_a }
it 'returns recent groups and projects events' do
recent_events_with_offset = (project_events[5..] + group_events[..4]).reverse
expect(subject).to eq(recent_events_with_offset)
end
end
end
end
end

View File

@ -7991,47 +7991,6 @@ RSpec.describe Project, factory_default: :keep do
end
end
describe '#context_commits_enabled?' do
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, namespace: group) }
subject(:result) { project.context_commits_enabled? }
context 'when context_commits feature flag is enabled' do
before do
stub_feature_flags(context_commits: true)
end
it { is_expected.to be_truthy }
end
context 'when context_commits feature flag is disabled' do
before do
stub_feature_flags(context_commits: false)
end
it { is_expected.to be_falsey }
end
context 'when context_commits feature flag is enabled on project group' do
before do
stub_feature_flags(context_commits: group)
end
it { is_expected.to be_truthy }
end
context 'when context_commits feature flag is enabled on another group' do
let(:another_group) { create(:group) }
before do
stub_feature_flags(context_commits: another_group)
end
it { is_expected.to be_falsey }
end
end
describe '.not_hidden' do
it 'lists projects that are not hidden' do
project = create(:project)