Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-02-24 06:11:32 +00:00
parent a0d18c1c5c
commit ea8c112615
24 changed files with 115688 additions and 45 deletions

View file

@ -18,6 +18,10 @@ module Types
description: 'Schedule for the build.'
field :artifacts, Types::Ci::JobArtifactType.connection_type, null: true,
description: 'Artifacts generated by the job.'
field :finished_at, Types::TimeType, null: true,
description: 'When a job has finished running.'
field :duration, GraphQL::INT_TYPE, null: true,
description: 'Duration of the job in seconds.'
def pipeline
Gitlab::Graphql::Loaders::BatchModelLoader.new(::Ci::Pipeline, object.pipeline_id).find

View file

@ -1165,6 +1165,10 @@ module Ci
end
end
def for_merged_result?
merge_request_event_type == :merged_result
end
def persistent_ref
@persistent_ref ||= PersistentRef.new(pipeline: self)
end

View file

@ -36,6 +36,10 @@ class MergeRequest < ApplicationRecord
SORTING_PREFERENCE_FIELD = :merge_requests_sort
ALLOWED_TO_USE_MERGE_BASE_PIPELINE_FOR_COMPARISON = {
'Ci::CompareCodequalityReportsService' => ->(project) { ::Gitlab::Ci::Features.display_codequality_backend_comparison?(project) }
}.freeze
belongs_to :target_project, class_name: "Project"
belongs_to :source_project, class_name: "Project"
belongs_to :merge_user, class_name: "User"
@ -1564,7 +1568,7 @@ class MergeRequest < ApplicationRecord
def compare_reports(service_class, current_user = nil, report_type = nil )
with_reactive_cache(service_class.name, current_user&.id, report_type) do |data|
unless service_class.new(project, current_user, id: id, report_type: report_type)
.latest?(base_pipeline, actual_head_pipeline, data)
.latest?(comparison_base_pipeline(service_class.name), actual_head_pipeline, data)
raise InvalidateReactiveCache
end
@ -1600,7 +1604,7 @@ class MergeRequest < ApplicationRecord
raise NameError, service_class unless service_class < Ci::CompareReportsBaseService
current_user = User.find_by(id: current_user_id)
service_class.new(project, current_user, id: id, report_type: report_type).execute(base_pipeline, actual_head_pipeline)
service_class.new(project, current_user, id: id, report_type: report_type).execute(comparison_base_pipeline(identifier), actual_head_pipeline)
end
def all_commits
@ -1724,6 +1728,14 @@ class MergeRequest < ApplicationRecord
end
end
def use_merge_base_pipeline_for_comparison?(service_class)
ALLOWED_TO_USE_MERGE_BASE_PIPELINE_FOR_COMPARISON[service_class]&.call(project)
end
def comparison_base_pipeline(service_class)
(use_merge_base_pipeline_for_comparison?(service_class) && merge_base_pipeline) || base_pipeline
end
def base_pipeline
@base_pipeline ||= project.ci_pipelines
.order(id: :desc)

View file

@ -157,7 +157,7 @@ class MergeRequestWidgetEntity < Grape::Entity
end
def use_merge_base_with_merged_results?
object.actual_head_pipeline&.merge_request_event_type == :merged_result
object.actual_head_pipeline&.for_merged_result?
end
def head_pipeline_downloadable_path_for_report_type(file_type)

View file

@ -0,0 +1,5 @@
---
title: Add duration and finishedAt GraphQL fields to jobType in the CI namespace
merge_request: 54358
author:
type: changed

View file

@ -0,0 +1,8 @@
---
name: api_v3_repos_events_optimization
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54618
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/322059
milestone: '13.10'
type: development
group: group::ecosystem
default_enabled: false

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -813,6 +813,8 @@ Autogenerated return type of CiCdSettingsUpdate.
| ----- | ---- | ----------- |
| `artifacts` | CiJobArtifactConnection | Artifacts generated by the job. |
| `detailedStatus` | DetailedStatus | Detailed status of the job. |
| `duration` | Int | Duration of the job in seconds. |
| `finishedAt` | Time | When a job has finished running. |
| `name` | String | Name of the job. |
| `needs` | CiBuildNeedConnection | References to builds that must complete before the jobs run. |
| `pipeline` | Pipeline | Pipeline the job belongs to. |

View file

