summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/boards/components/issue_card_inner.vue8
-rw-r--r--app/assets/javascripts/boards/components/issue_due_date.vue10
-rw-r--r--app/assets/javascripts/boards/models/issue.js1
-rw-r--r--app/assets/javascripts/diffs/components/diff_file.vue4
-rw-r--r--app/assets/javascripts/diffs/components/diff_file_header.vue6
-rw-r--r--app/assets/javascripts/diffs/components/diff_stats.vue2
-rw-r--r--app/assets/javascripts/diffs/components/image_diff_overlay.vue4
-rw-r--r--app/assets/javascripts/diffs/components/no_changes.vue6
-rw-r--r--app/assets/javascripts/diffs/store/utils.js10
-rw-r--r--app/assets/stylesheets/pages/notes.scss2
-rw-r--r--app/controllers/projects/graphs_controller.rb3
-rw-r--r--app/models/clusters/applications/runner.rb2
-rw-r--r--app/serializers/issue_board_entity.rb3
-rw-r--r--app/views/award_emoji/_awards_block.html.haml1
-rw-r--r--app/views/projects/graphs/charts.html.haml1
-rw-r--r--changelogs/unreleased/205184-change-omniauth-log-format-to-json.yml5
-rw-r--r--changelogs/unreleased/28627-adjust-commit-stats-over-limit-indication.yml5
-rw-r--r--changelogs/unreleased/Resolve-Migrate--fa-spinner-app-views-award_emoji.yml5
-rw-r--r--changelogs/unreleased/closed-issue-weight-grey.yml5
-rw-r--r--changelogs/unreleased/sh-fix-license-check-migration.yml5
-rw-r--r--changelogs/unreleased/update-gitlab-runner-helm-chart-to-0-14-0.yml5
-rw-r--r--config/initializers/0_license.rb2
-rw-r--r--config/initializers/omniauth.rb4
-rw-r--r--doc/.linting/vale/styles/gitlab/Contractions.yml33
-rw-r--r--doc/.linting/vale/styles/gitlab/LatinTerms.yml32
-rw-r--r--doc/.linting/vale/styles/gitlab/Substitutions.yml32
-rw-r--r--doc/development/event_tracking/frontend.md2
-rw-r--r--lib/gitlab/omniauth_logging/json_formatter.rb13
-rw-r--r--lib/gitlab/reactive_cache_set_cache.rb30
-rw-r--r--lib/gitlab/repository_set_cache.rb24
-rw-r--r--lib/gitlab/set_cache.rb55
-rw-r--r--locale/gitlab.pot3
-rw-r--r--spec/fixtures/api/schemas/entities/issue_board.json1
-rw-r--r--spec/frontend/boards/components/issue_due_date_spec.js13
-rw-r--r--spec/lib/gitlab/omniauth_logging/json_formatter_spec.rb12
-rw-r--r--spec/lib/gitlab/reactive_cache_set_cache_spec.rb74
-rw-r--r--spec/support/caching.rb15
37 files changed, 302 insertions, 136 deletions
diff --git a/app/assets/javascripts/boards/components/issue_card_inner.vue b/app/assets/javascripts/boards/components/issue_card_inner.vue
index bdaed17fd09..274565adab0 100644
--- a/app/assets/javascripts/boards/components/issue_card_inner.vue
+++ b/app/assets/javascripts/boards/components/issue_card_inner.vue
@@ -177,9 +177,9 @@ export default {
class="confidential-icon append-right-4"
:aria-label="__('Confidential')"
/>
- <a :href="issue.path" :title="issue.title" class="js-no-trigger" @mousemove.stop>
- {{ issue.title }}
- </a>
+ <a :href="issue.path" :title="issue.title" class="js-no-trigger" @mousemove.stop>{{
+ issue.title
+ }}</a>
</h4>
</div>
<div v-if="showLabelFooter" class="board-card-labels prepend-top-4 d-flex flex-wrap">
@@ -225,7 +225,7 @@ export default {
#{{ issue.iid }}
</span>
<span class="board-info-items prepend-top-8 d-inline-block">
- <issue-due-date v-if="issue.dueDate" :date="issue.dueDate" />
+ <issue-due-date v-if="issue.dueDate" :date="issue.dueDate" :closed="issue.closed" />
<issue-time-estimate v-if="issue.timeEstimate" :estimate="issue.timeEstimate" />
<issue-card-weight
v-if="validIssueWeight"
diff --git a/app/assets/javascripts/boards/components/issue_due_date.vue b/app/assets/javascripts/boards/components/issue_due_date.vue
index a32ebdab5e1..1d70c635c18 100644
--- a/app/assets/javascripts/boards/components/issue_due_date.vue
+++ b/app/assets/javascripts/boards/components/issue_due_date.vue
@@ -16,6 +16,11 @@ export default {
GlTooltip,
},
props: {
+ closed: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
date: {
type: String,
required: true,
@@ -66,7 +71,7 @@ export default {
return getDayDifference(today, this.issueDueDate);
},
isPastDue() {
- if (this.timeDifference >= 0) return false;
+ if (this.timeDifference >= 0 || this.closed) return false;
return true;
},
standardDateFormat() {
@@ -92,7 +97,8 @@ export default {
}}</time>
</span>
<gl-tooltip :target="() => $refs.issueDueDate" :placement="tooltipPlacement">
- <span class="bold">{{ __('Due date') }}</span> <br />
+ <span class="bold">{{ __('Due date') }}</span>
+ <br />
<span :class="{ 'text-danger-muted': isPastDue }">{{ title }}</span>
</gl-tooltip>
</span>
diff --git a/app/assets/javascripts/boards/models/issue.js b/app/assets/javascripts/boards/models/issue.js
index 044d96a9aec..0e86359534b 100644
--- a/app/assets/javascripts/boards/models/issue.js
+++ b/app/assets/javascripts/boards/models/issue.js
@@ -19,6 +19,7 @@ class ListIssue {
this.isFetching = {
subscriptions: true,
};
+ this.closed = obj.closed;
this.isLoading = {};
this.refreshData(obj, defaultAvatar);
diff --git a/app/assets/javascripts/diffs/components/diff_file.vue b/app/assets/javascripts/diffs/components/diff_file.vue
index f5051748f10..048dc274cf2 100644
--- a/app/assets/javascripts/diffs/components/diff_file.vue
+++ b/app/assets/javascripts/diffs/components/diff_file.vue
@@ -1,6 +1,6 @@
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
-import _ from 'underscore';
+import { escape as esc } from 'lodash';
import { GlLoadingIcon } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
import createFlash from '~/flash';
@@ -46,7 +46,7 @@ export default {
return sprintf(
__('You can %{linkStart}view the blob%{linkEnd} instead.'),
{
- linkStart: `<a href="${_.escape(this.file.view_path)}">`,
+ linkStart: `<a href="${esc(this.file.view_path)}">`,
linkEnd: '</a>',
},
false,
diff --git a/app/assets/javascripts/diffs/components/diff_file_header.vue b/app/assets/javascripts/diffs/components/diff_file_header.vue
index 731c53a7339..d4270960f57 100644
--- a/app/assets/javascripts/diffs/components/diff_file_header.vue
+++ b/app/assets/javascripts/diffs/components/diff_file_header.vue
@@ -1,5 +1,5 @@
<script>
-import _ from 'underscore';
+import { escape as esc } from 'lodash';
import { mapActions, mapGetters } from 'vuex';
import { GlButton, GlTooltipDirective, GlLoadingIcon } from '@gitlab/ui';
import { polyfillSticky } from '~/lib/utils/sticky';
@@ -91,7 +91,7 @@ export default {
return this.expanded ? 'chevron-down' : 'chevron-right';
},
viewFileButtonText() {
- const truncatedContentSha = _.escape(truncateSha(this.diffFile.content_sha));
+ const truncatedContentSha = esc(truncateSha(this.diffFile.content_sha));
return sprintf(
s__('MergeRequests|View file @ %{commitId}'),
{ commitId: truncatedContentSha },
@@ -99,7 +99,7 @@ export default {
);
},
viewReplacedFileButtonText() {
- const truncatedBaseSha = _.escape(truncateSha(this.diffFile.diff_refs.base_sha));
+ const truncatedBaseSha = esc(truncateSha(this.diffFile.diff_refs.base_sha));
return sprintf(
s__('MergeRequests|View replaced file @ %{commitId}'),
{
diff --git a/app/assets/javascripts/diffs/components/diff_stats.vue b/app/assets/javascripts/diffs/components/diff_stats.vue
index 9d362ceb429..0234fc4f40e 100644
--- a/app/assets/javascripts/diffs/components/diff_stats.vue
+++ b/app/assets/javascripts/diffs/components/diff_stats.vue
@@ -1,7 +1,7 @@
<script>
import Icon from '~/vue_shared/components/icon.vue';
import { n__ } from '~/locale';
-import { isNumber } from 'underscore';
+import { isNumber } from 'lodash';
export default {
components: { Icon },
diff --git a/app/assets/javascripts/diffs/components/image_diff_overlay.vue b/app/assets/javascripts/diffs/components/image_diff_overlay.vue
index 703a281308e..be7e6789216 100644
--- a/app/assets/javascripts/diffs/components/image_diff_overlay.vue
+++ b/app/assets/javascripts/diffs/components/image_diff_overlay.vue
@@ -1,6 +1,6 @@
<script>
import { mapActions, mapGetters } from 'vuex';
-import _ from 'underscore';
+import { isArray } from 'lodash';
import imageDiffMixin from 'ee_else_ce/diffs/mixins/image_diff';
import Icon from '~/vue_shared/components/icon.vue';
@@ -46,7 +46,7 @@ export default {
return this.getCommentFormForDiffFile(this.fileHash);
},
allDiscussions() {
- return _.isArray(this.discussions) ? this.discussions : [this.discussions];
+ return isArray(this.discussions) ? this.discussions : [this.discussions];
},
},
methods: {
diff --git a/app/assets/javascripts/diffs/components/no_changes.vue b/app/assets/javascripts/diffs/components/no_changes.vue
index 47e9627a957..09cb542c3dc 100644
--- a/app/assets/javascripts/diffs/components/no_changes.vue
+++ b/app/assets/javascripts/diffs/components/no_changes.vue
@@ -1,6 +1,6 @@
<script>
import { mapGetters } from 'vuex';
-import _ from 'underscore';
+import { escape as esc } from 'lodash';
import { GlButton } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
@@ -24,8 +24,8 @@ export default {
{
ref_start: '<span class="ref-name">',
ref_end: '</span>',
- source_branch: _.escape(this.getNoteableData.source_branch),
- target_branch: _.escape(this.getNoteableData.target_branch),
+ source_branch: esc(this.getNoteableData.source_branch),
+ target_branch: esc(this.getNoteableData.target_branch),
},
false,
);
diff --git a/app/assets/javascripts/diffs/store/utils.js b/app/assets/javascripts/diffs/store/utils.js
index 29133c814ea..9c788e283b9 100644
--- a/app/assets/javascripts/diffs/store/utils.js
+++ b/app/assets/javascripts/diffs/store/utils.js
@@ -1,4 +1,4 @@
-import _ from 'underscore';
+import { property, isEqual } from 'lodash';
import { truncatePathMiddleToLength } from '~/lib/utils/text_utility';
import { diffModes, diffViewerModes } from '~/ide/constants';
import {
@@ -442,7 +442,7 @@ export function isDiscussionApplicableToLine({ discussion, diffPosition, latestD
const originalRefs = discussion.original_position;
const refs = discussion.position;
- return _.isEqual(refs, diffPositionCopy) || _.isEqual(originalRefs, diffPositionCopy);
+ return isEqual(refs, diffPositionCopy) || isEqual(originalRefs, diffPositionCopy);
}
// eslint-disable-next-line
@@ -578,10 +578,10 @@ export const convertExpandLines = ({
for (let i = 0, diffLinesLength = diffLines.length; i < diffLinesLength; i += 1) {
const line = diffLines[i];
- if (_.property(typeKey)(line) === 'match') {
+ if (property(typeKey)(line) === 'match') {
const beforeLine = diffLines[i - 1];
const afterLine = diffLines[i + 1];
- const newLineProperty = _.property(newLineKey);
+ const newLineProperty = property(newLineKey);
const beforeLineIndex = newLineProperty(beforeLine) || 0;
const afterLineIndex = newLineProperty(afterLine) - 1 || dataLength;
@@ -589,7 +589,7 @@ export const convertExpandLines = ({
...data.slice(beforeLineIndex, afterLineIndex).map((l, index) =>
mapLine({
line: Object.assign(l, { hasForm: false, discussions: [] }),
- oldLine: (_.property(oldLineKey)(beforeLine) || 0) + index + 1,
+ oldLine: (property(oldLineKey)(beforeLine) || 0) + index + 1,
newLine: (newLineProperty(beforeLine) || 0) + index + 1,
}),
),
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index 1a06ae1ed41..347addcec37 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -316,7 +316,7 @@ $note-form-margin-left: 72px;
.btn.delete-description-history {
position: absolute;
top: 18px;
- right: 0;
+ right: 10px;
}
pre {
diff --git a/app/controllers/projects/graphs_controller.rb b/app/controllers/projects/graphs_controller.rb
index 67d3f49af18..889dcefb65a 100644
--- a/app/controllers/projects/graphs_controller.rb
+++ b/app/controllers/projects/graphs_controller.rb
@@ -37,7 +37,8 @@ class Projects::GraphsController < Projects::ApplicationController
private
def get_commits
- @commits = @project.repository.commits(@ref, limit: 2000, skip_merges: true)
+ @commits_limit = 2000
+ @commits = @project.repository.commits(@ref, limit: @commits_limit, skip_merges: true)
@commits_graph = Gitlab::Graphs::Commits.new(@commits)
@commits_per_week_days = @commits_graph.commits_per_week_days
@commits_per_time = @commits_graph.commits_per_time
diff --git a/app/models/clusters/applications/runner.rb b/app/models/clusters/applications/runner.rb
index 6a9cd77d356..4886f2debb1 100644
--- a/app/models/clusters/applications/runner.rb
+++ b/app/models/clusters/applications/runner.rb
@@ -3,7 +3,7 @@
module Clusters
module Applications
class Runner < ApplicationRecord
- VERSION = '0.13.1'
+ VERSION = '0.14.0'
self.table_name = 'clusters_applications_runners'
diff --git a/app/serializers/issue_board_entity.rb b/app/serializers/issue_board_entity.rb
index 13897279815..ea629d9d774 100644
--- a/app/serializers/issue_board_entity.rb
+++ b/app/serializers/issue_board_entity.rb
@@ -12,6 +12,9 @@ class IssueBoardEntity < Grape::Entity
expose :project_id
expose :relative_position
expose :time_estimate
+ expose :closed do |issue|
+ issue.closed?
+ end
expose :project do |issue|
API::Entities::Project.represent issue.project, only: [:id, :path]
diff --git a/app/views/award_emoji/_awards_block.html.haml b/app/views/award_emoji/_awards_block.html.haml
index 793ddef2c58..a063fe54c99 100644
--- a/app/views/award_emoji/_awards_block.html.haml
+++ b/app/views/award_emoji/_awards_block.html.haml
@@ -16,5 +16,4 @@
%span{ class: "award-control-icon award-control-icon-neutral" }= sprite_icon('slight-smile')
%span{ class: "award-control-icon award-control-icon-positive" }= sprite_icon('smiley')
%span{ class: "award-control-icon award-control-icon-super-positive" }= sprite_icon('smile')
- = icon('spinner spin', class: "award-control-icon award-control-icon-loading")
= yield
diff --git a/app/views/projects/graphs/charts.html.haml b/app/views/projects/graphs/charts.html.haml
index b38449b3ab9..cb76e89f736 100644
--- a/app/views/projects/graphs/charts.html.haml
+++ b/app/views/projects/graphs/charts.html.haml
@@ -20,6 +20,7 @@
- end_time = capture do
#{@commits_graph.end_date.strftime('%b %d')}
= (_("Commit statistics for %{ref} %{start_time} - %{end_time}") % { ref: "<strong>#{h @ref}</strong>", start_time: start_time, end_time: end_time }).html_safe
+ = _("Excluding merge commits. Limited to %{limit} commits.") % {limit: number_with_delimiter(@commits_limit, delimiter: ',')}
.col-md-6
.tree-ref-container
diff --git a/changelogs/unreleased/205184-change-omniauth-log-format-to-json.yml b/changelogs/unreleased/205184-change-omniauth-log-format-to-json.yml
new file mode 100644
index 00000000000..400640bf053
--- /dev/null
+++ b/changelogs/unreleased/205184-change-omniauth-log-format-to-json.yml
@@ -0,0 +1,5 @@
+---
+title: Change OmniAuth log format to JSON
+merge_request: 25086
+author:
+type: other
diff --git a/changelogs/unreleased/28627-adjust-commit-stats-over-limit-indication.yml b/changelogs/unreleased/28627-adjust-commit-stats-over-limit-indication.yml
new file mode 100644
index 00000000000..08ad9a7c183
--- /dev/null
+++ b/changelogs/unreleased/28627-adjust-commit-stats-over-limit-indication.yml
@@ -0,0 +1,5 @@
+---
+title: Add commits limit text at graphs page
+merge_request: 24990
+author:
+type: changed
diff --git a/changelogs/unreleased/Resolve-Migrate--fa-spinner-app-views-award_emoji.yml b/changelogs/unreleased/Resolve-Migrate--fa-spinner-app-views-award_emoji.yml
new file mode 100644
index 00000000000..cf1cce15919
--- /dev/null
+++ b/changelogs/unreleased/Resolve-Migrate--fa-spinner-app-views-award_emoji.yml
@@ -0,0 +1,5 @@
+---
+title: Remove spinner from app/views/award_emoji
+merge_request: 25032
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/closed-issue-weight-grey.yml b/changelogs/unreleased/closed-issue-weight-grey.yml
new file mode 100644
index 00000000000..283f88aa606
--- /dev/null
+++ b/changelogs/unreleased/closed-issue-weight-grey.yml
@@ -0,0 +1,5 @@
+---
+title: Board issue due dates appear grey for closed past-due issues
+merge_request: 25507
+author: rachelfox
+type: fixed
diff --git a/changelogs/unreleased/sh-fix-license-check-migration.yml b/changelogs/unreleased/sh-fix-license-check-migration.yml
new file mode 100644
index 00000000000..95e15c2f303
--- /dev/null
+++ b/changelogs/unreleased/sh-fix-license-check-migration.yml
@@ -0,0 +1,5 @@
+---
+title: Fix upgrade failure in EE displaying license
+merge_request: 25788
+author:
+type: fixed
diff --git a/changelogs/unreleased/update-gitlab-runner-helm-chart-to-0-14-0.yml b/changelogs/unreleased/update-gitlab-runner-helm-chart-to-0-14-0.yml
new file mode 100644
index 00000000000..5342809ca07
--- /dev/null
+++ b/changelogs/unreleased/update-gitlab-runner-helm-chart-to-0-14-0.yml
@@ -0,0 +1,5 @@
+---
+title: Update GitLab Runner Helm Chart to 0.14.0
+merge_request: 25749
+author:
+type: other
diff --git a/config/initializers/0_license.rb b/config/initializers/0_license.rb
index 5c4546f499f..19c71c34904 100644
--- a/config/initializers/0_license.rb
+++ b/config/initializers/0_license.rb
@@ -10,7 +10,7 @@ Gitlab.ee do
end
# Needed to run migration
- if Gitlab::Database.cached_table_exists?('licenses')
+ if ActiveRecord::Base.connected? && ActiveRecord::Base.connection.table_exists?('licenses')
message = LicenseHelper.license_message(signed_in: true, is_admin: true, in_html: false)
if ::License.block_changes? && message.present?
warn "WARNING: #{message}"
diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb
index ef23ca065c6..0e4cb88b50f 100644
--- a/config/initializers/omniauth.rb
+++ b/config/initializers/omniauth.rb
@@ -16,3 +16,7 @@ OmniAuth.config.allowed_request_methods << :get if Gitlab.config.omniauth.auto_s
OmniAuth.config.before_request_phase do |env|
Gitlab::RequestForgeryProtection.call(env)
end
+
+# Use json formatter
+OmniAuth.config.logger.formatter = Gitlab::OmniauthLogging::JSONFormatter.new
+OmniAuth.config.logger.level = Logger::ERROR if Rails.env.production?
diff --git a/doc/.linting/vale/styles/gitlab/Contractions.yml b/doc/.linting/vale/styles/gitlab/Contractions.yml
index 0f31f6b6aa9..5f389bd1ea4 100644
--- a/doc/.linting/vale/styles/gitlab/Contractions.yml
+++ b/doc/.linting/vale/styles/gitlab/Contractions.yml
@@ -1,35 +1,13 @@
---
-# `extends` indicates the Vale extension point being used.
-# Full list of styles: https://errata-ai.github.io/vale/styles/
+# Checks for use of common and uncommon contractions.
+#
+# For a list of all options, see https://errata-ai.github.io/vale/styles/
extends: substitution
-
-# Substitution rules can display the matched and suggested strings in the
-# message shown to the user. The first use of %s prints the suggested option,
-# and the second use of %s displays what was found in the text.
message: Use "%s" instead of "%s" in most cases.
-
-# Should a result be flagged as a suggestion, warning, or error?
-# Results that fall below the MinAlertLevel set in
-# https://gitlab.com/gitlab-org/gitlab/blob/master/.vale.ini won't be shown.
+link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#language
level: suggestion
-
-# Should a match be case-insensitive or case-sensitive?
-# Acceptable values are 'true' or 'false'
-ignorecase: true
-
-# Should this rule be limited to a specific scope? If yes, uncomment the line.
-# Possible scopes: https://errata-ai.github.io/vale/formats/#available-scopes
-# scope: heading
-
-# Should this rule ignore normal word boundaries, such as \b ?
-# Acceptable values are 'true' or 'false'
nonword: false
-
-# What is the source for this rule?
-link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#language
-
-# The 'swap' section provides a list of values, one per line, in the form of
-# $bad: $good
+ignorecase: true
swap:
# Common contractions are ok
@@ -73,4 +51,3 @@ swap:
who'll: who will
why's: why is
why'll: why will
-
diff --git a/doc/.linting/vale/styles/gitlab/LatinTerms.yml b/doc/.linting/vale/styles/gitlab/LatinTerms.yml
index 082b56147a4..8412631f8fe 100644
--- a/doc/.linting/vale/styles/gitlab/LatinTerms.yml
+++ b/doc/.linting/vale/styles/gitlab/LatinTerms.yml
@@ -1,35 +1,13 @@
---
-# `extends` indicates the Vale extension point being used.
-# Full list of styles: https://errata-ai.github.io/vale/styles/
+# Checks for use of latin terms..
+#
+# For a list of all options, see https://errata-ai.github.io/vale/styles/
extends: substitution
-
-# Substitution rules can display the matched and suggested strings in the
-# message shown to the user. The first use of %s prints the suggested option,
-# and the second use of %s displays what was found in the text.
message: Use "%s" instead of "%s," but consider rewriting the sentence.
-
-# Should a result be flagged as a suggestion, warning, or error?
-# Results that fall below the MinAlertLevel set in
-# https://gitlab.com/gitlab-org/gitlab/blob/master/.vale.ini won't be shown.
+link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#language
level: warning
-
-# Should a match be case-insensitive or case-sensitive?
-# Acceptable values are 'true' or 'false'
-ignorecase: true
-
-# Should this rule be limited to a specific scope? If yes, uncomment the line.
-# Possible scopes: https://errata-ai.github.io/vale/formats/#available-scopes
-# scope: heading
-
-# Should this rule ignore normal word boundaries, such as \b ?
-# Acceptable values are 'true' or 'false'
nonword: true
-
-# What is the source for this rule?
-link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#language
-
-# The 'swap' section provides a list of values, one per line, in the form of
-# $bad: $good
+ignorecase: true
swap:
e\.g\.: for example
e\. g\.: for example
diff --git a/doc/.linting/vale/styles/gitlab/Substitutions.yml b/doc/.linting/vale/styles/gitlab/Substitutions.yml
index d9ae1dfcb07..1ddd2f8bf4e 100644
--- a/doc/.linting/vale/styles/gitlab/Substitutions.yml
+++ b/doc/.linting/vale/styles/gitlab/Substitutions.yml
@@ -1,35 +1,13 @@
---
-# `extends` indicates the Vale extension point being used.
-# Full list of styles: https://errata-ai.github.io/vale/styles/
+# Checks for use of top misused terms at GitLab.
+#
+# For a list of all options, see https://errata-ai.github.io/vale/styles/
extends: substitution
-
-# Substitution rules can display the matched and suggested strings in the
-# message shown to the user. The first use of %s prints the suggested option,
-# and the second use of %s displays what was found in the text.
message: Use "%s" instead of "%s."
-
-# Should a result be flagged as a suggestion, warning, or error?
-# Results that fall below the MinAlertLevel set in
-# https://gitlab.com/gitlab-org/gitlab/blob/master/.vale.ini won't be shown.
+link: https://about.gitlab.com/handbook/communication/#top-misused-terms
level: warning
-
-# Should a match be case-insensitive or case-sensitive?
-# Acceptable values are 'true' or 'false'
-ignorecase: true
-
-# Should this rule be limited to a specific scope? If yes, uncomment the line.
-# Possible scopes: https://errata-ai.github.io/vale/formats/#available-scopes
-# scope: heading
-
-# Should this rule ignore normal word boundaries, such as \b ?
-# Acceptable values are 'true' or 'false'
nonword: true
-
-# What is the source for this rule?
-link: https://about.gitlab.com/handbook/communication/#top-misused-terms
-
-# The 'swap' section provides a list of values, one per line, in the form of
-# $bad: $good
+ignorecase: true
swap:
GitLabber: GitLab team member
self hosted: self-managed
diff --git a/doc/development/event_tracking/frontend.md b/doc/development/event_tracking/frontend.md
index c767efc65b2..4139bf2322d 100644
--- a/doc/development/event_tracking/frontend.md
+++ b/doc/development/event_tracking/frontend.md
@@ -104,7 +104,7 @@ And if needed within the template, you can use the `track` method directly as we
Custom event tracking and instrumentation can be added by directly calling the `Tracking.event` static function. The following example demonstrates tracking a click on a button by calling `Tracking.event` manually.
```javascript
-import Tracking from `~/tracking`;
+import Tracking from '~/tracking';
const button = document.getElementById('create_from_template_button');
button.addEventListener('click', () => {
diff --git a/lib/gitlab/omniauth_logging/json_formatter.rb b/lib/gitlab/omniauth_logging/json_formatter.rb
new file mode 100644
index 00000000000..cdd4da31803
--- /dev/null
+++ b/lib/gitlab/omniauth_logging/json_formatter.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'json'
+
+module Gitlab
+ module OmniauthLogging
+ class JSONFormatter
+ def call(severity, datetime, progname, msg)
+ { severity: severity, timestamp: datetime.utc.iso8601(3), pid: $$, progname: progname, message: msg }.to_json << "\n"
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/reactive_cache_set_cache.rb b/lib/gitlab/reactive_cache_set_cache.rb
new file mode 100644
index 00000000000..14d008c3dfb
--- /dev/null
+++ b/lib/gitlab/reactive_cache_set_cache.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+# Interface to the Redis-backed cache store to keep track of complete cache keys
+# for a ReactiveCache resource.
+module Gitlab
+ class ReactiveCacheSetCache < Gitlab::SetCache
+ attr_reader :expires_in
+
+ def initialize(expires_in: 10.minutes)
+ @expires_in = expires_in
+ end
+
+ def clear_cache!(key)
+ with do |redis|
+ keys = read(key).map { |value| "#{cache_type}#{value}" }
+ keys << cache_key(key)
+
+ redis.pipelined do
+ keys.each_slice(1000) { |subset| redis.del(*subset) }
+ end
+ end
+ end
+
+ private
+
+ def cache_type
+ "#{Gitlab::Redis::Cache::CACHE_NAMESPACE}:"
+ end
+ end
+end
diff --git a/lib/gitlab/repository_set_cache.rb b/lib/gitlab/repository_set_cache.rb
index 4797ec0b116..1e2d86b7ad2 100644
--- a/lib/gitlab/repository_set_cache.rb
+++ b/lib/gitlab/repository_set_cache.rb
@@ -2,7 +2,7 @@
# Interface to the Redis-backed cache store for keys that use a Redis set
module Gitlab
- class RepositorySetCache
+ class RepositorySetCache < Gitlab::SetCache
attr_reader :repository, :namespace, :expires_in
def initialize(repository, extra_namespace: nil, expires_in: 2.weeks)
@@ -17,18 +17,6 @@ module Gitlab
"#{type}:#{namespace}:set"
end
- def expire(key)
- with { |redis| redis.del(cache_key(key)) }
- end
-
- def exist?(key)
- with { |redis| redis.exists(cache_key(key)) }
- end
-
- def read(key)
- with { |redis| redis.smembers(cache_key(key)) }
- end
-
def write(key, value)
full_key = cache_key(key)
@@ -54,15 +42,5 @@ module Gitlab
write(key, yield)
end
end
-
- def include?(key, value)
- with { |redis| redis.sismember(cache_key(key), value) }
- end
-
- private
-
- def with(&blk)
- Gitlab::Redis::Cache.with(&blk) # rubocop:disable CodeReuse/ActiveRecord
- end
end
end
diff --git a/lib/gitlab/set_cache.rb b/lib/gitlab/set_cache.rb
new file mode 100644
index 00000000000..0927a3e64bb
--- /dev/null
+++ b/lib/gitlab/set_cache.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+# Interface to the Redis-backed cache store to keep track of complete cache keys
+# for a ReactiveCache resource.
+module Gitlab
+ class SetCache
+ attr_reader :expires_in
+
+ def initialize(expires_in: 2.weeks)
+ @expires_in = expires_in
+ end
+
+ def cache_key(key)
+ "#{key}:set"
+ end
+
+ def expire(key)
+ with { |redis| redis.del(cache_key(key)) }
+ end
+
+ def exist?(key)
+ with { |redis| redis.exists(cache_key(key)) }
+ end
+
+ def write(key, value)
+ with do |redis|
+ redis.pipelined do
+ redis.sadd(cache_key(key), value)
+
+ redis.expire(cache_key(key), expires_in)
+ end
+ end
+
+ value
+ end
+
+ def read(key)
+ with { |redis| redis.smembers(cache_key(key)) }
+ end
+
+ def include?(key, value)
+ with { |redis| redis.sismember(cache_key(key), value) }
+ end
+
+ def ttl(key)
+ with { |redis| redis.ttl(cache_key(key)) }
+ end
+
+ private
+
+ def with(&blk)
+ Gitlab::Redis::Cache.with(&blk) # rubocop:disable CodeReuse/ActiveRecord
+ end
+ end
+end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index d0cb12da37c..f241503c40d 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -7951,6 +7951,9 @@ msgstr ""
msgid "Except policy:"
msgstr ""
+msgid "Excluding merge commits. Limited to %{limit} commits."
+msgstr ""
+
msgid "Excluding merge commits. Limited to 6,000 commits."
msgstr ""
diff --git a/spec/fixtures/api/schemas/entities/issue_board.json b/spec/fixtures/api/schemas/entities/issue_board.json
index 09f66813c95..d7e3c45b13b 100644
--- a/spec/fixtures/api/schemas/entities/issue_board.json
+++ b/spec/fixtures/api/schemas/entities/issue_board.json
@@ -5,6 +5,7 @@
"iid": { "type": "integer" },
"title": { "type": "string" },
"confidential": { "type": "boolean" },
+ "closed": { "type": "boolean" },
"due_date": { "type": "date" },
"project_id": { "type": "integer" },
"relative_position": { "type": ["integer", "null"] },
diff --git a/spec/frontend/boards/components/issue_due_date_spec.js b/spec/frontend/boards/components/issue_due_date_spec.js
index 68e26b68f04..8cb1d963851 100644
--- a/spec/frontend/boards/components/issue_due_date_spec.js
+++ b/spec/frontend/boards/components/issue_due_date_spec.js
@@ -7,8 +7,8 @@ describe('Issue Due Date component', () => {
let vm;
let date;
const Component = Vue.extend(IssueDueDate);
- const createComponent = (dueDate = new Date()) =>
- mountComponent(Component, { date: dateFormat(dueDate, 'yyyy-mm-dd', true) });
+ const createComponent = (dueDate = new Date(), closed = false) =>
+ mountComponent(Component, { closed, date: dateFormat(dueDate, 'yyyy-mm-dd', true) });
beforeEach(() => {
date = new Date();
@@ -56,10 +56,17 @@ describe('Issue Due Date component', () => {
expect(vm.$el.querySelector('time').textContent.trim()).toEqual(dateFormat(date, format));
});
- it('should contain the correct `.text-danger` css class for overdue issue', () => {
+ it('should contain the correct `.text-danger` css class for overdue issue that is open', () => {
date.setDate(date.getDate() - 17);
vm = createComponent(date);
expect(vm.$el.querySelector('time').classList.contains('text-danger')).toEqual(true);
});
+
+ it('should not contain the `.text-danger` css class for overdue issue that is closed', () => {
+ date.setDate(date.getDate() - 17);
+ vm = createComponent(date, true);
+
+ expect(vm.$el.querySelector('time').classList.contains('text-danger')).toEqual(false);
+ });
});
diff --git a/spec/lib/gitlab/omniauth_logging/json_formatter_spec.rb b/spec/lib/gitlab/omniauth_logging/json_formatter_spec.rb
new file mode 100644
index 00000000000..36405daed5a
--- /dev/null
+++ b/spec/lib/gitlab/omniauth_logging/json_formatter_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::OmniauthLogging::JSONFormatter do
+ it "generates log in json format" do
+ Timecop.freeze(Time.utc(2019, 12, 04, 9, 10, 11, 123456)) do
+ expect(subject.call(:info, Time.now, 'omniauth', 'log message'))
+ .to eq %Q({"severity":"info","timestamp":"2019-12-04T09:10:11.123Z","pid":#{Process.pid},"progname":"omniauth","message":"log message"}\n)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/reactive_cache_set_cache_spec.rb b/spec/lib/gitlab/reactive_cache_set_cache_spec.rb
new file mode 100644
index 00000000000..58c8fd0c1c3
--- /dev/null
+++ b/spec/lib/gitlab/reactive_cache_set_cache_spec.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::ReactiveCacheSetCache, :clean_gitlab_redis_cache do
+ let_it_be(:project) { create(:project) }
+ let(:cache_prefix) { 'cache_prefix' }
+ let(:expires_in) { 10.minutes }
+ let(:cache) { described_class.new(expires_in: expires_in) }
+
+ describe '#cache_key' do
+ subject { cache.cache_key(cache_prefix) }
+
+ it 'includes the suffix' do
+ expect(subject).to eq "#{cache_prefix}:set"
+ end
+ end
+
+ describe '#read' do
+ subject { cache.read(cache_prefix) }
+
+ it { is_expected.to be_empty }
+
+ context 'after item added' do
+ before do
+ cache.write(cache_prefix, 'test_item')
+ end
+
+ it { is_expected.to contain_exactly('test_item') }
+ end
+ end
+
+ describe '#write' do
+ it 'writes the value to the cache' do
+ cache.write(cache_prefix, 'test_item')
+
+ expect(cache.read(cache_prefix)).to contain_exactly('test_item')
+ end
+
+ it 'sets the expiry of the set' do
+ cache.write(cache_prefix, 'test_item')
+
+ expect(cache.ttl(cache_prefix)).to be_within(1).of(expires_in.seconds)
+ end
+ end
+
+ describe '#clear_cache!', :use_clean_rails_redis_caching do
+ it 'deletes the cached items' do
+ # Cached key and value
+ Rails.cache.write('test_item', 'test_value')
+ # Add key to set
+ cache.write(cache_prefix, 'test_item')
+
+ expect(cache.read(cache_prefix)).to contain_exactly('test_item')
+ cache.clear_cache!(cache_prefix)
+
+ expect(cache.read(cache_prefix)).to be_empty
+ end
+ end
+
+ describe '#include?' do
+ subject { cache.include?(cache_prefix, 'test_item') }
+
+ it { is_expected.to be(false) }
+
+ context 'item added' do
+ before do
+ cache.write(cache_prefix, 'test_item')
+ end
+
+ it { is_expected.to be(true) }
+ end
+ end
+end
diff --git a/spec/support/caching.rb b/spec/support/caching.rb
index ecbe65f7e97..883d531550a 100644
--- a/spec/support/caching.rb
+++ b/spec/support/caching.rb
@@ -21,6 +21,21 @@ RSpec.configure do |config|
ActionController::Base.cache_store = caching_store
end
+ config.around(:each, :use_clean_rails_redis_caching) do |example|
+ original_null_store = Rails.cache
+ caching_config_hash = Gitlab::Redis::Cache.params
+ caching_config_hash[:namespace] = Gitlab::Redis::Cache::CACHE_NAMESPACE
+ Rails.cache = ActiveSupport::Cache::RedisCacheStore.new(caching_config_hash)
+
+ redis_cache_cleanup!
+
+ example.run
+
+ redis_cache_cleanup!
+
+ Rails.cache = original_null_store
+ end
+
config.around(:each, :use_sql_query_cache) do |example|
ActiveRecord::Base.cache do
example.run