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--GITALY_SERVER_VERSION2
-rw-r--r--GITLAB_PAGES_VERSION2
-rw-r--r--app/assets/javascripts/related_issues/components/related_issues_block.vue1
-rw-r--r--app/assets/javascripts/related_issues/components/related_issues_list.vue7
-rw-r--r--app/models/analytics/cycle_analytics/aggregation.rb10
-rw-r--r--app/views/layouts/_head.html.haml2
-rw-r--r--app/views/layouts/header/_translations.html.haml1
-rw-r--r--app/views/projects/_last_push.html.haml8
-rw-r--r--config/feature_flags/development/geo_token_user_authentication.yml4
-rw-r--r--config/feature_flags/development/spread_parallel_import.yml2
-rw-r--r--config/feature_flags/development/verify_protected_tags_for_pull_mirror.yml2
-rw-r--r--doc/ci/yaml/index.md4
-rw-r--r--doc/user/group/epics/img/related_epic_block_v14_9.pngbin0 -> 31319 bytes
-rw-r--r--doc/user/group/epics/img/related_epics_add_v14_9.pngbin0 -> 27785 bytes
-rw-r--r--doc/user/group/epics/img/related_epics_remove_v14_9.pngbin0 -> 5034 bytes
-rw-r--r--doc/user/group/epics/index.md1
-rw-r--r--doc/user/group/epics/linked_epics.md79
-rw-r--r--doc/user/project/merge_requests/commit_templates.md2
-rw-r--r--lib/gitlab/analytics/cycle_analytics/request_params.rb13
-rw-r--r--lib/gitlab/merge_requests/commit_message_generator.rb13
-rw-r--r--spec/frontend/issuable/related_issues/components/related_issues_list_spec.js5
-rw-r--r--spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb88
-rw-r--r--spec/models/analytics/cycle_analytics/aggregation_spec.rb19
-rw-r--r--spec/services/projects/branches_by_mode_service_spec.rb26
-rw-r--r--spec/support/helpers/test_env.rb3
25 files changed, 257 insertions, 37 deletions
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 86c60401bdf..804e2152697 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-3e152f5c73c61d6d0a17a5103077de4b049f233d
+d0d5fa790767c12eeadb40a1ecfbc00fde2a4768
diff --git a/GITLAB_PAGES_VERSION b/GITLAB_PAGES_VERSION
index 094d6ad00ce..3ebf789f5a8 100644
--- a/GITLAB_PAGES_VERSION
+++ b/GITLAB_PAGES_VERSION
@@ -1 +1 @@
-1.55.0
+1.56.0
diff --git a/app/assets/javascripts/related_issues/components/related_issues_block.vue b/app/assets/javascripts/related_issues/components/related_issues_block.vue
index bc97fab9ad2..d9184973304 100644
--- a/app/assets/javascripts/related_issues/components/related_issues_block.vue
+++ b/app/assets/javascripts/related_issues/components/related_issues_block.vue
@@ -210,6 +210,7 @@ export default {
<related-issues-list
v-for="category in categorisedIssues"
:key="category.linkType"
+ :list-link-type="category.linkType"
:heading="$options.linkedIssueTypesTextMap[category.linkType]"
:can-admin="canAdmin"
:can-reorder="canReorder"
diff --git a/app/assets/javascripts/related_issues/components/related_issues_list.vue b/app/assets/javascripts/related_issues/components/related_issues_list.vue
index 8b39851405e..174049b15fe 100644
--- a/app/assets/javascripts/related_issues/components/related_issues_list.vue
+++ b/app/assets/javascripts/related_issues/components/related_issues_list.vue
@@ -21,6 +21,11 @@ export default {
required: false,
default: false,
},
+ listLinkType: {
+ type: String,
+ required: false,
+ default: '',
+ },
heading: {
type: String,
required: false,
@@ -91,7 +96,7 @@ export default {
</script>
<template>
- <div>
+ <div :data-link-type="listLinkType">
<h4 v-if="heading" class="gl-font-base mt-0">{{ heading }}</h4>
<div
class="related-issues-token-body bordered-box bg-white"
diff --git a/app/models/analytics/cycle_analytics/aggregation.rb b/app/models/analytics/cycle_analytics/aggregation.rb
index d43293f40ea..279938511fd 100644
--- a/app/models/analytics/cycle_analytics/aggregation.rb
+++ b/app/models/analytics/cycle_analytics/aggregation.rb
@@ -14,7 +14,10 @@ class Analytics::CycleAnalytics::Aggregation < ApplicationRecord
return unless enabled
return if last_incremental_run_at.nil?
- estimation = (last_incremental_run_at - earliest_last_run_at) + average_aggregation_duration
+ estimation = duration_until_the_next_aggregation_job +
+ average_aggregation_duration +
+ (last_incremental_run_at - earliest_last_run_at)
+
estimation < 1 ? nil : estimation.from_now
end
@@ -29,6 +32,11 @@ class Analytics::CycleAnalytics::Aggregation < ApplicationRecord
private
+ # The aggregation job is scheduled every 10 minutes: */10 * * * *
+ def duration_until_the_next_aggregation_job
+ (10 - (DateTime.current.minute % 10)).minutes.seconds
+ end
+
def average_aggregation_duration
return 0.seconds if incremental_runtimes_in_seconds.empty?
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index a5e44ff8669..15cd9bece71 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -57,7 +57,7 @@
= Gon::Base.render_data(nonce: content_security_policy_nonce)
- = javascript_include_tag locale_path unless I18n.locale == :en
+ = render_if_exists 'layouts/header/translations'
= webpack_bundle_tag "sentry" if Gitlab.config.sentry.enabled
= webpack_bundle_tag 'performance_bar' if performance_bar_enabled?
diff --git a/app/views/layouts/header/_translations.html.haml b/app/views/layouts/header/_translations.html.haml
new file mode 100644
index 00000000000..979f39ad3e0
--- /dev/null
+++ b/app/views/layouts/header/_translations.html.haml
@@ -0,0 +1 @@
+= javascript_include_tag locale_path unless I18n.locale == :en
diff --git a/app/views/projects/_last_push.html.haml b/app/views/projects/_last_push.html.haml
index 9ba7d25b662..88cce9e71c0 100644
--- a/app/views/projects/_last_push.html.haml
+++ b/app/views/projects/_last_push.html.haml
@@ -1,9 +1,9 @@
- event = last_push_event
- if event && show_last_push_widget?(event)
- .gl-alert.gl-alert-success.mt-2{ role: 'alert' }
- = sprite_icon('check-circle', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- %button.js-close-banner.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss') }
- = sprite_icon('close', size: 16, css_class: 'gl-icon')
+ = render 'shared/global_alert',
+ variant: :success,
+ alert_class: 'gl-mt-3',
+ close_button_class: 'js-close-banner' do
.gl-alert-body
%span= s_("LastPushEvent|You pushed to")
%strong.gl-display-inline-flex.gl-max-w-50p{ data: { toggle: 'tooltip' }, title: event.ref_name }
diff --git a/config/feature_flags/development/geo_token_user_authentication.yml b/config/feature_flags/development/geo_token_user_authentication.yml
index 779e9b92351..aab95c93312 100644
--- a/config/feature_flags/development/geo_token_user_authentication.yml
+++ b/config/feature_flags/development/geo_token_user_authentication.yml
@@ -1,8 +1,8 @@
---
name: geo_token_user_authentication
-introduced_by_url:
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79431
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/351450
milestone: '14.8'
type: development
group: group::geo
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/spread_parallel_import.yml b/config/feature_flags/development/spread_parallel_import.yml
index e47a4c1e676..1e75502e032 100644
--- a/config/feature_flags/development/spread_parallel_import.yml
+++ b/config/feature_flags/development/spread_parallel_import.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353217
milestone: '14.9'
type: development
group: group::source code
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/verify_protected_tags_for_pull_mirror.yml b/config/feature_flags/development/verify_protected_tags_for_pull_mirror.yml
index df827808921..44da565181f 100644
--- a/config/feature_flags/development/verify_protected_tags_for_pull_mirror.yml
+++ b/config/feature_flags/development/verify_protected_tags_for_pull_mirror.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/352494
milestone: '14.9'
type: development
group: group::source code
-default_enabled: false
+default_enabled: true
diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md
index 85692d08c07..5143a9ee4de 100644
--- a/doc/ci/yaml/index.md
+++ b/doc/ci/yaml/index.md
@@ -135,7 +135,9 @@ The `include` files are:
- Always evaluated first and then merged with the content of the `.gitlab-ci.yml` file,
regardless of the position of the `include` keyword.
-You can [nest](includes.md#use-nested-includes) up to 100 includes, but you can't have duplicate includes.
+You can [nest](includes.md#use-nested-includes) up to 100 includes. In [GitLab 14.9 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/28987),
+the same file can be included multiple times in nested includes, but duplicates are ignored.
+
In [GitLab 12.4 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/28212),
the time limit to resolve all files is 30 seconds.
diff --git a/doc/user/group/epics/img/related_epic_block_v14_9.png b/doc/user/group/epics/img/related_epic_block_v14_9.png
new file mode 100644
index 00000000000..7b5824b84d1
--- /dev/null
+++ b/doc/user/group/epics/img/related_epic_block_v14_9.png
Binary files differ
diff --git a/doc/user/group/epics/img/related_epics_add_v14_9.png b/doc/user/group/epics/img/related_epics_add_v14_9.png
new file mode 100644
index 00000000000..3da6eeaff43
--- /dev/null
+++ b/doc/user/group/epics/img/related_epics_add_v14_9.png
Binary files differ
diff --git a/doc/user/group/epics/img/related_epics_remove_v14_9.png b/doc/user/group/epics/img/related_epics_remove_v14_9.png
new file mode 100644
index 00000000000..2cdded5965f
--- /dev/null
+++ b/doc/user/group/epics/img/related_epics_remove_v14_9.png
Binary files differ
diff --git a/doc/user/group/epics/index.md b/doc/user/group/epics/index.md
index d6f87a026b8..149c5362ac9 100644
--- a/doc/user/group/epics/index.md
+++ b/doc/user/group/epics/index.md
@@ -62,6 +62,7 @@ You can also consult the [group permissions table](../../permissions.md#group-me
## Related topics
- [Manage epics](manage_epics.md) and multi-level child epics.
+- Link [related epics](linked_epics.md) based on a type of relationship.
- Create workflows with [epic boards](epic_boards.md).
- [Turn on notifications](../../profile/notifications.md) for about epic events.
- [Award an emoji](../../award_emojis.md) to an epic or its comments.
diff --git a/doc/user/group/epics/linked_epics.md b/doc/user/group/epics/linked_epics.md
new file mode 100644
index 00000000000..d9cf61421e0
--- /dev/null
+++ b/doc/user/group/epics/linked_epics.md
@@ -0,0 +1,79 @@
+---
+stage: Plan
+group: Product Planning
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Linked epics **(ULTIMATE)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/353473) in GitLab 14.9 [with a flag](../../../administration/feature_flags.md) named `related_epics_widget`. Disabled by default.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available,
+ask an administrator to [enable the feature flag](../../../administration/feature_flags.md)
+named `related_epics_widget`. On GitLab.com, this feature is not available.
+
+Linked epics are a bi-directional relationship between any two epics and appear in a block below
+the epic description. You can link epics in different groups.
+
+The relationship only shows up in the UI if the user can see both epics. When you try to close an
+epic that has open blockers, a warning is displayed.
+
+NOTE:
+To manage linked epics through our API, visit the [epic links API documentation](../../../api/linked_epics.md).
+
+## Add a linked epic
+
+Prerequisites:
+
+- You must have at least the Reporter role for both groups.
+- For GitLab SaaS: the epic that you're editing must be in a group on GitLab Ultimate.
+ The epics you're linking can be in a group on a lower tier.
+
+To link one epic to another:
+
+1. In the **Linked epics** section of an epic,
+ select the add linked epic button (**{plus}**).
+1. Select the relationship between the two epics. Either:
+ - **relates to**
+ - **[blocks](#blocking-epics)**
+ - **[is blocked by](#blocking-epics)**
+1. Enter the epic number or paste in the full URL of the epic.
+
+ ![Adding a related epic](img/related_epics_add_v14_9.png)
+
+ Epics of the same group can be specified just by the reference number.
+ Epics from a different group require additional information like the
+ group name. For example:
+
+ - The same group: `&44`
+ - Different group: `group&44`
+
+ Valid references are added to a temporary list that you can review.
+
+1. Select **Add**.
+
+The linked epics are then displayed on the epic grouped by relationship.
+
+![Related epic block](img/related_epic_block_v14_9.png)
+
+## Remove a linked epic
+
+Prerequisites:
+
+- You must have at least the Reporter role for the epic's group.
+
+To remove a linked epic, in the **Linked epics** section of an epic,
+select **Remove** (**{close}**) next to
+each epic.
+
+The relationship is removed from both epics.
+
+![Removing a related epic](img/related_epics_remove_v14_9.png)
+
+## Blocking epics
+
+When you [add a linked epic](#add-a-linked-epic), you can show that it **blocks** or
+**is blocked by** another epic.
+
+If you try to close a blocked epic using the "Close epic" button, a confirmation message appears.
diff --git a/doc/user/project/merge_requests/commit_templates.md b/doc/user/project/merge_requests/commit_templates.md
index b00a0fb214b..ca371af56a3 100644
--- a/doc/user/project/merge_requests/commit_templates.md
+++ b/doc/user/project/merge_requests/commit_templates.md
@@ -69,6 +69,7 @@ GitLab creates a squash commit message with this template:
> - [Added](https://gitlab.com/gitlab-org/gitlab/-/issues/346805) `first_commit` and `first_multiline_commit` variables in GitLab 14.6.
> - [Added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75639) `url`, `approved_by`, and `merged_by` variables in GitLab 14.7.
> - [Added](https://gitlab.com/gitlab-org/gitlab/-/issues/20421) `co_authored_by` variable in GitLab 14.7.
+> - [Added](https://gitlab.com/gitlab-org/gitlab/-/issues/26303) `all_commits` variable in GitLab 14.9.
Commit message templates support these variables:
@@ -86,6 +87,7 @@ Commit message templates support these variables:
| `%{approved_by}` | Line-separated list of the merge request approvers. This value is not updated until the first page refresh after an approval. | `Approved-by: Sidney Jones <sjones@example.com>` <br> `Approved-by: Zhang Wei <zwei@example.com>` |
| `%{merged_by}` | User who merged the merge request. | `Alex Garcia <agarcia@example.com>` |
| `%{co_authored_by}` | Names and emails of commit authors in a `Co-authored-by` Git commit trailer format. Limited to authors of 100 most recent commits in merge request. | `Co-authored-by: Zane Doe <zdoe@example.com>` <br> `Co-authored-by: Blake Smith <bsmith@example.com>` |
+| `%{all_commits}` | Messages from all commits in the merge request. Limited to 100 most recent commits. Skips commit bodies exceeding 100KiB and merge commit messages. | `* Feature introduced` <br><br> `This commit implements feature` <br> `Changelog:added` <br><br> `* Bug fixed` <br><br> `* Documentation improved` <br><br>`This commit introduced better docs.`|
Any line containing only an empty variable is removed. If the line to be removed is both
preceded and followed by an empty line, the preceding empty line is also removed.
diff --git a/lib/gitlab/analytics/cycle_analytics/request_params.rb b/lib/gitlab/analytics/cycle_analytics/request_params.rb
index 623f9d8082d..af695c5cfa4 100644
--- a/lib/gitlab/analytics/cycle_analytics/request_params.rb
+++ b/lib/gitlab/analytics/cycle_analytics/request_params.rb
@@ -80,7 +80,7 @@ module Gitlab
direction: direction&.to_sym,
page: page,
end_event_filter: end_event_filter.to_sym,
- use_aggregated_data_collector: Feature.enabled?(:use_vsa_aggregated_tables, group || project, default_enabled: :yaml)
+ use_aggregated_data_collector: use_aggregated_backend?
}.merge(attributes.symbolize_keys.slice(*FINDER_PARAM_NAMES))
end
@@ -104,8 +104,13 @@ module Gitlab
private
+ def use_aggregated_backend?
+ group.present? && # for now it's only available on the group-level
+ aggregation.enabled &&
+ Feature.enabled?(:use_vsa_aggregated_tables, group, default_enabled: :yaml)
+ end
+
def aggregation_attributes
- aggregation = ::Analytics::CycleAnalytics::Aggregation.safe_create_for_group(group)
{
enabled: aggregation.enabled.to_s,
last_run_at: aggregation.last_incremental_run_at&.iso8601,
@@ -113,6 +118,10 @@ module Gitlab
}
end
+ def aggregation
+ @aggregation ||= ::Analytics::CycleAnalytics::Aggregation.safe_create_for_group(group)
+ end
+
def group_data_attributes
{
id: group.id,
diff --git a/lib/gitlab/merge_requests/commit_message_generator.rb b/lib/gitlab/merge_requests/commit_message_generator.rb
index 0515c17fe5d..ef5c63925c2 100644
--- a/lib/gitlab/merge_requests/commit_message_generator.rb
+++ b/lib/gitlab/merge_requests/commit_message_generator.rb
@@ -50,6 +50,19 @@ module Gitlab
.except(commit_author&.commit_email_or_default)
.map { |author_email, author_name| "Co-authored-by: #{author_name} <#{author_email}>" }
.join("\n")
+ end,
+ 'all_commits' => -> (merge_request, _, _) do
+ merge_request
+ .recent_commits
+ .without_merge_commits
+ .map do |commit|
+ if commit.safe_message&.bytesize&.>(100.kilobytes)
+ "* #{commit.title}\n\n-- Skipped commit body exceeding 100KiB in size."
+ else
+ "* #{commit.safe_message&.strip}"
+ end
+ end
+ .join("\n\n")
end
}.freeze
diff --git a/spec/frontend/issuable/related_issues/components/related_issues_list_spec.js b/spec/frontend/issuable/related_issues/components/related_issues_list_spec.js
index c7df3755e88..fd623ad9a5f 100644
--- a/spec/frontend/issuable/related_issues/components/related_issues_list_spec.js
+++ b/spec/frontend/issuable/related_issues/components/related_issues_list_spec.js
@@ -28,11 +28,16 @@ describe('RelatedIssuesList', () => {
propsData: {
pathIdSeparator: PathIdSeparator.Issue,
issuableType: 'issue',
+ listLinkType: 'relates_to',
heading,
},
});
});
+ it('assigns value of listLinkType prop to data attribute', () => {
+ expect(wrapper.attributes('data-link-type')).toBe('relates_to');
+ });
+
it('shows a heading', () => {
expect(wrapper.find('h4').text()).toContain(heading);
});
diff --git a/spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb b/spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb
index 2407b497249..ad528dca81a 100644
--- a/spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb
+++ b/spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb
@@ -403,6 +403,90 @@ RSpec.describe Gitlab::MergeRequests::CommitMessageGenerator do
end
end
+ context 'when project has commit template with all_commits' do
+ let(message_template_name) { "All commits:\n%{all_commits}" }
+
+ it 'returns all commit messages' do
+ expect(result_message).to eq <<~MSG.rstrip
+ All commits:
+ * Feature added
+
+ Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
+ MSG
+ end
+
+ context 'with 2 commits' do
+ let(:source_branch) { 'fix' }
+
+ it 'returns both messages' do
+ expect(result_message).to eq <<~MSG.rstrip
+ All commits:
+ * Test file for directories with a leading dot
+
+ * JS fix
+
+ Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
+ MSG
+ end
+ end
+
+ context 'with over 100 commits' do
+ let(:source_branch) { 'signed-commits' }
+
+ it 'returns first 100 commits skipping merge commit' do
+ expected_message = <<~MSG
+ All commits:
+ * Multiple signatures commit
+
+ * Add conflicting file
+
+ * Add conflicting file
+
+ MSG
+ expected_message += (5..100).to_a.reverse
+ .map { |n| "* Unrelated signed commit #{n} to exceed page size of endpoint\n\n" }
+ .join.rstrip
+ expect(result_message).to eq expected_message
+ end
+ end
+
+ context 'when branch has no unmerged commits' do
+ let(:source_branch) { 'v1.1.0' }
+
+ it 'is an empty string' do
+ expect(result_message).to eq "All commits:\n"
+ end
+ end
+
+ context 'when branch has commit with message over 100kb' do
+ let(:source_branch) { 'add_commit_with_5mb_subject' }
+
+ it 'skips commit body' do
+ expect(result_message).to eq <<~MSG.rstrip
+ All commits:
+ * Commit with 5MB text subject
+
+ -- Skipped commit body exceeding 100KiB in size.
+
+ * Correct test_env.rb path for adding branch
+
+ * Add file with a _flattable_ path
+
+
+ (cherry picked from commit ce369011c189f62c815f5971d096b26759bab0d1)
+
+ * Add file larger than 1 mb
+
+ In order to test Max File Size push rule we need a file larger than 1 MB
+
+ * LFS tracks "*.lfs" through .gitattributes
+
+ * Update README.md to include `Usage in testing and development`
+ MSG
+ end
+ end
+ end
+
context 'user' do
subject { described_class.new(merge_request: merge_request, current_user: nil) }
@@ -466,6 +550,7 @@ RSpec.describe Gitlab::MergeRequests::CommitMessageGenerator do
approved_by:%{approved_by}
merged_by:%{merged_by}
co_authored_by:%{co_authored_by}
+ all_commits:%{all_commits}
MSG
it 'uses custom template' do
@@ -486,6 +571,9 @@ RSpec.describe Gitlab::MergeRequests::CommitMessageGenerator do
approved_by:
merged_by:#{current_user.name} <#{current_user.commit_email_or_default}>
co_authored_by:Co-authored-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
+ all_commits:* Feature added
+
+ Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
MSG
end
end
diff --git a/spec/models/analytics/cycle_analytics/aggregation_spec.rb b/spec/models/analytics/cycle_analytics/aggregation_spec.rb
index cb439430dd4..7df1bf60e9c 100644
--- a/spec/models/analytics/cycle_analytics/aggregation_spec.rb
+++ b/spec/models/analytics/cycle_analytics/aggregation_spec.rb
@@ -76,9 +76,12 @@ RSpec.describe Analytics::CycleAnalytics::Aggregation, type: :model do
describe '#estimated_next_run_at' do
around do |example|
- freeze_time { example.run }
+ travel_to(Time.utc(2019, 3, 17, 13, 3)) { example.run }
end
+ # aggregation runs on every 10 minutes
+ let(:minutes_until_next_aggregation) { 7.minutes }
+
context 'when aggregation was not yet executed for the given group' do
let(:aggregation) { create(:cycle_analytics_aggregation, last_incremental_run_at: nil) }
@@ -91,7 +94,7 @@ RSpec.describe Analytics::CycleAnalytics::Aggregation, type: :model do
let!(:aggregation) { create(:cycle_analytics_aggregation, last_incremental_run_at: 5.minutes.ago) }
it 'returns the duration between the previous run timestamp and the earliest last_incremental_run_at' do
- expect(aggregation.estimated_next_run_at).to eq(10.minutes.from_now)
+ expect(aggregation.estimated_next_run_at).to eq((10.minutes + minutes_until_next_aggregation).from_now)
end
context 'when the aggregation has persisted previous runtimes' do
@@ -100,7 +103,7 @@ RSpec.describe Analytics::CycleAnalytics::Aggregation, type: :model do
end
it 'adds the runtime to the estimation' do
- expect(aggregation.estimated_next_run_at).to eq((10.minutes.seconds + 60.seconds).from_now)
+ expect(aggregation.estimated_next_run_at).to eq((10.minutes.seconds + 60.seconds + minutes_until_next_aggregation).from_now)
end
end
end
@@ -114,14 +117,8 @@ RSpec.describe Analytics::CycleAnalytics::Aggregation, type: :model do
context 'when only one aggregation record present' do
let!(:aggregation) { create(:cycle_analytics_aggregation, last_incremental_run_at: 5.minutes.ago) }
- it 'returns nil' do
- expect(aggregation.estimated_next_run_at).to eq(nil)
- end
- end
-
- context 'when the aggregation is disabled' do
- it 'returns nil' do
- expect(described_class.new(enabled: false).estimated_next_run_at).to eq(nil)
+ it 'returns the minutes until the next aggregation' do
+ expect(aggregation.estimated_next_run_at).to eq(minutes_until_next_aggregation.from_now)
end
end
end
diff --git a/spec/services/projects/branches_by_mode_service_spec.rb b/spec/services/projects/branches_by_mode_service_spec.rb
index e8bcda8a9c4..9a63563b37b 100644
--- a/spec/services/projects/branches_by_mode_service_spec.rb
+++ b/spec/services/projects/branches_by_mode_service_spec.rb
@@ -13,20 +13,22 @@ RSpec.describe Projects::BranchesByModeService do
describe '#execute' do
context 'page is passed' do
- let(:params) { { page: 4, mode: 'all', offset: 3 } }
+ let(:page) { (TestEnv::BRANCH_SHA.length.to_f / Kaminari.config.default_per_page).ceil }
+ let(:params) { { page: page, mode: 'all', offset: page - 1 } }
it 'uses offset pagination' do
expect(finder).to receive(:fetch_branches_via_offset_pagination).and_call_original
branches, prev_page, next_page = subject
+ remaining = TestEnv::BRANCH_SHA.length % Kaminari.config.default_per_page
- expect(branches.size).to eq(11)
+ expect(branches.size).to eq(remaining > 0 ? remaining : 20)
expect(next_page).to be_nil
- expect(prev_page).to eq("/#{project.full_path}/-/branches/all?offset=2&page=3")
+ expect(prev_page).to eq("/#{project.full_path}/-/branches/all?offset=#{page - 2}&page=#{page - 1}")
end
context 'but the page does not contain any branches' do
- let(:params) { { page: 10, mode: 'all' } }
+ let(:params) { { page: 100, mode: 'all' } }
it 'uses offset pagination' do
expect(finder).to receive(:fetch_branches_via_offset_pagination).and_call_original
@@ -61,9 +63,10 @@ RSpec.describe Projects::BranchesByModeService do
expect(finder).to receive(:fetch_branches_via_offset_pagination).and_call_original
branches, prev_page, next_page = subject
+ expected_page_token = ERB::Util.url_encode(TestEnv::BRANCH_SHA.sort[19][0])
expect(branches.size).to eq(20)
- expect(next_page).to eq("/#{project.full_path}/-/branches/all?offset=1&page_token=conflict-resolvable")
+ expect(next_page).to eq("/#{project.full_path}/-/branches/all?offset=1&page_token=#{expected_page_token}")
expect(prev_page).to be_nil
end
end
@@ -75,26 +78,31 @@ RSpec.describe Projects::BranchesByModeService do
it 'returns branches for the first page' do
branches, prev_page, next_page = subject
+ expected_page_token = ERB::Util.url_encode(TestEnv::BRANCH_SHA.sort[19][0])
expect(branches.size).to eq(20)
- expect(next_page).to eq("/#{project.full_path}/-/branches/all?offset=1&page_token=conflict-resolvable")
+ expect(next_page).to eq("/#{project.full_path}/-/branches/all?offset=1&page_token=#{expected_page_token}")
expect(prev_page).to be_nil
end
context 'when second page is requested' do
- let(:params) { { page_token: 'conflict-resolvable', mode: 'all', sort: 'name_asc', offset: 1 } }
+ let(:page_token) { 'conflict-resolvable' }
+ let(:params) { { page_token: page_token, mode: 'all', sort: 'name_asc', offset: 1 } }
it 'returns branches for the first page' do
branches, prev_page, next_page = subject
+ branch_index = TestEnv::BRANCH_SHA.sort.find_index { |a| a[0] == page_token }
+ expected_page_token = ERB::Util.url_encode(TestEnv::BRANCH_SHA.sort[20 + branch_index][0])
expect(branches.size).to eq(20)
- expect(next_page).to eq("/#{project.full_path}/-/branches/all?offset=2&page_token=improve%2Fawesome&sort=name_asc")
+ expect(next_page).to eq("/#{project.full_path}/-/branches/all?offset=2&page_token=#{expected_page_token}&sort=name_asc")
expect(prev_page).to eq("/#{project.full_path}/-/branches/all?offset=0&page=1&sort=name_asc")
end
end
context 'when last page is requested' do
- let(:params) { { page_token: 'signed-commits', mode: 'all', sort: 'name_asc', offset: 4 } }
+ let(:page_token) { TestEnv::BRANCH_SHA.sort[-16][0] }
+ let(:params) { { page_token: page_token, mode: 'all', sort: 'name_asc', offset: 4 } }
it 'returns branches after the specified branch' do
branches, prev_page, next_page = subject
diff --git a/spec/support/helpers/test_env.rb b/spec/support/helpers/test_env.rb
index 69b98166160..587d4e22828 100644
--- a/spec/support/helpers/test_env.rb
+++ b/spec/support/helpers/test_env.rb
@@ -80,7 +80,8 @@ module TestEnv
'invalid-utf8-diff-paths' => '99e4853',
'compare-with-merge-head-source' => 'f20a03d',
'compare-with-merge-head-target' => '2f1e176',
- 'trailers' => 'f0a5ed6'
+ 'trailers' => 'f0a5ed6',
+ 'add_commit_with_5mb_subject' => '8cf8e80'
}.freeze
# gitlab-test-fork is a fork of gitlab-fork, but we don't necessarily