diff options
34 files changed, 712 insertions, 212 deletions
diff --git a/app/graphql/types/merge_request_type.rb b/app/graphql/types/merge_request_type.rb index 95b7438460d..af198d03c3f 100644 --- a/app/graphql/types/merge_request_type.rb +++ b/app/graphql/types/merge_request_type.rb @@ -137,7 +137,7 @@ module Types null: true, complexity: 5, description: 'Assignees of the merge request.' - field :author, Types::UserType, null: true, + field :author, Types::MergeRequests::AuthorType, null: true, description: 'User who created this merge request.' field :discussion_locked, GraphQL::Types::Boolean, description: 'Indicates if comments on the merge request are locked to members only.', @@ -150,7 +150,7 @@ module Types description: 'Labels of the merge request.' field :milestone, Types::MilestoneType, null: true, description: 'Milestone of the merge request.' - field :participants, Types::UserType.connection_type, null: true, complexity: 15, + field :participants, Types::MergeRequests::ParticipantType.connection_type, null: true, complexity: 15, description: 'Participants in the merge request. This includes the author, assignees, reviewers, and users mentioned in notes.', resolver: Resolvers::Users::ParticipantsResolver field :reference, GraphQL::Types::String, null: false, method: :to_reference, diff --git a/app/graphql/types/merge_requests/assignee_type.rb b/app/graphql/types/merge_requests/assignee_type.rb index 24321d057a3..a0ba74597ba 100644 --- a/app/graphql/types/merge_requests/assignee_type.rb +++ b/app/graphql/types/merge_requests/assignee_type.rb @@ -6,7 +6,6 @@ module Types graphql_name 'MergeRequestAssignee' description 'A user assigned to a merge request.' - include FindClosest include ::Types::MergeRequests::InteractsWithMergeRequest authorize :read_user diff --git a/app/graphql/types/merge_requests/author_type.rb b/app/graphql/types/merge_requests/author_type.rb new file mode 100644 index 00000000000..56ad3190547 --- /dev/null +++ b/app/graphql/types/merge_requests/author_type.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Types + module MergeRequests + class AuthorType < ::Types::UserType + graphql_name 'MergeRequestAuthor' + description 'The author of the merge request.' + + include ::Types::MergeRequests::InteractsWithMergeRequest + + authorize :read_user + end + end +end diff --git a/app/graphql/types/merge_requests/participant_type.rb b/app/graphql/types/merge_requests/participant_type.rb new file mode 100644 index 00000000000..86d627097b2 --- /dev/null +++ b/app/graphql/types/merge_requests/participant_type.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Types + module MergeRequests + class ParticipantType < ::Types::UserType + graphql_name 'MergeRequestParticipant' + description 'A user participating in a merge request.' + + include ::Types::MergeRequests::InteractsWithMergeRequest + + authorize :read_user + end + end +end diff --git a/app/graphql/types/merge_requests/reviewer_type.rb b/app/graphql/types/merge_requests/reviewer_type.rb index 11f7ceaf461..e5bc5812816 100644 --- a/app/graphql/types/merge_requests/reviewer_type.rb +++ b/app/graphql/types/merge_requests/reviewer_type.rb @@ -6,7 +6,6 @@ module Types graphql_name 'MergeRequestReviewer' description 'A user assigned to a merge request as a reviewer.' - include FindClosest include ::Types::MergeRequests::InteractsWithMergeRequest authorize :read_user diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index de9497a2f40..803b9781ac4 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -316,7 +316,6 @@ class WikiPage end def update_front_matter(attrs) - return unless Gitlab::WikiPages::FrontMatterParser.enabled?(container) return unless attrs.has_key?(:front_matter) fm_yaml = serialize_front_matter(attrs[:front_matter]) @@ -327,7 +326,7 @@ class WikiPage def parsed_content strong_memoize(:parsed_content) do - Gitlab::WikiPages::FrontMatterParser.new(raw_content, container).parse + Gitlab::WikiPages::FrontMatterParser.new(raw_content).parse end end diff --git a/config/feature_flags/development/wiki_front_matter.yml b/config/feature_flags/development/wiki_front_matter.yml deleted file mode 100644 index 39196440d17..00000000000 --- a/config/feature_flags/development/wiki_front_matter.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: wiki_front_matter -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27706 -rollout_issue_url: -milestone: '12.10' -type: development -group: group::editor -default_enabled: false diff --git a/config/feature_flags/ops/api_kaminari_count_with_limit.yml b/config/feature_flags/ops/api_kaminari_count_with_limit.yml index a55e3e67710..c11c6758189 100644 --- a/config/feature_flags/ops/api_kaminari_count_with_limit.yml +++ b/config/feature_flags/ops/api_kaminari_count_with_limit.yml @@ -1,8 +1,8 @@ --- name: api_kaminari_count_with_limit introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/23931 -rollout_issue_url: +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353077 milestone: '11.8' type: ops group: group::integrations -default_enabled: false +default_enabled: true diff --git a/doc/administration/job_artifacts.md b/doc/administration/job_artifacts.md index 58d2953fa7a..544a5973052 100644 --- a/doc/administration/job_artifacts.md +++ b/doc/administration/job_artifacts.md @@ -414,6 +414,37 @@ space, and in some cases, manually delete job artifacts to reclaim disk space. One possible first step is to [clean up _orphaned_ artifact files](../raketasks/cleanup.md#remove-orphan-artifact-files). +#### List projects and builds with artifacts with a specific expiration (or no expiration) + +Using a [Rails console](operations/rails_console.md), you can find projects that have job artifacts with either: + +- No expiration date. +- An expiration date more than 7 days in the future. + +Similar to [deleting artifacts](#delete-job-artifacts-from-jobs-completed-before-a-specific-date), use the following example time frames +and alter them as needed: + +- `7.days.from_now` +- `10.days.from_now` +- `2.weeks.from_now` +- `3.months.from_now` + +Each of the following scripts also limits the search to 50 results with `.limit(50)`, but this number can also be changed as needed: + +```ruby +# Find builds & projects with artifacts that never expire +builds_with_artifacts_that_never_expire = Ci::Build.with_downloadable_artifacts.where(artifacts_expire_at: nil).limit(50) +builds_with_artifacts_that_never_expire.find_each do |build| + puts "Build with id #{build.id} has artifacts that don't expire and belongs to project #{build.project.full_path}" +end + +# Find builds & projects with artifacts that expire after 7 days from today +builds_with_artifacts_that_expire_in_a_week = Ci::Build.with_downloadable_artifacts.where('artifacts_expire_at > ?', 7.days.from_now).limit(50) +builds_with_artifacts_that_expire_in_a_week.find_each do |build| + puts "Build with id #{build.id} has artifacts that expire at #{build.artifacts_expire_at} and belongs to project #{build.project.full_path}" +end +``` + #### List projects by total size of job artifacts stored List the top 20 projects, sorted by the total size of job artifacts stored, by @@ -599,3 +630,15 @@ review: ``` In both cases, you might need to add `region` to the job artifact [object storage configuration](#connection-settings). + +### Job artifact upload fails with `500 Internal Server Error (Missing file)` + +Bucket names that include folder paths are not supported with [consolidated object storage](object_storage.md#consolidated-object-storage-configuration). +For example, `bucket/path`. If a bucket name has a path in it, you might receive an error similar to: + +```plaintext +WARNING: Uploading artifacts as "archive" to coordinator... POST https://gitlab.example.com/api/v4/jobs/job_id/artifacts?artifact_format=zip&artifact_type=archive&expire_in=1+day: 500 Internal Server Error (Missing file) +FATAL: invalid argument +``` + +If a job artifact fails to upload with the above error when using consolidated object storage, make sure you are [using separate buckets](object_storage.md#use-separate-buckets) for each data type. diff --git a/doc/api/features.md b/doc/api/features.md index 30efacb1d00..593e4adedd7 100644 --- a/doc/api/features.md +++ b/doc/api/features.md @@ -95,7 +95,7 @@ Example response: "milestone": "11.8", "type": "ops", "group": "group::ecosystem", - "default_enabled": false + "default_enabled": true }, { "name": "marginalia", diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 16d4a8a85be..8f89deb5b62 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -7113,6 +7113,29 @@ The edge type for [`MergeRequest`](#mergerequest). | <a id="mergerequestedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. | | <a id="mergerequestedgenode"></a>`node` | [`MergeRequest`](#mergerequest) | The item at the end of the edge. | +#### `MergeRequestParticipantConnection` + +The connection type for [`MergeRequestParticipant`](#mergerequestparticipant). + +##### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestparticipantconnectionedges"></a>`edges` | [`[MergeRequestParticipantEdge]`](#mergerequestparticipantedge) | A list of edges. | +| <a id="mergerequestparticipantconnectionnodes"></a>`nodes` | [`[MergeRequestParticipant]`](#mergerequestparticipant) | A list of nodes. | +| <a id="mergerequestparticipantconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. | + +#### `MergeRequestParticipantEdge` + +The edge type for [`MergeRequestParticipant`](#mergerequestparticipant). + +##### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestparticipantedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. | +| <a id="mergerequestparticipantedgenode"></a>`node` | [`MergeRequestParticipant`](#mergerequestparticipant) | The item at the end of the edge. | + #### `MergeRequestReviewerConnection` The connection type for [`MergeRequestReviewer`](#mergerequestreviewer). @@ -12362,7 +12385,7 @@ Maven metadata. | <a id="mergerequestapproved"></a>`approved` | [`Boolean!`](#boolean) | Indicates if the merge request has all the required approvals. Returns true if no required approvals are configured. | | <a id="mergerequestapprovedby"></a>`approvedBy` | [`UserCoreConnection`](#usercoreconnection) | Users who approved the merge request. (see [Connections](#connections)) | | <a id="mergerequestassignees"></a>`assignees` | [`MergeRequestAssigneeConnection`](#mergerequestassigneeconnection) | Assignees of the merge request. (see [Connections](#connections)) | -| <a id="mergerequestauthor"></a>`author` | [`UserCore`](#usercore) | User who created this merge request. | +| <a id="mergerequestauthor"></a>`author` | [`MergeRequestAuthor`](#mergerequestauthor) | User who created this merge request. | | <a id="mergerequestautomergeenabled"></a>`autoMergeEnabled` | [`Boolean!`](#boolean) | Indicates if auto merge is enabled for the merge request. | | <a id="mergerequestautomergestrategy"></a>`autoMergeStrategy` | [`String`](#string) | Selected auto merge strategy. | | <a id="mergerequestavailableautomergestrategies"></a>`availableAutoMergeStrategies` | [`[String!]`](#string) | Array of available auto merge strategies. | @@ -12408,7 +12431,7 @@ Maven metadata. | <a id="mergerequestmergedat"></a>`mergedAt` | [`Time`](#time) | Timestamp of when the merge request was merged, null if not merged. | | <a id="mergerequestmilestone"></a>`milestone` | [`Milestone`](#milestone) | Milestone of the merge request. | | <a id="mergerequestnotes"></a>`notes` | [`NoteConnection!`](#noteconnection) | All notes on this noteable. (see [Connections](#connections)) | -| <a id="mergerequestparticipants"></a>`participants` | [`UserCoreConnection`](#usercoreconnection) | Participants in the merge request. This includes the author, assignees, reviewers, and users mentioned in notes. (see [Connections](#connections)) | +| <a id="mergerequestparticipants"></a>`participants` | [`MergeRequestParticipantConnection`](#mergerequestparticipantconnection) | Participants in the merge request. This includes the author, assignees, reviewers, and users mentioned in notes. (see [Connections](#connections)) | | <a id="mergerequestproject"></a>`project` | [`Project!`](#project) | Alias for target_project. | | <a id="mergerequestprojectid"></a>`projectId` | [`Int!`](#int) | ID of the merge request project. | | <a id="mergerequestrebasecommitsha"></a>`rebaseCommitSha` | [`String`](#string) | Rebase commit SHA of the merge request. | @@ -12750,6 +12773,236 @@ four standard [pagination arguments](#connection-pagination-arguments): | <a id="mergerequestassigneetodosstate"></a>`state` | [`[TodoStateEnum!]`](#todostateenum) | State of the todo. | | <a id="mergerequestassigneetodostype"></a>`type` | [`[TodoTargetEnum!]`](#todotargetenum) | Type of the todo. | +### `MergeRequestAuthor` + +The author of the merge request. + +#### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestauthoravatarurl"></a>`avatarUrl` | [`String`](#string) | URL of the user's avatar. | +| <a id="mergerequestauthorbot"></a>`bot` | [`Boolean!`](#boolean) | Indicates if the user is a bot. | +| <a id="mergerequestauthorcallouts"></a>`callouts` | [`UserCalloutConnection`](#usercalloutconnection) | User callouts that belong to the user. (see [Connections](#connections)) | +| <a id="mergerequestauthoremail"></a>`email` **{warning-solid}** | [`String`](#string) | **Deprecated** in 13.7. This was renamed. Use: [`User.publicEmail`](#userpublicemail). | +| <a id="mergerequestauthorgitpodenabled"></a>`gitpodEnabled` | [`Boolean`](#boolean) | Whether Gitpod is enabled at the user level. | +| <a id="mergerequestauthorgroupcount"></a>`groupCount` | [`Int`](#int) | Group count for the user. | +| <a id="mergerequestauthorgroupmemberships"></a>`groupMemberships` | [`GroupMemberConnection`](#groupmemberconnection) | Group memberships of the user. (see [Connections](#connections)) | +| <a id="mergerequestauthorid"></a>`id` | [`ID!`](#id) | ID of the user. | +| <a id="mergerequestauthorlocation"></a>`location` | [`String`](#string) | Location of the user. | +| <a id="mergerequestauthormergerequestinteraction"></a>`mergeRequestInteraction` | [`UserMergeRequestInteraction`](#usermergerequestinteraction) | Details of this user's interactions with the merge request. | +| <a id="mergerequestauthorname"></a>`name` | [`String!`](#string) | Human-readable name of the user. Returns `****` if the user is a project bot and the requester does not have permission to view the project. | +| <a id="mergerequestauthornamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. | +| <a id="mergerequestauthorpreferencesgitpodpath"></a>`preferencesGitpodPath` | [`String`](#string) | Web path to the Gitpod section within user preferences. | +| <a id="mergerequestauthorprofileenablegitpodpath"></a>`profileEnableGitpodPath` | [`String`](#string) | Web path to enable Gitpod for the user. | +| <a id="mergerequestauthorprojectmemberships"></a>`projectMemberships` | [`ProjectMemberConnection`](#projectmemberconnection) | Project memberships of the user. (see [Connections](#connections)) | +| <a id="mergerequestauthorpublicemail"></a>`publicEmail` | [`String`](#string) | User's public email. | +| <a id="mergerequestauthorsavedreplies"></a>`savedReplies` | [`SavedReplyConnection`](#savedreplyconnection) | Saved replies authored by the user. (see [Connections](#connections)) | +| <a id="mergerequestauthorstate"></a>`state` | [`UserState!`](#userstate) | State of the user. | +| <a id="mergerequestauthorstatus"></a>`status` | [`UserStatus`](#userstatus) | User status. | +| <a id="mergerequestauthoruserpermissions"></a>`userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. | +| <a id="mergerequestauthorusername"></a>`username` | [`String!`](#string) | Username of the user. Unique within this instance of GitLab. | +| <a id="mergerequestauthorwebpath"></a>`webPath` | [`String!`](#string) | Web path of the user. | +| <a id="mergerequestauthorweburl"></a>`webUrl` | [`String!`](#string) | Web URL of the user. | + +#### Fields with arguments + +##### `MergeRequestAuthor.assignedMergeRequests` + +Merge requests assigned to the user. + +Returns [`MergeRequestConnection`](#mergerequestconnection). + +This field returns a [connection](#connections). It accepts the +four standard [pagination arguments](#connection-pagination-arguments): +`before: String`, `after: String`, `first: Int`, `last: Int`. + +###### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestauthorassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. | +| <a id="mergerequestauthorassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. | +| <a id="mergerequestauthorassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. | +| <a id="mergerequestauthorassignedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. | +| <a id="mergerequestauthorassignedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. | +| <a id="mergerequestauthorassignedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. | +| <a id="mergerequestauthorassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. | +| <a id="mergerequestauthorassignedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before this date. | +| <a id="mergerequestauthorassignedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. | +| <a id="mergerequestauthorassignedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. | +| <a id="mergerequestauthorassignedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. | +| <a id="mergerequestauthorassignedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. | +| <a id="mergerequestauthorassignedmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. | +| <a id="mergerequestauthorassignedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. | +| <a id="mergerequestauthorassignedmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. | +| <a id="mergerequestauthorassignedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. | +| <a id="mergerequestauthorassignedmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. | +| <a id="mergerequestauthorassignedmergerequestsupdatedafter"></a>`updatedAfter` | [`Time`](#time) | Merge requests updated after this timestamp. | +| <a id="mergerequestauthorassignedmergerequestsupdatedbefore"></a>`updatedBefore` | [`Time`](#time) | Merge requests updated before this timestamp. | + +##### `MergeRequestAuthor.authoredMergeRequests` + +Merge requests authored by the user. + +Returns [`MergeRequestConnection`](#mergerequestconnection). + +This field returns a [connection](#connections). It accepts the +four standard [pagination arguments](#connection-pagination-arguments): +`before: String`, `after: String`, `first: Int`, `last: Int`. + +###### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestauthorauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. | +| <a id="mergerequestauthorauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. | +| <a id="mergerequestauthorauthoredmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. | +| <a id="mergerequestauthorauthoredmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. | +| <a id="mergerequestauthorauthoredmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. | +| <a id="mergerequestauthorauthoredmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. | +| <a id="mergerequestauthorauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. | +| <a id="mergerequestauthorauthoredmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before this date. | +| <a id="mergerequestauthorauthoredmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. | +| <a id="mergerequestauthorauthoredmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. | +| <a id="mergerequestauthorauthoredmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. | +| <a id="mergerequestauthorauthoredmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. | +| <a id="mergerequestauthorauthoredmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. | +| <a id="mergerequestauthorauthoredmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. | +| <a id="mergerequestauthorauthoredmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. | +| <a id="mergerequestauthorauthoredmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. | +| <a id="mergerequestauthorauthoredmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. | +| <a id="mergerequestauthorauthoredmergerequestsupdatedafter"></a>`updatedAfter` | [`Time`](#time) | Merge requests updated after this timestamp. | +| <a id="mergerequestauthorauthoredmergerequestsupdatedbefore"></a>`updatedBefore` | [`Time`](#time) | Merge requests updated before this timestamp. | + +##### `MergeRequestAuthor.groups` + +Groups where the user has access. + +Returns [`GroupConnection`](#groupconnection). + +This field returns a [connection](#connections). It accepts the +four standard [pagination arguments](#connection-pagination-arguments): +`before: String`, `after: String`, `first: Int`, `last: Int`. + +###### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestauthorgroupspermissionscope"></a>`permissionScope` | [`GroupPermission`](#grouppermission) | Filter by permissions the user has on groups. | +| <a id="mergerequestauthorgroupssearch"></a>`search` | [`String`](#string) | Search by group name or path. | + +##### `MergeRequestAuthor.reviewRequestedMergeRequests` + +Merge requests assigned to the user for review. + +Returns [`MergeRequestConnection`](#mergerequestconnection). + +This field returns a [connection](#connections). It accepts the +four standard [pagination arguments](#connection-pagination-arguments): +`before: String`, `after: String`, `first: Int`, `last: Int`. + +###### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestauthorreviewrequestedmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. | +| <a id="mergerequestauthorreviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. | +| <a id="mergerequestauthorreviewrequestedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. | +| <a id="mergerequestauthorreviewrequestedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. | +| <a id="mergerequestauthorreviewrequestedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. | +| <a id="mergerequestauthorreviewrequestedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. | +| <a id="mergerequestauthorreviewrequestedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. | +| <a id="mergerequestauthorreviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. | +| <a id="mergerequestauthorreviewrequestedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before this date. | +| <a id="mergerequestauthorreviewrequestedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. | +| <a id="mergerequestauthorreviewrequestedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. | +| <a id="mergerequestauthorreviewrequestedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. | +| <a id="mergerequestauthorreviewrequestedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. | +| <a id="mergerequestauthorreviewrequestedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. | +| <a id="mergerequestauthorreviewrequestedmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. | +| <a id="mergerequestauthorreviewrequestedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. | +| <a id="mergerequestauthorreviewrequestedmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. | +| <a id="mergerequestauthorreviewrequestedmergerequestsupdatedafter"></a>`updatedAfter` | [`Time`](#time) | Merge requests updated after this timestamp. | +| <a id="mergerequestauthorreviewrequestedmergerequestsupdatedbefore"></a>`updatedBefore` | [`Time`](#time) | Merge requests updated before this timestamp. | + +##### `MergeRequestAuthor.snippets` + +Snippets authored by the user. + +Returns [`SnippetConnection`](#snippetconnection). + +This field returns a [connection](#connections). It accepts the +four standard [pagination arguments](#connection-pagination-arguments): +`before: String`, `after: String`, `first: Int`, `last: Int`. + +###### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestauthorsnippetsids"></a>`ids` | [`[SnippetID!]`](#snippetid) | Array of global snippet IDs. For example, `gid://gitlab/ProjectSnippet/1`. | +| <a id="mergerequestauthorsnippetstype"></a>`type` | [`TypeEnum`](#typeenum) | Type of snippet. | +| <a id="mergerequestauthorsnippetsvisibility"></a>`visibility` | [`VisibilityScopesEnum`](#visibilityscopesenum) | Visibility of the snippet. | + +##### `MergeRequestAuthor.starredProjects` + +Projects starred by the user. + +Returns [`ProjectConnection`](#projectconnection). + +This field returns a [connection](#connections). It accepts the +four standard [pagination arguments](#connection-pagination-arguments): +`before: String`, `after: String`, `first: Int`, `last: Int`. + +###### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestauthorstarredprojectssearch"></a>`search` | [`String`](#string) | Search query. | + +##### `MergeRequestAuthor.timelogs` + +Time logged by the user. + +Returns [`TimelogConnection`](#timelogconnection). + +This field returns a [connection](#connections). It accepts the +four standard [pagination arguments](#connection-pagination-arguments): +`before: String`, `after: String`, `first: Int`, `last: Int`. + +###### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestauthortimelogsenddate"></a>`endDate` | [`Time`](#time) | List timelogs within a date range where the logged date is equal to or before endDate. | +| <a id="mergerequestauthortimelogsendtime"></a>`endTime` | [`Time`](#time) | List timelogs within a time range where the logged time is equal to or before endTime. | +| <a id="mergerequestauthortimelogsgroupid"></a>`groupId` | [`GroupID`](#groupid) | List timelogs for a group. | +| <a id="mergerequestauthortimelogsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | List timelogs for a project. | +| <a id="mergerequestauthortimelogsstartdate"></a>`startDate` | [`Time`](#time) | List timelogs within a date range where the logged date is equal to or after startDate. | +| <a id="mergerequestauthortimelogsstarttime"></a>`startTime` | [`Time`](#time) | List timelogs within a time range where the logged time is equal to or after startTime. | +| <a id="mergerequestauthortimelogsusername"></a>`username` | [`String`](#string) | List timelogs for a user. | + +##### `MergeRequestAuthor.todos` + +To-do items of the user. + +Returns [`TodoConnection`](#todoconnection). + +This field returns a [connection](#connections). It accepts the +four standard [pagination arguments](#connection-pagination-arguments): +`before: String`, `after: String`, `first: Int`, `last: Int`. + +###### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestauthortodosaction"></a>`action` | [`[TodoActionEnum!]`](#todoactionenum) | Action to be filtered. | +| <a id="mergerequestauthortodosauthorid"></a>`authorId` | [`[ID!]`](#id) | ID of an author. | +| <a id="mergerequestauthortodosgroupid"></a>`groupId` | [`[ID!]`](#id) | ID of a group. | +| <a id="mergerequestauthortodosprojectid"></a>`projectId` | [`[ID!]`](#id) | ID of a project. | +| <a id="mergerequestauthortodosstate"></a>`state` | [`[TodoStateEnum!]`](#todostateenum) | State of the todo. | +| <a id="mergerequestauthortodostype"></a>`type` | [`[TodoTargetEnum!]`](#todotargetenum) | Type of the todo. | + ### `MergeRequestDiffRegistry` Represents the Geo sync and verification state of a Merge Request diff. @@ -12767,6 +13020,236 @@ Represents the Geo sync and verification state of a Merge Request diff. | <a id="mergerequestdiffregistryretrycount"></a>`retryCount` | [`Int`](#int) | Number of consecutive failed sync attempts of the MergeRequestDiffRegistry. | | <a id="mergerequestdiffregistrystate"></a>`state` | [`RegistryState`](#registrystate) | Sync state of the MergeRequestDiffRegistry. | +### `MergeRequestParticipant` + +A user participating in a merge request. + +#### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestparticipantavatarurl"></a>`avatarUrl` | [`String`](#string) | URL of the user's avatar. | +| <a id="mergerequestparticipantbot"></a>`bot` | [`Boolean!`](#boolean) | Indicates if the user is a bot. | +| <a id="mergerequestparticipantcallouts"></a>`callouts` | [`UserCalloutConnection`](#usercalloutconnection) | User callouts that belong to the user. (see [Connections](#connections)) | +| <a id="mergerequestparticipantemail"></a>`email` **{warning-solid}** | [`String`](#string) | **Deprecated** in 13.7. This was renamed. Use: [`User.publicEmail`](#userpublicemail). | +| <a id="mergerequestparticipantgitpodenabled"></a>`gitpodEnabled` | [`Boolean`](#boolean) | Whether Gitpod is enabled at the user level. | +| <a id="mergerequestparticipantgroupcount"></a>`groupCount` | [`Int`](#int) | Group count for the user. | +| <a id="mergerequestparticipantgroupmemberships"></a>`groupMemberships` | [`GroupMemberConnection`](#groupmemberconnection) | Group memberships of the user. (see [Connections](#connections)) | +| <a id="mergerequestparticipantid"></a>`id` | [`ID!`](#id) | ID of the user. | +| <a id="mergerequestparticipantlocation"></a>`location` | [`String`](#string) | Location of the user. | +| <a id="mergerequestparticipantmergerequestinteraction"></a>`mergeRequestInteraction` | [`UserMergeRequestInteraction`](#usermergerequestinteraction) | Details of this user's interactions with the merge request. | +| <a id="mergerequestparticipantname"></a>`name` | [`String!`](#string) | Human-readable name of the user. Returns `****` if the user is a project bot and the requester does not have permission to view the project. | +| <a id="mergerequestparticipantnamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. | +| <a id="mergerequestparticipantpreferencesgitpodpath"></a>`preferencesGitpodPath` | [`String`](#string) | Web path to the Gitpod section within user preferences. | +| <a id="mergerequestparticipantprofileenablegitpodpath"></a>`profileEnableGitpodPath` | [`String`](#string) | Web path to enable Gitpod for the user. | +| <a id="mergerequestparticipantprojectmemberships"></a>`projectMemberships` | [`ProjectMemberConnection`](#projectmemberconnection) | Project memberships of the user. (see [Connections](#connections)) | +| <a id="mergerequestparticipantpublicemail"></a>`publicEmail` | [`String`](#string) | User's public email. | +| <a id="mergerequestparticipantsavedreplies"></a>`savedReplies` | [`SavedReplyConnection`](#savedreplyconnection) | Saved replies authored by the user. (see [Connections](#connections)) | +| <a id="mergerequestparticipantstate"></a>`state` | [`UserState!`](#userstate) | State of the user. | +| <a id="mergerequestparticipantstatus"></a>`status` | [`UserStatus`](#userstatus) | User status. | +| <a id="mergerequestparticipantuserpermissions"></a>`userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. | +| <a id="mergerequestparticipantusername"></a>`username` | [`String!`](#string) | Username of the user. Unique within this instance of GitLab. | +| <a id="mergerequestparticipantwebpath"></a>`webPath` | [`String!`](#string) | Web path of the user. | +| <a id="mergerequestparticipantweburl"></a>`webUrl` | [`String!`](#string) | Web URL of the user. | + +#### Fields with arguments + +##### `MergeRequestParticipant.assignedMergeRequests` + +Merge requests assigned to the user. + +Returns [`MergeRequestConnection`](#mergerequestconnection). + +This field returns a [connection](#connections). It accepts the +four standard [pagination arguments](#connection-pagination-arguments): +`before: String`, `after: String`, `first: Int`, `last: Int`. + +###### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestparticipantassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. | +| <a id="mergerequestparticipantassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. | +| <a id="mergerequestparticipantassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. | +| <a id="mergerequestparticipantassignedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. | +| <a id="mergerequestparticipantassignedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. | +| <a id="mergerequestparticipantassignedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. | +| <a id="mergerequestparticipantassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. | +| <a id="mergerequestparticipantassignedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before this date. | +| <a id="mergerequestparticipantassignedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. | +| <a id="mergerequestparticipantassignedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. | +| <a id="mergerequestparticipantassignedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. | +| <a id="mergerequestparticipantassignedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. | +| <a id="mergerequestparticipantassignedmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. | +| <a id="mergerequestparticipantassignedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. | +| <a id="mergerequestparticipantassignedmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. | +| <a id="mergerequestparticipantassignedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. | +| <a id="mergerequestparticipantassignedmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. | +| <a id="mergerequestparticipantassignedmergerequestsupdatedafter"></a>`updatedAfter` | [`Time`](#time) | Merge requests updated after this timestamp. | +| <a id="mergerequestparticipantassignedmergerequestsupdatedbefore"></a>`updatedBefore` | [`Time`](#time) | Merge requests updated before this timestamp. | + +##### `MergeRequestParticipant.authoredMergeRequests` + +Merge requests authored by the user. + +Returns [`MergeRequestConnection`](#mergerequestconnection). + +This field returns a [connection](#connections). It accepts the +four standard [pagination arguments](#connection-pagination-arguments): +`before: String`, `after: String`, `first: Int`, `last: Int`. + +###### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestparticipantauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. | +| <a id="mergerequestparticipantauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. | +| <a id="mergerequestparticipantauthoredmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. | +| <a id="mergerequestparticipantauthoredmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. | +| <a id="mergerequestparticipantauthoredmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. | +| <a id="mergerequestparticipantauthoredmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. | +| <a id="mergerequestparticipantauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. | +| <a id="mergerequestparticipantauthoredmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before this date. | +| <a id="mergerequestparticipantauthoredmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. | +| <a id="mergerequestparticipantauthoredmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. | +| <a id="mergerequestparticipantauthoredmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. | +| <a id="mergerequestparticipantauthoredmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. | +| <a id="mergerequestparticipantauthoredmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. | +| <a id="mergerequestparticipantauthoredmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. | +| <a id="mergerequestparticipantauthoredmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. | +| <a id="mergerequestparticipantauthoredmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. | +| <a id="mergerequestparticipantauthoredmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. | +| <a id="mergerequestparticipantauthoredmergerequestsupdatedafter"></a>`updatedAfter` | [`Time`](#time) | Merge requests updated after this timestamp. | +| <a id="mergerequestparticipantauthoredmergerequestsupdatedbefore"></a>`updatedBefore` | [`Time`](#time) | Merge requests updated before this timestamp. | + +##### `MergeRequestParticipant.groups` + +Groups where the user has access. + +Returns [`GroupConnection`](#groupconnection). + +This field returns a [connection](#connections). It accepts the +four standard [pagination arguments](#connection-pagination-arguments): +`before: String`, `after: String`, `first: Int`, `last: Int`. + +###### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestparticipantgroupspermissionscope"></a>`permissionScope` | [`GroupPermission`](#grouppermission) | Filter by permissions the user has on groups. | +| <a id="mergerequestparticipantgroupssearch"></a>`search` | [`String`](#string) | Search by group name or path. | + +##### `MergeRequestParticipant.reviewRequestedMergeRequests` + +Merge requests assigned to the user for review. + +Returns [`MergeRequestConnection`](#mergerequestconnection). + +This field returns a [connection](#connections). It accepts the +four standard [pagination arguments](#connection-pagination-arguments): +`before: String`, `after: String`, `first: Int`, `last: Int`. + +###### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestparticipantreviewrequestedmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. | +| <a id="mergerequestparticipantreviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. | +| <a id="mergerequestparticipantreviewrequestedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. | +| <a id="mergerequestparticipantreviewrequestedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. | +| <a id="mergerequestparticipantreviewrequestedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. | +| <a id="mergerequestparticipantreviewrequestedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. | +| <a id="mergerequestparticipantreviewrequestedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. | +| <a id="mergerequestparticipantreviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. | +| <a id="mergerequestparticipantreviewrequestedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before this date. | +| <a id="mergerequestparticipantreviewrequestedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. | +| <a id="mergerequestparticipantreviewrequestedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. | +| <a id="mergerequestparticipantreviewrequestedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. | +| <a id="mergerequestparticipantreviewrequestedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. | +| <a id="mergerequestparticipantreviewrequestedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. | +| <a id="mergerequestparticipantreviewrequestedmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. | +| <a id="mergerequestparticipantreviewrequestedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. | +| <a id="mergerequestparticipantreviewrequestedmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. | +| <a id="mergerequestparticipantreviewrequestedmergerequestsupdatedafter"></a>`updatedAfter` | [`Time`](#time) | Merge requests updated after this timestamp. | +| <a id="mergerequestparticipantreviewrequestedmergerequestsupdatedbefore"></a>`updatedBefore` | [`Time`](#time) | Merge requests updated before this timestamp. | + +##### `MergeRequestParticipant.snippets` + +Snippets authored by the user. + +Returns [`SnippetConnection`](#snippetconnection). + +This field returns a [connection](#connections). It accepts the +four standard [pagination arguments](#connection-pagination-arguments): +`before: String`, `after: String`, `first: Int`, `last: Int`. + +###### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestparticipantsnippetsids"></a>`ids` | [`[SnippetID!]`](#snippetid) | Array of global snippet IDs. For example, `gid://gitlab/ProjectSnippet/1`. | +| <a id="mergerequestparticipantsnippetstype"></a>`type` | [`TypeEnum`](#typeenum) | Type of snippet. | +| <a id="mergerequestparticipantsnippetsvisibility"></a>`visibility` | [`VisibilityScopesEnum`](#visibilityscopesenum) | Visibility of the snippet. | + +##### `MergeRequestParticipant.starredProjects` + +Projects starred by the user. + +Returns [`ProjectConnection`](#projectconnection). + +This field returns a [connection](#connections). It accepts the +four standard [pagination arguments](#connection-pagination-arguments): +`before: String`, `after: String`, `first: Int`, `last: Int`. + +###### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestparticipantstarredprojectssearch"></a>`search` | [`String`](#string) | Search query. | + +##### `MergeRequestParticipant.timelogs` + +Time logged by the user. + +Returns [`TimelogConnection`](#timelogconnection). + +This field returns a [connection](#connections). It accepts the +four standard [pagination arguments](#connection-pagination-arguments): +`before: String`, `after: String`, `first: Int`, `last: Int`. + +###### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestparticipanttimelogsenddate"></a>`endDate` | [`Time`](#time) | List timelogs within a date range where the logged date is equal to or before endDate. | +| <a id="mergerequestparticipanttimelogsendtime"></a>`endTime` | [`Time`](#time) | List timelogs within a time range where the logged time is equal to or before endTime. | +| <a id="mergerequestparticipanttimelogsgroupid"></a>`groupId` | [`GroupID`](#groupid) | List timelogs for a group. | +| <a id="mergerequestparticipanttimelogsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | List timelogs for a project. | +| <a id="mergerequestparticipanttimelogsstartdate"></a>`startDate` | [`Time`](#time) | List timelogs within a date range where the logged date is equal to or after startDate. | +| <a id="mergerequestparticipanttimelogsstarttime"></a>`startTime` | [`Time`](#time) | List timelogs within a time range where the logged time is equal to or after startTime. | +| <a id="mergerequestparticipanttimelogsusername"></a>`username` | [`String`](#string) | List timelogs for a user. | + +##### `MergeRequestParticipant.todos` + +To-do items of the user. + +Returns [`TodoConnection`](#todoconnection). + +This field returns a [connection](#connections). It accepts the +four standard [pagination arguments](#connection-pagination-arguments): +`before: String`, `after: String`, `first: Int`, `last: Int`. + +###### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mergerequestparticipanttodosaction"></a>`action` | [`[TodoActionEnum!]`](#todoactionenum) | Action to be filtered. | +| <a id="mergerequestparticipanttodosauthorid"></a>`authorId` | [`[ID!]`](#id) | ID of an author. | +| <a id="mergerequestparticipanttodosgroupid"></a>`groupId` | [`[ID!]`](#id) | ID of a group. | +| <a id="mergerequestparticipanttodosprojectid"></a>`projectId` | [`[ID!]`](#id) | ID of a project. | +| <a id="mergerequestparticipanttodosstate"></a>`state` | [`[TodoStateEnum!]`](#todostateenum) | State of the todo. | +| <a id="mergerequestparticipanttodostype"></a>`type` | [`[TodoTargetEnum!]`](#todotargetenum) | Type of the todo. | + ### `MergeRequestPermissions` Check permissions for the current user on a merge request. @@ -19668,6 +20151,8 @@ Representation of a GitLab user. Implementations: - [`MergeRequestAssignee`](#mergerequestassignee) +- [`MergeRequestAuthor`](#mergerequestauthor) +- [`MergeRequestParticipant`](#mergerequestparticipant) - [`MergeRequestReviewer`](#mergerequestreviewer) - [`UserCore`](#usercore) diff --git a/doc/development/integrations/secure.md b/doc/development/integrations/secure.md index 2205d11fd18..11fb06bd128 100644 --- a/doc/development/integrations/secure.md +++ b/doc/development/integrations/secure.md @@ -329,18 +329,40 @@ You can find the schemas for these scanners here: ### Enable report validation -In GitLab 14.10 and later, report validation against the schemas is enabled. To enable report validation for versions earlier than 14.10, -set [`VALIDATE_SCHEMA`](../../user/application_security/#enable-security-report-validation) to -`"true"`. +> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/354928) in GitLab 14.9, and planned for removal in GitLab 15.0. +DISCLAIMER: +This page contains information related to upcoming products, features, and functionality. +It is important to note that the information presented is for informational purposes only. +Please do not rely on this information for purchasing or planning purposes. +As with all projects, the items mentioned on this page are subject to change or delay. +The development, release, and timing of any products, features, or functionality remain at the +sole discretion of GitLab Inc. +In GitLab 15.0 and later, report validation is enabled and enforced. Reports that fail validation +are not ingested, and an error message displays on the corresponding pipeline. -Reports that don't pass validation are not ingested by GitLab, and an error message -displays on the corresponding pipeline. +In GitLab 14.10 and later, report validation against the schemas is enabled but not enforced. +Reports that fail validation are ingested but display a warning in the pipeline security tab. -You should ensure that reports generated by the scanner pass validation against the schema version -declared in your reports. GitLab uses the +To enforce report validation for GitLab version 14.10 and earlier, set +[`VALIDATE_SCHEMA`](../../user/application_security/#enable-security-report-validation) to `"true"`. + +### Report validation + +You must ensure that reports generated by the scanner pass validation against the schema version +declared in your reports. Reports that don't pass validation are not ingested by GitLab, and an +error message displays on the corresponding pipeline. + +Reports that use a deprecated version of the secure report schema are ingested but cause a warning +message to display on the corresponding pipeline. If you see this warning, update your +analyzer to use the latest available schemas. + +After the deprecation period for a schema version, the file is removed from GitLab. Reports that +declare removed versions are rejected, and an error message displays on the corresponding pipeline. + +GitLab uses the [`json_schemer`](https://www.rubydoc.info/gems/json_schemer) gem to perform validation. -Ongoing improvements to report validation is tracked [in this epic](https://gitlab.com/groups/gitlab-org/-/epics/6968). +Ongoing improvements to report validation are tracked [in this epic](https://gitlab.com/groups/gitlab-org/-/epics/6968). In the meantime, you can see which versions are supported in the [source code](https://gitlab.com/gitlab-org/gitlab/-/blob/08dd756429731a0cca1e27ca9d59eea226398a7d/lib/gitlab/ci/parsers/security/validators/schema_validator.rb#L9-27). diff --git a/doc/user/admin_area/credentials_inventory.md b/doc/user/admin_area/credentials_inventory.md index 5190dd810ab..21ac0f720ec 100644 --- a/doc/user/admin_area/credentials_inventory.md +++ b/doc/user/admin_area/credentials_inventory.md @@ -51,6 +51,8 @@ If you see a **Revoke** button, you can revoke that user's PAT. Whether you see When a PAT is revoked from the credentials inventory, the instance notifies the user by email. +![Credentials inventory page - Personal access tokens](img/credentials_inventory_personal_access_tokens_v14_9.png) + ## Revoke a user's project access token > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/243833) in GitLab 14.8. @@ -60,6 +62,8 @@ The **Revoke** button next to a project access token can be selected to revoke t - Revoke the token project access token. - Enqueue a background worker to delete the project bot user. +![Credentials inventory page - Project access tokens](img/credentials_inventory_project_access_tokens_v14_9.png) + ## Delete a user's SSH key > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/225248) in GitLab 13.5. @@ -67,7 +71,7 @@ The **Revoke** button next to a project access token can be selected to revoke t You can **Delete** a user's SSH key by navigating to the credentials inventory's SSH Keys tab. The instance then notifies the user. -![Credentials inventory page - SSH keys](img/credentials_inventory_ssh_keys_v13_5.png) +![Credentials inventory page - SSH keys](img/credentials_inventory_ssh_keys_v14_9.png) ## Review existing GPG keys @@ -81,4 +85,4 @@ credentials inventory GPG Keys tab, as well as the following properties: - The ID of the GPG key. - Whether the GPG key is [verified or unverified](../project/repository/gpg_signed_commits/index.md) -![Credentials inventory page - GPG keys](img/credentials_inventory_gpg_keys_v13_10.png) +![Credentials inventory page - GPG keys](img/credentials_inventory_gpg_keys_v14_9.png) diff --git a/doc/user/admin_area/img/credentials_inventory_gpg_keys_v13_10.png b/doc/user/admin_area/img/credentials_inventory_gpg_keys_v13_10.png Binary files differdeleted file mode 100644 index a88d80a72b6..00000000000 --- a/doc/user/admin_area/img/credentials_inventory_gpg_keys_v13_10.png +++ /dev/null diff --git a/doc/user/admin_area/img/credentials_inventory_gpg_keys_v14_9.png b/doc/user/admin_area/img/credentials_inventory_gpg_keys_v14_9.png Binary files differnew file mode 100644 index 00000000000..6c4c8f30df6 --- /dev/null +++ b/doc/user/admin_area/img/credentials_inventory_gpg_keys_v14_9.png diff --git a/doc/user/admin_area/img/credentials_inventory_personal_access_tokens_v14_9.png b/doc/user/admin_area/img/credentials_inventory_personal_access_tokens_v14_9.png Binary files differnew file mode 100644 index 00000000000..254d520d538 --- /dev/null +++ b/doc/user/admin_area/img/credentials_inventory_personal_access_tokens_v14_9.png diff --git a/doc/user/admin_area/img/credentials_inventory_project_access_tokens_v14_9.png b/doc/user/admin_area/img/credentials_inventory_project_access_tokens_v14_9.png Binary files differnew file mode 100644 index 00000000000..ae204ac09ef --- /dev/null +++ b/doc/user/admin_area/img/credentials_inventory_project_access_tokens_v14_9.png diff --git a/doc/user/admin_area/img/credentials_inventory_ssh_keys_v13_5.png b/doc/user/admin_area/img/credentials_inventory_ssh_keys_v13_5.png Binary files differdeleted file mode 100644 index f5edf513bbf..00000000000 --- a/doc/user/admin_area/img/credentials_inventory_ssh_keys_v13_5.png +++ /dev/null diff --git a/doc/user/admin_area/img/credentials_inventory_ssh_keys_v14_9.png b/doc/user/admin_area/img/credentials_inventory_ssh_keys_v14_9.png Binary files differnew file mode 100644 index 00000000000..8f2f11515eb --- /dev/null +++ b/doc/user/admin_area/img/credentials_inventory_ssh_keys_v14_9.png diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md index b98312d5b3c..881c1fb8c78 100644 --- a/doc/user/application_security/dependency_scanning/index.md +++ b/doc/user/application_security/dependency_scanning/index.md @@ -995,7 +995,13 @@ BUNDLER_AUDIT_ADVISORY_DB_REF_NAME: "master" BUNDLER_AUDIT_ADVISORY_DB_URL: "gitlab.example.com/ruby-advisory-db.git" ``` -#### Python (setup tools) +#### Python (pip) + +If you need to install Python packages before the analyzer runs, you should use `pip install --user` in the `before_script` of the scanning job. The `--user` flag causes project dependencies to be installed in the user directory. If you do not pass the `--user` option, packages are installed globally, and they are not scanned and don't show up when listing project dependencies. + +#### Python (setuptools) + +If you need to install Python packages before the analyzer runs, you should use `python setup.py install --user` in the `before_script` of the scanning job. The `--user` flag causes project dependencies to be installed in the user directory. If you do not pass the `--user` option, packages are installed globally, and they are not scanned and don't show up when listing project dependencies. When using self-signed certificates for your private PyPi repository, no extra job configuration (aside from the template `.gitlab-ci.yml` above) is needed. However, you must update your `setup.py` to diff --git a/doc/user/application_security/index.md b/doc/user/application_security/index.md index e76497ab5de..ff548f1d29f 100644 --- a/doc/user/application_security/index.md +++ b/doc/user/application_security/index.md @@ -395,6 +395,8 @@ any report artifacts that failed validation. ### Enable security report validation +> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/354928) in GitLab 14.9, and planned for removal in GitLab 15.0. + To enable report artifacts validation, set the `VALIDATE_SCHEMA` environment variable to `"true"` for the desired jobs in the `.gitlab-ci.yml` file. diff --git a/doc/user/group/index.md b/doc/user/group/index.md index 00fa51eddc9..86c33933144 100644 --- a/doc/user/group/index.md +++ b/doc/user/group/index.md @@ -575,7 +575,7 @@ To prevent members from being added to projects in a group: 1. Go to the group's **Settings > General** page. 1. Expand the **Permissions and group features** section. -1. Under **Member lock**, select **Prevent adding new members to project membership within this group**. +1. Under **Membership**, select **Prevent adding new members to projects within this group**. 1. Select **Save changes**. All users who previously had permissions can no longer add members to a group. diff --git a/lib/gitlab/pagination/offset_pagination.rb b/lib/gitlab/pagination/offset_pagination.rb index 8cb959769ee..fca75d1fe01 100644 --- a/lib/gitlab/pagination/offset_pagination.rb +++ b/lib/gitlab/pagination/offset_pagination.rb @@ -27,7 +27,7 @@ module Gitlab end return pagination_data unless pagination_data.is_a?(ActiveRecord::Relation) - return pagination_data unless Feature.enabled?(:api_kaminari_count_with_limit, type: :ops) + return pagination_data unless Feature.enabled?(:api_kaminari_count_with_limit, type: :ops, default_enabled: :yaml) limited_total_count = pagination_data.total_count_with_limit if limited_total_count > Kaminari::ActiveRecordRelationMethods::MAX_COUNT_LIMIT diff --git a/lib/gitlab/wiki_pages/front_matter_parser.rb b/lib/gitlab/wiki_pages/front_matter_parser.rb index 071b0dde619..ee30fa907f4 100644 --- a/lib/gitlab/wiki_pages/front_matter_parser.rb +++ b/lib/gitlab/wiki_pages/front_matter_parser.rb @@ -3,8 +3,6 @@ module Gitlab module WikiPages class FrontMatterParser - FEATURE_FLAG = :wiki_front_matter - # We limit the maximum length of text we are prepared to parse as YAML, to # avoid exploitations and attempts to consume memory and CPU. We allow for: # - a title line @@ -30,18 +28,12 @@ module Gitlab end # @param [String] wiki_content - # @param [FeatureGate] feature_gate The scope for feature availability - def initialize(wiki_content, feature_gate) + def initialize(wiki_content) @wiki_content = wiki_content - @feature_gate = feature_gate - end - - def self.enabled?(gate = nil) - Feature.enabled?(FEATURE_FLAG, gate) end def parse - return empty_result unless enabled? && wiki_content.present? + return empty_result unless wiki_content.present? return empty_result(block.error) unless block.valid? Result.new(front_matter: block.data, content: strip_front_matter_block) @@ -94,16 +86,12 @@ module Gitlab private - attr_reader :wiki_content, :feature_gate + attr_reader :wiki_content def empty_result(reason = nil, error = nil) Result.new(content: wiki_content, reason: reason, error: error) end - def enabled? - self.class.enabled?(feature_gate) - end - def block @block ||= parse_front_matter_block end diff --git a/qa/Gemfile b/qa/Gemfile index 8dee3fb9326..05acab5653f 100644 --- a/qa/Gemfile +++ b/qa/Gemfile @@ -29,7 +29,6 @@ gem 'influxdb-client', '~> 1.17' gem 'terminal-table', '~> 3.0.0', require: false gem 'slack-notifier', '~> 2.4', require: false gem 'fog-google', '~> 1.17', require: false -gem 'google-cloud-storage', '~> 1.36', require: false gem 'confiner', '~> 0.2' diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock index ac683ad549d..369ab0860ed 100644 --- a/qa/Gemfile.lock +++ b/qa/Gemfile.lock @@ -65,8 +65,6 @@ GEM deprecation_toolkit (1.5.1) activesupport (>= 4.2) diff-lcs (1.3) - digest-crc (0.6.4) - rake (>= 12.0.0, < 14.0.0) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) equalizer (0.0.11) @@ -152,20 +150,8 @@ GEM google-apis-core (>= 0.4, < 2.a) google-apis-storage_v1 (0.9.0) google-apis-core (>= 0.4, < 2.a) - google-cloud-core (1.6.0) - google-cloud-env (~> 1.0) - google-cloud-errors (~> 1.0) google-cloud-env (1.5.0) faraday (>= 0.17.3, < 2.0) - google-cloud-errors (1.2.0) - google-cloud-storage (1.36.1) - addressable (~> 2.8) - digest-crc (~> 0.4) - google-apis-iamcredentials_v1 (~> 0.1) - google-apis-storage_v1 (~> 0.1) - google-cloud-core (~> 1.6) - googleauth (>= 0.16.2, < 2.a) - mini_mime (~> 1.0) googleauth (1.1.0) faraday (>= 0.17.3, < 2.0) jwt (>= 1.4, < 3.0) @@ -382,7 +368,6 @@ DEPENDENCIES faker (~> 2.19, >= 2.19.0) fog-google (~> 1.17) gitlab-qa - google-cloud-storage (~> 1.36) influxdb-client (~> 1.17) knapsack (~> 4.0) octokit (~> 4.21) diff --git a/qa/qa/tools/test_resources_handler.rb b/qa/qa/tools/test_resources_handler.rb index c298be25160..97b983913b4 100644 --- a/qa/qa/tools/test_resources_handler.rb +++ b/qa/qa/tools/test_resources_handler.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require "google/cloud/storage" +require "fog/google" # This script handles resources created during E2E test runs # @@ -67,7 +67,7 @@ module QA files.each do |file| file_name = "#{environment_name}/#{file.split('/').last}" Runtime::Logger.info("Uploading #{file_name}...") - gcs_bucket.create_file(file, file_name) + gcs_storage.put_object(BUCKET, file_name, File.read(file)) end puts "\nDone" @@ -76,17 +76,20 @@ module QA # Download files from GCS bucket by environment name # Delete the files afterward def download(environment_name) - files_list = gcs_bucket.files(prefix: "#{environment_name}") + files_list = gcs_storage.list_objects(BUCKET, prefix: environment_name).items.each_with_object([]) do |obj, arr| + arr << obj.name + end return puts "\nNothing to download!" if files_list.empty? - files_list.each do |file| - local_path = "tmp/#{file.name.split('/').last}" - Runtime::Logger.info("Downloading #{file.name} to #{local_path}") - file.download(local_path) + files_list.each do |file_name| + local_path = "tmp/#{file_name.split('/').last}" + Runtime::Logger.info("Downloading #{file_name} to #{local_path}") + file = gcs_storage.get_object(BUCKET, file_name) + File.write(local_path, file[:body]) - Runtime::Logger.info("Deleting #{file.name} from bucket") - file.delete + Runtime::Logger.info("Deleting #{file_name} from bucket") + gcs_storage.delete_object(BUCKET, file_name) end puts "\nDone" @@ -158,18 +161,14 @@ module QA end def gcs_storage - @gcs_storage ||= Google::Cloud::Storage.new( - project_id: PROJECT, - credentials: json_key + @gcs_storage ||= Fog::Storage::Google.new( + google_project: PROJECT, + **(File.exist?(json_key) ? { google_json_key_location: json_key } : { google_json_key_string: json_key }) ) rescue StandardError => e abort("\nThere might be something wrong with the JSON key file - [ERROR] #{e}") end - def gcs_bucket - @gcs_bucket ||= gcs_storage.bucket(BUCKET, skip_lookup: true) - end - # Path to GCS service account json key file # Or the content of the key file as a hash def json_key diff --git a/spec/graphql/types/merge_requests/assignee_type_spec.rb b/spec/graphql/types/merge_requests/assignee_type_spec.rb new file mode 100644 index 00000000000..d67d20860b2 --- /dev/null +++ b/spec/graphql/types/merge_requests/assignee_type_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GitlabSchema.types['MergeRequestAssignee'] do + it_behaves_like "a user type with merge request interaction type" +end diff --git a/spec/graphql/types/merge_requests/author_type_spec.rb b/spec/graphql/types/merge_requests/author_type_spec.rb new file mode 100644 index 00000000000..2a5a31f210c --- /dev/null +++ b/spec/graphql/types/merge_requests/author_type_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GitlabSchema.types['MergeRequestAuthor'] do + it_behaves_like "a user type with merge request interaction type" +end diff --git a/spec/graphql/types/merge_requests/participant_type_spec.rb b/spec/graphql/types/merge_requests/participant_type_spec.rb new file mode 100644 index 00000000000..083762c7064 --- /dev/null +++ b/spec/graphql/types/merge_requests/participant_type_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GitlabSchema.types['MergeRequestParticipant'] do + it_behaves_like "a user type with merge request interaction type" +end diff --git a/spec/graphql/types/merge_requests/reviewer_type_spec.rb b/spec/graphql/types/merge_requests/reviewer_type_spec.rb index 377f82bb00a..92cb51df27a 100644 --- a/spec/graphql/types/merge_requests/reviewer_type_spec.rb +++ b/spec/graphql/types/merge_requests/reviewer_type_spec.rb @@ -3,55 +3,5 @@ require 'spec_helper' RSpec.describe GitlabSchema.types['MergeRequestReviewer'] do - specify { expect(described_class).to require_graphql_authorizations(:read_user) } - - it 'has the expected fields' do - expected_fields = %w[ - id - bot - user_permissions - snippets - name - username - email - publicEmail - avatarUrl - webUrl - webPath - todos - state - status - location - authoredMergeRequests - assignedMergeRequests - reviewRequestedMergeRequests - groupMemberships - groupCount - projectMemberships - starredProjects - callouts - merge_request_interaction - namespace - timelogs - groups - gitpodEnabled - preferencesGitpodPath - profileEnableGitpodPath - savedReplies - ] - - expect(described_class).to have_graphql_fields(*expected_fields) - end - - describe '#merge_request_interaction' do - subject { described_class.fields['mergeRequestInteraction'] } - - it 'returns the correct type' do - is_expected.to have_graphql_type(Types::UserMergeRequestInteractionType) - end - - it 'has the correct arguments' do - is_expected.to have_attributes(arguments: be_empty) - end - end + it_behaves_like "a user type with merge request interaction type" end diff --git a/spec/lib/gitlab/wiki_pages/front_matter_parser_spec.rb b/spec/lib/gitlab/wiki_pages/front_matter_parser_spec.rb index 3152dc2ad2f..c0629c8d795 100644 --- a/spec/lib/gitlab/wiki_pages/front_matter_parser_spec.rb +++ b/spec/lib/gitlab/wiki_pages/front_matter_parser_spec.rb @@ -3,11 +3,10 @@ require 'spec_helper' RSpec.describe Gitlab::WikiPages::FrontMatterParser do - subject(:parser) { described_class.new(raw_content, gate) } + subject(:parser) { described_class.new(raw_content) } let(:content) { 'This is the content' } let(:end_divider) { '---' } - let(:gate) { stub_feature_flag_gate('Gate') } let(:with_front_matter) do <<~MD @@ -62,32 +61,6 @@ RSpec.describe Gitlab::WikiPages::FrontMatterParser do it { is_expected.to have_attributes(reason: :no_match) } end - context 'the feature flag is disabled' do - let(:raw_content) { with_front_matter } - - before do - stub_feature_flags(Gitlab::WikiPages::FrontMatterParser::FEATURE_FLAG => false) - end - - it { is_expected.to have_attributes(front_matter: be_empty, content: raw_content) } - end - - context 'the feature flag is enabled for the gated object' do - let(:raw_content) { with_front_matter } - - before do - stub_feature_flags(Gitlab::WikiPages::FrontMatterParser::FEATURE_FLAG => gate) - end - - it do - is_expected.to have_attributes( - front_matter: have_correct_front_matter, - content: content + "\n", - reason: be_nil - ) - end - end - context 'the end divider is ...' do let(:end_divider) { '...' } let(:raw_content) { with_front_matter } diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index 699dd35196f..0016d2f517b 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -24,14 +24,6 @@ RSpec.describe WikiPage do container.wiki end - def disable_front_matter - stub_feature_flags(Gitlab::WikiPages::FrontMatterParser::FEATURE_FLAG => false) - end - - def enable_front_matter_for(thing) - stub_feature_flags(Gitlab::WikiPages::FrontMatterParser::FEATURE_FLAG => thing) - end - # Use for groups of tests that do not modify their `subject`. # # include_context 'subject is persisted page', title: 'my title' @@ -48,12 +40,6 @@ RSpec.describe WikiPage do it { expect(wiki_page).to have_attributes(front_matter: {}, content: content) } end - shared_examples 'a page with front-matter' do - let(:front_matter) { { title: 'Foo', slugs: %w[slug_a slug_b] } } - - it { expect(wiki_page.front_matter).to eq(front_matter) } - end - context 'the wiki page has front matter' do let(:content) do <<~MD @@ -68,27 +54,13 @@ RSpec.describe WikiPage do MD end - it_behaves_like 'a page with front-matter' + it 'has front-matter' do + expect(wiki_page.front_matter).to eq({ title: 'Foo', slugs: %w[slug_a slug_b] }) + end it 'strips the front matter from the content' do expect(wiki_page.content.strip).to eq('My actual content') end - - context 'the feature flag is off' do - before do - disable_front_matter - end - - it_behaves_like 'a page without front-matter' - - context 'but enabled for the container' do - before do - enable_front_matter_for(container) - end - - it_behaves_like 'a page with front-matter' - end - end end context 'the wiki page does not have front matter' do @@ -471,29 +443,6 @@ RSpec.describe WikiPage do end end - context 'the front-matter feature flag is not enabled' do - before do - disable_front_matter - end - - it 'does not update the front-matter' do - content = subject.content - subject.update(front_matter: { slugs: ['x'] }) - - page = wiki.find_page(subject.title) - - expect([subject, page]).to all(have_attributes(front_matter: be_empty, content: content)) - end - - context 'but it is enabled for the container' do - before do - enable_front_matter_for(container) - end - - it_behaves_like 'able to update front-matter' - end - end - it 'updates the wiki-page front-matter and content together' do content = 'totally new content' subject.update(content: content, front_matter: { slugs: ['x'] }) diff --git a/spec/support/shared_examples/graphql/types/merge_request_interactions_type_shared_examples.rb b/spec/support/shared_examples/graphql/types/merge_request_interactions_type_shared_examples.rb new file mode 100644 index 00000000000..0d0dbb112de --- /dev/null +++ b/spec/support/shared_examples/graphql/types/merge_request_interactions_type_shared_examples.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.shared_examples "a user type with merge request interaction type" do + specify { expect(described_class).to require_graphql_authorizations(:read_user) } + + it 'has the expected fields' do + expected_fields = %w[ + id + bot + user_permissions + snippets + name + username + email + publicEmail + avatarUrl + webUrl + webPath + todos + state + status + location + authoredMergeRequests + assignedMergeRequests + reviewRequestedMergeRequests + groupMemberships + groupCount + projectMemberships + starredProjects + callouts + merge_request_interaction + namespace + timelogs + groups + gitpodEnabled + preferencesGitpodPath + profileEnableGitpodPath + savedReplies + ] + + expect(described_class).to have_graphql_fields(*expected_fields) + end + + describe '#merge_request_interaction' do + subject { described_class.fields['mergeRequestInteraction'] } + + it 'returns the correct type' do + is_expected.to have_graphql_type(Types::UserMergeRequestInteractionType) + end + + it 'has the correct arguments' do + is_expected.to have_attributes(arguments: be_empty) + end + end +end |