Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-08-28 03:11:59 +00:00
parent db0baf7d00
commit 6359d1ca43
35 changed files with 558 additions and 72 deletions

View File

@ -6,7 +6,7 @@ workflow:
include:
- local: .gitlab/ci/version.yml
- component: "gitlab.com/gitlab-org/quality/pipeline-common/allure-report@8.20.0"
- component: "gitlab.com/gitlab-org/quality/pipeline-common/allure-report@8.21.0"
inputs:
job_name: "e2e-test-report"
job_stage: "report"
@ -16,7 +16,7 @@ include:
gitlab_auth_token_variable_name: "PROJECT_TOKEN_FOR_CI_SCRIPTS_API_USAGE"
allure_job_name: "${QA_RUN_TYPE}"
- project: gitlab-org/quality/pipeline-common
ref: 8.20.0
ref: 8.21.0
file:
- /ci/base.gitlab-ci.yml
- /ci/knapsack-report.yml

View File

@ -18,4 +18,4 @@ variables:
# Retry failed specs in separate process
QA_RETRY_FAILED_SPECS: "true"
# helm chart ref used by test-on-cng pipeline
GITLAB_HELM_CHART_REF: "da231f62fc4157de23850d1b5b23aabc71a8f6b5"
GITLAB_HELM_CHART_REF: "e7f459ab671d8fdaecddd34c739e3d53c498bae2"

View File

@ -1,6 +0,0 @@
---
# Cop supports --autocorrect.
GraphQL/UnusedArgument:
Exclude:
- 'app/graphql/mutations/jira_import/start.rb'
- 'app/graphql/resolvers/packages_base_resolver.rb'

View File