@ -29,7 +29,7 @@ To change the default branch protection:
For more details, see [Protected branches](../../project/protected_branches.md).
To change this setting for a specific group, see [Default branch protection for groups](../../group/index.md#changing-the-default-branch-protection-of-a-group)
To change this setting for a specific group, see [Default branch protection for groups](../../group/index.md#change-the-default-branch-protection-of-a-group)
### Disable group owners from updating default branch protection **(PREMIUM SELF)**

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

View file

@ -148,54 +148,35 @@ To remove a member from a group:
> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/228675) in GitLab 13.7.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/289911) in GitLab 13.8.
The following sections illustrate how you can filter and sort members in a group. To view these options,
navigate to your desired group, go to **Members**, and include the noted search terms.
To find members in a group, you can sort, filter, or search.
### Membership filter
### Filter a group
By default, inherited and direct members are displayed. The [membership](subgroups/index.md#membership) filter can be used to display only inherited or only direct members.
Filter a group to find members. By default, all members in the group and subgroups are displayed.
#### Only display inherited members
1. Go to the group and select **Members** (**{users}**).
1. Above the list of members, in the **Filter members** box, enter filter criteria.
- To view members in the group only, select **Membership = Direct**.
- To view members of the group and its subgroups, select **Membership = Inherited**.
- To view members with two-factor authentication enabled or disabled, select **2FA = Enabled** or **Disabled**.
Include `Membership` `=` `Inherited` in the search text box.
![Group members filter inherited](img/group_members_filter_inherited_13_7.png)
#### Only display direct members
Include `Membership` `=` `Direct` in the search text box.
![Group members filter direct](img/group_members_filter_direct_13_7.png)
### 2FA filter
[Owner](../permissions.md#group-members-permissions) permissions required.
By default, members with 2FA enabled and disabled are displayed. The 2FA filter can be used to display only members with 2FA enabled or only members with 2FA disabled.
#### Only display members with 2FA enabled
Include `2FA` `=` `Enabled` in the search text box.
![Group members filter 2FA enabled](img/group_members_filter_2fa_enabled_13_7.png)
#### Only display members with 2FA disabled
Include `2FA` `=` `Disabled` in the search text box.
![Group members filter 2FA disabled](img/group_members_filter_2fa_disabled_13_7.png)
### Search
### Search a group
You can search for members by name, username, or email.
![Group members search](img/group_members_search_13_7.png)
1. Go to the group and select **Members** (**{users}**).
1. Above the list of members, in the **Filter members** box, enter search criteria.
1. To the right of the **Filter members** box, select the magnifying glass (**{search}**).
### Sort
### Sort members in a group
You can sort members by **Account**, **Access granted**, **Max role**, or **Last sign-in** in ascending or descending order.
You can sort members by **Account**, **Access granted**, **Max role**, or **Last sign-in**.
![Group members sort](img/group_members_sort_13_7.png)
1. Go to the group and select **Members** (**{users}**).
1. Above the list of members, on the top right, from the **Account** list, select
the criteria to filter by.
1. To switch the sort between ascending and descending, to the right of the **Account** list, select the
arrow (**{sort-lowest}** or **{sort-highest}**).
## Mention a group in an issue or merge request
@ -209,7 +190,7 @@ added to their To-do list.
A to-do item is created for all the group and subgroup members.
## Changing the default branch protection of a group
## Change the default branch protection of a group
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7583) in GitLab 12.9.

View file

@ -147,7 +147,7 @@ From the image above, we can deduce the following things:
- Administrator is the Owner and member of **all** subgroups and for that reason,
as with User 3, the **Source** column indicates **Direct member**.
Members can be [filtered by inherited or direct membership](../index.md#membership-filter).
Members can be [filtered by inherited or direct membership](../index.md#filter-a-group).
### Overriding the ancestor group membership

View file

@ -303,7 +303,7 @@ group.
- The [instance level](admin_area/settings/visibility_and_access_controls.md#default-project-creation-protection).
- The [group level](group/index.md#default-project-creation-level).
1. Does not apply to subgroups.
1. Developers can push commits to the default branch of a new project only if the [default branch protection](group/index.md#changing-the-default-branch-protection-of-a-group) is set to "Partially protected" or "Not protected".
1. Developers can push commits to the default branch of a new project only if the [default branch protection](group/index.md#change-the-default-branch-protection-of-a-group) is set to "Partially protected" or "Not protected".
1. In addition, if your group is public or internal, all users who can see the group can also see group wiki pages.
1. Users can only view events based on their individual actions.

View file

@ -194,13 +194,19 @@ module API
# Self-hosted Jira (tested on 7.11.1) requests this endpoint right
# after fetching branches.
# rubocop: disable CodeReuse/ActiveRecord
get ':namespace/:project/events' do
user_project = find_project_with_access(params)
merge_requests = authorized_merge_requests_for_project(user_project)
if Feature.enabled?(:api_v3_repos_events_optimization, user_project)
merge_requests = merge_requests.preload(:author, :assignees, :metrics, source_project: :namespace, target_project: :namespace)
end
present paginate(merge_requests), with: ::API::Github::Entities::PullRequestEvent
end
# rubocop: enable CodeReuse/ActiveRecord
params do
use :project_full_path

View file

@ -14,6 +14,8 @@ RSpec.describe Types::Ci::JobType do
detailedStatus
scheduledAt
artifacts
finished_at
duration
]
expect(described_class).to have_graphql_fields(*expected_fields)

View file

@ -412,6 +412,24 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
end
end
describe '#for_merged_result?' do
subject { pipeline.for_merged_result? }
let(:pipeline) { merge_request.all_pipelines.last }
context 'when pipeline is merge request pipeline' do
let(:merge_request) { create(:merge_request, :with_merge_request_pipeline) }
it { is_expected.to be_truthy }
end
context 'when pipeline is detached merge request pipeline' do
let(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline) }
it { is_expected.to be_falsey }
end
end
describe '#legacy_detached_merge_request_pipeline?' do
subject { pipeline.legacy_detached_merge_request_pipeline? }

View file

@ -3839,6 +3839,87 @@ RSpec.describe MergeRequest, factory_default: :keep do
end
end
describe '#use_merge_base_pipeline_for_comparison?' do
let(:project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request, :with_codequality_reports, source_project: project) }
subject { merge_request.use_merge_base_pipeline_for_comparison?(service_class) }
context 'when service class is Ci::CompareCodequalityReportsService' do
let(:service_class) { 'Ci::CompareCodequalityReportsService' }
context 'when feature flag is enabled' do
it { is_expected.to be_truthy }
end
context 'when feature flag is disabled' do
before do
stub_feature_flags(codequality_backend_comparison: false)
end
it { is_expected.to be_falsey }
end
end
context 'when service class is different' do
let(:service_class) { 'Ci::GenerateCoverageReportsService' }
it { is_expected.to be_falsey }
end
end
describe '#comparison_base_pipeline' do
subject(:pipeline) { merge_request.comparison_base_pipeline(service_class) }
let(:project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request, :with_codequality_reports, source_project: project) }
let!(:base_pipeline) do
create(:ci_pipeline,
:with_test_reports,
project: project,
ref: merge_request.target_branch,
sha: merge_request.diff_base_sha
)
end
context 'when service class is Ci::CompareCodequalityReportsService' do
let(:service_class) { 'Ci::CompareCodequalityReportsService' }
context 'when merge request has a merge request pipeline' do
let(:merge_request) do
create(:merge_request, :with_merge_request_pipeline)
end
let(:merge_base_pipeline) do
create(:ci_pipeline, ref: merge_request.target_branch, sha: merge_request.target_branch_sha)
end
before do
merge_base_pipeline
merge_request.update_head_pipeline
end
it 'returns the merge_base_pipeline' do
expect(pipeline).to eq(merge_base_pipeline)
end
end
context 'when merge does not have a merge request pipeline' do
it 'returns the base_pipeline' do
expect(pipeline).to eq(base_pipeline)
end
end
end
context 'when service_class is different' do
let(:service_class) { 'Ci::GenerateCoverageReportsService' }
it 'returns the base_pipeline' do
expect(pipeline).to eq(base_pipeline)
end
end
end
describe '#base_pipeline' do
let(:pipeline_arguments) do
{

View file

@ -149,6 +149,8 @@ RSpec.describe API::V3::Github do
end
describe 'GET events' do
include ProjectForksHelper
let(:group) { create(:group) }
let(:project) { create(:project, :empty_repo, path: 'project.with.dot', group: group) }
let(:events_path) { "/repos/#{group.path}/#{project.path}/events" }
@ -174,6 +176,34 @@ RSpec.describe API::V3::Github do
end
end
it 'avoids N+1 queries' do
create(:merge_request, source_project: project)
source_project = fork_project(project, nil, repository: true)
control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) { jira_get v3_api(events_path, user) }.count
create_list(:merge_request, 2, :unique_branches, source_project: source_project, target_project: project)
expect { jira_get v3_api(events_path, user) }.not_to exceed_all_query_limit(control_count)
end
context 'with `api_v3_repos_events_optimization` feature flag disabled' do
before do
stub_feature_flags(api_v3_repos_events_optimization: false)
end
it 'falls back to less optimal query performance' do
create(:merge_request, source_project: project)
source_project = fork_project(project, nil, repository: true)
control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) { jira_get v3_api(events_path, user) }.count
create_list(:merge_request, 2, :unique_branches, source_project: source_project, target_project: project)
expect { jira_get v3_api(events_path, user) }.to exceed_all_query_limit(control_count)
end
end
context 'if there are more merge requests' do
let!(:merge_request) { create(:merge_request, id: 10000, source_project: project, target_project: project, author: user) }
let!(:merge_request2) { create(:merge_request, id: 10001, source_project: project, source_branch: generate(:branch), target_project: project, author: user) }