Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-01-05 03:10:20 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-01-05 03:10:20 +0300
commitb28aa8bd7d9f4289d6e73df2eb9d308b80b70d95 (patch)
treef2b8ee3eea854b76543b52ca1bc63f46d9ccb2c8
parent9248363e3eb740b2f1dccb3a63f09aff4fcdf94f (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/commons/nav/user_merge_requests.js24
-rw-r--r--app/assets/javascripts/sidebar/components/reviewers/sidebar_reviewers.vue4
-rw-r--r--app/assets/stylesheets/framework/dropdowns.scss8
-rw-r--r--app/assets/stylesheets/framework/header.scss4
-rw-r--r--app/helpers/dashboard_helper.rb4
-rw-r--r--app/helpers/merge_requests_helper.rb26
-rw-r--r--app/models/user.rb7
-rw-r--r--app/policies/project_policy.rb6
-rw-r--r--app/services/merge_requests/update_service.rb2
-rw-r--r--app/views/layouts/header/_default.html.haml31
-rw-r--r--changelogs/unreleased/296563-follow-up-from-fix-project-access-token-regression.yml5
-rw-r--r--changelogs/unreleased/eliminate-tz-sensitivity-ci-analytics-charts.yml5
-rw-r--r--doc/development/internal_api.md4
-rw-r--r--doc/user/admin_area/img/license_admin_area.pngbin27826 -> 0 bytes
-rw-r--r--doc/user/admin_area/img/license_upload.pngbin10043 -> 0 bytes
-rw-r--r--doc/user/admin_area/img/license_upload_v13_8.pngbin0 -> 32860 bytes
-rw-r--r--doc/user/admin_area/license.md27
-rw-r--r--doc/user/admin_area/settings/sign_up_restrictions.md3
-rw-r--r--doc/user/packages/npm_registry/index.md8
-rw-r--r--doc/user/packages/pypi_repository/index.md5
-rw-r--r--lib/api/user_counts.rb4
-rw-r--r--lib/gitlab/auth.rb6
-rw-r--r--lib/gitlab/ci/charts.rb8
-rw-r--r--locale/gitlab.pot6
-rw-r--r--spec/features/dashboard/merge_requests_spec.rb6
-rw-r--r--spec/frontend/commons/nav/user_merge_requests_spec.js15
-rw-r--r--spec/helpers/dashboard_helper_spec.rb6
-rw-r--r--spec/helpers/merge_requests_helper_spec.rb33
-rw-r--r--spec/lib/gitlab/ci/charts_spec.rb35
-rw-r--r--spec/models/user_spec.rb15
-rw-r--r--spec/policies/project_policy_spec.rb34
-rw-r--r--spec/services/merge_requests/update_service_spec.rb13
32 files changed, 227 insertions, 127 deletions
diff --git a/app/assets/javascripts/commons/nav/user_merge_requests.js b/app/assets/javascripts/commons/nav/user_merge_requests.js
index 1e2cf756059..eab2b5a31d7 100644
--- a/app/assets/javascripts/commons/nav/user_merge_requests.js
+++ b/app/assets/javascripts/commons/nav/user_merge_requests.js
@@ -11,7 +11,17 @@ function broadcastCount(newCount) {
}
function updateUserMergeRequestCounts(newCount) {
- const mergeRequestsCountEl = document.querySelector('.merge-requests-count');
+ const mergeRequestsCountEl = document.querySelector('.js-assigned-mr-count');
+ mergeRequestsCountEl.textContent = newCount.toLocaleString();
+}
+
+function updateReviewerMergeRequestCounts(newCount) {
+ const mergeRequestsCountEl = document.querySelector('.js-reviewer-mr-count');
+ mergeRequestsCountEl.textContent = newCount.toLocaleString();
+}
+
+function updateMergeRequestCounts(newCount) {
+ const mergeRequestsCountEl = document.querySelector('.js-merge-requests-count');
mergeRequestsCountEl.textContent = newCount.toLocaleString();
mergeRequestsCountEl.classList.toggle('hidden', Number(newCount) === 0);
}
@@ -22,10 +32,14 @@ function updateUserMergeRequestCounts(newCount) {
export function refreshUserMergeRequestCounts() {
return Api.userCounts()
.then(({ data }) => {
- const count = data.merge_requests;
+ const assignedMergeRequests = data.assigned_merge_requests;
+ const reviewerMergeRequests = data.review_requested_merge_requests;
+ const fullCount = assignedMergeRequests + reviewerMergeRequests;
- updateUserMergeRequestCounts(count);
- broadcastCount(count);
+ updateUserMergeRequestCounts(assignedMergeRequests);
+ updateReviewerMergeRequestCounts(reviewerMergeRequests);
+ updateMergeRequestCounts(fullCount);
+ broadcastCount(fullCount);
})
.catch((ex) => {
console.error(ex); // eslint-disable-line no-console
@@ -60,7 +74,7 @@ export function openUserCountsBroadcast() {
if (currentUserId) {
channel = new BroadcastChannel(`mr_count_channel_${currentUserId}`);
channel.onmessage = (ev) => {
- updateUserMergeRequestCounts(ev.data);
+ updateMergeRequestCounts(ev.data);
};
}
}
diff --git a/app/assets/javascripts/sidebar/components/reviewers/sidebar_reviewers.vue b/app/assets/javascripts/sidebar/components/reviewers/sidebar_reviewers.vue
index aee94a55134..d9228450371 100644
--- a/app/assets/javascripts/sidebar/components/reviewers/sidebar_reviewers.vue
+++ b/app/assets/javascripts/sidebar/components/reviewers/sidebar_reviewers.vue
@@ -2,6 +2,7 @@
// NOTE! For the first iteration, we are simply copying the implementation of Assignees
// It will soon be overhauled in Issue https://gitlab.com/gitlab-org/gitlab/-/issues/233736
import { deprecatedCreateFlash as Flash } from '~/flash';
+import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests';
import eventHub from '~/sidebar/event_hub';
import Store from '~/sidebar/stores/sidebar_store';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
@@ -80,8 +81,7 @@ export default {
.saveReviewers(this.field)
.then(() => {
this.loading = false;
- // Uncomment once this issue has been addressed > https://gitlab.com/gitlab-org/gitlab/-/issues/237922
- // refreshUserMergeRequestCounts();
+ refreshUserMergeRequestCounts();
})
.catch(() => {
this.loading = false;
diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss
index e2335c184b0..c5ffcb48814 100644
--- a/app/assets/stylesheets/framework/dropdowns.scss
+++ b/app/assets/stylesheets/framework/dropdowns.scss
@@ -796,6 +796,14 @@
.navbar-gitlab {
li.dropdown {
position: static;
+
+ &.user-counter {
+ margin-left: 8px !important;
+
+ > a {
+ padding: 0 4px !important;
+ }
+ }
}
}
diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss
index a6a01c7b090..730e10114c3 100644
--- a/app/assets/stylesheets/framework/header.scss
+++ b/app/assets/stylesheets/framework/header.scss
@@ -172,7 +172,7 @@
}
li {
- .badge.badge-pill {
+ .badge.badge-pill:not(.merge-request-badge) {
box-shadow: none;
font-weight: $gl-font-weight-bold;
}
@@ -438,7 +438,7 @@
.title-container,
.navbar-nav {
- .badge.badge-pill {
+ .badge.badge-pill:not(.merge-request-badge) {
position: inherit;
font-weight: $gl-font-weight-normal;
margin-left: -6px;
diff --git a/app/helpers/dashboard_helper.rb b/app/helpers/dashboard_helper.rb
index 195b3162039..08f357916b5 100644
--- a/app/helpers/dashboard_helper.rb
+++ b/app/helpers/dashboard_helper.rb
@@ -11,6 +11,10 @@ module DashboardHelper
merge_requests_dashboard_path(assignee_username: current_user.username)
end
+ def reviewer_mrs_dashboard_path
+ merge_requests_dashboard_path(reviewer_username: current_user.username)
+ end
+
def dashboard_nav_links
@dashboard_nav_links ||= get_dashboard_nav_links
end
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index 37e701c1c2b..bbfd06ca06d 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -159,6 +159,32 @@ module MergeRequestsHelper
issuable_path(issuable, { merge_request: { wip_event: wip_event } })
end
+
+ def user_merge_requests_counts
+ @user_merge_requests_counts ||= begin
+ assigned_count = assigned_issuables_count(:merge_requests)
+ review_requested_count = review_requested_merge_requests_count
+ total_count = assigned_count + review_requested_count
+
+ {
+ assigned: assigned_count,
+ review_requested: review_requested_count,
+ total: total_count
+ }
+ end
+ end
+
+ def merge_request_reviewers_enabled?
+ Feature.enabled?(:merge_request_reviewers, default_enabled: :yaml)
+ end
+
+ private
+
+ def review_requested_merge_requests_count
+ return 0 unless merge_request_reviewers_enabled?
+
+ current_user.review_requested_open_merge_requests_count
+ end
end
MergeRequestsHelper.prepend_if_ee('EE::MergeRequestsHelper')
diff --git a/app/models/user.rb b/app/models/user.rb
index c735f20b92c..284182797c0 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1564,6 +1564,12 @@ class User < ApplicationRecord
end
end
+ def review_requested_open_merge_requests_count(force: false)
+ Rails.cache.fetch(['users', id, 'review_requested_open_merge_requests_count'], force: force, expires_in: 20.minutes) do
+ MergeRequestsFinder.new(self, reviewer_id: id, state: 'opened', non_archived: true).execute.count
+ end
+ end
+
def assigned_open_issues_count(force: false)
Rails.cache.fetch(['users', id, 'assigned_open_issues_count'], force: force, expires_in: 20.minutes) do
IssuesFinder.new(self, assignee_id: self.id, state: 'opened', non_archived: true).execute.count
@@ -1607,6 +1613,7 @@ class User < ApplicationRecord
def invalidate_merge_request_cache_counts
Rails.cache.delete(['users', id, 'assigned_open_merge_requests_count'])
+ Rails.cache.delete(['users', id, 'review_requested_open_merge_requests_count'])
end
def invalidate_todos_done_count
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index 403fb34803e..3b8c59c6bf8 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -135,10 +135,6 @@ class ProjectPolicy < BasePolicy
::Feature.enabled?(:build_service_proxy, @subject)
end
- condition(:project_bot_is_member) do
- user.project_bot? & team_member?
- end
-
with_scope :subject
condition(:packages_disabled) { !@subject.packages_enabled }
@@ -619,8 +615,6 @@ class ProjectPolicy < BasePolicy
enable :admin_resource_access_tokens
end
- rule { project_bot_is_member & ~blocked }.enable :bot_log_in
-
private
def user_is_user?
diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb
index 1d0ab403f12..d2e5a2a1619 100644
--- a/app/services/merge_requests/update_service.rb
+++ b/app/services/merge_requests/update_service.rb
@@ -112,9 +112,11 @@ module MergeRequests
end
def handle_reviewers_change(merge_request, old_reviewers)
+ affected_reviewers = (old_reviewers + merge_request.reviewers) - (old_reviewers & merge_request.reviewers)
create_reviewer_note(merge_request, old_reviewers)
notification_service.async.changed_reviewer_of_merge_request(merge_request, current_user, old_reviewers)
todo_service.reassigned_reviewable(merge_request, current_user, old_reviewers)
+ invalidate_cache_counts(merge_request, users: affected_reviewers.compact)
end
def create_branch_change_note(issuable, branch_type, old_branch, new_branch)
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index 70ab0a56581..1394f15cd15 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -47,17 +47,36 @@
%span.badge.badge-pill.issues-count.green-badge{ class: ('hidden' if issues_count == 0) }
= number_with_delimiter(issues_count)
- if header_link?(:merge_requests)
- = nav_link(path: 'dashboard#merge_requests', html_options: { class: "user-counter" }) do
- = link_to assigned_mrs_dashboard_path, title: _('Merge requests'), class: 'dashboard-shortcuts-merge_requests', aria: { label: _('Merge requests') },
- data: { qa_selector: 'merge_requests_shortcut_button', toggle: 'tooltip', placement: 'bottom',
+ - reviewers_enabled = merge_request_reviewers_enabled?
+ = nav_link(path: 'dashboard#merge_requests', html_options: { class: "user-counter #{reviewers_enabled ? 'dropdown' : ''}" }) do
+ = link_to assigned_mrs_dashboard_path, class: 'dashboard-shortcuts-merge_requests', title: _('Merge requests'), aria: { label: _('Merge requests') },
+ data: { qa_selector: 'merge_requests_shortcut_button',
+ toggle: reviewers_enabled ? "dropdown" : "tooltip",
+ placement: 'bottom',
track_label: 'main_navigation',
track_event: 'click_merge_link',
track_property: 'navigation',
container: 'body' } do
= sprite_icon('git-merge')
- - merge_requests_count = assigned_issuables_count(:merge_requests)
- %span.badge.badge-pill.merge-requests-count{ class: ('hidden' if merge_requests_count == 0) }
- = number_with_delimiter(merge_requests_count)
+ %span.badge.badge-pill.merge-requests-count.js-merge-requests-count{ class: ('hidden' if user_merge_requests_counts[:total] == 0) }
+ = number_with_delimiter(user_merge_requests_counts[:total])
+ - if reviewers_enabled
+ = sprite_icon('chevron-down', css_class: 'caret-down gl-mx-0!')
+ - if reviewers_enabled
+ .dropdown-menu.dropdown-menu-right
+ %ul
+ %li.dropdown-header
+ = _('Merge requests')
+ %li
+ = link_to assigned_mrs_dashboard_path, class: 'gl-display-flex! gl-align-items-center' do
+ = _('Assigned to you')
+ %span.badge.gl-badge.badge-pill.badge-muted.merge-request-badge.gl-ml-auto.js-assigned-mr-count{ class: "" }
+ = user_merge_requests_counts[:assigned]
+ %li
+ = link_to reviewer_mrs_dashboard_path, class: 'gl-display-flex! gl-align-items-center' do
+ = _('Review requests for you')
+ %span.badge.gl-badge.badge-pill.badge-muted.merge-request-badge.gl-ml-auto.js-reviewer-mr-count{ class: "" }
+ = user_merge_requests_counts[:review_requested]
- if header_link?(:todos)
= nav_link(controller: 'dashboard/todos', html_options: { class: "user-counter" }) do
= link_to dashboard_todos_path, title: _('To-Do List'), aria: { label: _('To-Do List') }, class: 'shortcuts-todos',
diff --git a/changelogs/unreleased/296563-follow-up-from-fix-project-access-token-regression.yml b/changelogs/unreleased/296563-follow-up-from-fix-project-access-token-regression.yml
new file mode 100644
index 00000000000..c280ccb21ec
--- /dev/null
+++ b/changelogs/unreleased/296563-follow-up-from-fix-project-access-token-regression.yml
@@ -0,0 +1,5 @@
+---
+title: Fix project access token regression
+merge_request: 50800
+author:
+type: fixed
diff --git a/changelogs/unreleased/eliminate-tz-sensitivity-ci-analytics-charts.yml b/changelogs/unreleased/eliminate-tz-sensitivity-ci-analytics-charts.yml
deleted file mode 100644
index 23b00c80186..00000000000
--- a/changelogs/unreleased/eliminate-tz-sensitivity-ci-analytics-charts.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix empty pipeline analytics charts when time_zone is non-UTC
-merge_request: 50760
-author:
-type: fixed
diff --git a/doc/development/internal_api.md b/doc/development/internal_api.md
index 9a1ec0285c0..43655c37048 100644
--- a/doc/development/internal_api.md
+++ b/doc/development/internal_api.md
@@ -459,11 +459,11 @@ Cluster.
| `alert` | Hash | yes | Alerts detail. Currently same format as [3rd party alert](../operations/incident_management/alert_integrations.md#customize-the-alert-payload-outside-of-gitlab). |
```plaintext
-POST internal/kubernetes/modules/cilium/network_alert
+POST internal/kubernetes/modules/cilium_alert
```
Example Request:
```shell
-curl --request POST --header "Gitlab-Kas-Api-Request: <JWT token>" --header "Authorization: Bearer <agent token>" --header "Content-Type: application/json" --data '"{\"alert\":{\"title\":\"minimal\",\"message\":\"network problem\",\"evalMatches\":[{\"value\":1,\"metric\":\"Count\",\"tags\":{}}]}}"' "http://localhost:3000/api/v4/internal/kubernetes/modules/cilium/network_alert"
+curl --request POST --header "Gitlab-Kas-Api-Request: <JWT token>" --header "Authorization: Bearer <agent token>" --header "Content-Type: application/json" --data '"{\"alert\":{\"title\":\"minimal\",\"message\":\"network problem\",\"evalMatches\":[{\"value\":1,\"metric\":\"Count\",\"tags\":{}}]}}"' "http://localhost:3000/api/v4/internal/kubernetes/modules/cilium_alert"
```
diff --git a/doc/user/admin_area/img/license_admin_area.png b/doc/user/admin_area/img/license_admin_area.png
deleted file mode 100644
index b5662b81c5e..00000000000
--- a/doc/user/admin_area/img/license_admin_area.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/admin_area/img/license_upload.png b/doc/user/admin_area/img/license_upload.png
deleted file mode 100644
index 29d55175a2d..00000000000
--- a/doc/user/admin_area/img/license_upload.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/admin_area/img/license_upload_v13_8.png b/doc/user/admin_area/img/license_upload_v13_8.png
new file mode 100644
index 00000000000..c15bc2bfa02
--- /dev/null
+++ b/doc/user/admin_area/img/license_upload_v13_8.png
Binary files differ
diff --git a/doc/user/admin_area/license.md b/doc/user/admin_area/license.md
index 9838dc61c2d..dab98982e26 100644
--- a/doc/user/admin_area/license.md
+++ b/doc/user/admin_area/license.md
@@ -42,18 +42,21 @@ Otherwise, you can:
1. Navigate to the **License** tab, and click **Upload New License**.
- ![License Admin Area](img/license_admin_area.png)
-
- - *If you've received a `.gitlab-license` file,* you should have already downloaded
- it in your local machine. You can then upload it directly by choosing the
- license file and clicking the **Upload license** button. In the image below,
- the selected license file is named `GitLab.gitlab-license`.
-
- ![Upload license](img/license_upload.png)
-
- - *If you've received your license as plain text,* select the
- **Enter license key** option, copy the license, paste it into the **License key**
- field, and click **Upload license**.
+ - *If you've received a `.gitlab-license` file:*
+ 1. Download the license file to your local machine.
+ 1. Select **Upload `.gitlab-license` file**.
+ 1. Select **Choose File** and select the license file.
+ In this example the license file is named `GitLab.gitlab-license`.
+ 1. Check the **Subscription Agreement** checkbox.
+ 1. Select **Upload License**.
+
+ ![Upload license](img/license_upload_v13_8.png)
+
+ - *If you've received your license as plain text:*
+ 1. Select **Enter license key**.
+ 1. Copy the license and paste it into the **License key** field.
+ 1. Check the **Subscription Agreement** checkbox.
+ 1. Select **Upload License**.
## Add your license at install time
diff --git a/doc/user/admin_area/settings/sign_up_restrictions.md b/doc/user/admin_area/settings/sign_up_restrictions.md
index 213c8c4116a..781241ffd20 100644
--- a/doc/user/admin_area/settings/sign_up_restrictions.md
+++ b/doc/user/admin_area/settings/sign_up_restrictions.md
@@ -47,6 +47,9 @@ To enforce confirmation of the email address used for new sign ups:
1. Go to **Admin Area > Settings > General** and expand **Sign-up restrictions**.
1. Select the **Enable email restrictions for sign ups** checkbox, then select **Save changes**.
+In [GitLab 13.7 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/273258), if an administrator disables this setting, the users in pending approval state are
+automatically approved in a background job.
+
## User cap **(CORE ONLY)**
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/4315) in GitLab 13.6.
diff --git a/doc/user/packages/npm_registry/index.md b/doc/user/packages/npm_registry/index.md
index c411fd556df..38f829c94e8 100644
--- a/doc/user/packages/npm_registry/index.md
+++ b/doc/user/packages/npm_registry/index.md
@@ -102,7 +102,7 @@ To authenticate to the Package Registry, you must use one of the following:
- It's not recommended, but you can use [OAuth tokens](../../../api/oauth2.md#resource-owner-password-credentials-flow).
Standard OAuth tokens cannot authenticate to the GitLab NPM Registry. You must use a personal access token with OAuth headers.
- A [CI job token](#authenticate-with-a-ci-job-token).
-- Your NPM package name must be in the format of [@scope:package-name](#package-naming-convention). It must match exactly, including the case.
+- Your NPM package name must be in the format of [@scope/package-name](#package-naming-convention). It must match exactly, including the case.
### Authenticate with a personal access token or deploy token
@@ -201,7 +201,7 @@ Then, you can run `npm publish` either locally or by using GitLab CI/CD.
## Package naming convention
-Your NPM package name must be in the format of `@scope:package-name`.
+Your NPM package name must be in the format of `@scope/package-name`.
- The `@scope` is the root namespace of the GitLab project. It must match exactly, including the case.
- The `package-name` can be whatever you want.
@@ -241,7 +241,7 @@ Prerequisites:
- [Authenticate](#authenticate-to-the-package-registry) to the Package Registry.
- Set a [project-level NPM endpoint](#use-the-gitlab-endpoint-for-npm-packages).
-- Your NPM package name must be in the format of [@scope:package-name](#package-naming-convention). It must match exactly, including the case.
+- Your NPM package name must be in the format of [@scope/package-name](#package-naming-convention). It must match exactly, including the case.
To upload an NPM package to your project, run this command:
@@ -461,7 +461,7 @@ If you get this error, ensure that:
### `npm publish` returns `npm ERR! 400 Bad Request`
If you get this error, your package name may not meet the
-[@scope:package-name package naming convention](#package-naming-convention).
+[@scope/package-name package naming convention](#package-naming-convention).
Ensure the name meets the convention exactly, including the case.
Then try to publish again.
diff --git a/doc/user/packages/pypi_repository/index.md b/doc/user/packages/pypi_repository/index.md
index 954ea91ba28..187d964c422 100644
--- a/doc/user/packages/pypi_repository/index.md
+++ b/doc/user/packages/pypi_repository/index.md
@@ -235,9 +235,12 @@ password = ${env.CI_JOB_TOKEN}
When publishing packages, note that:
-- The maximum allowed size is 50 MB.
+- You must [authenticate with the Package Registry](#authenticate-with-the-package-registry).
+- Your [version string must be valid](#ensure-your-version-string-is-valid).
+- The maximum allowed package size is 5 GB.
- You can't upload the same version of a package multiple times. If you try,
you receive the error `Validation failed: File name has already been taken`.
+- You cannot publish PyPI packages to a group, only to a project.
### Ensure your version string is valid
diff --git a/lib/api/user_counts.rb b/lib/api/user_counts.rb
index 3071f08e1de..31c923a219a 100644
--- a/lib/api/user_counts.rb
+++ b/lib/api/user_counts.rb
@@ -12,7 +12,9 @@ module API
unauthorized! unless current_user
{
- merge_requests: current_user.assigned_open_merge_requests_count
+ merge_requests: current_user.assigned_open_merge_requests_count, # @deprecated
+ assigned_merge_requests: current_user.assigned_open_merge_requests_count,
+ review_requested_merge_requests: current_user.review_requested_open_merge_requests_count
}
end
end
diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb
index 1aabb05f19e..1f5cce249d8 100644
--- a/lib/gitlab/auth.rb
+++ b/lib/gitlab/auth.rb
@@ -198,7 +198,9 @@ module Gitlab
return unless valid_scoped_token?(token, all_available_scopes)
- if token.user.can?(:log_in) || token.user.can?(:bot_log_in, project)
+ return if project && token.user.project_bot? && !project.bots.include?(token.user)
+
+ if token.user.can?(:log_in) || token.user.project_bot?
Gitlab::Auth::Result.new(token.user, nil, :personal_access_token, abilities_for_scopes(token.scopes))
end
end
@@ -283,7 +285,7 @@ module Gitlab
return unless build.project.builds_enabled?
if build.user
- return unless build.user.can?(:log_in) || build.user.can?(:bot_log_in, build.project)
+ return unless build.user.can?(:log_in) || (build.user.project_bot? && build.project.bots&.include?(build.user))
# If user is assigned to build, use restricted credentials of user
Gitlab::Auth::Result.new(build.user, build.project, :build, build_authentication_abilities)
diff --git a/lib/gitlab/ci/charts.rb b/lib/gitlab/ci/charts.rb
index 797193a6be5..25fb9c0ca97 100644
--- a/lib/gitlab/ci/charts.rb
+++ b/lib/gitlab/ci/charts.rb
@@ -31,10 +31,9 @@ module Gitlab
current = @from
while current <= @to
- label = current.strftime(@format)
- @labels << label
- @total << (totals_count[label] || 0)
- @success << (success_count[label] || 0)
+ @labels << current.strftime(@format)
+ @total << (totals_count[current] || 0)
+ @success << (success_count[current] || 0)
current += interval_step
end
@@ -46,7 +45,6 @@ module Gitlab
query
.group("date_trunc('#{interval}', #{::Ci::Pipeline.table_name}.created_at)")
.count(:created_at)
- .transform_keys { |date| date.strftime(@format) }
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index b27d977225a..9e8b50f39d7 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -3943,6 +3943,9 @@ msgstr ""
msgid "Assigned to me"
msgstr ""
+msgid "Assigned to you"
+msgstr ""
+
msgid "Assignee"
msgid_plural "%d Assignees"
msgstr[0] ""
@@ -24032,6 +24035,9 @@ msgstr ""
msgid "Review requested from %{name}"
msgstr ""
+msgid "Review requests for you"
+msgstr ""
+
msgid "Review the changes locally"
msgstr ""
diff --git a/spec/features/dashboard/merge_requests_spec.rb b/spec/features/dashboard/merge_requests_spec.rb
index 0e76b5478a1..26b376be660 100644
--- a/spec/features/dashboard/merge_requests_spec.rb
+++ b/spec/features/dashboard/merge_requests_spec.rb
@@ -110,6 +110,12 @@ RSpec.describe 'Dashboard Merge Requests' do
visit merge_requests_dashboard_path(assignee_username: current_user.username)
end
+ it 'includes assigned and reviewers in badge' do
+ expect(find('.merge-requests-count')).to have_content('3')
+ expect(find('.js-assigned-mr-count')).to have_content('2')
+ expect(find('.js-reviewer-mr-count')).to have_content('1')
+ end
+
it 'shows assigned merge requests' do
expect(page).to have_content(assigned_merge_request.title)
expect(page).to have_content(assigned_merge_request_from_fork.title)
diff --git a/spec/frontend/commons/nav/user_merge_requests_spec.js b/spec/frontend/commons/nav/user_merge_requests_spec.js
index 4da6d53557a..5f81067f84f 100644
--- a/spec/frontend/commons/nav/user_merge_requests_spec.js
+++ b/spec/frontend/commons/nav/user_merge_requests_spec.js
@@ -8,7 +8,7 @@ import Api from '~/api';
jest.mock('~/api');
const TEST_COUNT = 1000;
-const MR_COUNT_CLASS = 'merge-requests-count';
+const MR_COUNT_CLASS = 'js-merge-requests-count';
describe('User Merge Requests', () => {
let channelMock;
@@ -24,7 +24,9 @@ describe('User Merge Requests', () => {
newBroadcastChannelMock = jest.fn().mockImplementation(() => channelMock);
global.BroadcastChannel = newBroadcastChannelMock;
- setFixtures(`<div class="${MR_COUNT_CLASS}">0</div>`);
+ setFixtures(
+ `<div><div class="${MR_COUNT_CLASS}">0</div><div class="js-assigned-mr-count"></div><div class="js-reviewer-mr-count"></div></div>`,
+ );
});
const findMRCountText = () => document.body.querySelector(`.${MR_COUNT_CLASS}`).textContent;
@@ -33,7 +35,10 @@ describe('User Merge Requests', () => {
beforeEach(() => {
Api.userCounts.mockReturnValue(
Promise.resolve({
- data: { merge_requests: TEST_COUNT },
+ data: {
+ assigned_merge_requests: TEST_COUNT,
+ review_requested_merge_requests: TEST_COUNT,
+ },
}),
);
});
@@ -46,7 +51,7 @@ describe('User Merge Requests', () => {
});
it('updates the top count of merge requests', () => {
- expect(findMRCountText()).toEqual(TEST_COUNT.toLocaleString());
+ expect(findMRCountText()).toEqual(Number(TEST_COUNT + TEST_COUNT).toLocaleString());
});
it('calls the API', () => {
@@ -54,7 +59,7 @@ describe('User Merge Requests', () => {
});
it('posts count to BroadcastChannel', () => {
- expect(channelMock.postMessage).toHaveBeenCalledWith(TEST_COUNT);
+ expect(channelMock.postMessage).toHaveBeenCalledWith(TEST_COUNT + TEST_COUNT);
});
});
diff --git a/spec/helpers/dashboard_helper_spec.rb b/spec/helpers/dashboard_helper_spec.rb
index 65182dcb729..8a76771be0a 100644
--- a/spec/helpers/dashboard_helper_spec.rb
+++ b/spec/helpers/dashboard_helper_spec.rb
@@ -89,4 +89,10 @@ RSpec.describe DashboardHelper do
it { is_expected.to eq(false) }
end
+
+ describe '#reviewer_mrs_dashboard_path' do
+ subject { helper.reviewer_mrs_dashboard_path }
+
+ it { is_expected.to eq(merge_requests_dashboard_path(reviewer_username: user.username)) }
+ end
end
diff --git a/spec/helpers/merge_requests_helper_spec.rb b/spec/helpers/merge_requests_helper_spec.rb
index 377e2c43a72..821faaab194 100644
--- a/spec/helpers/merge_requests_helper_spec.rb
+++ b/spec/helpers/merge_requests_helper_spec.rb
@@ -67,4 +67,37 @@ RSpec.describe MergeRequestsHelper do
end
end
end
+
+ describe '#user_merge_requests_counts' do
+ let(:user) do
+ double(
+ assigned_open_merge_requests_count: 1,
+ review_requested_open_merge_requests_count: 2
+ )
+ end
+
+ subject { helper.user_merge_requests_counts }
+
+ before do
+ allow(helper).to receive(:current_user).and_return(user)
+ end
+
+ it "returns assigned, review requested and total merge request counts" do
+ expect(subject).to eq(
+ assigned: user.assigned_open_merge_requests_count,
+ review_requested: user.review_requested_open_merge_requests_count,
+ total: user.assigned_open_merge_requests_count + user.review_requested_open_merge_requests_count
+ )
+ end
+
+ context 'when merge_request_reviewers is disabled' do
+ before do
+ stub_feature_flags(merge_request_reviewers: false)
+ end
+
+ it 'returns review_requested as 0' do
+ expect(subject[:review_requested]).to eq(0)
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/ci/charts_spec.rb b/spec/lib/gitlab/ci/charts_spec.rb
index c7869383dc4..cfc2019a89b 100644
--- a/spec/lib/gitlab/ci/charts_spec.rb
+++ b/spec/lib/gitlab/ci/charts_spec.rb
@@ -47,10 +47,6 @@ RSpec.describe Gitlab::Ci::Charts do
subject { chart.to }
- before do
- create(:ci_empty_pipeline, project: project, duration: 120)
- end
-
it 'includes the whole current day' do
is_expected.to eq(Date.today.end_of_day)
end
@@ -62,37 +58,6 @@ RSpec.describe Gitlab::Ci::Charts do
it 'uses %d %B as labels format' do
expect(chart.labels).to include(chart.from.strftime('%d %B'))
end
-
- it 'returns count of pipelines run each day in the current week' do
- expect(chart.total).to contain_exactly(0, 0, 0, 0, 0, 0, 0, 1)
- end
- end
-
- context 'weekchart_non_utc' do
- today = Date.today
- end_of_today = Time.use_zone(Time.find_zone('Asia/Dubai')) { today.end_of_day }
-
- let(:project) { create(:project) }
- let(:chart) do
- allow(Date).to receive(:today).and_return(today)
- allow(today).to receive(:end_of_day).and_return(end_of_today)
- Gitlab::Ci::Charts::WeekChart.new(project)
- end
-
- subject { chart.total }
-
- before do
- create(:ci_empty_pipeline, project: project, duration: 120)
- end
-
- it 'uses a non-utc time zone for range times' do
- expect(chart.to.zone).to eq(end_of_today.zone)
- expect(chart.from.zone).to eq(end_of_today.zone)
- end
-
- it 'returns count of pipelines run each day in the current week' do
- is_expected.to contain_exactly(0, 0, 0, 0, 0, 0, 0, 1)
- end
end
context 'pipeline_times' do
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index fb05c9e8052..3c5bc125011 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -4084,6 +4084,7 @@ RSpec.describe User do
cache_mock = double
expect(cache_mock).to receive(:delete).with(['users', user.id, 'assigned_open_merge_requests_count'])
+ expect(cache_mock).to receive(:delete).with(['users', user.id, 'review_requested_open_merge_requests_count'])
allow(Rails).to receive(:cache).and_return(cache_mock)
@@ -4163,6 +4164,20 @@ RSpec.describe User do
end
end
+ describe '#review_requested_open_merge_requests_count' do
+ it 'returns number of open merge requests from non-archived projects' do
+ user = create(:user)
+ project = create(:project, :public)
+ archived_project = create(:project, :public, :archived)
+
+ create(:merge_request, source_project: project, author: user, reviewers: [user])
+ create(:merge_request, :closed, source_project: project, author: user, reviewers: [user])
+ create(:merge_request, source_project: archived_project, author: user, reviewers: [user])
+
+ expect(user.review_requested_open_merge_requests_count(force: true)).to eq 1
+ end
+ end
+
describe '#assigned_open_issues_count' do
it 'returns number of open issues from non-archived projects' do
user = create(:user)
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index 7f6c47d675b..c21d3b0939f 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -401,40 +401,6 @@ RSpec.describe ProjectPolicy do
end
end
- describe 'bot_log_in' do
- let(:bot_user) { create(:user, :project_bot) }
- let(:project) { private_project }
-
- context 'when bot is in project and is not blocked' do
- before do
- project.add_maintainer(bot_user)
- end
-
- it 'is a valid project bot' do
- expect(bot_user.can?(:bot_log_in, project)).to be_truthy
- end
- end
-
- context 'when project bot is invalid' do
- context 'when bot is not in project' do
- it 'is not a valid project bot' do
- expect(bot_user.can?(:bot_log_in, project)).to be_falsy
- end
- end
-
- context 'when bot user is blocked' do
- before do
- project.add_maintainer(bot_user)
- bot_user.block!
- end
-
- it 'is not a valid project bot' do
- expect(bot_user.can?(:bot_log_in, project)).to be_falsy
- end
- end
- end
- end
-
context 'support bot' do
let(:current_user) { User.support_bot }
diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb
index be802c430ff..fdda1515cce 100644
--- a/spec/services/merge_requests/update_service_spec.rb
+++ b/spec/services/merge_requests/update_service_spec.rb
@@ -521,6 +521,19 @@ RSpec.describe MergeRequests::UpdateService, :mailer do
should_email(user2)
should_email(user3)
end
+
+ it 'updates open merge request counter for reviewers', :use_clean_rails_memory_store_caching do
+ merge_request.reviewers = [user3]
+
+ # Cache them to ensure the cache gets invalidated on update
+ expect(user2.review_requested_open_merge_requests_count).to eq(0)
+ expect(user3.review_requested_open_merge_requests_count).to eq(1)
+
+ update_merge_request(reviewer_ids: [user2.id])
+
+ expect(user2.review_requested_open_merge_requests_count).to eq(1)
+ expect(user3.review_requested_open_merge_requests_count).to eq(0)
+ end
end
context 'when the milestone is removed' do