@ -91,7 +91,7 @@ export default {
const currentUser = this.isCurrentUser(user);
const thisIsYouText = currentUser ? __('This is you.') : '';
let titleType = 'default';
let titleType;
if (this.type === 'ASSIGNEES') {
titleType = this.type;
@ -100,7 +100,7 @@ export default {
}
return sprintf(
USER_TOOLTIP_TITLES[titleType],
USER_TOOLTIP_TITLES[titleType] || USER_TOOLTIP_TITLES.default,
{
name: user.name,
you: thisIsYouText,

View File

@ -1,14 +1,21 @@
<script>
import reviewerQuery from '../queries/reviewer.query.graphql';
import assigneeQuery from '../queries/assignee.query.graphql';
import assigneeOrReviewerQuery from '../queries/assignee_or_reviewer.query.graphql';
const PER_PAGE = 20;
const QUERIES = {
reviewRequestedMergeRequests: reviewerQuery,
assignedMergeRequests: assigneeQuery,
assigneeOrReviewerMergeRequests: assigneeOrReviewerQuery,
};
export default {
apollo: {
mergeRequests: {
query() {
return this.query === 'reviewRequestedMergeRequests' ? reviewerQuery : assigneeQuery;
return QUERIES[this.query];
},
update(d) {
return d.currentUser?.[this.query] || {};

View File

@ -0,0 +1,31 @@
#import "~/graphql_shared/fragments/page_info.fragment.graphql"
#import "./merge_request.fragment.graphql"
query assigneeOrReviewer(
$state: MergeRequestState = opened
$assignedReviewStates: [MergeRequestReviewState!]
$reviewerReviewStates: [MergeRequestReviewState!]
$mergedAfter: Time
$perPage: Int!
$afterCursor: String
) {
currentUser {
id
assigneeOrReviewerMergeRequests(
state: $state
assignedReviewStates: $assignedReviewStates
reviewerReviewStates: $reviewerReviewStates
mergedAfter: $mergedAfter
first: $perPage
after: $afterCursor
) {
count
pageInfo {
...PageInfo
}
nodes {
...MergeRequestDashboardFragment
}
}
}
}

View File

@ -82,6 +82,7 @@ class MergeRequestsFinder < IssuableFinder
items = by_review_state(items)
items = by_source_project_id(items)
items = by_resource_event_state(items)
items = by_assignee_or_reviewer(items)
by_approved(items)
end
@ -268,6 +269,17 @@ class MergeRequestsFinder < IssuableFinder
end
end
def by_assignee_or_reviewer(items)
return items unless current_user&.merge_request_dashboard_enabled?
return items unless params.assigned_user
items.assignee_or_reviewer(
params.assigned_user,
params.assigned_review_states,
params.reviewer_review_states
)
end
def parse_datetime(input)
# NOTE: Input from GraphQL query is a Time object already.
# Just return DateTime object for consistency instead of trying to parse it.

View File

@ -20,6 +20,14 @@ class MergeRequestsFinder
end
end
def assigned_user
strong_memoize(:assigned_user) do
next unless params[:assigned_user_id].present?
User.find_by_id(params[:assigned_user_id])
end
end
def merge_user
strong_memoize(:merge_user) do
if merge_user_id?
@ -30,6 +38,18 @@ class MergeRequestsFinder
end
end
def assigned_review_states
return unless params[:assigned_review_states].present?
params[:assigned_review_states].map { |state| MergeRequestReviewer.states[state] }
end
def reviewer_review_states
return unless params[:reviewer_review_states].present?
params[:reviewer_review_states].map { |state| MergeRequestReviewer.states[state] }
end
def review_state
if params[:review_state].present?
MergeRequestReviewer.states[params[:review_state]]

View File

@ -19,7 +19,8 @@ module Mutations
description: 'Project key of the importer Jira project.'
argument :jira_project_name, GraphQL::Types::String,
required: false,
description: 'Project name of the importer Jira project.'
description: 'Project name of the importer Jira project.',
deprecated: { milestone: '17.4', reason: 'Argument is not used' }
argument :project_path, GraphQL::Types::ID,
required: true,
description: 'Project to import the Jira project into.'
@ -28,7 +29,7 @@ module Mutations
required: false,
description: 'Mapping of Jira to GitLab users.'
def resolve(project_path:, jira_project_key:, users_mapping:)
def resolve(project_path:, jira_project_key:, users_mapping:) # rubocop: disable GraphQL/UnusedArgument -- `jira_project_name` must be deprecated before we can remove it
project = authorized_find!(project_path)
mapping = users_mapping.to_ary.map(&:to_hash)

View File

@ -0,0 +1,27 @@
# frozen_string_literal: true
module Resolvers
module MergeRequests
class AssigneeOrReviewerMergeRequestsResolver < UserMergeRequestsResolverBase
type ::Types::MergeRequestType.connection_type, null: true
argument :assigned_review_states, [::Types::MergeRequestReviewStateEnum],
required: false,
description: 'Reviewer states for merge requests the current user is assigned to.'
argument :reviewer_review_states, [::Types::MergeRequestReviewStateEnum],
required: false,
description: 'Reviewer states for the merge requests the current user is a reviewer of.'
def resolve(**args)
return unless current_user.merge_request_dashboard_enabled?
super(**args)
end
def user_role
:assigned_user
end
end
end
end

View File

@ -46,7 +46,7 @@ module Resolvers
type_asc: { order_by: 'type', sort: 'asc' }
}.freeze
def resolve
def resolve(**_args)
raise NotImplementedError
end

View File

@ -5,6 +5,12 @@ module Types
class CurrentUserType < ::Types::UserType
graphql_name 'CurrentUser'
description 'The currently authenticated GitLab user.'
field :assignee_or_reviewer_merge_requests,
resolver: Resolvers::MergeRequests::AssigneeOrReviewerMergeRequestsResolver,
description: 'Merge requests the current user is an assignee or a reviewer of.' \
'Ignored if `merge_request_dashboard` feature flag is disabled.',
alpha: { milestone: '17.4' }
end
# rubocop:enable Graphql/AuthorizeTypes
end

View File

@ -362,71 +362,56 @@ module MergeRequestsHelper
{
lists: [
{
title: _('Open'),
title: _('Returned to you'),
query: 'assignedMergeRequests',
variables: {
reviewerWildcardId: 'NONE'
reviewStates: %w[REVIEWED REQUESTED_CHANGES]
}
},
{
title: _('Reviews requested'),
query: 'reviewRequestedMergeRequests',
variables: {
reviewStates: %w[UNREVIEWED REVIEW_STARTED]
reviewStates: %w[UNAPPROVED UNREVIEWED REVIEW_STARTED]
}
},
{
title: _('Returned to you'),
title: _('Assigned to you'),
query: 'assignedMergeRequests',
variables: {
reviewStates: %w[REQUESTED_CHANGES REVIEWED]
reviewerWildcardId: 'NONE'
}
},
{
title: _('Waiting for reviewers'),
query: 'assignedMergeRequests',
title: _('Waiting for others'),
query: 'assigneeOrReviewerMergeRequests',
variables: {
reviewStates: %w[UNREVIEWED UNAPPROVED REVIEW_STARTED]
reviewerReviewStates: %w[REVIEWED REQUESTED_CHANGES],
assignedReviewStates: %w[UNREVIEWED UNAPPROVED REVIEW_STARTED]
}
},
{
title: _('Yours approved'),
query: 'assignedMergeRequests',
variables: {
reviewState: 'APPROVED'
}
},
{
title: _('Reviewed'),
query: 'reviewRequestedMergeRequests',
variables: {
reviewStates: %w[REQUESTED_CHANGES REVIEWED]
}
},
{
title: _('Reviews approved'),
title: _('Approved by you'),
query: 'reviewRequestedMergeRequests',
variables: {
reviewState: 'APPROVED'
}
},
{
title: _('Merged as assignee (1 week ago)'),
title: _('Approved by others'),
query: 'assignedMergeRequests',
variables: {
state: 'merged',
mergedAfter: 1.week.ago.to_time.iso8601
reviewState: 'APPROVED'
}
},
{
title: _('Merged as reviewer (1 week ago)'),
query: 'reviewRequestedMergeRequests',
title: _('Merged recently'),
query: 'assigneeOrReviewerMergeRequests',
variables: {
state: 'merged',
mergedAfter: 1.week.ago.to_time.iso8601
mergedAfter: 2.weeks.ago.to_time.iso8601
}
}
]
}
end

View File

@ -465,6 +465,16 @@ class MergeRequest < ApplicationRecord
)
end
scope :assignee_or_reviewer, ->(user, assigned_review_states, reviewer_state) do
assigned_to_scope = assigned_to(user)
assigned_to_scope = assigned_to_scope.review_states(assigned_review_states) if assigned_review_states
from_union(
assigned_to_scope,
review_requested_to(user, reviewer_state)
)
end
scope :without_hidden, -> {
if Feature.enabled?(:hide_merge_requests_from_banned_users)
where_not_exists(Users::BannedUser.where('merge_requests.author_id = banned_users.user_id'))

View File

@ -0,0 +1,20 @@
# frozen_string_literal: true
class ChangeZoektIndexFkOnZoektRepositories < Gitlab::Database::Migration[2.2]
disable_ddl_transaction!
milestone '17.4'
NEW_CONSTRAINT_NAME = 'fk_zoekt_repositories_on_zoekt_index_id'
def up
add_concurrent_foreign_key(:zoekt_repositories, :zoekt_indices, column: :zoekt_index_id, on_delete: :restrict,
validate: false, name: NEW_CONSTRAINT_NAME)
end
def down
with_lock_retries do
remove_foreign_key_if_exists(:zoekt_repositories, column: :zoekt_index_id, on_delete: :restrict,
name: NEW_CONSTRAINT_NAME)
end
end
end

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class ValidateZoektIndexFkChangeOnZoektRepositories < Gitlab::Database::Migration[2.2]
milestone '17.4'
NEW_CONSTRAINT_NAME = ChangeZoektIndexFkOnZoektRepositories::NEW_CONSTRAINT_NAME
# foreign key added in ChangeZoektIndexFkOnZoektRepositories migration
def up
validate_foreign_key(:zoekt_repositories, :zoekt_index_id, name: NEW_CONSTRAINT_NAME)
end
def down
# no-op
end
end

View File

@ -0,0 +1,23 @@
# frozen_string_literal: true
class RemoveCascadeDeleteZoektIndexFkOnZoektRepositories < Gitlab::Database::Migration[2.2]
disable_ddl_transaction!
milestone '17.4'
OLD_CONSTRAINT_NAME = "fk_94edfec0da"
# new foreign key added in ChangeZoektIndexFkOnZoektRepositories migration
# and validated in ValidateZoektIndexFkChangeOnZoektRepositories migration
def up
with_lock_retries do
remove_foreign_key_if_exists(:zoekt_repositories, column: :zoekt_index_id, on_delete: :cascade,
name: OLD_CONSTRAINT_NAME)
end
end
def down
# Validation is skipped here, so if rolled back, this will need to be revalidated in a separate migration
add_concurrent_foreign_key(:zoekt_repositories, :zoekt_indices, column: :zoekt_index_id, on_delete: :cascade,
name: OLD_CONSTRAINT_NAME)
end
end

View File

@ -0,0 +1,20 @@
# frozen_string_literal: true
class ChangeZoektReplicaFkOnZoektIndices < Gitlab::Database::Migration[2.2]
disable_ddl_transaction!
milestone '17.4'
NEW_CONSTRAINT_NAME = 'fk_zoekt_indices_on_zoekt_replica_id'
def up
add_concurrent_foreign_key(:zoekt_indices, :zoekt_replicas, column: :zoekt_replica_id, on_delete: :nullify,
validate: false, name: NEW_CONSTRAINT_NAME)
end
def down
with_lock_retries do
remove_foreign_key_if_exists(:zoekt_indices, column: :zoekt_replica_id, on_delete: :nullify,
name: NEW_CONSTRAINT_NAME)
end
end
end

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class ValidateZoektReplicaFkChangeOnZoektIndices < Gitlab::Database::Migration[2.2]
milestone '17.4'
NEW_CONSTRAINT_NAME = ChangeZoektReplicaFkOnZoektIndices::NEW_CONSTRAINT_NAME
# foreign key added in ChangeZoektReplicaFKOnZoektIndices migration
def up
validate_foreign_key(:zoekt_indices, :zoekt_replica_id, name: NEW_CONSTRAINT_NAME)
end
def down
# no-op
end
end

View File

@ -0,0 +1,23 @@
# frozen_string_literal: true
class RemoveCascadeDeleteZoektReplicaFkOnZoektIndices < Gitlab::Database::Migration[2.2]
disable_ddl_transaction!
milestone '17.4'
OLD_CONSTRAINT_NAME = "fk_ef0e75ac42"
# new foreign key added in ChangeZoektReplicaFkOnZoektIndices migration
# and validated in ValidateZoektReplicaFKOnZoektIndices migration
def up
with_lock_retries do
remove_foreign_key_if_exists(:zoekt_indices, column: :zoekt_replica_id, on_delete: :cascade,
name: OLD_CONSTRAINT_NAME)
end
end
def down
# Validation is skipped here, so if rolled back, this will need to be revalidated in a separate migration
add_concurrent_foreign_key(:zoekt_indices, :zoekt_replicas, column: :zoekt_replica_id, on_delete: :cascade,
name: OLD_CONSTRAINT_NAME)
end
end

View File

@ -0,0 +1 @@
ec02499522082f6c638ab589aee70c5ae40e4314d029c7b1df03563c0ac42b30

View File

@ -0,0 +1 @@
5e1ab418c5a986cf32a4b543b186ba1b88b36659d523282a21ad2bf0f63f750a

View File

@ -0,0 +1 @@
1285f79fd944ba921797928eab318cef4be358e4156a7f73bbf91535f5a61f8c

View File

@ -0,0 +1 @@
d862c4016d2b4802af673072ab4f300d8e97b338325209f6c9830914ff4eaea4

View File

@ -0,0 +1 @@
b17601c8db386cfe3fcabf419e72cd293fd1d27f2de7a0431838034fb461ce05

View File

@ -0,0 +1 @@
038f008d226cf8c912d507240e53f81b0d7aeff8deb7d8510d22def761262ce8

View File

@ -33658,9 +33658,6 @@ ALTER TABLE ONLY packages_debian_group_architectures
ALTER TABLE ONLY dast_site_profiles_builds
ADD CONSTRAINT fk_94e80df60e FOREIGN KEY (dast_site_profile_id) REFERENCES dast_site_profiles(id) ON DELETE CASCADE;
ALTER TABLE ONLY zoekt_repositories
ADD CONSTRAINT fk_94edfec0da FOREIGN KEY (zoekt_index_id) REFERENCES zoekt_indices(id) ON DELETE CASCADE;
ALTER TABLE ONLY vulnerability_feedback
ADD CONSTRAINT fk_94f7c8a81e FOREIGN KEY (comment_author_id) REFERENCES users(id) ON DELETE SET NULL;
@ -34234,9 +34231,6 @@ ALTER TABLE ONLY workspaces
ALTER TABLE ONLY merge_requests_compliance_violations
ADD CONSTRAINT fk_ec881c1c6f FOREIGN KEY (violating_user_id) REFERENCES users(id) ON DELETE CASCADE;
ALTER TABLE ONLY zoekt_indices
ADD CONSTRAINT fk_ef0e75ac42 FOREIGN KEY (zoekt_replica_id) REFERENCES zoekt_replicas(id) ON DELETE CASCADE;
ALTER TABLE ONLY coverage_fuzzing_corpuses
ADD CONSTRAINT fk_ef5ebf339f FOREIGN KEY (package_id) REFERENCES packages_packages(id) ON DELETE CASCADE;
@ -36307,6 +36301,12 @@ ALTER TABLE ONLY work_item_colors
ALTER TABLE ONLY work_item_dates_sources
ADD CONSTRAINT fk_work_item_dates_sources_on_namespace_id FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY zoekt_indices
ADD CONSTRAINT fk_zoekt_indices_on_zoekt_replica_id FOREIGN KEY (zoekt_replica_id) REFERENCES zoekt_replicas(id) ON DELETE SET NULL;
ALTER TABLE ONLY zoekt_repositories
ADD CONSTRAINT fk_zoekt_repositories_on_zoekt_index_id FOREIGN KEY (zoekt_index_id) REFERENCES zoekt_indices(id) ON DELETE RESTRICT;
ALTER TABLE issue_search_data
ADD CONSTRAINT issue_search_data_issue_id_fkey FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE;

View File

@ -6442,7 +6442,7 @@ Input type: `JiraImportStartInput`
| ---- | ---- | ----------- |
| <a id="mutationjiraimportstartclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationjiraimportstartjiraprojectkey"></a>`jiraProjectKey` | [`String!`](#string) | Project key of the importer Jira project. |
| <a id="mutationjiraimportstartjiraprojectname"></a>`jiraProjectName` | [`String`](#string) | Project name of the importer Jira project. |
| <a id="mutationjiraimportstartjiraprojectname"></a>`jiraProjectName` **{warning-solid}** | [`String`](#string) | **Deprecated:** Argument is not used. Deprecated in GitLab 17.4. |
| <a id="mutationjiraimportstartprojectpath"></a>`projectPath` | [`ID!`](#id) | Project to import the Jira project into. |
| <a id="mutationjiraimportstartusersmapping"></a>`usersMapping` | [`[JiraUsersMappingInputType!]`](#jirausersmappinginputtype) | Mapping of Jira to GitLab users. |
@ -19996,6 +19996,57 @@ four standard [pagination arguments](#pagination-arguments):
| <a id="currentuserassignedmergerequestsupdatedafter"></a>`updatedAfter` | [`Time`](#time) | Merge requests updated after the timestamp. |
| <a id="currentuserassignedmergerequestsupdatedbefore"></a>`updatedBefore` | [`Time`](#time) | Merge requests updated before the timestamp. |
##### `CurrentUser.assigneeOrReviewerMergeRequests`
Merge requests the current user is an assignee or a reviewer of.Ignored if `merge_request_dashboard` feature flag is disabled.
DETAILS:
**Introduced** in GitLab 17.4.
**Status**: Experiment.
Returns [`MergeRequestConnection`](#mergerequestconnection).
This field returns a [connection](#connections). It accepts the
four standard [pagination arguments](#pagination-arguments):
`before: String`, `after: String`, `first: Int`, and `last: Int`.
###### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="currentuserassigneeorreviewermergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
| <a id="currentuserassigneeorreviewermergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
| <a id="currentuserassigneeorreviewermergerequestsassignedreviewstates"></a>`assignedReviewStates` | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | Reviewer states for merge requests the current user is assigned to. |
| <a id="currentuserassigneeorreviewermergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after the timestamp. |
| <a id="currentuserassigneeorreviewermergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before the timestamp. |
| <a id="currentuserassigneeorreviewermergerequestsdeployedafter"></a>`deployedAfter` | [`Time`](#time) | Merge requests deployed after the timestamp. |
| <a id="currentuserassigneeorreviewermergerequestsdeployedbefore"></a>`deployedBefore` | [`Time`](#time) | Merge requests deployed before the timestamp. |
| <a id="currentuserassigneeorreviewermergerequestsdeploymentid"></a>`deploymentId` | [`String`](#string) | ID of the deployment. |
| <a id="currentuserassigneeorreviewermergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="currentuserassigneeorreviewermergerequestsgroupid"></a>`groupId` | [`GroupID`](#groupid) | The global ID of the group the authored merge requests should be in. Merge requests in subgroups are included. |
| <a id="currentuserassigneeorreviewermergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="currentuserassigneeorreviewermergerequestslabelname"></a>`labelName` | [`[String]`](#string) | Labels applied to the merge request. |
| <a id="currentuserassigneeorreviewermergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
| <a id="currentuserassigneeorreviewermergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
| <a id="currentuserassigneeorreviewermergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
| <a id="currentuserassigneeorreviewermergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
| <a id="currentuserassigneeorreviewermergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
| <a id="currentuserassigneeorreviewermergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
| <a id="currentuserassigneeorreviewermergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
| <a id="currentuserassigneeorreviewermergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
| <a id="currentuserassigneeorreviewermergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
| <a id="currentuserassigneeorreviewermergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
| <a id="currentuserassigneeorreviewermergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
| <a id="currentuserassigneeorreviewermergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
| <a id="currentuserassigneeorreviewermergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
| <a id="currentuserassigneeorreviewermergerequestsreviewerreviewstates"></a>`reviewerReviewStates` | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | Reviewer states for the merge requests the current user is a reviewer of. |
| <a id="currentuserassigneeorreviewermergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by the criteria. |
| <a id="currentuserassigneeorreviewermergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
| <a id="currentuserassigneeorreviewermergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have the state. |
| <a id="currentuserassigneeorreviewermergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
| <a id="currentuserassigneeorreviewermergerequestsupdatedafter"></a>`updatedAfter` | [`Time`](#time) | Merge requests updated after the timestamp. |
| <a id="currentuserassigneeorreviewermergerequestsupdatedbefore"></a>`updatedBefore` | [`Time`](#time) | Merge requests updated before the timestamp. |
##### `CurrentUser.authoredMergeRequests`
Merge requests authored by the user.
@ -25253,8 +25304,8 @@ Defines which user roles, users, or groups can merge into a protected branch.
| <a id="mergerequestmergestatus"></a>`mergeStatus` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 14.0. This was renamed. Use: [`MergeRequest.mergeStatusEnum`](#mergerequestmergestatusenum). |
| <a id="mergerequestmergestatusenum"></a>`mergeStatusEnum` | [`MergeStatus`](#mergestatus) | Merge status of the merge request. |
| <a id="mergerequestmergetraincar"></a>`mergeTrainCar` **{warning-solid}** | [`MergeTrainCar`](#mergetraincar) | **Introduced** in GitLab 17.2. **Status**: Experiment. Represents the merge request in a merge train. |
| <a id="mergerequestmergetrainindex"></a>`mergeTrainIndex` | [`Int`](#int) | Zero-based position of the merge request in the merge train. Returns `null` if the merge request is not in a merge train. |
| <a id="mergerequestmergetrainscount"></a>`mergeTrainsCount` | [`Int`](#int) | Number of merge requests in the merge train. |
| <a id="mergerequestmergetrainindex"></a>`mergeTrainIndex` **{warning-solid}** | [`Int`](#int) | **Deprecated** in GitLab 17.4. Use `index` on `MergeTrains::CarType` instead. |
| <a id="mergerequestmergetrainscount"></a>`mergeTrainsCount` **{warning-solid}** | [`Int`](#int) | **Deprecated** in GitLab 17.4. Use `count` from `cars` connection on `MergeTrains::TrainType` instead. |
| <a id="mergerequestmergeuser"></a>`mergeUser` | [`UserCore`](#usercore) | User who merged this merge request or set it to auto-merge. |
| <a id="mergerequestmergewhenpipelinesucceeds"></a>`mergeWhenPipelineSucceeds` | [`Boolean`](#boolean) | Indicates if the merge has been set to auto-merge. |
| <a id="mergerequestmergeabilitychecks"></a>`mergeabilityChecks` **{warning-solid}** | [`[MergeRequestMergeabilityCheck!]!`](#mergerequestmergeabilitycheck) | **Introduced** in GitLab 16.5. **Status**: Experiment. Status of all mergeability checks of the merge request. |
@ -27039,6 +27090,7 @@ MergeTrainCar represents an attempt to merge a merge requestusing merge trains.
| <a id="mergetraincarcreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp of when the car was created. |
| <a id="mergetraincarduration"></a>`duration` | [`Int`](#int) | Duration of the car. |
| <a id="mergetraincarid"></a>`id` | [`MergeTrainsCarID!`](#mergetrainscarid) | Global ID of the car. |
| <a id="mergetraincarindex"></a>`index` | [`Int`](#int) | Zero-based position of the car in the merge train. Returns `null` if the car is not active in a merge train. |
| <a id="mergetraincarmergerequest"></a>`mergeRequest` | [`MergeRequest!`](#mergerequest) | Merge request the car contains. |
| <a id="mergetraincarmergedat"></a>`mergedAt` | [`Time`](#time) | Timestamp of when the car was merged. |
| <a id="mergetraincarpipeline"></a>`pipeline` | [`Pipeline`](#pipeline) | Pipeline of the car. |

View File

@ -256,3 +256,14 @@ To remove the unneeded data:
PackageMetadata::PackageVersionLicense.delete_all
PackageMetadata::PackageVersion.delete_all
```
### Dependency licenses are unknown
Open source license information is stored in the database and used to resolve licenses for a
project's dependencies. A dependency's license may appear as `unknown` if license information does
not exist or if that data is not yet available in the database.
Lookups for a dependency's licenses are done upon pipeline completion, so if this data was not
available at that time an `unknown` license is recorded. This license is shown up until a subsequent
pipeline is executed at which point another license lookup is made. If a lookup confirms the
dependency's license has changed, the new license is shown at this time.

View File

@ -7123,6 +7123,12 @@ msgstr ""
msgid "Approved"
msgstr ""
msgid "Approved by others"
msgstr ""
msgid "Approved by you"
msgstr ""
msgid "Approved members will use an additional seat in your subscription, which may override your user cap."
msgid_plural "Approved members will use an additional %d seats in your subscription, which may override your user cap."
msgstr[0] ""
@ -7517,6 +7523,9 @@ msgstr ""
msgid "Assigned to me"
msgstr ""
msgid "Assigned to you"
msgstr ""
msgid "Assignee"
msgid_plural "%d Assignees"
msgstr[0] ""
@ -33745,18 +33754,15 @@ msgstr ""
msgid "Merged %{timeAgo} by"
msgstr ""
msgid "Merged as assignee (1 week ago)"
msgstr ""
msgid "Merged as reviewer (1 week ago)"
msgstr ""
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
msgid "Merged by"
msgstr ""
msgid "Merged recently"
msgstr ""
msgid "Merged this merge request."
msgstr ""
@ -45805,9 +45811,6 @@ msgstr ""
msgid "Review time is the amount of time since the first comment in a merge request."
msgstr ""
msgid "Reviewed"
msgstr ""
msgid "Reviewer"
msgid_plural "%d Reviewers"
msgstr[0] ""
@ -45822,9 +45825,6 @@ msgstr ""
msgid "Reviewing (merge request !%{mergeRequestId})"
msgstr ""
msgid "Reviews approved"
msgstr ""
msgid "Reviews requested"
msgstr ""
@ -60103,7 +60103,7 @@ msgstr ""
msgid "Waiting for merge (open and assigned)"
msgstr ""
msgid "Waiting for reviewers"
msgid "Waiting for others"
msgstr ""
msgid "Want to see the data? Please ask an administrator for access."
@ -62976,9 +62976,6 @@ msgstr ""
msgid "Your work items are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
msgid "Yours approved"
msgstr ""
msgid "Youre about to permanently delete the %{issuableType} %{strongOpen}%{issuableTitle}%{strongClose}. To avoid data loss, consider %{strongOpen}closing this %{issuableType}%{strongClose} instead. Once deleted, it cannot be undone or recovered."
msgstr ""

View File

@ -1,4 +1,4 @@
ARG GDK_SHA=451c0201d6ce5686fc863290994b8cf92f037dfc
ARG GDK_SHA=9d28846535331fae67117bd94aa541e51a154b0d
# Use tag prefix when running on 'stable' branch to make sure 'protected' image is used which is not deleted by registry cleanup
ARG GDK_BASE_TAG_PREFIX

View File

@ -569,6 +569,73 @@ RSpec.describe MergeRequestsFinder, feature_category: :code_review_workflow do
it { is_expected.to contain_exactly(*expected_mr) }
end
context 'assignee or reviewer filtering' do
let(:dashboard_flag_enabled) { true }
let(:params) { { assigned_user_id: user.id } }
let(:expected_mrs) { [merge_request1, merge_request2, merge_request3] }
subject { described_class.new(user, params).execute }
before do
stub_feature_flags(merge_request_dashboard: dashboard_flag_enabled)
end
context 'when merge_request_dashboard feature flag is disabled' do
let(:dashboard_flag_enabled) { false }
let(:expected_mrs) { [merge_request1, merge_request2, merge_request3, merge_request4, merge_request5] }
it { is_expected.to contain_exactly(*expected_mrs) }
end
it { is_expected.to contain_exactly(*expected_mrs) }
end
context 'assignee or reviewer filtering with assigned_review_states' do
let(:params) { { assigned_user_id: user.id, assigned_review_states: [:reviewed] } }
let(:expected_mr) { [merge_request1, merge_request3] }
subject { described_class.new(user, params).execute }
before do
stub_feature_flags(merge_request_dashboard: true)
merge_request1.merge_request_reviewers.update_all(state: :reviewed)
end
it { is_expected.to contain_exactly(*expected_mr) }
end
context 'assignee or reviewer filtering with reviewer_review_states' do
let(:params) { { assigned_user_id: user2.id, reviewer_review_states: [:reviewed] } }
let(:expected_mr) { [merge_request1, merge_request3] }
subject { described_class.new(user2, params).execute }
before do
stub_feature_flags(merge_request_dashboard: true)
merge_request1.merge_request_reviewers.update_all(state: :reviewed)
end
it { is_expected.to contain_exactly(*expected_mr) }
end
context 'assignee or reviewer filtering with assigned_review_states and reviewer_review_states' do
let(:params) { { assigned_user_id: user.id, assigned_review_states: [:requested_changes], reviewer_review_states: [:reviewed] } }
let(:expected_mr) { [merge_request1, merge_request3] }
subject { described_class.new(user, params).execute }
before do
stub_feature_flags(merge_request_dashboard: true)
merge_request1.merge_request_reviewers.update_all(state: :requested_changes)
merge_request3.merge_request_reviewers.update_all(state: :reviewed)
end
it { is_expected.to contain_exactly(*expected_mr) }
end
context 'filtering by group milestone' do
let(:group_milestone) { create(:milestone, group: group) }

View File

@ -5,8 +5,21 @@ require 'spec_helper'
RSpec.describe Resolvers::PackagesBaseResolver do
include GraphqlHelpers
let(:args) do
{
sort: :created_desc,
package_name: nil,
package_type: nil,
package_version: nil,
status: nil,
include_versionless: false
}
end
describe '#resolve' do
subject { resolve(described_class, arg_style: :internal) }
subject do
resolve(described_class, args: args, arg_style: :internal)
end
it 'throws an error' do
expect { subject }.to raise_error(NotImplementedError)

View File

@ -233,6 +233,33 @@ RSpec.describe MergeRequest, factory_default: :keep, feature_category: :code_rev
end
end
describe '.assignee_or_reviewer' do
let_it_be(:merge_request5) do
create(:merge_request, :prepared, :unique_branches, assignees: [user1], reviewers: [user2], created_at:
2.days.ago)
end
it 'returns merge requests that the user is a reviewer or an assignee of' do
expect(described_class.assignee_or_reviewer(user1, nil, nil)).to match_array([merge_request1, merge_request2, merge_request5])
end
context 'when the user is an assignee and a reviewer reviewed' do
before_all do
merge_request5.merge_request_reviewers.update_all(state: :reviewed)
end
it { expect(described_class.assignee_or_reviewer(user1, MergeRequestReviewer.states[:reviewed], nil)).to match_array([merge_request1, merge_request2, merge_request5]) }
it { expect(described_class.assignee_or_reviewer(user1, MergeRequestReviewer.states[:requested_changes], nil)).to match_array([merge_request1, merge_request2]) }
end
context 'when the user is a reviewer and left a review' do
it { expect(described_class.assignee_or_reviewer(user1, nil, MergeRequestReviewer.states[:reviewed])).to match_array([merge_request2, merge_request5]) }
it { expect(described_class.assignee_or_reviewer(user1, nil, MergeRequestReviewer.states[:requested_changes])).to match_array([merge_request1, merge_request5]) }
end
end
describe '.drafts' do
it 'returns MRs where draft == true' do
expect(described_class.drafts).to eq([merge_request4])

View File

@ -0,0 +1,102 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'getting current users assigned or review requested merge requests', feature_category: :code_review_workflow do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository, :public) }
let_it_be(:current_user) { create(:user) }
let_it_be(:merge_request_1) do
create(:merge_request, :unique_branches, source_project: project, reviewers: [current_user])
end
let_it_be(:reviewer_change_requested) do
create(:merge_request, :unique_branches, source_project: project, assignees: [current_user],
reviewers: create_list(:user, 2))
end
let_it_be(:merge_request_3) do
create(:merge_request, :unique_branches, source_project: project, assignees: [current_user])
end
let(:merge_requests) { graphql_data.dig('currentUser', 'assigneeOrReviewerMergeRequests', 'nodes') }
let(:fields) do
<<~GRAPHQL
nodes { id }
GRAPHQL
end
def query(params = {})
graphql_query_for('currentUser', {}, query_graphql_field('assigneeOrReviewerMergeRequests', params, fields))
end
before_all do
project.add_developer(current_user)
reviewer_change_requested.merge_request_reviewers[0].update!(state: :requested_changes)
end
context 'when merge_request_dashboard feature flag is disabled' do
before do
stub_feature_flags(merge_request_dashboard: false)
end
it do
post_graphql(query, current_user: current_user)
expect(merge_requests).to be_nil
end
end
context 'when merge_request_dashboard feature flag is enabled' do
before do
stub_feature_flags(merge_request_dashboard: true)
end
it do
post_graphql(query, current_user: current_user)
expect(merge_requests).to contain_exactly(
a_hash_including('id' => merge_request_1.to_global_id.to_s),
a_hash_including('id' => reviewer_change_requested.to_global_id.to_s),
a_hash_including('id' => merge_request_3.to_global_id.to_s)
)
end
context 'when assigned_review_states argument is sent' do
it do
post_graphql(query({ assigned_review_states: [:REVIEWED] }), current_user: current_user)
expect(merge_requests).to contain_exactly(
a_hash_including('id' => merge_request_1.to_global_id.to_s)
)
end
end
context 'when reviewer_review_states argument is sent' do
it do
post_graphql(query({ reviewer_review_states: [:REQUESTED_CHANGES] }), current_user: current_user)
expect(merge_requests).to contain_exactly(
a_hash_including('id' => reviewer_change_requested.to_global_id.to_s),
a_hash_including('id' => merge_request_3.to_global_id.to_s)
)
end
end
context 'when reviewer_review_states and assigned_review_states arguments are sent' do
it do
post_graphql(query({ reviewer_review_states: [:UNREVIEWED], assigned_review_states: [:REQUESTED_CHANGES] }),
current_user: current_user)
expect(merge_requests).to contain_exactly(
a_hash_including('id' => merge_request_1.to_global_id.to_s),
a_hash_including('id' => reviewer_change_requested.to_global_id.to_s)
)
end
end
end
end