diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-28 21:13:52 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-28 21:13:52 +0000 |
commit | 8de745957a9c3c2a48ca47dd3bd69ee4db7424e0 (patch) | |
tree | d3c9c9eb8a50246059746565e6e23d2bdbba76a7 | |
parent | de3e5b677261e4cdd9fbad6fbe461c9c605cbfa6 (diff) | |
download | gitlab-ce-8de745957a9c3c2a48ca47dd3bd69ee4db7424e0.tar.gz |
Add latest changes from gitlab-org/gitlab@master
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 Binary files differdeleted file mode 100644 index 31d8c490ed1..00000000000 --- a/doc/user/project/img/time_tracking_example_v12_2.png +++ /dev/null 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) |