summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-01-28 21:13:52 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-01-28 21:13:52 +0000
commit8de745957a9c3c2a48ca47dd3bd69ee4db7424e0 (patch)
treed3c9c9eb8a50246059746565e6e23d2bdbba76a7
parentde3e5b677261e4cdd9fbad6fbe461c9c605cbfa6 (diff)
downloadgitlab-ce-8de745957a9c3c2a48ca47dd3bd69ee4db7424e0.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/issue_templates/Deprecations.md8
-rw-r--r--.gitlab/merge_request_templates/Deprecations.md3
-rw-r--r--app/graphql/types/member_interface.rb12
-rw-r--r--app/graphql/types/merge_requests/interacts_with_merge_request.rb5
-rw-r--r--app/models/ci/runner.rb2
-rw-r--r--config/feature_flags/development/ci_runner_projects_disable_joins.yml8
-rw-r--r--config/metrics/counts_all/20210216175206_merged_merge_requests_using_approval_rules.yml21
-rw-r--r--db/post_migrate/20220121214753_re_remove_projects_ci_stages_project_id_fk.rb19
-rw-r--r--db/post_migrate/20220124153234_re_remove_projects_ci_job_artifacts_project_id_fk.rb19
-rw-r--r--db/post_migrate/20220124180705_re_remove_projects_ci_builds_metadata_project_id_fk.rb19
-rw-r--r--db/post_migrate/20220126210022_re_remove_projects_ci_builds_project_id_fk.rb19
-rw-r--r--db/schema_migrations/202201212147531
-rw-r--r--db/schema_migrations/202201241532341
-rw-r--r--db/schema_migrations/202201241807051
-rw-r--r--db/schema_migrations/202201262100221
-rw-r--r--doc/administration/geo/replication/using_a_geo_server.md4
-rw-r--r--doc/api/graphql/reference/index.md42
-rw-r--r--doc/development/agent/gitops.md4
-rw-r--r--doc/development/agent/identity.md4
-rw-r--r--doc/development/agent/index.md4
-rw-r--r--doc/development/agent/local.md4
-rw-r--r--doc/development/agent/repository_overview.md4
-rw-r--r--doc/development/agent/routing.md4
-rw-r--r--doc/development/agent/user_stories.md4
-rw-r--r--doc/development/cicd/templates.md2
-rw-r--r--doc/user/packages/container_registry/index.md17
-rw-r--r--doc/user/project/img/time_tracking_example_v12_2.pngbin16362 -> 0 bytes
-rw-r--r--doc/user/project/time_tracking.md124
-rw-r--r--lib/api/terraform/modules/v1/packages.rb2
-rw-r--r--qa/qa/support/formatters/allure_metadata_formatter.rb32
-rw-r--r--spec/features/admin/admin_groups_spec.rb17
-rw-r--r--spec/graphql/types/member_interface_spec.rb13
-rw-r--r--spec/models/ci/runner_spec.rb10
-rw-r--r--spec/requests/api/graphql/project/project_members_spec.rb96
34 files changed, 402 insertions, 124 deletions
diff --git a/.gitlab/issue_templates/Deprecations.md b/.gitlab/issue_templates/Deprecations.md
index 85db4314233..d833efd61f4 100644
--- a/.gitlab/issue_templates/Deprecations.md
+++ b/.gitlab/issue_templates/Deprecations.md
@@ -46,14 +46,18 @@ Which tier is this feature available in?
<!-- In which milestone will this deprecation be announced ? -->
-### Planned Removal Milestone
+### Planned Removal Milestone
<!-- In which milestone will the feature or functionality be removed and announced? -->
### Links
<!--
-Add links to any relevant documentation or code that will provide additional details or clarity regarding the planned change. Also, include a link to the removal issue if relevant.
+Add links to any relevant documentation or code that will provide additional details or clarity regarding the planned change.
+
+This issue is the main SSOT for the deprecations and removals process. Be sure to link all
+issues and MRs related to this deprecation/removal to this issue. This can include removal
+issues that were created ahead of time, and the MRs doing the actual deprecation/removal work.
-->
<!-- Label reminders - you should have one of each of the following labels.
diff --git a/.gitlab/merge_request_templates/Deprecations.md b/.gitlab/merge_request_templates/Deprecations.md
index b06be633c67..f8803768d88 100644
--- a/.gitlab/merge_request_templates/Deprecations.md
+++ b/.gitlab/merge_request_templates/Deprecations.md
@@ -7,9 +7,8 @@
**Be sure to link this MR to the relevant deprecation issue(s).**
- Deprecation Issue:
-- MR that deprecates the feature (optional):
-If there is no relevant removal or deprecation issue, hit pause and:
+If there is no relevant deprecation issue, hit pause and:
- Review the [process for deprecating and removing features](https://about.gitlab.com/handbook/product/gitlab-the-product/#process-for-deprecating-and-removing-a-feature).
- Connect with the Product Manager DRI.
diff --git a/app/graphql/types/member_interface.rb b/app/graphql/types/member_interface.rb
index c5623cd4710..67d0e18b522 100644
--- a/app/graphql/types/member_interface.rb
+++ b/app/graphql/types/member_interface.rb
@@ -25,6 +25,12 @@ module Types
field :user, Types::UserType, null: true,
description: 'User that is associated with the member object.'
+ field :merge_request_interaction, Types::UserMergeRequestInteractionType,
+ null: true,
+ description: 'Find a merge request.' do
+ argument :id, ::Types::GlobalIDType[::MergeRequest], required: true, description: 'Global ID of the merge request.'
+ end
+
definition_methods do
def resolve_type(object, context)
case object
@@ -37,5 +43,11 @@ module Types
end
end
end
+
+ def merge_request_interaction(id: nil)
+ Gitlab::Graphql::Lazy.with_value(GitlabSchema.object_from_id(id, expected_class: ::MergeRequest)) do |merge_request|
+ Users::MergeRequestInteraction.new(user: object.user, merge_request: merge_request) if merge_request
+ end
+ end
end
end
diff --git a/app/graphql/types/merge_requests/interacts_with_merge_request.rb b/app/graphql/types/merge_requests/interacts_with_merge_request.rb
index d4a1f2faa8d..15621ef1472 100644
--- a/app/graphql/types/merge_requests/interacts_with_merge_request.rb
+++ b/app/graphql/types/merge_requests/interacts_with_merge_request.rb
@@ -5,6 +5,8 @@ module Types
module InteractsWithMergeRequest
extend ActiveSupport::Concern
+ include FindClosest
+
included do
field :merge_request_interaction,
type: ::Types::UserMergeRequestInteractionType,
@@ -13,8 +15,9 @@ module Types
description: "Details of this user's interactions with the merge request."
end
- def merge_request_interaction(parent:)
+ def merge_request_interaction(parent:, id: nil)
merge_request = closest_parent([::Types::MergeRequestType], parent)
+
return unless merge_request
Users::MergeRequestInteraction.new(user: object, merge_request: merge_request)
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index 41994095976..d08cc71305e 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -67,7 +67,7 @@ module Ci
has_many :builds
has_many :runner_projects, inverse_of: :runner, autosave: true, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
- has_many :projects, through: :runner_projects, disable_joins: -> { ::Feature.enabled?(:ci_runner_projects_disable_joins, default_enabled: :yaml) }
+ has_many :projects, through: :runner_projects, disable_joins: true
has_many :runner_namespaces, inverse_of: :runner, autosave: true
has_many :groups, through: :runner_namespaces, disable_joins: true
diff --git a/config/feature_flags/development/ci_runner_projects_disable_joins.yml b/config/feature_flags/development/ci_runner_projects_disable_joins.yml
deleted file mode 100644
index 4200a4a55b9..00000000000
--- a/config/feature_flags/development/ci_runner_projects_disable_joins.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: ci_runner_projects_disable_joins
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78372
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350538
-milestone: '14.8'
-type: development
-group: group::pipeline execution
-default_enabled: false
diff --git a/config/metrics/counts_all/20210216175206_merged_merge_requests_using_approval_rules.yml b/config/metrics/counts_all/20210216175206_merged_merge_requests_using_approval_rules.yml
deleted file mode 100644
index d71c35ef2e2..00000000000
--- a/config/metrics/counts_all/20210216175206_merged_merge_requests_using_approval_rules.yml
+++ /dev/null
@@ -1,21 +0,0 @@
----
-data_category: optional
-key_path: counts.merged_merge_requests_using_approval_rules
-description: Count of merge requests merged using approval rules
-product_section: dev
-product_stage: manage
-product_group: group::compliance
-product_category: compliance_management
-value_type: number
-status: active
-time_frame: all
-data_source: database
-distribution:
-- ce
-- ee
-tier:
-- free
-- premium
-- ultimate
-performance_indicator_type: []
-milestone: "<13.9"
diff --git a/db/post_migrate/20220121214753_re_remove_projects_ci_stages_project_id_fk.rb b/db/post_migrate/20220121214753_re_remove_projects_ci_stages_project_id_fk.rb
new file mode 100644
index 00000000000..45dec15a5a7
--- /dev/null
+++ b/db/post_migrate/20220121214753_re_remove_projects_ci_stages_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class ReRemoveProjectsCiStagesProjectIdFk < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ return unless foreign_key_exists?(:ci_stages, :projects, name: "fk_2360681d1d")
+
+ with_lock_retries do
+ execute('LOCK projects, ci_stages IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+ remove_foreign_key_if_exists(:ci_stages, :projects, name: "fk_2360681d1d")
+ end
+ end
+
+ def down
+ # no-op, since the FK will be added via rollback by prior-migration
+ end
+end
diff --git a/db/post_migrate/20220124153234_re_remove_projects_ci_job_artifacts_project_id_fk.rb b/db/post_migrate/20220124153234_re_remove_projects_ci_job_artifacts_project_id_fk.rb
new file mode 100644
index 00000000000..bb59134b927
--- /dev/null
+++ b/db/post_migrate/20220124153234_re_remove_projects_ci_job_artifacts_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class ReRemoveProjectsCiJobArtifactsProjectIdFk < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ return unless foreign_key_exists?(:ci_job_artifacts, :projects, name: "fk_rails_9862d392f9")
+
+ with_lock_retries do
+ execute('LOCK projects, ci_job_artifacts IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+ remove_foreign_key_if_exists(:ci_job_artifacts, :projects, name: "fk_rails_9862d392f9")
+ end
+ end
+
+ def down
+ # no-op, since the FK will be added via rollback by prior-migration
+ end
+end
diff --git a/db/post_migrate/20220124180705_re_remove_projects_ci_builds_metadata_project_id_fk.rb b/db/post_migrate/20220124180705_re_remove_projects_ci_builds_metadata_project_id_fk.rb
new file mode 100644
index 00000000000..6483b8e0643
--- /dev/null
+++ b/db/post_migrate/20220124180705_re_remove_projects_ci_builds_metadata_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class ReRemoveProjectsCiBuildsMetadataProjectIdFk < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ return unless foreign_key_exists?(:ci_builds_metadata, :projects, name: "fk_rails_ffcf702a02")
+
+ with_lock_retries do
+ execute('LOCK projects, ci_builds_metadata IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+ remove_foreign_key_if_exists(:ci_builds_metadata, :projects, name: "fk_rails_ffcf702a02")
+ end
+ end
+
+ def down
+ # no-op, since the FK will be added via rollback by prior-migration
+ end
+end
diff --git a/db/post_migrate/20220126210022_re_remove_projects_ci_builds_project_id_fk.rb b/db/post_migrate/20220126210022_re_remove_projects_ci_builds_project_id_fk.rb
new file mode 100644
index 00000000000..2a026388bbf
--- /dev/null
+++ b/db/post_migrate/20220126210022_re_remove_projects_ci_builds_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class ReRemoveProjectsCiBuildsProjectIdFk < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ return unless foreign_key_exists?(:ci_builds, :projects, name: "fk_befce0568a")
+
+ with_lock_retries do
+ execute('LOCK projects, ci_builds IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+ remove_foreign_key_if_exists(:ci_builds, :projects, name: "fk_befce0568a")
+ end
+ end
+
+ def down
+ # no-op, since the FK will be added via rollback by prior-migration
+ end
+end
diff --git a/db/schema_migrations/20220121214753 b/db/schema_migrations/20220121214753
new file mode 100644
index 00000000000..5142044be97
--- /dev/null
+++ b/db/schema_migrations/20220121214753
@@ -0,0 +1 @@
+b7b9f5e516664e7eb3f7a5307d1871bb4f58a31f4807e0298fbf9414bad567fa \ No newline at end of file
diff --git a/db/schema_migrations/20220124153234 b/db/schema_migrations/20220124153234
new file mode 100644
index 00000000000..dfca9995395
--- /dev/null
+++ b/db/schema_migrations/20220124153234
@@ -0,0 +1 @@
+0e8559121504f1a34394b5f613ef2c5554261f6aeaeaaf5a15d018803c4e5452 \ No newline at end of file
diff --git a/db/schema_migrations/20220124180705 b/db/schema_migrations/20220124180705
new file mode 100644
index 00000000000..c1600192af1
--- /dev/null
+++ b/db/schema_migrations/20220124180705
@@ -0,0 +1 @@
+6c147287ba8436bd0231dc22195c95a71d19987d23741c1291a117407f493184 \ No newline at end of file
diff --git a/db/schema_migrations/20220126210022 b/db/schema_migrations/20220126210022
new file mode 100644
index 00000000000..32cb73ee3ee
--- /dev/null
+++ b/db/schema_migrations/20220126210022
@@ -0,0 +1 @@
+80a75bf72b40ee791bebd9ae97a793ce41fbd352841d83421525b6ad78e1c5e8 \ No newline at end of file
diff --git a/doc/administration/geo/replication/using_a_geo_server.md b/doc/administration/geo/replication/using_a_geo_server.md
index 04c30514a89..62562a1149d 100644
--- a/doc/administration/geo/replication/using_a_geo_server.md
+++ b/doc/administration/geo/replication/using_a_geo_server.md
@@ -1,9 +1,9 @@
---
redirect_to: '../../geo/replication/usage.md'
-remove_date: '2022-06-01'
+remove_date: '2022-02-01'
---
This document was moved to [another location](../../geo/replication/usage.md).
-<!-- This redirect file can be deleted after 2022-06-01 -->
+<!-- This redirect file can be deleted after 2022-02-01 -->
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 12ea1e13b57..74b871adb20 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -11382,6 +11382,20 @@ Represents a Group Membership.
| <a id="groupmemberuser"></a>`user` | [`UserCore`](#usercore) | User that is associated with the member object. |
| <a id="groupmemberuserpermissions"></a>`userPermissions` | [`GroupPermissions!`](#grouppermissions) | Permissions for the current user on the resource. |
+#### Fields with arguments
+
+##### `GroupMember.mergeRequestInteraction`
+
+Find a merge request.
+
+Returns [`UserMergeRequestInteraction`](#usermergerequestinteraction).
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="groupmembermergerequestinteractionid"></a>`id` | [`MergeRequestID!`](#mergerequestid) | Global ID of the merge request. |
+
### `GroupPermissions`
#### Fields
@@ -14311,6 +14325,20 @@ Represents a Project Membership.
| <a id="projectmemberuser"></a>`user` | [`UserCore`](#usercore) | User that is associated with the member object. |
| <a id="projectmemberuserpermissions"></a>`userPermissions` | [`ProjectPermissions!`](#projectpermissions) | Permissions for the current user on the resource. |
+#### Fields with arguments
+
+##### `ProjectMember.mergeRequestInteraction`
+
+Find a merge request.
+
+Returns [`UserMergeRequestInteraction`](#usermergerequestinteraction).
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="projectmembermergerequestinteractionid"></a>`id` | [`MergeRequestID!`](#mergerequestid) | Global ID of the merge request. |
+
### `ProjectPermissions`
#### Fields
@@ -18725,6 +18753,20 @@ Implementations:
| <a id="memberinterfaceupdatedat"></a>`updatedAt` | [`Time`](#time) | Date and time the membership was last updated. |
| <a id="memberinterfaceuser"></a>`user` | [`UserCore`](#usercore) | User that is associated with the member object. |
+##### Fields with arguments
+
+###### `MemberInterface.mergeRequestInteraction`
+
+Find a merge request.
+
+Returns [`UserMergeRequestInteraction`](#usermergerequestinteraction).
+
+####### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="memberinterfacemergerequestinteractionid"></a>`id` | [`MergeRequestID!`](#mergerequestid) | Global ID of the merge request. |
+
#### `NoteableInterface`
Implementations:
diff --git a/doc/development/agent/gitops.md b/doc/development/agent/gitops.md
index 3d59f5bd845..7c741408ae6 100644
--- a/doc/development/agent/gitops.md
+++ b/doc/development/agent/gitops.md
@@ -1,9 +1,9 @@
---
redirect_to: 'https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/gitops.md'
-remove_date: '2022-06-24'
+remove_date: '2022-02-01'
---
This file was moved to [another location](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/gitops.md).
-<!-- This redirect file can be deleted after <2022-06-24>. -->
+<!-- This redirect file can be deleted after <2022-02-01>. -->
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/development/agent/identity.md b/doc/development/agent/identity.md
index 67084a6d995..6caf108a32a 100644
--- a/doc/development/agent/identity.md
+++ b/doc/development/agent/identity.md
@@ -1,9 +1,9 @@
---
redirect_to: 'https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/identity_and_auth.md'
-remove_date: '2022-06-24'
+remove_date: '2022-02-01'
---
This file was moved to [another location](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/identity_and_auth.md).
-<!-- This redirect file can be deleted after <2022-06-24>. -->
+<!-- This redirect file can be deleted after <2022-02-01>. -->
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/development/agent/index.md b/doc/development/agent/index.md
index 2cb05e2dd8f..474f8a02933 100644
--- a/doc/development/agent/index.md
+++ b/doc/development/agent/index.md
@@ -1,9 +1,9 @@
---
redirect_to: 'https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/architecture.md'
-remove_date: '2022-06-24'
+remove_date: '2022-02-01'
---
This file was moved to [another location](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/architecture.md).
-<!-- This redirect file can be deleted after <2022-06-24>. -->
+<!-- This redirect file can be deleted after <2022-02-01>. -->
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/development/agent/local.md b/doc/development/agent/local.md
index 1fff5607de4..a4b29bea838 100644
--- a/doc/development/agent/local.md
+++ b/doc/development/agent/local.md
@@ -1,9 +1,9 @@
---
redirect_to: 'https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/local.md'
-remove_date: '2022-06-24'
+remove_date: '2022-02-01'
---
This file was moved to [another location](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/local.md).
-<!-- This redirect file can be deleted after <2022-06-24>. -->
+<!-- This redirect file can be deleted after <2022-02-01>. -->
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/development/agent/repository_overview.md b/doc/development/agent/repository_overview.md
index 43ea99889c5..8ea9dceb32a 100644
--- a/doc/development/agent/repository_overview.md
+++ b/doc/development/agent/repository_overview.md
@@ -1,9 +1,9 @@
---
redirect_to: 'https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/repository_overview.md'
-remove_date: '2022-06-24'
+remove_date: '2022-02-01'
---
This file was moved to [another location](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/repository_overview.md).
-<!-- This redirect file can be deleted after <2022-06-24>. -->
+<!-- This redirect file can be deleted after <2022-02-01>. -->
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/development/agent/routing.md b/doc/development/agent/routing.md
index 7792d6d56a4..364267a45fe 100644
--- a/doc/development/agent/routing.md
+++ b/doc/development/agent/routing.md
@@ -1,9 +1,9 @@
---
redirect_to: 'https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/kas_request_routing.md'
-remove_date: '2022-06-24'
+remove_date: '2022-02-01'
---
This file was moved to [another location](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/kas_request_routing.md).
-<!-- This redirect file can be deleted after <2022-06-24>. -->
+<!-- This redirect file can be deleted after <2022-02-01>. -->
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/development/agent/user_stories.md b/doc/development/agent/user_stories.md
index ce38064b31b..2ed4bbdc9f6 100644
--- a/doc/development/agent/user_stories.md
+++ b/doc/development/agent/user_stories.md
@@ -1,9 +1,9 @@
---
redirect_to: 'https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/user_stories.md'
-remove_date: '2022-06-24'
+remove_date: '2022-02-01'
---
This file was moved to [another location](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/user_stories.md).
-<!-- This redirect file can be deleted after <2022-06-24>. -->
+<!-- This redirect file can be deleted after <2022-02-01>. -->
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/development/cicd/templates.md b/doc/development/cicd/templates.md
index ba5ca18896e..d7edad842b8 100644
--- a/doc/development/cicd/templates.md
+++ b/doc/development/cicd/templates.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: index, concepts, howto
---
-# Development guide for GitLab CI/CD templates
+# Development guide for GitLab CI/CD templates **(FREE)**
This document explains how to develop [GitLab CI/CD templates](../../ci/examples/index.md).
diff --git a/doc/user/packages/container_registry/index.md b/doc/user/packages/container_registry/index.md
index c9d836137df..8a3a6c77d7a 100644
--- a/doc/user/packages/container_registry/index.md
+++ b/doc/user/packages/container_registry/index.md
@@ -583,11 +583,22 @@ For information on how to update your images, see the [Docker help](https://docs
### `Blob unknown to registry` error when pushing a manifest list
-When [pushing a Docker manifest list](https://docs.docker.com/engine/reference/commandline/manifest/#create-and-push-a-manifest-list) to the GitLab Container Registry, you may receive the error `manifest blob unknown: blob unknown to registry`. [This issue](https://gitlab.com/gitlab-org/gitlab/-/issues/209008) occurs when the individual child manifests referenced in the manifest list were not pushed to the same repository.
+When [pushing a Docker manifest list](https://docs.docker.com/engine/reference/commandline/manifest/#create-and-push-a-manifest-list)
+to the GitLab Container Registry, you may receive the error
+`manifest blob unknown: blob unknown to registry`. This is likely caused by having multiple images
+with different architectures, spread out over several repositories instead of the same repository.
-For example, you may have two individual images, one for `amd64` and another for `arm64v8`, and you want to build a multi-arch image with them. The `amd64` and `arm64v8` images must be pushed to the same repository where you want to push the multi-arch image.
+For example, you may have two images, each representing an architecture:
-As a workaround, you should include the architecture in the tag name of individual images. For example, use `mygroup/myapp:1.0.0-amd64` instead of using sub repositories, like `mygroup/myapp/amd64:1.0.0`. You can then tag the manifest list with `mygroup/myapp:1.0.0`.
+- The `amd64` platform
+- The `arm64v8` platform
+
+To build a multi-arch image with these images, you must push them to the same repository as the
+multi-arch image.
+
+To address the `Blob unknown to registry` error, include the architecture in the tag name of
+individual images. For example, use `mygroup/myapp:1.0.0-amd64` and `mygroup/myapp:1.0.0-arm64v8`.
+You can then tag the manifest list with `mygroup/myapp:1.0.0`.
### The cleanup policy doesn't delete any tags
diff --git a/doc/user/project/img/time_tracking_example_v12_2.png b/doc/user/project/img/time_tracking_example_v12_2.png
deleted file mode 100644
index 31d8c490ed1..00000000000
--- a/doc/user/project/img/time_tracking_example_v12_2.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/time_tracking.md b/doc/user/project/time_tracking.md
index 6ceb8c94934..7a6df9972ec 100644
--- a/doc/user/project/time_tracking.md
+++ b/doc/user/project/time_tracking.md
@@ -8,76 +8,81 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Time tracking **(FREE)**
-With time tracking you can track estimates and time spent on issues and merge
-requests in GitLab.
+You can estimate and track the time you spend on [issues](issues/index.md)
+and [merge requests](merge_requests/index.md).
+
+Then you can [view a report](#view-a-time-tracking-report) that shows totals over time.
Use time tracking for these tasks:
- Record the time spent working on an issue or a merge request.
- Add or update an estimate of the total time to complete an issue or a merge
-request.
+ request.
- View a breakdown of time spent working on an issue or a merge request.
You don't have to indicate an estimate to enter the time spent, and vice versa.
-Data about time tracking shows up on the issue and merge request sidebar:
+To enter and remove time tracking data, you must use [quick actions](quick_actions.md).
+Type all quick actions on their own lines.
+If you use any quick action more than once in a single comment, only its last occurrence is applied.
+
+You can see the data about time tracking on the right sidebar in issues and merge requests:
![Time tracking in the sidebar](img/time_tracking_sidebar_v13_12.png)
-## How to enter data
+## Estimates
-Time tracking uses two [quick actions](quick_actions.md): `/spend` and `/estimate`.
+The estimate is designed to show the total time needed to complete an issue or merge request.
-If you use either quick action more than once in a single comment, only the last occurrence is applied.
+You can see the estimated time remaining when you hover over the time tracking information in the right sidebar.
-Below is an example of how you can use those new quick actions inside a comment.
+![Estimated time remaining](img/remaining_time_v14_2.png)
-![Time tracking example in a comment](img/time_tracking_example_v12_2.png)
+### Add an estimate
-Adding time entries (time spent or estimates) is limited to project members
-with [Reporter and higher permission levels](../permissions.md).
+Prerequisites:
-### Estimates
+- You must have at least the Reporter role for the project.
-To enter an estimate, type `/estimate`, followed by the time.
+To enter an estimate, use the `/estimate` [quick action](quick_actions.md), followed by the time.
For example, if you need to enter an estimate of 1 month, 2 weeks, 3 days, 4 hours, and 5 minutes,
type `/estimate 1mo 2w 3d 4h 5m`.
-Check the [time units you can use](#configuration).
+Check the [time units you can use](#available-time-units).
-The estimate is designed to show the total estimated time. The estimated
-time remaining is automatically calculated and displayed when hovering over
-the time tracking information in the right sidebar.
+An issue or a merge request can have only one estimate.
+Every time you enter a new time estimate, it overwrites the previous value.
-![Estimated time remaining](img/remaining_time_v14_2.png)
+### Remove an estimate
-An issue or a merge request can have only one estimate. Every time you enter a
-new time estimate, it overwrites the previous value.
+Prerequisites:
-To remove an estimation entirely, use `/remove_estimate`.
+- You must have at least the Reporter role for the project.
-### Time spent
+To remove an estimate entirely, use the `/remove_estimate` [quick action](quick_actions.md).
-To enter time spent, type `/spend`, followed by the time.
+## Time spent
-For example, if you need
-to log 1 month, 2 weeks, 3 days, 4 hours, and 5 minutes, type `/spend 1mo 2w 3d 4h 5m`.
-Check the [time units you can use](#configuration).
+As you work, you can log the time you've spent.
Every new time spent entry is added to the current total time spent for the
issue or the merge request.
-To subtract time, enter a negative value. For example, `/spend -3d` removes three
-days from the total time spent. You can't go below 0 minutes of time spent,
-so if you remove more time than already entered, GitLab ignores the subtraction.
+### Add time spent
-You can log time in the past by providing a date after the time.
-For example, if you want to log 1 hour of time spent on the 31 January 2021,
-you would type `/spend 1h 2021-01-31`. If you supply a date in the future, the
-command fails and no time is logged.
+Prerequisites:
+
+- You must have at least the Reporter role for the project.
+
+To enter time spent, use the `/spend` [quick action](quick_actions.md), followed by the time.
+
+For example, if you need
+to log 1 month, 2 weeks, 3 days, 4 hours, and 5 minutes, type `/spend 1mo 2w 3d 4h 5m`.
+Check the [time units you can use](#available-time-units).
-To add a timelog entry with a note, create a comment with a description and the quick action.
-It then shows in the timelog "Summary/Notes" column. For example:
+To add a [time tracking report](#view-a-time-tracking-report) entry with a note, create a comment
+with a description and the quick action.
+It then shows in the time tracking report **Summary/Notes** column. For example:
```plaintext
Draft MR and respond to initial comments
@@ -85,7 +90,29 @@ Draft MR and respond to initial comments
/spend 30m
```
-To remove all the time spent at once, use `/remove_time_spent`.
+### Add time spent on a specific date
+
+Prerequisites:
+
+- You must have at least the Reporter role for the project.
+
+You can log time in the past by providing a date after the time.
+For example, to log 1 hour of time spent on 31 January 2021,
+type `/spend 1h 2021-01-31`.
+
+If you type a future date, no time is logged.
+
+### Remove time spent
+
+Prerequisites:
+
+- You must have at least the Reporter role for the project.
+
+To subtract time, enter a negative value. For example, `/spend -3d` removes three
+days from the total time spent. You can't go below 0 minutes of time spent,
+so if you remove more time than already entered, GitLab ignores the subtraction.
+
+To remove all the time spent at once, use the `/remove_time_spent` [quick action](quick_actions.md).
## View a time tracking report
@@ -97,31 +124,32 @@ Prerequisites:
- You must have at least the [Reporter role](../permissions.md#project-members-permissions) for a project.
-To view a time tracking report, go to an issue or a merge request and select **Time tracking report**
-in the right sidebar.
+To view a time tracking report:
+
+1. Go to an issue or a merge request.
+1. In the right sidebar, select **Time tracking report**.
![Time tracking report](img/time_tracking_report_v13_12.png)
The breakdown of spent time is limited to a maximum of 100 entries.
-## Configuration
+## Available time units
The following time units are available:
-| Time unit | What to type | Default conversion rate |
-| --------- | ------------ | ----------------------- |
-| Month | `mo` | 4w |
-| Week | `w` | 5d |
-| Day | `d` | 8h |
-| Hour | `h` | 60m |
-| Minute | `m` | |
+| Time unit | What to type | Conversion rate |
+| --------- | --------------------------- | --------------- |
+| Month | `mo`, `month`, or `months` | 4w (160h) |
+| Week | `w`, `week`, or `weeks` | 5d (40h) |
+| Day | `d`, `day`, or `days` | 8h |
+| Hour | `h`, `hour`, or `hours` | 60m |
+| Minute | `m`, `minute`, or `minutes` | |
### Limit displayed units to hours **(FREE SELF)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/29469/) in GitLab 12.1.
-In GitLab self-managed instances, you can limit the display of time units to
-hours.
+In GitLab self-managed instances, you can limit the display of time units to hours.
To do so:
1. On the top bar, select **Menu > Admin**.
diff --git a/lib/api/terraform/modules/v1/packages.rb b/lib/api/terraform/modules/v1/packages.rb
index 970fdeba734..b2eb3155b34 100644
--- a/lib/api/terraform/modules/v1/packages.rb
+++ b/lib/api/terraform/modules/v1/packages.rb
@@ -21,7 +21,7 @@ module API
module_version: SEMVER_REGEX
}.freeze
- feature_category :package_registry
+ feature_category :infrastructure_as_code
after_validation do
require_packages_enabled!
diff --git a/qa/qa/support/formatters/allure_metadata_formatter.rb b/qa/qa/support/formatters/allure_metadata_formatter.rb
index 10769ba5c57..da35ffde1ae 100644
--- a/qa/qa/support/formatters/allure_metadata_formatter.rb
+++ b/qa/qa/support/formatters/allure_metadata_formatter.rb
@@ -15,14 +15,42 @@ module QA
def example_started(example_notification)
example = example_notification.example
- quarantine_issue = example.metadata.dig(:quarantine, :issue)
- example.issue('Quarantine issue', quarantine_issue) if quarantine_issue
+ add_quarantine_issue_link(example)
+ add_failure_issues_link(example)
+ add_ci_job_link(example)
+ end
+
+ private
+
+ # Add quarantine issue links
+ #
+ # @param [RSpec::Core::Example] example
+ # @return [void]
+ def add_quarantine_issue_link(example)
+ issue_link = example.metadata.dig(:quarantine, :issue)
+
+ return unless issue_link
+ return example.issue('Quarantine issue', issue_link) if issue_link.is_a?(String)
+ return issue_link.each { |link| example.issue('Quarantine issue', link) } if issue_link.is_a?(Array)
+ end
+ # Add failure issues link
+ #
+ # @param [RSpec::Core::Example] example
+ # @return [void]
+ def add_failure_issues_link(example)
spec_file = example.file_path.split('/').last
example.issue(
'Failure issues',
"https://gitlab.com/gitlab-org/gitlab/-/issues?scope=all&state=opened&search=#{spec_file}"
)
+ end
+
+ # Add ci job link
+ #
+ # @param [RSpec::Core::Example] example
+ # @return [void]
+ def add_ci_job_link(example)
return unless Runtime::Env.running_in_ci?
example.add_link(name: "Job(#{Runtime::Env.ci_job_name})", url: Runtime::Env.ci_job_url)
diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb
index 8d4e7a7442c..a0a41061d64 100644
--- a/spec/features/admin/admin_groups_spec.rb
+++ b/spec/features/admin/admin_groups_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe 'Admin Groups' do
include Select2Helper
include Spec::Support::Helpers::Features::MembersHelpers
include Spec::Support::Helpers::Features::InviteMembersModalHelper
+ include Spec::Support::Helpers::ModalHelpers
let(:internal) { Gitlab::VisibilityLevel::INTERNAL }
@@ -250,26 +251,26 @@ RSpec.describe 'Admin Groups' do
end
end
- describe 'admin remove themself from a group', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/222342' do
+ describe 'admin removes themself from a group', :js do
it 'removes admin from the group' do
- stub_feature_flags(bootstrap_confirmation_modals: false)
group.add_user(current_user, Gitlab::Access::DEVELOPER)
visit group_group_members_path(group)
- page.within '[data-qa-selector="members_list"]' do # rubocop:disable QA/SelectorUsage
+ page.within members_table do
expect(page).to have_content(current_user.name)
expect(page).to have_content('Developer')
end
- accept_confirm { find(:css, 'li', text: current_user.name).find(:css, 'a.btn-danger').click }
+ find_member_row(current_user).click_button(title: 'Leave')
+
+ accept_gl_confirm(button_text: 'Leave')
+
+ wait_for_all_requests
visit group_group_members_path(group)
- page.within '[data-qa-selector="members_list"]' do # rubocop:disable QA/SelectorUsage
- expect(page).not_to have_content(current_user.name)
- expect(page).not_to have_content('Developer')
- end
+ expect(members_table).not_to have_content(current_user.name)
end
end
diff --git a/spec/graphql/types/member_interface_spec.rb b/spec/graphql/types/member_interface_spec.rb
index 11fd09eb335..8ecaaa46bed 100644
--- a/spec/graphql/types/member_interface_spec.rb
+++ b/spec/graphql/types/member_interface_spec.rb
@@ -12,6 +12,7 @@ RSpec.describe Types::MemberInterface do
updated_at
expires_at
user
+ merge_request_interaction
]
expect(described_class).to have_graphql_fields(*expected_fields)
@@ -40,4 +41,16 @@ RSpec.describe Types::MemberInterface do
end
end
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
+ expect(subject.arguments).to have_key('id')
+ end
+ end
end
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index b9d73443a21..14ffb714c6e 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -31,16 +31,6 @@ RSpec.describe Ci::Runner do
expect(runner.projects.count).to eq(1)
end
end
-
- context 'when ci_runner_projects_disable_joins is disabled' do
- before do
- stub_feature_flags(ci_runner_projects_disable_joins: false)
- end
-
- it 'creates a cross-database query' do
- expect { runner.projects.count }.to raise_error(Database::PreventCrossJoins::CrossJoinAcrossUnsupportedTablesError)
- end
- end
end
describe 'validation' do
diff --git a/spec/requests/api/graphql/project/project_members_spec.rb b/spec/requests/api/graphql/project/project_members_spec.rb
index 466464f600c..315d44884ff 100644
--- a/spec/requests/api/graphql/project/project_members_spec.rb
+++ b/spec/requests/api/graphql/project/project_members_spec.rb
@@ -110,6 +110,102 @@ RSpec.describe 'getting project members information' do
end
end
+ context 'merge request interactions' do
+ let(:project_path) { var('ID!').with(parent_project.full_path) }
+ let(:mr_a) do
+ var('MergeRequestID!')
+ .with(global_id_of(create(:merge_request, source_project: parent_project, source_branch: 'branch-1')))
+ end
+
+ let(:mr_b) do
+ var('MergeRequestID!')
+ .with(global_id_of(create(:merge_request, source_project: parent_project, source_branch: 'branch-2')))
+ end
+
+ let(:interaction_query) do
+ <<~HEREDOC
+ edges {
+ node {
+ user {
+ id
+ }
+ mrA: #{query_graphql_field(:merge_request_interaction, { id: mr_a }, 'canMerge')}
+ }
+ }
+ HEREDOC
+ end
+
+ let(:interaction_b_query) do
+ <<~HEREDOC
+ edges {
+ node {
+ user {
+ id
+ }
+ mrA: #{query_graphql_field(:merge_request_interaction, { id: mr_a }, 'canMerge')}
+ mrB: #{query_graphql_field(:merge_request_interaction, { id: mr_b }, 'canMerge')}
+ }
+ }
+ HEREDOC
+ end
+
+ it 'avoids N+1 queries, when requesting multiple MRs' do
+ control_query = with_signature(
+ [project_path, mr_a],
+ graphql_query_for(:project, { full_path: project_path },
+ query_graphql_field(:project_members, nil, interaction_query))
+ )
+ query_two = with_signature(
+ [project_path, mr_a, mr_b],
+ graphql_query_for(:project, { full_path: project_path },
+ query_graphql_field(:project_members, nil, interaction_b_query))
+ )
+
+ control_count = ActiveRecord::QueryRecorder.new do
+ post_graphql(control_query, current_user: user, variables: [project_path, mr_a])
+ end
+
+ # two project members, neither of whom can merge
+ expect(can_merge(:mrA)).to eq [false, false]
+
+ expect do
+ post_graphql(query_two, current_user: user, variables: [project_path, mr_a, mr_b])
+
+ expect(can_merge(:mrA)).to eq [false, false]
+ expect(can_merge(:mrB)).to eq [false, false]
+ end.not_to exceed_query_limit(control_count)
+ end
+
+ it 'avoids N+1 queries, when more users are involved' do
+ new_user = create(:user)
+
+ query = with_signature(
+ [project_path, mr_a],
+ graphql_query_for(:project, { full_path: project_path },
+ query_graphql_field(:project_members, nil, interaction_query))
+ )
+
+ control_count = ActiveRecord::QueryRecorder.new do
+ post_graphql(query, current_user: user, variables: [project_path, mr_a])
+ end
+
+ # two project members, neither of whom can merge
+ expect(can_merge(:mrA)).to eq [false, false]
+
+ parent_project.add_guest(new_user)
+
+ expect do
+ post_graphql(query, current_user: user, variables: [project_path, mr_a])
+
+ expect(can_merge(:mrA)).to eq [false, false, false]
+ end.not_to exceed_query_limit(control_count)
+ end
+
+ def can_merge(name)
+ graphql_data_at(:project, :project_members, :edges, :node, name, :can_merge)
+ end
+ end
+
context 'when unauthenticated' do
it 'returns members' do
fetch_members(current_user: nil, project: parent_project)