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:
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.checksum2
-rw-r--r--Gemfile.lock4
-rw-r--r--app/assets/javascripts/design_management/components/design_notes/design_note.vue21
-rw-r--r--app/assets/javascripts/diffs/components/diff_content.vue2
-rw-r--r--app/assets/javascripts/emoji/components/picker.vue12
-rw-r--r--app/assets/javascripts/notes/components/note_actions.vue24
-rw-r--r--app/assets/javascripts/observability/components/skeleton/index.vue2
-rw-r--r--app/assets/javascripts/work_items/components/notes/work_item_note_actions.vue18
-rw-r--r--app/models/concerns/expirable.rb6
-rw-r--r--app/models/namespace.rb4
-rw-r--r--app/views/admin/runners/edit.html.haml3
-rw-r--r--app/views/profiles/two_factor_auths/show.html.haml3
-rw-r--r--app/views/shared/form_elements/_description.html.haml1
-rw-r--r--app/views/shared/integrations/gitlab_slack_application/_slack_button.html.haml4
-rw-r--r--app/views/shared/integrations/gitlab_slack_application/_slack_integration_form.html.haml13
-rw-r--r--app/views/shared/issue_type/_details_header.html.haml3
-rw-r--r--config/locales/en.yml5
-rw-r--r--config/metrics/counts_28d/20210216175132_i_code_review_user_create_mr_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210216181323_g_project_management_issue_created_monthly.yml2
-rw-r--r--config/metrics/counts_7d/20210216175130_i_code_review_user_create_mr_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210216181321_g_project_management_issue_created_weekly.yml2
-rw-r--r--config/metrics/schema.json3
-rw-r--r--doc/ci/pipelines/pipeline_architectures.md6
-rw-r--r--doc/development/internal_analytics/service_ping/metrics_dictionary.md2
-rw-r--r--doc/user/analytics/analytics_dashboards.md57
-rw-r--r--doc/user/analytics/index.md4
-rw-r--r--doc/user/img/objective_two_column_view_v16_2.pngbin0 -> 31451 bytes
-rw-r--r--doc/user/img/task_two_column_view_v16_2.pngbin0 -> 32287 bytes
-rw-r--r--doc/user/okrs.md15
-rw-r--r--doc/user/project/releases/index.md2
-rw-r--r--doc/user/tasks.md15
-rw-r--r--generator_templates/gitlab_internal_events/metric_definition.yml2
-rw-r--r--lib/gitlab/checks/file_size_check/allow_existing_oversized_blobs.rb38
-rw-r--r--lib/gitlab/checks/file_size_check/any_oversized_blobs.rb (renamed from lib/gitlab/checks/file_size_check/any_oversized_blob.rb)11
-rw-r--r--lib/gitlab/git/finders/refs_finder.rb40
-rw-r--r--lib/gitlab/usage/metrics/aggregates.rb6
-rw-r--r--locale/gitlab.pot39
-rw-r--r--spec/frontend/ci/pipeline_editor/components/commit/commit_section_spec.js21
-rw-r--r--spec/lib/generators/gitlab/analytics/internal_events_generator_spec.rb2
-rw-r--r--spec/lib/gitlab/checks/file_size_check/allow_existing_oversized_blobs_spec.rb86
-rw-r--r--spec/lib/gitlab/checks/file_size_check/any_oversized_blobs_spec.rb (renamed from spec/lib/gitlab/checks/file_size_check/any_oversized_blob_spec.rb)11
-rw-r--r--spec/lib/gitlab/git/finders/refs_finder_spec.rb62
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml1
-rw-r--r--spec/lib/gitlab/usage/metrics/aggregates/aggregate_spec.rb5
-rw-r--r--spec/lib/gitlab/usage_data_metrics_spec.rb6
-rw-r--r--spec/models/concerns/expirable_spec.rb2
47 files changed, 434 insertions, 139 deletions
diff --git a/Gemfile b/Gemfile
index faaa7c7a328..19dea298c2c 100644
--- a/Gemfile
+++ b/Gemfile
@@ -491,7 +491,7 @@ group :test do
# Moved in `test` because https://gitlab.com/gitlab-org/gitlab/-/issues/217527
gem 'derailed_benchmarks', require: false
- gem 'gitlab_quality-test_tooling', '~> 0.9.0', require: false
+ gem 'gitlab_quality-test_tooling', '~> 0.9.1', require: false
end
gem 'octokit', '~> 4.15'
diff --git a/Gemfile.checksum b/Gemfile.checksum
index d4b18852044..65a4045b5b9 100644
--- a/Gemfile.checksum
+++ b/Gemfile.checksum
@@ -218,7 +218,7 @@
{"name":"gitlab-styles","version":"10.1.0","platform":"ruby","checksum":"f42745f5397d042fe24cf2d0eb56c995b37f9f43d8fb79b834d197a1cafdc84a"},
{"name":"gitlab_chronic_duration","version":"0.10.6.2","platform":"ruby","checksum":"6dda4cfe7dca9b958f163ac8835c3d9cc70cf8df8cbb89bb2fbf9ba4375105fb"},
{"name":"gitlab_omniauth-ldap","version":"2.2.0","platform":"ruby","checksum":"bb4d20acb3b123ed654a8f6a47d3fac673ece7ed0b6992edb92dca14bad2838c"},
-{"name":"gitlab_quality-test_tooling","version":"0.9.0","platform":"ruby","checksum":"b61089778282fc52cb0f0437ee22dbc2ca4974e9312ffc5661c968de438a44e8"},
+{"name":"gitlab_quality-test_tooling","version":"0.9.1","platform":"ruby","checksum":"b69c661779f6cf44c336e5e8f73eb95a5b10988bb9158962af44a33a9a831fa2"},
{"name":"globalid","version":"1.1.0","platform":"ruby","checksum":"b337e1746f0c8cb0a6c918234b03a1ddeb4966206ce288fbb57779f59b2d154f"},
{"name":"gon","version":"6.4.0","platform":"ruby","checksum":"e3a618d659392890f1aa7db420f17c75fd7d35aeb5f8fe003697d02c4b88d2f0"},
{"name":"google-apis-androidpublisher_v3","version":"0.34.0","platform":"ruby","checksum":"d7e1d7dd92f79c498fe2082222a1740d788e022e660c135564b3fd299cab5425"},
diff --git a/Gemfile.lock b/Gemfile.lock
index 6193a196c86..75b7953edaf 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -675,7 +675,7 @@ GEM
omniauth (>= 1.3, < 3)
pyu-ruby-sasl (>= 0.0.3.3, < 0.1)
rubyntlm (~> 0.5)
- gitlab_quality-test_tooling (0.9.0)
+ gitlab_quality-test_tooling (0.9.1)
activesupport (>= 6.1, < 7.1)
gitlab (~> 4.19)
http (~> 5.0)
@@ -1826,7 +1826,7 @@ DEPENDENCIES
gitlab-utils!
gitlab_chronic_duration (~> 0.10.6.2)
gitlab_omniauth-ldap (~> 2.2.0)
- gitlab_quality-test_tooling (~> 0.9.0)
+ gitlab_quality-test_tooling (~> 0.9.1)
gon (~> 6.4.0)
google-apis-androidpublisher_v3 (~> 0.34.0)
google-apis-cloudbilling_v1 (~> 0.21.0)
diff --git a/app/assets/javascripts/design_management/components/design_notes/design_note.vue b/app/assets/javascripts/design_management/components/design_notes/design_note.vue
index d4982e39525..1f2c9f19a95 100644
--- a/app/assets/javascripts/design_management/components/design_notes/design_note.vue
+++ b/app/assets/javascripts/design_management/components/design_notes/design_note.vue
@@ -5,7 +5,6 @@ import {
GlButton,
GlDisclosureDropdown,
GlLink,
- GlIcon,
GlTooltipDirective,
} from '@gitlab/ui';
import * as Sentry from '@sentry/browser';
@@ -32,10 +31,9 @@ export default {
deleteCommentText: __('Delete comment'),
},
components: {
- EmojiPicker,
DesignNoteAwardsList,
DesignReplyForm,
- GlIcon,
+ EmojiPicker,
GlAvatar,
GlAvatarLink,
GlButton,
@@ -296,22 +294,7 @@ export default {
:right="false"
data-testid="note-emoji-button"
@click="handleAwardEmoji"
- >
- <template #button-content>
- <gl-icon
- class="award-control-icon-neutral gl-button-icon gl-icon"
- name="slight-smile"
- />
- <gl-icon
- class="award-control-icon-positive gl-button-icon gl-icon gl-left-3!"
- name="smiley"
- />
- <gl-icon
- class="award-control-icon-super-positive gl-button-icon gl-icon gl-left-3!"
- name="smile"
- />
- </template>
- </emoji-picker>
+ />
<gl-button
v-if="isEditingAndHasPermissions"
v-gl-tooltip
diff --git a/app/assets/javascripts/diffs/components/diff_content.vue b/app/assets/javascripts/diffs/components/diff_content.vue
index 64cabaf4367..1c93cb4d021 100644
--- a/app/assets/javascripts/diffs/components/diff_content.vue
+++ b/app/assets/javascripts/diffs/components/diff_content.vue
@@ -163,7 +163,7 @@ export default {
{{ __('Contains only whitespace changes.') }}
<gl-button
category="tertiary"
- variant="info"
+ variant="confirm"
size="small"
class="gl-ml-3"
data-testid="diff-load-file-button"
diff --git a/app/assets/javascripts/emoji/components/picker.vue b/app/assets/javascripts/emoji/components/picker.vue
index b6e86cc2a60..0e3dd9f7535 100644
--- a/app/assets/javascripts/emoji/components/picker.vue
+++ b/app/assets/javascripts/emoji/components/picker.vue
@@ -107,7 +107,17 @@ export default {
@hidden="$emit('hidden')"
>
<template #button-content>
- <slot name="button-content"></slot>
+ <slot name="button-content">
+ <gl-icon class="award-control-icon-neutral gl-button-icon gl-icon" name="slight-smile" />
+ <gl-icon
+ class="award-control-icon-positive gl-button-icon gl-icon gl-left-3!"
+ name="smiley"
+ />
+ <gl-icon
+ class="award-control-icon-super-positive gl-button-icon gl-icon gl-left-3!"
+ name="smile"
+ />
+ </slot>
<span class="gl-sr-only">{{ __('Add reaction') }}</span>
</template>
<gl-search-box-by-type
diff --git a/app/assets/javascripts/notes/components/note_actions.vue b/app/assets/javascripts/notes/components/note_actions.vue
index d17db6c6b4c..8d2d8095a44 100644
--- a/app/assets/javascripts/notes/components/note_actions.vue
+++ b/app/assets/javascripts/notes/components/note_actions.vue
@@ -1,7 +1,6 @@
<script>
import {
GlTooltipDirective,
- GlIcon,
GlButton,
GlDisclosureDropdown,
GlDisclosureDropdownItem,
@@ -30,15 +29,14 @@ export default {
},
name: 'NoteActions',
components: {
- GlIcon,
- ReplyButton,
- TimelineEventButton,
+ AbuseCategorySelector,
+ EmojiPicker: () => import('~/emoji/components/picker.vue'),
GlButton,
GlDisclosureDropdown,
GlDisclosureDropdownItem,
+ ReplyButton,
+ TimelineEventButton,
UserAccessRoleBadge,
- EmojiPicker: () => import('~/emoji/components/picker.vue'),
- AbuseCategorySelector,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -323,19 +321,7 @@ export default {
toggle-class="note-action-button note-emoji-button btn-icon btn-default-tertiary"
data-testid="note-emoji-button"
@click="setAwardEmoji"
- >
- <template #button-content>
- <gl-icon class="award-control-icon-neutral gl-button-icon gl-icon" name="slight-smile" />
- <gl-icon
- class="award-control-icon-positive gl-button-icon gl-icon gl-left-3!"
- name="smiley"
- />
- <gl-icon
- class="award-control-icon-super-positive gl-button-icon gl-icon gl-left-3!"
- name="smile"
- />
- </template>
- </emoji-picker>
+ />
<reply-button
v-if="showReply"
ref="replyButton"
diff --git a/app/assets/javascripts/observability/components/skeleton/index.vue b/app/assets/javascripts/observability/components/skeleton/index.vue
index ecf68d6488c..4df0f86be1f 100644
--- a/app/assets/javascripts/observability/components/skeleton/index.vue
+++ b/app/assets/javascripts/observability/components/skeleton/index.vue
@@ -143,7 +143,7 @@ export default {
<!-- The double condition is only here temporarily for back-compatibility reasons. Will be removed in next iteration https://gitlab.com/gitlab-org/opstrace/opstrace/-/issues/2275 -->
<div
- v-if="spinnerVariant && skeletonHidden"
+ v-else-if="spinnerVariant && skeletonHidden"
data-testid="content-wrapper"
class="gl-flex-grow-1 gl-display-flex gl-flex-direction-column gl-flex-align-items-stretch"
>
diff --git a/app/assets/javascripts/work_items/components/notes/work_item_note_actions.vue b/app/assets/javascripts/work_items/components/notes/work_item_note_actions.vue
index 427115695d6..e5da3d346ae 100644
--- a/app/assets/javascripts/work_items/components/notes/work_item_note_actions.vue
+++ b/app/assets/javascripts/work_items/components/notes/work_item_note_actions.vue
@@ -1,7 +1,6 @@
<script>
import {
GlButton,
- GlIcon,
GlTooltipDirective,
GlDisclosureDropdown,
GlDisclosureDropdownItem,
@@ -24,12 +23,11 @@ export default {
reportAbuseText: __('Report abuse to administrator'),
},
components: {
+ EmojiPicker: () => import('~/emoji/components/picker.vue'),
GlButton,
- GlIcon,
GlDisclosureDropdown,
GlDisclosureDropdownItem,
ReplyButton,
- EmojiPicker: () => import('~/emoji/components/picker.vue'),
UserAccessRoleBadge,
},
directives: {
@@ -201,19 +199,7 @@ export default {
toggle-class="note-action-button note-emoji-button btn-icon btn-default-tertiary"
data-testid="note-emoji-button"
@click="setAwardEmoji"
- >
- <template #button-content>
- <gl-icon class="award-control-icon-neutral gl-button-icon gl-icon" name="slight-smile" />
- <gl-icon
- class="award-control-icon-positive gl-button-icon gl-icon gl-left-3!"
- name="smiley"
- />
- <gl-icon
- class="award-control-icon-super-positive gl-button-icon gl-icon gl-left-3!"
- name="smile"
- />
- </template>
- </emoji-picker>
+ />
<reply-button v-if="showReply" ref="replyButton" @startReplying="$emit('startReplying')" />
<gl-button
v-if="showEdit"
diff --git a/app/models/concerns/expirable.rb b/app/models/concerns/expirable.rb
index cc55315d6d7..af139e735af 100644
--- a/app/models/concerns/expirable.rb
+++ b/app/models/concerns/expirable.rb
@@ -6,10 +6,8 @@ module Expirable
DAYS_TO_EXPIRE = 7
included do
- scope :not, ->(scope) { where(scope.arel.constraints.reduce(:and).not) }
-
- scope :expired, -> { where.not(expires_at: nil).where(arel_table[:expires_at].lteq(Time.current)) }
- scope :not_expired, -> { self.not(expired) }
+ scope :expired, -> { where(arel_table[:expires_at].lteq(Time.current)) }
+ scope :not_expired, -> { where(arel_table[:expires_at].gt(Time.current)).or(where(expires_at: nil)) }
end
def expired?
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 4561c1b82cc..5449f006a2e 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -424,6 +424,10 @@ class Namespace < ApplicationRecord
false
end
+ def all_project_ids
+ all_projects.pluck(:id)
+ end
+
def all_project_ids_except(ids)
all_projects.where.not(id: ids).pluck(:id)
end
diff --git a/app/views/admin/runners/edit.html.haml b/app/views/admin/runners/edit.html.haml
index 3d245722270..6ce094bacf1 100644
--- a/app/views/admin/runners/edit.html.haml
+++ b/app/views/admin/runners/edit.html.haml
@@ -39,7 +39,8 @@
.input-group
= search_field_tag :search, params[:search], class: 'form-control gl-form-input', spellcheck: false
.input-group-append
- = submit_tag _('Search'), class: 'gl-button btn btn-default'
+ = render Pajamas::ButtonComponent.new(type: 'submit', variant: :default) do
+ = _('Search')
%td
- @projects.each do |project|
diff --git a/app/views/profiles/two_factor_auths/show.html.haml b/app/views/profiles/two_factor_auths/show.html.haml
index bfd6b133a93..42297a0cf3d 100644
--- a/app/views/profiles/two_factor_auths/show.html.haml
+++ b/app/views/profiles/two_factor_auths/show.html.haml
@@ -55,7 +55,8 @@
= label_tag :pin_code, _('Enter verification code'), class: "label-bold"
= text_field_tag :pin_code, nil, autocomplete: 'off', inputmode: 'numeric', class: "form-control gl-form-input", required: true, data: { qa_selector: 'pin_code_field' }
.gl-mt-3
- = submit_tag _('Register with two-factor app'), class: 'gl-button btn btn-confirm', data: { qa_selector: 'register_2fa_app_button' }
+ = render Pajamas::ButtonComponent.new(type: :submit, variant: :confirm, button_options: { data: { qa_selector: 'register_2fa_app_button' } }) do
+ = _('Register with two-factor app')
%hr
diff --git a/app/views/shared/form_elements/_description.html.haml b/app/views/shared/form_elements/_description.html.haml
index 415849672b6..9c06efc9398 100644
--- a/app/views/shared/form_elements/_description.html.haml
+++ b/app/views/shared/form_elements/_description.html.haml
@@ -21,6 +21,7 @@
quick_actions_docs_path: help_page_path('user/project/quick_actions'),
qa_selector: 'issuable_form_description_field',
form_field_placeholder: placeholder,
+ autofocus: 'false',
form_field_classes: 'js-gfm-input markdown-area note-textarea rspec-issuable-form-description' } }
= form.hidden_field :description
diff --git a/app/views/shared/integrations/gitlab_slack_application/_slack_button.html.haml b/app/views/shared/integrations/gitlab_slack_application/_slack_button.html.haml
deleted file mode 100644
index 1ec669d5745..00000000000
--- a/app/views/shared/integrations/gitlab_slack_application/_slack_button.html.haml
+++ /dev/null
@@ -1,4 +0,0 @@
-= link_button_to add_to_slack_link(project, slack_app_id), class: 'gl-pr-6!' do
- = image_tag 'illustrations/slack_logo.svg', class: 'gl-icon gl-button-icon gl-w-9! gl-h-9! gl-my-n3! gl-mr-0!'
- %strong.gl-button-text
- = label
diff --git a/app/views/shared/integrations/gitlab_slack_application/_slack_integration_form.html.haml b/app/views/shared/integrations/gitlab_slack_application/_slack_integration_form.html.haml
index e6e7ec28807..e5d05a8a83d 100644
--- a/app/views/shared/integrations/gitlab_slack_application/_slack_integration_form.html.haml
+++ b/app/views/shared/integrations/gitlab_slack_application/_slack_integration_form.html.haml
@@ -20,13 +20,16 @@
%td{ class: 'gl-py-3!' }
= time_ago_with_tooltip(slack_integration.created_at)
%td{ class: 'gl-py-3!' }
- .controls
+ .controls.gl-display-flex.gl-gap-3
- project = integration.project
- = link_button_to _('Edit'), edit_project_settings_slack_path(project)
- = link_to sprite_icon('remove', css_class: 'gl-icon'), project_settings_slack_path(project), method: :delete, class: 'btn gl-button btn-danger btn-danger-secondary', aria: { label: s_('SlackIntegration|Remove project') }, data: { confirm_btn_variant: "danger", confirm: s_('SlackIntegration|Are you sure you want to remove this project from the GitLab for Slack app?') }
+ = render Pajamas::ButtonComponent.new(href: edit_project_settings_slack_path(project)) do
+ = _('Edit')
+ = render Pajamas::ButtonComponent.new(method: :delete, category: 'secondary', variant: "danger", href: project_settings_slack_path(project), icon: 'remove', button_options: { aria: { label: s_('SlackIntegration|Remove project') }, data: { confirm_btn_variant: "danger", confirm: s_('SlackIntegration|Are you sure you want to remove this project from the GitLab for Slack app?') }})
.gl-my-5
- = render 'shared/integrations/gitlab_slack_application/slack_button', project: @project, label: s_('SlackIntegration|Reinstall GitLab for Slack app')
+ = render Pajamas::ButtonComponent.new(href: add_to_slack_link(@project, slack_app_id)) do
+ = s_('SlackIntegration|Reinstall GitLab for Slack app…')
%p
= html_escape(s_('SlackIntegration|You may need to reinstall the GitLab for Slack app when we %{linkStart}make updates or change permissions%{linkEnd}.')) % { linkStart: %(<a href="#{help_page_path('user/project/integrations/gitlab_slack_application.md', anchor: 'update-the-gitlab-for-slack-app')}">).html_safe, linkEnd: '</a>'.html_safe}
- else
- = render 'shared/integrations/gitlab_slack_application/slack_button', project: @project, label: s_('SlackIntegration|Install GitLab for Slack app')
+ = render Pajamas::ButtonComponent.new(href: add_to_slack_link(@project, slack_app_id)) do
+ = s_('SlackIntegration|Install GitLab for Slack app…')
diff --git a/app/views/shared/issue_type/_details_header.html.haml b/app/views/shared/issue_type/_details_header.html.haml
index b6c0b73a83d..4997d429587 100644
--- a/app/views/shared/issue_type/_details_header.html.haml
+++ b/app/views/shared/issue_type/_details_header.html.haml
@@ -16,7 +16,6 @@
#js-issuable-header-warnings{ data: { hidden: issue_hidden?(issuable).to_s } }
= issuable_meta(issuable, @project)
- %a.btn.gl-button.btn-default.btn-icon.float-right.gl-display-block.d-sm-none.gutter-toggle.issuable-gutter-toggle.js-sidebar-toggle{ href: "#" }
- = sprite_icon('chevron-double-lg-left')
+ = render Pajamas::ButtonComponent.new(href: '#', icon: 'chevron-double-lg-left', button_options: { class: 'gl-float-right gl-display-block gl-sm-display-none! gutter-toggle issuable-gutter-toggle js-sidebar-toggle' })
.js-issue-header-actions{ data: issue_header_actions_data(@project, issuable, current_user, @issuable_sidebar) }
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 0d7110be68a..9f00439294c 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -39,6 +39,11 @@ en:
grafana_enabled: "Grafana integration enabled"
service_desk_setting:
project_key: "Project name suffix"
+ system_access/microsoft_application:
+ tenant_xid: "Tenant ID"
+ client_xid: "Client ID"
+ login_endpoint: "Login API endpoint"
+ graph_endpoint: "Graph API endpoint"
user/user_detail:
job_title: 'Job title'
bio: 'Bio'
diff --git a/config/metrics/counts_28d/20210216175132_i_code_review_user_create_mr_monthly.yml b/config/metrics/counts_28d/20210216175132_i_code_review_user_create_mr_monthly.yml
index fbcacf73dfc..400d7f2600d 100644
--- a/config/metrics/counts_28d/20210216175132_i_code_review_user_create_mr_monthly.yml
+++ b/config/metrics/counts_28d/20210216175132_i_code_review_user_create_mr_monthly.yml
@@ -8,7 +8,7 @@ product_group: code_review
value_type: number
status: active
time_frame: 28d
-data_source: redis_hll
+data_source: internal_events
instrumentation_class: RedisHLLMetric
options:
events:
diff --git a/config/metrics/counts_28d/20210216181323_g_project_management_issue_created_monthly.yml b/config/metrics/counts_28d/20210216181323_g_project_management_issue_created_monthly.yml
index cd5f4142e80..1171cf48812 100644
--- a/config/metrics/counts_28d/20210216181323_g_project_management_issue_created_monthly.yml
+++ b/config/metrics/counts_28d/20210216181323_g_project_management_issue_created_monthly.yml
@@ -8,7 +8,7 @@ product_group: project_management
value_type: number
status: active
time_frame: 28d
-data_source: redis_hll
+data_source: internal_events
instrumentation_class: RedisHLLMetric
options:
events:
diff --git a/config/metrics/counts_7d/20210216175130_i_code_review_user_create_mr_weekly.yml b/config/metrics/counts_7d/20210216175130_i_code_review_user_create_mr_weekly.yml
index 0159d8c6507..71a0be2fe13 100644
--- a/config/metrics/counts_7d/20210216175130_i_code_review_user_create_mr_weekly.yml
+++ b/config/metrics/counts_7d/20210216175130_i_code_review_user_create_mr_weekly.yml
@@ -8,7 +8,7 @@ product_group: code_review
value_type: number
status: active
time_frame: 7d
-data_source: redis_hll
+data_source: internal_events
instrumentation_class: RedisHLLMetric
options:
events:
diff --git a/config/metrics/counts_7d/20210216181321_g_project_management_issue_created_weekly.yml b/config/metrics/counts_7d/20210216181321_g_project_management_issue_created_weekly.yml
index ca0194db21b..97c32f8f7ae 100644
--- a/config/metrics/counts_7d/20210216181321_g_project_management_issue_created_weekly.yml
+++ b/config/metrics/counts_7d/20210216181321_g_project_management_issue_created_weekly.yml
@@ -8,7 +8,7 @@ product_group: project_management
value_type: number
status: active
time_frame: 7d
-data_source: redis_hll
+data_source: internal_events
instrumentation_class: RedisHLLMetric
options:
events:
diff --git a/config/metrics/schema.json b/config/metrics/schema.json
index 56fd617932c..90951f1b3dc 100644
--- a/config/metrics/schema.json
+++ b/config/metrics/schema.json
@@ -135,7 +135,8 @@
"redis_hll",
"prometheus",
"system",
- "license"
+ "license",
+ "internal_events"
]
},
"data_category": {
diff --git a/doc/ci/pipelines/pipeline_architectures.md b/doc/ci/pipelines/pipeline_architectures.md
index cdd00fd2412..ac4c8c1a731 100644
--- a/doc/ci/pipelines/pipeline_architectures.md
+++ b/doc/ci/pipelines/pipeline_architectures.md
@@ -13,7 +13,7 @@ some of the important concepts related to them.
You can structure your pipelines with different methods, each with their
own advantages. These methods can be mixed and matched if needed:
-- [Basic](#basic-pipelines): Good for straightforward projects where all the configuration is in one easy-to-find place.
+- [Basic](#basic-pipelines): Good for straightforward projects where all the configuration is in one place.
- [Directed Acyclic Graph](#directed-acyclic-graph-pipelines): Good for large, complex projects that need efficient execution.
- [Parent-child pipelines](#parent-child-pipelines): Good for monorepos and projects with lots of independently defined components.
@@ -31,9 +31,9 @@ own advantages. These methods can be mixed and matched if needed:
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
For an overview, see the [Multi-project pipelines demo](https://www.youtube.com/watch?v=g_PIwBM1J84).
-## Basic Pipelines
+## Basic pipelines
-This is the simplest pipeline in GitLab. It runs everything in the build stage concurrently,
+Basic pipelines are the simplest pipelines in GitLab. It runs everything in the build stage concurrently,
and once all of those finish, it runs everything in the test and subsequent stages the same way.
It's not the most efficient, and if you have lots of steps it can grow quite complex, but it's
easier to maintain:
diff --git a/doc/development/internal_analytics/service_ping/metrics_dictionary.md b/doc/development/internal_analytics/service_ping/metrics_dictionary.md
index 90a99d1ec56..f56955ed422 100644
--- a/doc/development/internal_analytics/service_ping/metrics_dictionary.md
+++ b/doc/development/internal_analytics/service_ping/metrics_dictionary.md
@@ -40,7 +40,7 @@ Each metric is defined in a separate YAML file consisting of a number of fields:
| `value_type` | yes | `string`; one of [`string`, `number`, `boolean`, `object`](https://json-schema.org/understanding-json-schema/reference/type.html). |
| `status` | yes | `string`; [status](#metric-statuses) of the metric, may be set to `active`, `removed`, `broken`. |
| `time_frame` | yes | `string`; may be set to a value like `7d`, `28d`, `all`, `none`. |
-| `data_source` | yes | `string`; may be set to a value like `database`, `redis`, `redis_hll`, `prometheus`, `system`, `license`. |
+| `data_source` | yes | `string`; may be set to a value like `database`, `redis`, `redis_hll`, `prometheus`, `system`, `license`, `internal_events`. |
| `data_category` | yes | `string`; [categories](#data-category) of the metric, may be set to `operational`, `optional`, `subscription`, `standard`. The default value is `optional`.|
| `instrumentation_class` | yes | `string`; [the class that implements the metric](metrics_instrumentation.md). |
| `distribution` | yes | `array`; may be set to one of `ce, ee` or `ee`. The [distribution](https://about.gitlab.com/handbook/marketing/brand-and-product-marketing/product-and-solution-marketing/tiers/#definitions) where the tracked feature is available. |
diff --git a/doc/user/analytics/analytics_dashboards.md b/doc/user/analytics/analytics_dashboards.md
index 55e32819ccc..9d2c91b6bc8 100644
--- a/doc/user/analytics/analytics_dashboards.md
+++ b/doc/user/analytics/analytics_dashboards.md
@@ -13,17 +13,10 @@ On self-managed GitLab, by default this feature is not available. To make it ava
On GitLab.com, this feature is not available.
This feature is not ready for production use.
-## Dashboards
+Analytics dashboards help you visualize the collected data.
+You can use built-in dashboards or create your own with custom visualizations.
-Each project can have an unlimited number of dashboards, only limited by the instances [repository size limits](../project/repository/reducing_the_repo_size_using_git.md#storage-limits).
-These dashboards are defined using the GitLab YAML schema, and stored in the `.gitlab/analytics/dashboards/` directory of a project repository.
-The dashboard file name and containing directory should be the same, for example `my_dashboard/my_dashboard.yaml`. For more information see [defining a dashboard](#define-a-dashboard).
-Each dashboard can reference one or more [visualizations](#define-a-chart-visualization), which are shared across dashboards.
-
-Project maintainers can enforce approval rules on dashboard changes using features such as [code owners](../project/codeowners/index.md) and [approval rules](../project/merge_requests/approvals/rules.md).
-Your dashboard files are versioned in source control with the rest of a project's code.
-
-### Data sources
+## Data sources
A data source is a connection to a database or collection of data which can be used by your dashboard
filters and visualizations to query and retrieve results.
@@ -32,7 +25,30 @@ The following data sources are configured for analytics dashboards:
- [Product analytics](../product_analytics/index.md)
-## Dashboards designer
+## Built-in dashboards
+
+To help you get started with analytics, GitLab provides two built-in dashboards with predefined visualizations:
+
+- **Audience**, which displays metrics related to traffic, such as number of users and sessions.
+- **Behavior**, which displays metrics related to user activity, such as number of page views and events.
+
+These dashboards are labeled **By GitLab**, and you cannot edit them.
+Instead, you can create a custom dashboard with a similar style.
+
+## Custom dashboards
+
+With custom dashboards, you can design and create visualizations for the metrics that are most relevant to your use case.
+You can create custom dashboards with the dashboard designer.
+
+- Each project can have an unlimited number of dashboards.
+The only limitation might be the [repository size limit](../project/repository/reducing_the_repo_size_using_git.md#storage-limits).
+- Each dashboard can reference one or more [visualizations](#define-a-chart-visualization).
+- Visualizations are shared across dashboards.
+
+Project maintainers can enforce approval rules on dashboard changes with features such as [code owners](../project/codeowners/index.md) and [approval rules](../project/merge_requests/approvals/rules.md).
+Your dashboard files are versioned in source control with the rest of a project's code.
+
+## Dashboard designer
> Introduced in GitLab 16.1 [with a flag](../../administration/feature_flags.md) named `combined_analytics_dashboards_editor`. Disabled by default.
@@ -44,19 +60,16 @@ This feature is not ready for production use.
NOTE:
This feature does not work in conjunction with the `product_analytics_snowplow_support` feature flag.
-You can use the dashboards designer to:
-
-- Create custom dashboards
-- Rename custom dashboards
-- Add visualizations to new and existing custom dashboards
-- Resize or move panels within custom dashboards
+You can use the dashboard designer to:
-You cannot edit the built-in dashboards labeled as `By GitLab`.
-To edit these dashboards you should create a new custom dashboard which uses the same visualizations.
+- Create custom dashboards.
+- Rename custom dashboards.
+- Add visualizations to new and existing custom dashboards.
+- Resize or move panels in custom dashboards.
## View project dashboards
-To view a list of dashboards for a project:
+To view a list of dashboards (both built-in and custom) for a project:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Analyze > Dashboards**.
@@ -166,7 +179,7 @@ To create a custom dashboard:
## Edit a custom dashboard
-You can edit your custom dashboard's title and add or resize visualizations within the dashboard designer.
+You can edit your custom dashboard's title and add or resize visualizations in the dashboard designer.
To edit an existing custom dashboard:
@@ -194,4 +207,4 @@ If a dashboard panel displays an error message:
- Check your [Cube query](../product_analytics/index.md#product-analytics-dashboards) and [visualization](../analytics/analytics_dashboards.md#define-a-chart-visualization)
configurations, and make sure they are set up correctly.
-- For [product analytics](../product_analytics/index.md), also check that your visualization's Cube query is valid.
+- For [product analytics](../product_analytics/index.md), also check that your visualization's Cube query is valid.
diff --git a/doc/user/analytics/index.md b/doc/user/analytics/index.md
index e78f55911e6..c057a8b193d 100644
--- a/doc/user/analytics/index.md
+++ b/doc/user/analytics/index.md
@@ -27,7 +27,7 @@ GitLab provides several analytics features at the group level. Some of these fea
- [Issue](../group/issues_analytics/index.md)
- [Productivity](productivity_analytics.md)
- [Repositories](../group/repositories_analytics/index.md)
-- [Value Stream](../group/value_stream_analytics/index.md)
+- [Value Stream Management Analytics](value_stream_analytics.md), and [Value Stream Management Dashboard](value_streams_dashboard.md)
## Project-level analytics
@@ -43,7 +43,7 @@ You can use GitLab to review analytics at the project level. Some of these featu
- [Merge Request](merge_request_analytics.md), enabled with the `project_merge_request_analytics`
[feature flag](../../development/feature_flags/index.md#enabling-a-feature-flag-locally-in-development)
- [Repository](repository_analytics.md)
-- [Value Stream](value_stream_analytics.md)
+- [Value Stream Management Analytics](value_stream_analytics.md), and [Value Stream Management Dashboard](value_streams_dashboard.md)
### Remove project analytics from the left sidebar
diff --git a/doc/user/img/objective_two_column_view_v16_2.png b/doc/user/img/objective_two_column_view_v16_2.png
new file mode 100644
index 00000000000..d3f4f733e7e
--- /dev/null
+++ b/doc/user/img/objective_two_column_view_v16_2.png
Binary files differ
diff --git a/doc/user/img/task_two_column_view_v16_2.png b/doc/user/img/task_two_column_view_v16_2.png
new file mode 100644
index 00000000000..8ca87f55f8a
--- /dev/null
+++ b/doc/user/img/task_two_column_view_v16_2.png
Binary files differ
diff --git a/doc/user/okrs.md b/doc/user/okrs.md
index c88edd6fc83..6579ecbadbc 100644
--- a/doc/user/okrs.md
+++ b/doc/user/okrs.md
@@ -353,3 +353,18 @@ Prerequisites:
By default, child OKRs are ordered by creation date.
To reorder them, drag them around.
+
+## Two-column layout
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/415077) in GitLab 16.2 [with a flag](../administration/feature_flags.md) named `work_items_mvc_2`. Disabled by default.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available, an administrator can [enable the feature flag](../administration/feature_flags.md) named `work_items_mvc_2`.
+On GitLab.com, this feature is not available.
+This feature is not ready for production use.
+
+When enabled, OKRs use a two-column layout, similar to issues.
+The description and threads are on the left, and attributes, such as labels
+or assignees, on the right.
+
+![OKR two column view](img/objective_two_column_view_v16_2.png)
diff --git a/doc/user/project/releases/index.md b/doc/user/project/releases/index.md
index 3030df8df41..40fb6969def 100644
--- a/doc/user/project/releases/index.md
+++ b/doc/user/project/releases/index.md
@@ -75,7 +75,7 @@ Prerequisites:
To create a release in the Releases page:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
-1. On the left sidebar, select **Build > Releases** and select **New release**.
+1. On the left sidebar, select **Deploy > Releases** and select **New release**.
1. From the [**Tag name**](release_fields.md#tag-name) dropdown list, either:
- Select an existing Git tag. Selecting an existing tag that is already associated with a release
results in a validation error.
diff --git a/doc/user/tasks.md b/doc/user/tasks.md
index 1487db1a399..ecd5ef0c42f 100644
--- a/doc/user/tasks.md
+++ b/doc/user/tasks.md
@@ -359,3 +359,18 @@ To copy the task's email address:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Plan > Issues**, then select your issue to view it.
1. In the top right corner, select the vertical ellipsis (**{ellipsis_v}**), then select **Copy task email address**.
+
+## Two-column layout
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/415077) in GitLab 16.2 [with a flag](../administration/feature_flags.md) named `work_items_mvc_2`. Disabled by default.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available, an administrator can [enable the feature flag](../administration/feature_flags.md) named `work_items_mvc_2`.
+On GitLab.com, this feature is not available.
+This feature is not ready for production use.
+
+When enabled, tasks use a two-column layout, similar to issues.
+The description and threads are on the left, and attributes, such as labels
+or assignees, on the right.
+
+![Task two column view](img/task_two_column_view_v16_2.png)
diff --git a/generator_templates/gitlab_internal_events/metric_definition.yml b/generator_templates/gitlab_internal_events/metric_definition.yml
index c0ff71a09ce..108db77d0d0 100644
--- a/generator_templates/gitlab_internal_events/metric_definition.yml
+++ b/generator_templates/gitlab_internal_events/metric_definition.yml
@@ -10,7 +10,7 @@ status: active
milestone: "<%= milestone %>"
introduced_by_url: <%= options.fetch(:mr) %>
time_frame: <%= args.third %>
-data_source: redis_hll
+data_source: internal_events
data_category: optional
instrumentation_class: <%= class_name %>
distribution: <%= distributions %>
diff --git a/lib/gitlab/checks/file_size_check/allow_existing_oversized_blobs.rb b/lib/gitlab/checks/file_size_check/allow_existing_oversized_blobs.rb
new file mode 100644
index 00000000000..78f1716274e
--- /dev/null
+++ b/lib/gitlab/checks/file_size_check/allow_existing_oversized_blobs.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Checks
+ module FileSizeCheck
+ class AllowExistingOversizedBlobs
+ def initialize(project:, changes:, file_size_limit_megabytes:)
+ @project = project
+ @changes = changes
+ @oldrevs = changes.pluck(:oldrev).compact # rubocop:disable CodeReuse/ActiveRecord just plucking from an array
+ @file_size_limit_megabytes = file_size_limit_megabytes
+ end
+
+ def find(timeout: nil)
+ oversize_blobs = any_oversize_blobs.find(timeout: timeout)
+
+ return oversize_blobs unless oldrevs.present?
+
+ revs_paths = oldrevs.product(oversize_blobs.map(&:path))
+ existing_blobs = project.repository.blobs_at(revs_paths, blob_size_limit: 1)
+ map_existing_path_to_size = existing_blobs.group_by(&:path).transform_values { |blobs| blobs.map(&:size).max }
+
+ # return blobs that are going to be over the limit that were previously within the limit
+ oversize_blobs.select { |blob| map_existing_path_to_size.fetch(blob.path, 0) <= file_size_limit_megabytes }
+ end
+
+ private
+
+ attr_reader :project, :changes, :newrevs, :oldrevs, :file_size_limit_megabytes
+
+ def any_oversize_blobs
+ AnyOversizedBlobs.new(project: project, changes: changes,
+ file_size_limit_megabytes: file_size_limit_megabytes)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/checks/file_size_check/any_oversized_blob.rb b/lib/gitlab/checks/file_size_check/any_oversized_blobs.rb
index dcdcd0e64ad..35f969dbb46 100644
--- a/lib/gitlab/checks/file_size_check/any_oversized_blob.rb
+++ b/lib/gitlab/checks/file_size_check/any_oversized_blobs.rb
@@ -3,21 +3,24 @@
module Gitlab
module Checks
module FileSizeCheck
- class AnyOversizedBlob
+ class AnyOversizedBlobs
def initialize(project:, changes:, file_size_limit_megabytes:)
@project = project
@newrevs = changes.pluck(:newrev).compact # rubocop:disable CodeReuse/ActiveRecord just plucking from an array
@file_size_limit_megabytes = file_size_limit_megabytes
end
- attr_reader :project, :newrevs, :file_size_limit_megabytes
- def find!(timeout: nil)
+ def find(timeout: nil)
blobs = project.repository.new_blobs(newrevs, dynamic_timeout: timeout)
- blobs.find do |blob|
+ blobs.select do |blob|
::Gitlab::Utils.bytes_to_megabytes(blob.size) > file_size_limit_megabytes
end
end
+
+ private
+
+ attr_reader :project, :newrevs, :file_size_limit_megabytes
end
end
end
diff --git a/lib/gitlab/git/finders/refs_finder.rb b/lib/gitlab/git/finders/refs_finder.rb
new file mode 100644
index 00000000000..a0117bc0fa9
--- /dev/null
+++ b/lib/gitlab/git/finders/refs_finder.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Git
+ module Finders
+ class RefsFinder
+ attr_reader :repository, :search, :ref_type
+
+ UnknownRefTypeError = Class.new(StandardError)
+
+ def initialize(repository, search:, ref_type:)
+ @repository = repository
+ @search = search
+ @ref_type = ref_type
+ end
+
+ def execute
+ pattern = [prefix, search, "*"].compact.join
+
+ repository.list_refs(
+ [pattern]
+ )
+ end
+
+ private
+
+ def prefix
+ case ref_type
+ when :branches
+ Gitlab::Git::BRANCH_REF_PREFIX
+ when :tags
+ Gitlab::Git::TAG_REF_PREFIX
+ else
+ raise UnknownRefTypeError, "ref_type must be one of [:branches, :tags]"
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/usage/metrics/aggregates.rb b/lib/gitlab/usage/metrics/aggregates.rb
index 4b38809dde4..0edd9f7914a 100644
--- a/lib/gitlab/usage/metrics/aggregates.rb
+++ b/lib/gitlab/usage/metrics/aggregates.rb
@@ -15,10 +15,14 @@ module Gitlab
DATABASE_SOURCE = 'database'
REDIS_SOURCE = 'redis_hll'
+ INTERNAL_EVENTS_SOURCE = 'internal_events'
SOURCES = {
DATABASE_SOURCE => Sources::PostgresHll,
- REDIS_SOURCE => Sources::RedisHll
+ REDIS_SOURCE => Sources::RedisHll,
+ # Same strategy as RedisHLL, since they are a part of internal events
+ # and should get counted together with other RedisHLL-based aggregations
+ INTERNAL_EVENTS_SOURCE => Sources::RedisHll
}.freeze
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index ca22bcb59fb..abca9f4db05 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -29170,6 +29170,39 @@ msgstr ""
msgid "Mi"
msgstr ""
+msgid "Microsoft|Client ID"
+msgstr ""
+
+msgid "Microsoft|Client secret"
+msgstr ""
+
+msgid "Microsoft|Enable Microsoft Azure integration for this group"
+msgstr ""
+
+msgid "Microsoft|Graph API endpoint"
+msgstr ""
+
+msgid "Microsoft|Login API endpoint"
+msgstr ""
+
+msgid "Microsoft|Microsoft Azure Integration"
+msgstr ""
+
+msgid "Microsoft|Microsoft Azure integration settings failed to save. %{errors}"
+msgstr ""
+
+msgid "Microsoft|Microsoft Azure integration settings were successfully updated."
+msgstr ""
+
+msgid "Microsoft|Tenant ID"
+msgstr ""
+
+msgid "Microsoft|Use the default value, unless you're using Azure AD for US Government or Azure AD China operated by 22Vianet."
+msgstr ""
+
+msgid "Microsoft|Use the default value, unless you're using using Microsoft Graph for US Government or Microsoft Graph China operated by 22Vianet."
+msgstr ""
+
msgid "Migrated %{success_count}/%{total_count} files."
msgstr ""
@@ -43348,7 +43381,7 @@ msgstr ""
msgid "SlackIntegration|GitLab slash commands"
msgstr ""
-msgid "SlackIntegration|Install GitLab for Slack app"
+msgid "SlackIntegration|Install GitLab for Slack app…"
msgstr ""
msgid "SlackIntegration|Interact with GitLab without leaving your Slack workspace!"
@@ -43360,7 +43393,7 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
-msgid "SlackIntegration|Reinstall GitLab for Slack app"
+msgid "SlackIntegration|Reinstall GitLab for Slack app…"
msgstr ""
msgid "SlackIntegration|Remove project"
@@ -49346,7 +49379,7 @@ msgstr ""
msgid "UsageQuotas|An error occurred loading the transfer data. Please refresh the page to try again."
msgstr ""
-msgid "UsageQuotas|Container Registry storage statistics are not used to calculate the total project storage. After namespace container deduplication, the total of all unique containers is added to the namespace storage total."
+msgid "UsageQuotas|Container Registry storage statistics are not used to calculate the total project storage. Total project storage is calculated after namespace container deduplication, where the total of all unique containers is added to the namespace storage total."
msgstr ""
msgid "UsageQuotas|Namespace transfer data used"
diff --git a/spec/frontend/ci/pipeline_editor/components/commit/commit_section_spec.js b/spec/frontend/ci/pipeline_editor/components/commit/commit_section_spec.js
index 8834231aaef..7a9b4ffdce8 100644
--- a/spec/frontend/ci/pipeline_editor/components/commit/commit_section_spec.js
+++ b/spec/frontend/ci/pipeline_editor/components/commit/commit_section_spec.js
@@ -17,7 +17,8 @@ import {
import { resolvers } from '~/ci/pipeline_editor/graphql/resolvers';
import commitCreate from '~/ci/pipeline_editor/graphql/mutations/commit_ci_file.mutation.graphql';
import getCurrentBranch from '~/ci/pipeline_editor/graphql/queries/client/current_branch.query.graphql';
-import updatePipelineEtag from '~/ci/pipeline_editor/graphql/mutations/client/update_pipeline_etag.mutation.graphql';
+import getPipelineEtag from '~/ci/pipeline_editor/graphql/queries/client/pipeline_etag.query.graphql';
+
import {
mockCiConfigPath,
mockCiYml,
@@ -253,18 +254,20 @@ describe('Pipeline Editor | Commit section', () => {
describe('when the commit returns a different etag path', () => {
beforeEach(async () => {
createComponentWithApollo();
- jest.spyOn(wrapper.vm.$apollo, 'mutate');
+ jest.spyOn(mockApollo.clients.defaultClient.cache, 'writeQuery');
+
mockMutateCommitData.mockResolvedValue(mockCommitCreateResponseNewEtag);
await submitCommit();
});
- it('calls the client mutation to update the etag', () => {
- // 1:Commit submission, 2:etag update, 3:currentBranch update, 4:lastCommit update
- expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledTimes(4);
- expect(wrapper.vm.$apollo.mutate).toHaveBeenNthCalledWith(2, {
- mutation: updatePipelineEtag,
- variables: {
- pipelineEtag: mockCommitCreateResponseNewEtag.data.commitCreate.commitPipelinePath,
+ it('calls the client mutation to update the etag in the cache', () => {
+ expect(mockApollo.clients.defaultClient.cache.writeQuery).toHaveBeenCalledWith({
+ query: getPipelineEtag,
+ data: {
+ etags: {
+ __typename: 'EtagValues',
+ pipeline: mockCommitCreateResponseNewEtag.data.commitCreate.commitPipelinePath,
+ },
},
});
});
diff --git a/spec/lib/generators/gitlab/analytics/internal_events_generator_spec.rb b/spec/lib/generators/gitlab/analytics/internal_events_generator_spec.rb
index a97695af398..336226c48a1 100644
--- a/spec/lib/generators/gitlab/analytics/internal_events_generator_spec.rb
+++ b/spec/lib/generators/gitlab/analytics/internal_events_generator_spec.rb
@@ -46,7 +46,7 @@ RSpec.describe Gitlab::Analytics::InternalEventsGenerator, :silence_stdout, feat
"milestone" => "13.9",
"introduced_by_url" => mr,
"time_frame" => "7d",
- "data_source" => "redis_hll",
+ "data_source" => "internal_events",
"data_category" => "optional",
"instrumentation_class" => "RedisHLLMetric",
"distribution" => %w[ce ee],
diff --git a/spec/lib/gitlab/checks/file_size_check/allow_existing_oversized_blobs_spec.rb b/spec/lib/gitlab/checks/file_size_check/allow_existing_oversized_blobs_spec.rb
new file mode 100644
index 00000000000..3b52d2e1364
--- /dev/null
+++ b/spec/lib/gitlab/checks/file_size_check/allow_existing_oversized_blobs_spec.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Checks::FileSizeCheck::AllowExistingOversizedBlobs, feature_category: :source_code_management do
+ subject { checker.find }
+
+ let_it_be(:project) { create(:project, :public, :repository) }
+ let(:checker) do
+ described_class.new(
+ project: project,
+ changes: changes,
+ file_size_limit_megabytes: 1)
+ end
+
+ describe '#find' do
+ let(:branch_name) { SecureRandom.uuid }
+ let(:other_branch_name) { SecureRandom.uuid }
+ let(:filename) { 'log.log' }
+ let(:create_file) do
+ project.repository.create_file(
+ project.owner,
+ filename,
+ initial_contents,
+ branch_name: branch_name,
+ message: 'whatever'
+ )
+ end
+
+ let(:changed_ref) do
+ project.repository.update_file(
+ project.owner,
+ filename,
+ changed_contents,
+ branch_name: other_branch_name,
+ start_branch_name: branch_name,
+ message: 'whatever'
+ )
+ end
+
+ let(:changes) { [oldrev: create_file, newrev: changed_ref] }
+
+ before do
+ # set up a branch
+ create_file
+
+ # branch off that branch
+ changed_ref
+
+ # delete stuff so it can be picked up by new_blobs
+ project.repository.delete_branch(other_branch_name)
+ end
+
+ context 'when changing from valid to oversized' do
+ let(:initial_contents) { 'a' }
+ let(:changed_contents) { 'a' * ((2**20) + 1) } # 1 MB + 1 byte
+
+ it 'returns an array with blobs that became oversized' do
+ blob = subject.first
+ expect(blob.path).to eq(filename)
+ expect(subject).to contain_exactly(blob)
+ end
+ end
+
+ context 'when changing from oversized to oversized' do
+ let(:initial_contents) { 'a' * ((2**20) + 1) } # 1 MB + 1 byte
+ let(:changed_contents) { 'a' * ((2**20) + 2) } # 1 MB + 1 byte
+
+ it { is_expected.to be_blank }
+ end
+
+ context 'when changing from oversized to valid' do
+ let(:initial_contents) { 'a' * ((2**20) + 1) } # 1 MB + 1 byte
+ let(:changed_contents) { 'aa' }
+
+ it { is_expected.to be_blank }
+ end
+
+ context 'when changing from valid to valid' do
+ let(:initial_contents) { 'abc' }
+ let(:changed_contents) { 'def' }
+
+ it { is_expected.to be_blank }
+ end
+ end
+end
diff --git a/spec/lib/gitlab/checks/file_size_check/any_oversized_blob_spec.rb b/spec/lib/gitlab/checks/file_size_check/any_oversized_blobs_spec.rb
index bf24d6b63c6..7c786c2ba24 100644
--- a/spec/lib/gitlab/checks/file_size_check/any_oversized_blob_spec.rb
+++ b/spec/lib/gitlab/checks/file_size_check/any_oversized_blobs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Checks::FileSizeCheck::AnyOversizedBlob, feature_category: :source_code_management do
+RSpec.describe Gitlab::Checks::FileSizeCheck::AnyOversizedBlobs, feature_category: :source_code_management do
let_it_be(:project) { create(:project, :public, :repository) }
let(:any_blob) do
described_class.new(
@@ -11,8 +11,8 @@ RSpec.describe Gitlab::Checks::FileSizeCheck::AnyOversizedBlob, feature_category
file_size_limit_megabytes: 1)
end
- describe '#find!' do
- subject { any_blob.find! }
+ describe '#find' do
+ subject { any_blob.find }
# SHA of the 2-mb-file branch
let(:newrev) { 'bf12d2567099e26f59692896f73ac819bae45b00' }
@@ -24,9 +24,8 @@ RSpec.describe Gitlab::Checks::FileSizeCheck::AnyOversizedBlob, feature_category
end
it 'returns the blob exceeding the file size limit' do
- blob = subject
- expect(blob).to be_kind_of(Gitlab::Git::Blob)
- expect(blob.path).to eq('file.bin')
+ expect(subject).to contain_exactly(kind_of(Gitlab::Git::Blob))
+ expect(subject[0].path).to eq('file.bin')
end
end
end
diff --git a/spec/lib/gitlab/git/finders/refs_finder_spec.rb b/spec/lib/gitlab/git/finders/refs_finder_spec.rb
new file mode 100644
index 00000000000..63d794d1e59
--- /dev/null
+++ b/spec/lib/gitlab/git/finders/refs_finder_spec.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe Gitlab::Git::Finders::RefsFinder, feature_category: :source_code_management do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :repository) }
+
+ let(:repository) { project.repository }
+ let(:finder) { described_class.new(repository, **params) }
+ let(:params) { {} }
+
+ describe "#execute" do
+ subject { finder.execute }
+
+ context "when :ref_type is :branches" do
+ let(:params) do
+ { search: "mast", ref_type: :branches }
+ end
+
+ it { is_expected.to be_an(Array) }
+
+ it "returns matching ref object" do
+ expect(subject.length).to eq(1)
+
+ ref = subject.first
+
+ expect(ref).to be_a(Gitaly::ListRefsResponse::Reference)
+ expect(ref.name).to eq("refs/heads/master")
+ expect(ref.target).to be_a(String)
+ end
+ end
+
+ context "when :ref_type is :tags" do
+ let(:params) do
+ { search: "v1.0.", ref_type: :tags }
+ end
+
+ it { is_expected.to be_an(Array) }
+
+ it "returns matching ref object" do
+ expect(subject.length).to eq(1)
+
+ ref = subject.first
+
+ expect(ref).to be_a(Gitaly::ListRefsResponse::Reference)
+ expect(ref.name).to eq("refs/tags/v1.0.0")
+ expect(ref.target).to be_a(String)
+ end
+ end
+
+ context "when :ref_type is invalid" do
+ let(:params) do
+ { search: "master", ref_type: nil }
+ end
+
+ it "raises an error" do
+ expect { subject }.to raise_error(described_class::UnknownRefTypeError)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index aa7d4b84fb5..981802ad09d 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -816,6 +816,7 @@ project:
- compliance_standards_adherence
- scan_result_policy_reads
- project_state
+- security_policy_bots
award_emoji:
- awardable
- user
diff --git a/spec/lib/gitlab/usage/metrics/aggregates/aggregate_spec.rb b/spec/lib/gitlab/usage/metrics/aggregates/aggregate_spec.rb
index 8be0769a379..c3060cd4927 100644
--- a/spec/lib/gitlab/usage/metrics/aggregates/aggregate_spec.rb
+++ b/spec/lib/gitlab/usage/metrics/aggregates/aggregate_spec.rb
@@ -28,6 +28,10 @@ RSpec.describe Gitlab::Usage::Metrics::Aggregates::Aggregate, :clean_gitlab_redi
7 | 'OR' | 'redis_hll' | :calculate_metrics_union
28 | 'OR' | 'database' | :calculate_metrics_union
7 | 'OR' | 'database' | :calculate_metrics_union
+ 28 | 'AND' | 'internal_events' | :calculate_metrics_intersections
+ 7 | 'AND' | 'internal_events' | :calculate_metrics_intersections
+ 28 | 'OR' | 'internal_events' | :calculate_metrics_union
+ 7 | 'OR' | 'internal_events' | :calculate_metrics_union
end
with_them do
@@ -152,6 +156,7 @@ RSpec.describe Gitlab::Usage::Metrics::Aggregates::Aggregate, :clean_gitlab_redi
where(:time_frame, :operator, :datasource) do
'28d' | 'OR' | 'redis_hll'
'7d' | 'OR' | 'database'
+ '28d' | 'OR' | 'internal_events'
end
with_them do
diff --git a/spec/lib/gitlab/usage_data_metrics_spec.rb b/spec/lib/gitlab/usage_data_metrics_spec.rb
index e8881e986eb..34e62523d45 100644
--- a/spec/lib/gitlab/usage_data_metrics_spec.rb
+++ b/spec/lib/gitlab/usage_data_metrics_spec.rb
@@ -62,7 +62,11 @@ RSpec.describe Gitlab::UsageDataMetrics, :with_license, feature_category: :servi
let(:metric_files_key_paths) do
Gitlab::Usage::MetricDefinition
.definitions
- .select { |k, v| v.attributes[:data_source] == 'redis_hll' && v.key_path.starts_with?('redis_hll_counters') && v.available? }
+ .select do |_, v|
+ (v.data_source == 'redis_hll' || v.data_source == 'internal_events') &&
+ v.key_path.starts_with?('redis_hll_counters') &&
+ v.available?
+ end
.keys
.sort
end
diff --git a/spec/models/concerns/expirable_spec.rb b/spec/models/concerns/expirable_spec.rb
index 68a25917ce1..78fe265a6bb 100644
--- a/spec/models/concerns/expirable_spec.rb
+++ b/spec/models/concerns/expirable_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe Expirable do
end
describe '.expired' do
- it { expect(ProjectMember.expired).to match_array([expired]) }
+ it { expect(ProjectMember.expired).to contain_exactly(expired) }
it 'scopes the query when multiple models are expirable' do
expired_access_token = create(:personal_access_token, :expired, user: no_expire.user)