Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
f019a07d
Commit
f019a07d
authored
Dec 14, 2017
by
Valery Sizov
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ee into ce-to-ee-2017-12-12[ci skip]
parents
9d4e5e30
38b06690
Changes
96
Hide whitespace changes
Inline
Side-by-side
Showing
96 changed files
with
971 additions
and
502 deletions
+971
-502
app/assets/javascripts/activities.js
app/assets/javascripts/activities.js
+2
-1
app/assets/javascripts/commits.js
app/assets/javascripts/commits.js
+2
-1
app/assets/javascripts/compare.js
app/assets/javascripts/compare.js
+2
-1
app/assets/javascripts/deploy_keys/components/key.vue
app/assets/javascripts/deploy_keys/components/key.vue
+2
-1
app/assets/javascripts/diff_notes/models/discussion.js
app/assets/javascripts/diff_notes/models/discussion.js
+2
-1
app/assets/javascripts/job.js
app/assets/javascripts/job.js
+2
-1
app/assets/javascripts/lib/utils/axios_utils.js
app/assets/javascripts/lib/utils/axios_utils.js
+2
-0
app/assets/javascripts/lib/utils/cache.js
app/assets/javascripts/lib/utils/cache.js
+1
-3
app/assets/javascripts/lib/utils/constants.js
app/assets/javascripts/lib/utils/constants.js
+0
-1
app/assets/javascripts/lib/utils/datetime_utility.js
app/assets/javascripts/lib/utils/datetime_utility.js
+116
-97
app/assets/javascripts/main.js
app/assets/javascripts/main.js
+3
-3
app/assets/javascripts/merge_request_tabs.js
app/assets/javascripts/merge_request_tabs.js
+3
-2
app/assets/javascripts/milestone_select.js
app/assets/javascripts/milestone_select.js
+2
-1
app/assets/javascripts/notes.js
app/assets/javascripts/notes.js
+3
-2
app/assets/javascripts/users/activity_calendar.js
app/assets/javascripts/users/activity_calendar.js
+3
-2
app/assets/javascripts/users/user_tabs.js
app/assets/javascripts/users/user_tabs.js
+2
-1
app/assets/javascripts/vue_merge_request_widget/components/mr_widget_deployment.js
...e_merge_request_widget/components/mr_widget_deployment.js
+2
-2
app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
...cripts/vue_merge_request_widget/stores/mr_widget_store.js
+2
-1
app/assets/javascripts/vue_shared/components/memory_graph.js
app/assets/javascripts/vue_shared/components/memory_graph.js
+3
-1
app/assets/javascripts/vue_shared/mixins/timeago.js
app/assets/javascripts/vue_shared/mixins/timeago.js
+3
-3
app/views/projects/commits/_commit.html.haml
app/views/projects/commits/_commit.html.haml
+2
-2
app/workers/all_queues.yml
app/workers/all_queues.yml
+132
-0
app/workers/build_finished_worker.rb
app/workers/build_finished_worker.rb
+1
-1
app/workers/build_hooks_worker.rb
app/workers/build_hooks_worker.rb
+1
-1
app/workers/build_queue_worker.rb
app/workers/build_queue_worker.rb
+1
-1
app/workers/build_success_worker.rb
app/workers/build_success_worker.rb
+1
-1
app/workers/concerns/application_worker.rb
app/workers/concerns/application_worker.rb
+22
-2
app/workers/concerns/cluster_queue.rb
app/workers/concerns/cluster_queue.rb
+1
-1
app/workers/concerns/cronjob_queue.rb
app/workers/concerns/cronjob_queue.rb
+2
-1
app/workers/concerns/geo_queue.rb
app/workers/concerns/geo_queue.rb
+1
-1
app/workers/concerns/gitlab/github_import/queue.rb
app/workers/concerns/gitlab/github_import/queue.rb
+3
-1
app/workers/concerns/pipeline_queue.rb
app/workers/concerns/pipeline_queue.rb
+1
-9
app/workers/concerns/repository_check_queue.rb
app/workers/concerns/repository_check_queue.rb
+3
-1
app/workers/create_pipeline_worker.rb
app/workers/create_pipeline_worker.rb
+1
-1
app/workers/expire_job_cache_worker.rb
app/workers/expire_job_cache_worker.rb
+1
-1
app/workers/expire_pipeline_cache_worker.rb
app/workers/expire_pipeline_cache_worker.rb
+1
-1
app/workers/geo/base_scheduler_worker.rb
app/workers/geo/base_scheduler_worker.rb
+0
-1
app/workers/geo/file_download_dispatch_worker.rb
app/workers/geo/file_download_dispatch_worker.rb
+2
-0
app/workers/geo/repository_shard_sync_worker.rb
app/workers/geo/repository_shard_sync_worker.rb
+1
-3
app/workers/gitlab/github_import/advance_stage_worker.rb
app/workers/gitlab/github_import/advance_stage_worker.rb
+1
-1
app/workers/pages_worker.rb
app/workers/pages_worker.rb
+1
-1
app/workers/pipeline_hooks_worker.rb
app/workers/pipeline_hooks_worker.rb
+1
-1
app/workers/pipeline_process_worker.rb
app/workers/pipeline_process_worker.rb
+1
-1
app/workers/pipeline_success_worker.rb
app/workers/pipeline_success_worker.rb
+1
-1
app/workers/pipeline_update_worker.rb
app/workers/pipeline_update_worker.rb
+1
-1
app/workers/stage_update_worker.rb
app/workers/stage_update_worker.rb
+1
-1
app/workers/update_head_pipeline_for_merge_request_worker.rb
app/workers/update_head_pipeline_for_merge_request_worker.rb
+1
-2
changelogs/unreleased-ee/3501-fix-rebase-in-ie.yml
changelogs/unreleased-ee/3501-fix-rebase-in-ie.yml
+5
-0
changelogs/unreleased-ee/39734-fix-protected-refs-roles.yml
changelogs/unreleased-ee/39734-fix-protected-refs-roles.yml
+5
-0
changelogs/unreleased-ee/add-eeu-to-usage-ping.yml
changelogs/unreleased-ee/add-eeu-to-usage-ping.yml
+5
-0
changelogs/unreleased-ee/check-environment-regex.yml
changelogs/unreleased-ee/check-environment-regex.yml
+5
-0
changelogs/unreleased/25317-prioritize-author-date-over-commit.yml
...s/unreleased/25317-prioritize-author-date-over-commit.yml
+5
-0
config/initializers/sidekiq.rb
config/initializers/sidekiq.rb
+2
-16
config/sidekiq_queues.yml
config/sidekiq_queues.yml
+5
-4
db/post_migrate/20171213160445_migrate_github_importer_advance_stage_sidekiq_queue.rb
...45_migrate_github_importer_advance_stage_sidekiq_queue.rb
+16
-0
db/schema.rb
db/schema.rb
+1
-1
doc/administration/operations/extra_sidekiq_processes.md
doc/administration/operations/extra_sidekiq_processes.md
+8
-2
doc/development/sidekiq_style_guide.md
doc/development/sidekiq_style_guide.md
+44
-15
ee/app/assets/javascripts/protected_branches/protected_branch_access_dropdown.js
...ts/protected_branches/protected_branch_access_dropdown.js
+9
-1
ee/app/assets/javascripts/protected_tags/protected_tag_access_dropdown.js
...vascripts/protected_tags/protected_tag_access_dropdown.js
+9
-1
ee/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue
...rge_request_widget/components/states/mr_widget_rebase.vue
+3
-6
ee/app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js
...ts/vue_merge_request_widget/services/mr_widget_service.js
+12
-17
ee/app/workers/rebase_worker.rb
ee/app/workers/rebase_worker.rb
+0
-2
lib/gitlab/regex.rb
lib/gitlab/regex.rb
+1
-1
lib/gitlab/sidekiq_cluster/cli.rb
lib/gitlab/sidekiq_cluster/cli.rb
+6
-1
lib/gitlab/sidekiq_config.rb
lib/gitlab/sidekiq_config.rb
+24
-13
lib/gitlab/sidekiq_versioning.rb
lib/gitlab/sidekiq_versioning.rb
+25
-0
lib/gitlab/sidekiq_versioning/manager.rb
lib/gitlab/sidekiq_versioning/manager.rb
+12
-0
lib/gitlab/usage_data.rb
lib/gitlab/usage_data.rb
+2
-0
rubocop/cop/include_sidekiq_worker.rb
rubocop/cop/include_sidekiq_worker.rb
+29
-0
rubocop/cop/sidekiq_options_queue.rb
rubocop/cop/sidekiq_options_queue.rb
+27
-0
rubocop/rubocop.rb
rubocop/rubocop.rb
+2
-0
spec/ee/spec/lib/ee/gitlab/regex_spec.rb
spec/ee/spec/lib/ee/gitlab/regex_spec.rb
+12
-0
spec/ee/spec/models/concerns/has_environment_scope_spec.rb
spec/ee/spec/models/concerns/has_environment_scope_spec.rb
+1
-1
spec/ee/spec/models/ee/project_spec.rb
spec/ee/spec/models/ee/project_spec.rb
+8
-8
spec/features/commits_spec.rb
spec/features/commits_spec.rb
+1
-1
spec/javascripts/datetime_utility_spec.js
spec/javascripts/datetime_utility_spec.js
+92
-94
spec/javascripts/deploy_keys/components/key_spec.js
spec/javascripts/deploy_keys/components/key_spec.js
+2
-1
spec/javascripts/notes_spec.js
spec/javascripts/notes_spec.js
+0
-2
spec/javascripts/vue_mr_widget/components/mr_widget_deployment_spec.js
...pts/vue_mr_widget/components/mr_widget_deployment_spec.js
+2
-1
spec/javascripts/vue_mr_widget/ee_mr_widget_options_spec.js
spec/javascripts/vue_mr_widget/ee_mr_widget_options_spec.js
+44
-117
spec/javascripts/vue_shared/components/time_ago_tooltip_spec.js
...avascripts/vue_shared/components/time_ago_tooltip_spec.js
+3
-3
spec/lib/gitlab/sidekiq_cluster/cli_spec.rb
spec/lib/gitlab/sidekiq_cluster/cli_spec.rb
+20
-7
spec/lib/gitlab/sidekiq_config_spec.rb
spec/lib/gitlab/sidekiq_config_spec.rb
+22
-1
spec/lib/gitlab/sidekiq_versioning/manager_spec.rb
spec/lib/gitlab/sidekiq_versioning/manager_spec.rb
+22
-0
spec/lib/gitlab/sidekiq_versioning_spec.rb
spec/lib/gitlab/sidekiq_versioning_spec.rb
+44
-0
spec/rubocop/cop/include_sidekiq_worker_spec.rb
spec/rubocop/cop/include_sidekiq_worker_spec.rb
+31
-0
spec/rubocop/cop/sidekiq_options_queue_spec.rb
spec/rubocop/cop/sidekiq_options_queue_spec.rb
+26
-0
spec/workers/concerns/application_worker_spec.rb
spec/workers/concerns/application_worker_spec.rb
+8
-0
spec/workers/concerns/cluster_queue_spec.rb
spec/workers/concerns/cluster_queue_spec.rb
+1
-1
spec/workers/concerns/cronjob_queue_spec.rb
spec/workers/concerns/cronjob_queue_spec.rb
+1
-1
spec/workers/concerns/geo_queue_spec.rb
spec/workers/concerns/geo_queue_spec.rb
+1
-1
spec/workers/concerns/gitlab/github_import/queue_spec.rb
spec/workers/concerns/gitlab/github_import/queue_spec.rb
+1
-1
spec/workers/concerns/pipeline_queue_spec.rb
spec/workers/concerns/pipeline_queue_spec.rb
+1
-10
spec/workers/concerns/repository_check_queue_spec.rb
spec/workers/concerns/repository_check_queue_spec.rb
+1
-1
spec/workers/every_sidekiq_worker_spec.rb
spec/workers/every_sidekiq_worker_spec.rb
+23
-8
No files found.
app/assets/javascripts/activities.js
View file @
f019a07d
...
...
@@ -2,6 +2,7 @@
/* global Pager */
import
Cookies
from
'
js-cookie
'
;
import
{
localTimeAgo
}
from
'
./lib/utils/datetime_utility
'
;
class
Activities
{
constructor
()
{
...
...
@@ -15,7 +16,7 @@ class Activities {
}
updateTooltips
()
{
gl
.
utils
.
localTimeAgo
(
$
(
'
.js-timeago
'
,
'
.content_list
'
));
localTimeAgo
(
$
(
'
.js-timeago
'
,
'
.content_list
'
));
}
reloadActivities
()
{
...
...
app/assets/javascripts/commits.js
View file @
f019a07d
...
...
@@ -4,6 +4,7 @@
/* global Pager */
import
{
pluralize
}
from
'
./lib/utils/text_utility
'
;
import
{
localTimeAgo
}
from
'
./lib/utils/datetime_utility
'
;
export
default
(
function
()
{
const
CommitsList
=
{};
...
...
@@ -91,7 +92,7 @@ export default (function () {
$commitsHeadersLast
.
find
(
'
span.commits-count
'
).
text
(
`
${
commitsCount
}
${
pluralize
(
'
commit
'
,
commitsCount
)}
`
);
}
gl
.
utils
.
localTimeAgo
(
$processedData
.
find
(
'
.js-timeago
'
));
localTimeAgo
(
$processedData
.
find
(
'
.js-timeago
'
));
return
processedData
;
};
...
...
app/assets/javascripts/compare.js
View file @
f019a07d
/* eslint-disable func-names, space-before-function-paren, wrap-iife, quotes, no-var, object-shorthand, consistent-return, no-unused-vars, comma-dangle, vars-on-top, prefer-template, max-len */
import
{
localTimeAgo
}
from
'
./lib/utils/datetime_utility
'
;
export
default
class
Compare
{
constructor
(
opts
)
{
...
...
@@ -81,7 +82,7 @@ export default class Compare {
loading
.
hide
();
$target
.
html
(
html
);
var
className
=
'
.
'
+
$target
[
0
].
className
.
replace
(
'
'
,
'
.
'
);
gl
.
utils
.
localTimeAgo
(
$
(
'
.js-timeago
'
,
className
));
localTimeAgo
(
$
(
'
.js-timeago
'
,
className
));
}
});
}
...
...
app/assets/javascripts/deploy_keys/components/key.vue
View file @
f019a07d
<
script
>
import
actionBtn
from
'
./action_btn.vue
'
;
import
{
getTimeago
}
from
'
../../lib/utils/datetime_utility
'
;
export
default
{
props
:
{
...
...
@@ -21,7 +22,7 @@
},
computed
:
{
timeagoDate
()
{
return
g
l
.
utils
.
g
etTimeago
().
format
(
this
.
deployKey
.
created_at
);
return
getTimeago
().
format
(
this
.
deployKey
.
created_at
);
},
editDeployKeyPath
()
{
return
`
${
this
.
endpoint
}
/
${
this
.
deployKey
.
id
}
/edit`
;
...
...
app/assets/javascripts/diff_notes/models/discussion.js
View file @
f019a07d
...
...
@@ -2,6 +2,7 @@
/* global NoteModel */
import
Vue
from
'
vue
'
;
import
{
localTimeAgo
}
from
'
../../lib/utils/datetime_utility
'
;
class
DiscussionModel
{
constructor
(
discussionId
)
{
...
...
@@ -71,7 +72,7 @@ class DiscussionModel {
$
(
`
${
discussionSelector
}
.discussion-header`
).
append
(
data
.
discussion_headline_html
);
}
gl
.
utils
.
localTimeAgo
(
$
(
'
.js-timeago
'
,
`
${
discussionSelector
}
`
));
localTimeAgo
(
$
(
'
.js-timeago
'
,
`
${
discussionSelector
}
`
));
}
else
{
$discussionHeadline
.
remove
();
}
...
...
app/assets/javascripts/job.js
View file @
f019a07d
...
...
@@ -3,6 +3,7 @@ import { visitUrl } from './lib/utils/url_utility';
import
bp
from
'
./breakpoints
'
;
import
{
bytesToKiB
}
from
'
./lib/utils/number_utils
'
;
import
{
setCiStatusFavicon
}
from
'
./lib/utils/common_utils
'
;
import
{
timeFor
}
from
'
./lib/utils/datetime_utility
'
;
export
default
class
Job
{
constructor
(
options
)
{
...
...
@@ -261,7 +262,7 @@ export default class Job {
if
(
$date
.
length
)
{
const
date
=
$date
.
text
();
return
$date
.
text
(
gl
.
utils
.
timeFor
(
new
Date
(
date
.
replace
(
/
([
0-9
]
+
)
-
([
0-9
]
+
)
-
([
0-9
]
+
)
/g
,
'
$1/$2/$3
'
)),
'
'
),
timeFor
(
new
Date
(
date
.
replace
(
/
([
0-9
]
+
)
-
([
0-9
]
+
)
-
([
0-9
]
+
)
/g
,
'
$1/$2/$3
'
))
),
);
}
}
...
...
app/assets/javascripts/lib/utils/axios_utils.js
View file @
f019a07d
...
...
@@ -2,6 +2,8 @@ import axios from 'axios';
import
csrf
from
'
./csrf
'
;
axios
.
defaults
.
headers
.
common
[
csrf
.
headerKey
]
=
csrf
.
token
;
// Used by Rails to check if it is a valid XHR request
axios
.
defaults
.
headers
.
common
[
'
X-Requested-With
'
]
=
'
XMLHttpRequest
'
;
// Maintain a global counter for active requests
// see: spec/support/wait_for_requests.rb
...
...
app/assets/javascripts/lib/utils/cache.js
View file @
f019a07d
class
Cache
{
export
default
class
Cache
{
constructor
()
{
this
.
internalStorage
=
{
};
}
...
...
@@ -15,5 +15,3 @@ class Cache {
delete
this
.
internalStorage
[
key
];
}
}
export
default
Cache
;
app/assets/javascripts/lib/utils/constants.js
View file @
f019a07d
/* eslint-disable import/prefer-default-export */
export
const
BYTES_IN_KIB
=
1024
;
export
const
HIDDEN_CLASS
=
'
hidden
'
;
app/assets/javascripts/lib/utils/datetime_utility.js
View file @
f019a07d
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-param-reassign, no-cond-assign, comma-dangle, no-unused-expressions, prefer-template, max-len */
import
timeago
from
'
timeago.js
'
;
import
dateFormat
from
'
vendor/date.format
'
;
import
{
pluralize
}
from
'
./text_utility
'
;
import
{
lang
,
s__
,
...
...
@@ -12,27 +9,65 @@ import {
window
.
timeago
=
timeago
;
window
.
dateFormat
=
dateFormat
;
(
function
()
{
(
function
(
w
)
{
var
base
;
var
timeagoInstance
;
/**
* Given a date object returns the day of the week in English
* @param {date} date
* @returns {String}
*/
export
const
getDayName
=
date
=>
[
'
Sunday
'
,
'
Monday
'
,
'
Tuesday
'
,
'
Wednesday
'
,
'
Thursday
'
,
'
Friday
'
,
'
Saturday
'
][
date
.
getDay
()];
if
(
w
.
gl
==
null
)
{
w
.
gl
=
{};
}
if
((
base
=
w
.
gl
).
utils
==
null
)
{
base
.
utils
=
{};
}
w
.
gl
.
utils
.
days
=
[
'
Sunday
'
,
'
Monday
'
,
'
Tuesday
'
,
'
Wednesday
'
,
'
Thursday
'
,
'
Friday
'
,
'
Saturday
'
]
;
/**
* @example
* dateFormat('2017-12-05','mmm d, yyyy h:MMtt Z' ) -> "Dec 5, 2017 12:00am GMT+0000"
* @param {date} datetime
* @returns {String}
*/
export
const
formatDate
=
datetime
=>
dateFormat
(
datetime
,
'
mmm d, yyyy h:MMtt Z
'
)
;
w
.
gl
.
utils
.
formatDate
=
function
(
datetime
)
{
return
dateFormat
(
datetime
,
'
mmm d, yyyy h:MMtt Z
'
);
let
timeagoInstance
;
/**
* Sets a timeago Instance
*/
export
function
getTimeago
()
{
if
(
!
timeagoInstance
)
{
const
localeRemaining
=
function
getLocaleRemaining
(
number
,
index
)
{
return
[
[
s__
(
'
Timeago|less than a minute ago
'
),
s__
(
'
Timeago|in a while
'
)],
[
s__
(
'
Timeago|less than a minute ago
'
),
s__
(
'
Timeago|%s seconds remaining
'
)],
[
s__
(
'
Timeago|about a minute ago
'
),
s__
(
'
Timeago|1 minute remaining
'
)],
[
s__
(
'
Timeago|%s minutes ago
'
),
s__
(
'
Timeago|%s minutes remaining
'
)],
[
s__
(
'
Timeago|about an hour ago
'
),
s__
(
'
Timeago|1 hour remaining
'
)],
[
s__
(
'
Timeago|about %s hours ago
'
),
s__
(
'
Timeago|%s hours remaining
'
)],
[
s__
(
'
Timeago|a day ago
'
),
s__
(
'
Timeago|1 day remaining
'
)],
[
s__
(
'
Timeago|%s days ago
'
),
s__
(
'
Timeago|%s days remaining
'
)],
[
s__
(
'
Timeago|a week ago
'
),
s__
(
'
Timeago|1 week remaining
'
)],
[
s__
(
'
Timeago|%s weeks ago
'
),
s__
(
'
Timeago|%s weeks remaining
'
)],
[
s__
(
'
Timeago|a month ago
'
),
s__
(
'
Timeago|1 month remaining
'
)],
[
s__
(
'
Timeago|%s months ago
'
),
s__
(
'
Timeago|%s months remaining
'
)],
[
s__
(
'
Timeago|a year ago
'
),
s__
(
'
Timeago|1 year remaining
'
)],
[
s__
(
'
Timeago|%s years ago
'
),
s__
(
'
Timeago|%s years remaining
'
)],
][
index
];
};
w
.
gl
.
utils
.
getDayName
=
function
(
date
)
{
return
this
.
days
[
date
.
getDay
()];
const
locale
=
function
getLocale
(
number
,
index
)
{
return
[
[
s__
(
'
Timeago|less than a minute ago
'
),
s__
(
'
Timeago|in a while
'
)],
[
s__
(
'
Timeago|less than a minute ago
'
),
s__
(
'
Timeago|in %s seconds
'
)],
[
s__
(
'
Timeago|about a minute ago
'
),
s__
(
'
Timeago|in 1 minute
'
)],
[
s__
(
'
Timeago|%s minutes ago
'
),
s__
(
'
Timeago|in %s minutes
'
)],
[
s__
(
'
Timeago|about an hour ago
'
),
s__
(
'
Timeago|in 1 hour
'
)],
[
s__
(
'
Timeago|about %s hours ago
'
),
s__
(
'
Timeago|in %s hours
'
)],
[
s__
(
'
Timeago|a day ago
'
),
s__
(
'
Timeago|in 1 day
'
)],
[
s__
(
'
Timeago|%s days ago
'
),
s__
(
'
Timeago|in %s days
'
)],
[
s__
(
'
Timeago|a week ago
'
),
s__
(
'
Timeago|in 1 week
'
)],
[
s__
(
'
Timeago|%s weeks ago
'
),
s__
(
'
Timeago|in %s weeks
'
)],
[
s__
(
'
Timeago|a month ago
'
),
s__
(
'
Timeago|in 1 month
'
)],
[
s__
(
'
Timeago|%s months ago
'
),
s__
(
'
Timeago|in %s months
'
)],
[
s__
(
'
Timeago|a year ago
'
),
s__
(
'
Timeago|in 1 year
'
)],
[
s__
(
'
Timeago|%s years ago
'
),
s__
(
'
Timeago|in %s years
'
)],
][
index
];
};
<<<<<<<
HEAD
w
.
gl
.
utils
.
localTimeAgo
=
function
(
$timeagoEls
,
setTimeago
=
true
)
{
$timeagoEls
.
each
((
i
,
el
)
=>
{
if
(
setTimeago
)
{
...
...
@@ -41,92 +76,69 @@ window.dateFormat = dateFormat;
template
:
'
<div class="tooltip local-timeago" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>
'
});
}
=======
timeago
.
register
(
lang
,
locale
);
timeago
.
register
(
`
${
lang
}
-remaining`
,
localeRemaining
);
timeagoInstance
=
timeago
();
}
el
.
classList
.
add
(
'
js-timeago-render
'
);
});
return
timeagoInstance
;
}
>>>>>>>
38
b066905132eff84ec50caa8b785d3118b462c2
gl
.
utils
.
renderTimeago
(
$timeagoEls
);
};
/**
* For the given element, renders a timeago instance.
* @param {jQuery} $els
*/
export
const
renderTimeago
=
(
$els
)
=>
{
const
timeagoEls
=
$els
||
document
.
querySelectorAll
(
'
.js-timeago-render
'
);
w
.
gl
.
utils
.
getTimeago
=
function
()
{
var
locale
;
if
(
!
timeagoInstance
)
{
const
localeRemaining
=
function
(
number
,
index
)
{
return
[
[
s__
(
'
Timeago|less than a minute ago
'
),
s__
(
'
Timeago|in a while
'
)],
[
s__
(
'
Timeago|less than a minute ago
'
),
s__
(
'
Timeago|%s seconds remaining
'
)],
[
s__
(
'
Timeago|about a minute ago
'
),
s__
(
'
Timeago|1 minute remaining
'
)],
[
s__
(
'
Timeago|%s minutes ago
'
),
s__
(
'
Timeago|%s minutes remaining
'
)],
[
s__
(
'
Timeago|about an hour ago
'
),
s__
(
'
Timeago|1 hour remaining
'
)],
[
s__
(
'
Timeago|about %s hours ago
'
),
s__
(
'
Timeago|%s hours remaining
'
)],
[
s__
(
'
Timeago|a day ago
'
),
s__
(
'
Timeago|1 day remaining
'
)],
[
s__
(
'
Timeago|%s days ago
'
),
s__
(
'
Timeago|%s days remaining
'
)],
[
s__
(
'
Timeago|a week ago
'
),
s__
(
'
Timeago|1 week remaining
'
)],
[
s__
(
'
Timeago|%s weeks ago
'
),
s__
(
'
Timeago|%s weeks remaining
'
)],
[
s__
(
'
Timeago|a month ago
'
),
s__
(
'
Timeago|1 month remaining
'
)],
[
s__
(
'
Timeago|%s months ago
'
),
s__
(
'
Timeago|%s months remaining
'
)],
[
s__
(
'
Timeago|a year ago
'
),
s__
(
'
Timeago|1 year remaining
'
)],
[
s__
(
'
Timeago|%s years ago
'
),
s__
(
'
Timeago|%s years remaining
'
)]
][
index
];
};
locale
=
function
(
number
,
index
)
{
return
[
[
s__
(
'
Timeago|less than a minute ago
'
),
s__
(
'
Timeago|in a while
'
)],
[
s__
(
'
Timeago|less than a minute ago
'
),
s__
(
'
Timeago|in %s seconds
'
)],
[
s__
(
'
Timeago|about a minute ago
'
),
s__
(
'
Timeago|in 1 minute
'
)],
[
s__
(
'
Timeago|%s minutes ago
'
),
s__
(
'
Timeago|in %s minutes
'
)],
[
s__
(
'
Timeago|about an hour ago
'
),
s__
(
'
Timeago|in 1 hour
'
)],
[
s__
(
'
Timeago|about %s hours ago
'
),
s__
(
'
Timeago|in %s hours
'
)],
[
s__
(
'
Timeago|a day ago
'
),
s__
(
'
Timeago|in 1 day
'
)],
[
s__
(
'
Timeago|%s days ago
'
),
s__
(
'
Timeago|in %s days
'
)],
[
s__
(
'
Timeago|a week ago
'
),
s__
(
'
Timeago|in 1 week
'
)],
[
s__
(
'
Timeago|%s weeks ago
'
),
s__
(
'
Timeago|in %s weeks
'
)],
[
s__
(
'
Timeago|a month ago
'
),
s__
(
'
Timeago|in 1 month
'
)],
[
s__
(
'
Timeago|%s months ago
'
),
s__
(
'
Timeago|in %s months
'
)],
[
s__
(
'
Timeago|a year ago
'
),
s__
(
'
Timeago|in 1 year
'
)],
[
s__
(
'
Timeago|%s years ago
'
),
s__
(
'
Timeago|in %s years
'
)]
][
index
];
};
timeago
.
register
(
lang
,
locale
);
timeago
.
register
(
`
${
lang
}
-remaining`
,
localeRemaining
);
timeagoInstance
=
timeago
();
}
return
timeagoInstance
;
};
// timeago.js sets timeouts internally for each timeago value to be updated in real time
getTimeago
().
render
(
timeagoEls
,
lang
);
};
w
.
gl
.
utils
.
timeFor
=
function
(
time
,
suffix
,
expiredLabel
)
{
var
timefor
;
if
(
!
time
)
{
return
''
;
}
if
(
new
Date
(
time
)
<
new
Date
())
{
expiredLabel
||
(
expiredLabel
=
s__
(
'
Timeago|Past due
'
));
timefor
=
expiredLabel
;
}
else
{
timefor
=
gl
.
utils
.
getTimeago
().
format
(
time
,
`
${
lang
}
-remaining`
).
trim
();
}
return
timefor
;
}
;
/**
* For the given elements, sets a tooltip with a formatted date.
* @param {jQuery}
* @param {Boolean} setTimeago
*/
export
const
localTimeAgo
=
(
$timeagoEls
,
setTimeago
=
true
)
=>
{
$timeagoEls
.
each
((
i
,
el
)
=>
{
if
(
setTimeago
)
{
// Recreate with custom template
$
(
el
).
tooltip
({
template
:
'
<div class="tooltip local-timeago" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>
'
,
})
;
}
w
.
gl
.
utils
.
renderTimeago
=
function
(
$els
)
{
const
timeagoEls
=
$els
||
document
.
querySelectorAll
(
'
.js-timeago-render
'
);
el
.
classList
.
add
(
'
js-timeago-render
'
);
}
);
// timeago.js sets timeouts internally for each timeago value to be updated in real time
gl
.
utils
.
getTimeago
().
render
(
timeagoEls
,
lang
);
};
renderTimeago
(
$timeagoEls
);
};
w
.
gl
.
utils
.
getDayDifference
=
function
(
a
,
b
)
{
var
millisecondsPerDay
=
1000
*
60
*
60
*
24
;
var
date1
=
Date
.
UTC
(
a
.
getFullYear
(),
a
.
getMonth
(),
a
.
getDate
());
var
date2
=
Date
.
UTC
(
b
.
getFullYear
(),
b
.
getMonth
(),
b
.
getDate
());
/**
* Returns remaining or passed time over the given time.
* @param {*} time
* @param {*} expiredLabel
*/
export
const
timeFor
=
(
time
,
expiredLabel
)
=>
{
if
(
!
time
)
{
return
''
;
}
if
(
new
Date
(
time
)
<
new
Date
())
{
return
expiredLabel
||
s__
(
'
Timeago|Past due
'
);
}
return
getTimeago
().
format
(
time
,
`
${
lang
}
-remaining`
).
trim
();
};
return
Math
.
floor
((
date2
-
date1
)
/
millisecondsPerDay
);
};
})(
window
);
}).
call
(
window
);
export
const
getDayDifference
=
(
a
,
b
)
=>
{
const
millisecondsPerDay
=
1000
*
60
*
60
*
24
;
const
date1
=
Date
.
UTC
(
a
.
getFullYear
(),
a
.
getMonth
(),
a
.
getDate
());
const
date2
=
Date
.
UTC
(
b
.
getFullYear
(),
b
.
getMonth
(),
b
.
getDate
());
return
Math
.
floor
((
date2
-
date1
)
/
millisecondsPerDay
);
};
/**
* Port of ruby helper time_interval_in_words.
...
...
@@ -161,3 +173,10 @@ export function dateInWords(date, abbreviated = false) {
return
`
${
monthName
}
${
date
.
getDate
()}
,
${
year
}
`
;
}
window
.
gl
=
window
.
gl
||
{};
window
.
gl
.
utils
=
{
...(
window
.
gl
.
utils
||
{}),
getTimeago
,
localTimeAgo
,
};
app/assets/javascripts/main.js
View file @
f019a07d
...
...
@@ -28,7 +28,7 @@ import './commit/image_file';
// lib/utils
import
{
handleLocationHash
}
from
'
./lib/utils/common_utils
'
;
import
'
./lib/utils/datetime_utility
'
;
import
{
localTimeAgo
,
renderTimeago
}
from
'
./lib/utils/datetime_utility
'
;
import
{
getLocationHash
,
visitUrl
}
from
'
./lib/utils/url_utility
'
;
// behaviors
...
...
@@ -195,7 +195,7 @@ $(function () {
return
$
(
this
).
parents
(
'
form
'
).
submit
();
// Form submitter
});
gl
.
utils
.
localTimeAgo
(
$
(
'
abbr.timeago, .js-timeago
'
),
true
);
localTimeAgo
(
$
(
'
abbr.timeago, .js-timeago
'
),
true
);
// Disable form buttons while a form is submitting
$body
.
on
(
'
ajax:complete, ajax:beforeSend, submit
'
,
'
form
'
,
function
(
e
)
{
var
buttons
;
...
...
@@ -287,7 +287,7 @@ $(function () {
loadAwardsHandler
();
new
Aside
();
gl
.
utils
.
renderTimeago
();
renderTimeago
();
$
(
document
).
trigger
(
'
init.scrolling-tabs
'
);
...
...
app/assets/javascripts/merge_request_tabs.js
View file @
f019a07d
...
...
@@ -14,6 +14,7 @@ import {
import
{
getLocationHash
}
from
'
./lib/utils/url_utility
'
;
import
initDiscussionTab
from
'
./image_diff/init_discussion_tab
'
;
import
Diff
from
'
./diff
'
;
import
{
localTimeAgo
}
from
'
./lib/utils/datetime_utility
'
;
import
syntaxHighlight
from
'
./syntax_highlight
'
;
/* eslint-disable max-len */
...
...
@@ -248,7 +249,7 @@ import syntaxHighlight from './syntax_highlight';
url
:
`
${
source
}
.json`
,
success
:
(
data
)
=>
{
document
.
querySelector
(
'
div#commits
'
).
innerHTML
=
data
.
html
;
gl
.
utils
.
localTimeAgo
(
$
(
'
.js-timeago
'
,
'
div#commits
'
));
localTimeAgo
(
$
(
'
.js-timeago
'
,
'
div#commits
'
));
this
.
commitsLoaded
=
true
;
this
.
scrollToElement
(
'
#commits
'
);
},
...
...
@@ -295,7 +296,7 @@ import syntaxHighlight from './syntax_highlight';
gl
.
diffNotesCompileComponents
();
}
gl
.
utils
.
localTimeAgo
(
$
(
'
.js-timeago
'
,
'
div#diffs
'
));
localTimeAgo
(
$
(
'
.js-timeago
'
,
'
div#diffs
'
));
syntaxHighlight
(
$
(
'
#diffs .js-syntax-highlight
'
));
if
(
this
.
diffViewType
()
===
'
parallel
'
&&
this
.
isDiffAction
(
this
.
currentAction
))
{
...
...
app/assets/javascripts/milestone_select.js
View file @
f019a07d
...
...
@@ -2,6 +2,7 @@
/* global Issuable */
/* global ListMilestone */
import
_
from
'
underscore
'
;
import
{
timeFor
}
from
'
./lib/utils/datetime_utility
'
;
(
function
()
{
this
.
MilestoneSelect
=
(
function
()
{
...
...
@@ -239,7 +240,7 @@ import _ from 'underscore';
$value
.
css
(
'
display
'
,
''
);
if
(
data
.
milestone
!=
null
)
{
data
.
milestone
.
full_path
=
_this
.
currentProject
.
full_path
;
data
.
milestone
.
remaining
=
gl
.
utils
.
timeFor
(
data
.
milestone
.
due_date
);
data
.
milestone
.
remaining
=
timeFor
(
data
.
milestone
.
due_date
);
data
.
milestone
.
name
=
data
.
milestone
.
title
;
$value
.
html
(
milestoneLinkTemplate
(
data
.
milestone
));
return
$sidebarCollapsedValue
.
find
(
'
span
'
).
html
(
collapsedSidebarLabelTemplate
(
data
.
milestone
));
...
...
app/assets/javascripts/notes.js
View file @
f019a07d
...
...
@@ -25,6 +25,7 @@ import Autosave from './autosave';
import
TaskList
from
'
./task_list
'
;
import
{
ajaxPost
,
isInViewport
,
getPagePath
,
scrollToElement
,
isMetaKey
}
from
'
./lib/utils/common_utils
'
;
import
imageDiffHelper
from
'
./image_diff/helpers/index
'
;
import
{
localTimeAgo
}
from
'
./lib/utils/datetime_utility
'
;
window
.
autosize
=
Autosize
;
...
...
@@ -311,7 +312,7 @@ export default class Notes {
setupNewNote
(
$note
)
{
// Update datetime format on the recent note
gl
.
utils
.
localTimeAgo
(
$note
.
find
(
'
.js-timeago
'
),
false
);
localTimeAgo
(
$note
.
find
(
'
.js-timeago
'
),
false
);
this
.
collapseLongCommitList
();
this
.
taskList
.
init
();
...
...
@@ -463,7 +464,7 @@ export default class Notes {
this
.
renderDiscussionAvatar
(
diffAvatarContainer
,
noteEntity
);
}
gl
.
utils
.
localTimeAgo
(
$
(
'
.js-timeago
'
),
false
);
localTimeAgo
(
$
(
'
.js-timeago
'
),
false
);
Notes
.
checkMergeRequestStatus
();
return
this
.
updateNotesCount
(
1
);
}
...
...
app/assets/javascripts/users/activity_calendar.js
View file @
f019a07d
import
_
from
'
underscore
'
;
import
d3
from
'
d3
'
;
import
{
getDayName
,
getDayDifference
}
from
'
../lib/utils/datetime_utility
'
;
const
LOADING_HTML
=
`
<div class="text-center">
...
...
@@ -17,7 +18,7 @@ function getSystemDate(systemUtcOffsetSeconds) {
function
formatTooltipText
({
date
,
count
})
{
const
dateObject
=
new
Date
(
date
);
const
dateDayName
=
g
l
.
utils
.
g
etDayName
(
dateObject
);
const
dateDayName
=
getDayName
(
dateObject
);
const
dateText
=
dateObject
.
format
(
'
mmm d, yyyy
'
);
let
contribText
=
'
No contributions
'
;
...
...
@@ -51,7 +52,7 @@ export default class ActivityCalendar {
const
oneYearAgo
=
new
Date
(
today
);
oneYearAgo
.
setFullYear
(
today
.
getFullYear
()
-
1
);
const
days
=
g
l
.
utils
.
g
etDayDifference
(
oneYearAgo
,
today
);
const
days
=
getDayDifference
(
oneYearAgo
,
today
);
for
(
let
i
=
0
;
i
<=
days
;
i
+=
1
)
{
const
date
=
new
Date
(
oneYearAgo
);
...
...
app/assets/javascripts/users/user_tabs.js
View file @
f019a07d
import
ActivityCalendar
from
'
./activity_calendar
'
;
import
{
localTimeAgo
}
from
'
../lib/utils/datetime_utility
'
;
/**
* UserTabs
...
...
@@ -138,7 +139,7 @@ export default class UserTabs {
const
tabSelector
=
`div#
${
action
}
`
;
this
.
$parentEl
.
find
(
tabSelector
).
html
(
data
.
html
);
this
.
loaded
[
action
]
=
true
;
gl
.
utils
.
localTimeAgo
(
$
(
'
.js-timeago
'
,
tabSelector
));
localTimeAgo
(
$
(
'
.js-timeago
'
,
tabSelector
));
},
});
}
...
...
app/assets/javascripts/vue_merge_request_widget/components/mr_widget_deployment.js
View file @
f019a07d
import
'
~/lib/utils/datetime_utility
'
;
import
{
getTimeago
}
from
'
~/lib/utils/datetime_utility
'
;
import
{
visitUrl
}
from
'
../../lib/utils/url_utility
'
;
import
Flash
from
'
../../flash
'
;
import
MemoryUsage
from
'
./mr_widget_memory_usage
'
;
...
...
@@ -17,7 +17,7 @@ export default {
},
methods
:
{
formatDate
(
date
)
{
return
g
l
.
utils
.
g
etTimeago
().
format
(
date
);
return
getTimeago
().
format
(
date
);
},
hasExternalUrls
(
deployment
=
{})
{
return
deployment
.
external_url
&&
deployment
.
external_url_formatted
;
...
...
app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
View file @
f019a07d
import
Timeago
from
'
timeago.js
'
;
import
{
getStateKey
}
from
'
../dependencies
'
;
import
{
formatDate
}
from
'
../../lib/utils/datetime_utility
'
;
export
default
class
MergeRequestStore
{
constructor
(
data
)
{
...
...
@@ -124,7 +125,7 @@ export default class MergeRequestStore {
static
getEventObject
(
event
)
{
return
{
author
:
MergeRequestStore
.
getAuthorObject
(
event
),
updatedAt
:
gl
.
utils
.
formatDate
(
MergeRequestStore
.
getEventUpdatedAtDate
(
event
)),
updatedAt
:
formatDate
(
MergeRequestStore
.
getEventUpdatedAtDate
(
event
)),
formattedUpdatedAt
:
MergeRequestStore
.
getEventDate
(
event
),
};
}
...
...
app/assets/javascripts/vue_shared/components/memory_graph.js
View file @
f019a07d
import
{
getTimeago
}
from
'
../../lib/utils/datetime_utility
'
;
export
default
{
name
:
'
MemoryGraph
'
,
props
:
{
...
...
@@ -16,7 +18,7 @@ export default {
},
computed
:
{
getFormattedMedian
()
{
const
deployedSince
=
g
l
.
utils
.
g
etTimeago
().
format
(
this
.
deploymentTime
*
1000
);
const
deployedSince
=
getTimeago
().
format
(
this
.
deploymentTime
*
1000
);
return
`Deployed
${
deployedSince
}
`
;
},
},
...
...
app/assets/javascripts/vue_shared/mixins/timeago.js
View file @
f019a07d
import
'
../../lib/utils/datetime_utility
'
;
import
{
formatDate
,
getTimeago
}
from
'
../../lib/utils/datetime_utility
'
;
/**
* Mixin with time ago methods used in some vue components
...
...
@@ -6,13 +6,13 @@ import '../../lib/utils/datetime_utility';
export
default
{
methods
:
{
timeFormated
(
time
)
{
const
timeago
=
g
l
.
utils
.
g
etTimeago
();
const
timeago
=
getTimeago
();
return
timeago
.
format
(
time
);
},
tooltipTitle
(
time
)
{
return
gl
.
utils
.
formatDate
(
time
);
return
formatDate
(
time
);
},
},
};
app/views/projects/commits/_commit.html.haml
View file @
f019a07d
...
...
@@ -42,8 +42,8 @@
.commiter
-
commit_author_link
=
commit_author_link
(
commit
,
avatar:
false
,
size:
24
)
-
commit_timeago
=
time_ago_with_tooltip
(
commit
.
committ
ed_date
,
placement:
'bottom'
)
-
commit_text
=
_
(
'%{commit_author_link}
committ
ed %{commit_timeago}'
)
%
{
commit_author_link:
commit_author_link
,
commit_timeago:
commit_timeago
}
-
commit_timeago
=
time_ago_with_tooltip
(
commit
.
author
ed_date
,
placement:
'bottom'
)
-
commit_text
=
_
(
'%{commit_author_link}
author
ed %{commit_timeago}'
)
%
{
commit_author_link:
commit_author_link
,
commit_timeago:
commit_timeago
}
#{
commit_text
.
html_safe
}
-
if
show_project_name
%span
.project_namespace
...
...
app/workers/all_queues.yml
0 → 100644
View file @
f019a07d
---
-
cronjob:admin_email
-
cronjob:expire_build_artifacts
-
cronjob:gitlab_usage_ping
-
cronjob:import_export_project_cleanup
-
cronjob:pipeline_schedule
-
cronjob:prune_old_events
-
cronjob:remove_expired_group_links
-
cronjob:remove_expired_members
-
cronjob:remove_old_web_hook_logs
-
cronjob:remove_unreferenced_lfs_objects
-
cronjob:repository_archive_cache
-
cronjob:repository_check_batch
-
cronjob:requests_profiles
-
cronjob:schedule_update_user_activity
-
cronjob:stuck_ci_jobs
-
cronjob:stuck_import_jobs
-
cronjob:stuck_merge_jobs
-
cronjob:trending_projects
-
gcp_cluster:cluster_install_app
-
gcp_cluster:cluster_provision
-
gcp_cluster:cluster_wait_for_app_installation
-
gcp_cluster:wait_for_cluster_creation
-
github_import_advance_stage
-
github_importer:github_import_import_diff_note
-
github_importer:github_import_import_issue
-
github_importer:github_import_import_note
-
github_importer:github_import_import_pull_request
-
github_importer:github_import_refresh_import_jid
-
github_importer:github_import_stage_finish_import
-
github_importer:github_import_stage_import_base_data
-
github_importer:github_import_stage_import_issues_and_diff_notes
-
github_importer:github_import_stage_import_notes
-
github_importer:github_import_stage_import_pull_requests
-
github_importer:github_import_stage_import_repository
-
pipeline_cache:expire_job_cache
-
pipeline_cache:expire_pipeline_cache
-
pipeline_creation:create_pipeline
-
pipeline_default:build_coverage
-
pipeline_default:build_trace_sections
-
pipeline_default:pipeline_metrics
-
pipeline_default:pipeline_notification
-
pipeline_default:update_head_pipeline_for_merge_request
-
pipeline_hooks:build_hooks
-
pipeline_hooks:pipeline_hooks
-
pipeline_processing:build_finished
-
pipeline_processing:build_queue
-
pipeline_processing:build_success
-
pipeline_processing:pipeline_process
-
pipeline_processing:pipeline_success
-
pipeline_processing:pipeline_update
-
pipeline_processing:stage_update
-
repository_check:repository_check_clear
-
repository_check:repository_check_single_repository
-
default
-
mailers
# ActionMailer::DeliveryJob.queue_name
-
authorized_projects
-
background_migration
-
create_gpg_signature
-
delete_merged_branches
-
delete_user
-
email_receiver
-
emails_on_push
-
expire_build_instance_artifacts
-
git_garbage_collect
-
gitlab_shell
-
group_destroy
-
invalid_gpg_signature_update
-
irker
-
merge
-
namespaceless_project_destroy
-
new_issue
-
new_merge_request
-
new_note
-
pages
-
post_receive
-
process_commit
-
project_cache
-
project_destroy
-
project_export
-
project_migrate_hashed_storage
-
project_service
-
propagate_service_template
-
reactive_caching
-
repository_fork
-
repository_import
-
storage_migrator
-
system_hook_push
-
update_merge_requests
-
update_user_activity
-
upload_checksum
-
web_hook
# EE-specific queues
-
cronjob:clear_shared_runners_minutes
-
cronjob:geo_file_download_dispatch
-
cronjob:geo_metrics_update
-
cronjob:geo_prune_event_log
-
cronjob:geo_repository_sync
-
cronjob:historical_data
-
cronjob:ldap_all_groups_sync
-
cronjob:ldap_sync
-
cronjob:update_all_mirrors
-
geo:geo_file_removal
-
geo:geo_hashed_storage_attachments_migration
-
geo:geo_hashed_storage_migration
-
geo:geo_rename_repository
-
geo:geo_repositories_clean_up
-
geo:geo_repository_destroy
-
admin_emails
-
elastic_batch_project_indexer
-
elastic_commit_indexer
-
elastic_indexer
-
export_csv
-
geo_base_scheduler
-
geo_file_download
-
geo_project_sync
-
geo_repository_shard_sync
-
ldap_group_sync
-
object_storage_upload
-
project_update_repository_storage
-
rebase
-
repository_update_mirror
-
repository_update_remote_mirror
app/workers/build_finished_worker.rb
View file @
f019a07d
...
...
@@ -2,7 +2,7 @@ class BuildFinishedWorker
include
ApplicationWorker
include
PipelineQueue
enqueue_in
group: :
processing
queue_namespace
:pipeline_
processing
def
perform
(
build_id
)
Ci
::
Build
.
find_by
(
id:
build_id
).
try
do
|
build
|
...
...
app/workers/build_hooks_worker.rb
View file @
f019a07d
...
...
@@ -2,7 +2,7 @@ class BuildHooksWorker
include
ApplicationWorker
include
PipelineQueue
enqueue_in
group: :
hooks
queue_namespace
:pipeline_
hooks
def
perform
(
build_id
)
Ci
::
Build
.
find_by
(
id:
build_id
)
...
...
app/workers/build_queue_worker.rb
View file @
f019a07d
...
...
@@ -2,7 +2,7 @@ class BuildQueueWorker
include
ApplicationWorker
include
PipelineQueue
enqueue_in
group: :
processing
queue_namespace
:pipeline_
processing
def
perform
(
build_id
)
Ci
::
Build
.
find_by
(
id:
build_id
).
try
do
|
build
|
...
...
app/workers/build_success_worker.rb
View file @
f019a07d
...
...
@@ -2,7 +2,7 @@ class BuildSuccessWorker
include
ApplicationWorker
include
PipelineQueue
enqueue_in
group: :
processing
queue_namespace
:pipeline_
processing
def
perform
(
build_id
)
Ci
::
Build
.
find_by
(
id:
build_id
).
try
do
|
build
|
...
...
app/workers/concerns/application_worker.rb
View file @
f019a07d
...
...
@@ -3,13 +3,23 @@ Sidekiq::Worker.extend ActiveSupport::Concern
module
ApplicationWorker
extend
ActiveSupport
::
Concern
include
Sidekiq
::
Worker
include
Sidekiq
::
Worker
# rubocop:disable Cop/IncludeSidekiqWorker
included
do
s
idekiq_options
queue:
base_queue_nam
e
s
et_queu
e
end
module
ClassMethods
def
inherited
(
subclass
)
subclass
.
set_queue
end
def
set_queue
queue_name
=
[
queue_namespace
,
base_queue_name
].
compact
.
join
(
':'
)
sidekiq_options
queue:
queue_name
# rubocop:disable Cop/SidekiqOptionsQueue
end
def
base_queue_name
name
.
sub
(
/\AGitlab::/
,
''
)
...
...
@@ -18,6 +28,16 @@ module ApplicationWorker
.
tr
(
'/'
,
'_'
)
end
def
queue_namespace
(
new_namespace
=
nil
)
if
new_namespace
sidekiq_options
queue_namespace:
new_namespace
set_queue
else
get_sidekiq_options
[
'queue_namespace'
]
&
.
to_s
end
end
def
queue
get_sidekiq_options
[
'queue'
].
to_s
end
...
...
app/workers/concerns/cluster_queue.rb
View file @
f019a07d
...
...
@@ -5,6 +5,6 @@ module ClusterQueue
extend
ActiveSupport
::
Concern
included
do
sidekiq_options
queue:
:gcp_cluster
queue_namespace
:gcp_cluster
end
end
app/workers/concerns/cronjob_queue.rb
View file @
f019a07d
...
...
@@ -4,6 +4,7 @@ module CronjobQueue
extend
ActiveSupport
::
Concern
included
do
sidekiq_options
queue: :cronjob
,
retry:
false
queue_namespace
:cronjob
sidekiq_options
retry:
false
end
end
app/workers/concerns/geo_queue.rb
View file @
f019a07d
...
...
@@ -3,6 +3,6 @@ module GeoQueue
extend
ActiveSupport
::
Concern
included
do
sidekiq_options
queue:
:geo
queue_namespace
:geo
end
end
app/workers/concerns/gitlab/github_import/queue.rb
View file @
f019a07d
...
...
@@ -4,12 +4,14 @@ module Gitlab
extend
ActiveSupport
::
Concern
included
do
queue_namespace
:github_importer
# If a job produces an error it may block a stage from advancing
# forever. To prevent this from happening we prevent jobs from going to
# the dead queue. This does mean some resources may not be imported, but
# this is better than a project being stuck in the "import" state
# forever.
sidekiq_options
queue:
'github_importer'
,
dead:
false
,
retry:
5
sidekiq_options
dead:
false
,
retry:
5
end
end
end
...
...
app/workers/concerns/pipeline_queue.rb
View file @
f019a07d
...
...
@@ -5,14 +5,6 @@ module PipelineQueue
extend
ActiveSupport
::
Concern
included
do
sidekiq_options
queue:
'pipeline_default'
end
class_methods
do
def
enqueue_in
(
group
:)
raise
ArgumentError
,
'Unspecified queue group!'
if
group
.
empty?
sidekiq_options
queue:
"pipeline_
#{
group
}
"
end
queue_namespace
:pipeline_default
end
end
app/workers/concerns/repository_check_queue.rb
View file @
f019a07d
...
...
@@ -3,6 +3,8 @@ module RepositoryCheckQueue
extend
ActiveSupport
::
Concern
included
do
sidekiq_options
queue: :repository_check
,
retry:
false
queue_namespace
:repository_check
sidekiq_options
retry:
false
end
end
app/workers/create_pipeline_worker.rb
View file @
f019a07d
...
...
@@ -2,7 +2,7 @@ class CreatePipelineWorker
include
ApplicationWorker
include
PipelineQueue
enqueue_in
group: :
creation
queue_namespace
:pipeline_
creation
def
perform
(
project_id
,
user_id
,
ref
,
source
,
params
=
{})
project
=
Project
.
find
(
project_id
)
...
...
app/workers/expire_job_cache_worker.rb
View file @
f019a07d
...
...
@@ -2,7 +2,7 @@ class ExpireJobCacheWorker
include
ApplicationWorker
include
PipelineQueue
enqueue_in
group: :
cache
queue_namespace
:pipeline_
cache
def
perform
(
job_id
)
job
=
CommitStatus
.
joins
(
:pipeline
,
:project
).
find_by
(
id:
job_id
)
...
...
app/workers/expire_pipeline_cache_worker.rb
View file @
f019a07d
...
...
@@ -2,7 +2,7 @@ class ExpirePipelineCacheWorker
include
ApplicationWorker
include
PipelineQueue
enqueue_in
group: :
cache
queue_namespace
:pipeline_
cache
def
perform
(
pipeline_id
)
pipeline
=
Ci
::
Pipeline
.
find_by
(
id:
pipeline_id
)
...
...
app/workers/geo/base_scheduler_worker.rb
View file @
f019a07d
module
Geo
class
BaseSchedulerWorker
include
ApplicationWorker
include
CronjobQueue
include
ExclusiveLeaseGuard
DB_RETRIEVE_BATCH_SIZE
=
1000
...
...
app/workers/geo/file_download_dispatch_worker.rb
View file @
f019a07d
module
Geo
class
FileDownloadDispatchWorker
<
Geo
::
BaseSchedulerWorker
include
CronjobQueue
private
def
max_capacity
...
...
app/workers/geo/repository_shard_sync_worker.rb
View file @
f019a07d
module
Geo
class
RepositoryShardSyncWorker
<
Geo
::
BaseSchedulerWorker
# We may have many long-running threads, so split them out
# into their own queue to make it possible for other jobs to run.
sidekiq_options
queue: :geo_repository_shard_sync
,
retry:
false
sidekiq_options
retry:
false
attr_accessor
:shard_name
...
...
app/workers/gitlab/github_import/advance_stage_worker.rb
View file @
f019a07d
...
...
@@ -9,7 +9,7 @@ module Gitlab
class
AdvanceStageWorker
include
ApplicationWorker
sidekiq_options
queue:
'github_importer_advance_stage'
,
dead:
false
sidekiq_options
dead:
false
INTERVAL
=
30
.
seconds
.
to_i
...
...
app/workers/pages_worker.rb
View file @
f019a07d
class
PagesWorker
include
ApplicationWorker
sidekiq_options
queue: :pages
,
retry:
false
sidekiq_options
retry:
false
def
perform
(
action
,
*
arg
)
send
(
action
,
*
arg
)
# rubocop:disable GitlabSecurity/PublicSend
...
...
app/workers/pipeline_hooks_worker.rb
View file @
f019a07d
...
...
@@ -2,7 +2,7 @@ class PipelineHooksWorker
include
ApplicationWorker
include
PipelineQueue
enqueue_in
group: :
hooks
queue_namespace
:pipeline_
hooks
def
perform
(
pipeline_id
)
Ci
::
Pipeline
.
find_by
(
id:
pipeline_id
)
...
...
app/workers/pipeline_process_worker.rb
View file @
f019a07d
...
...
@@ -2,7 +2,7 @@ class PipelineProcessWorker
include
ApplicationWorker
include
PipelineQueue
enqueue_in
group: :
processing
queue_namespace
:pipeline_
processing
def
perform
(
pipeline_id
)
Ci
::
Pipeline
.
find_by
(
id:
pipeline_id
)
...
...
app/workers/pipeline_success_worker.rb
View file @
f019a07d
...
...
@@ -2,7 +2,7 @@ class PipelineSuccessWorker
include
ApplicationWorker
include
PipelineQueue
enqueue_in
group: :
processing
queue_namespace
:pipeline_
processing
def
perform
(
pipeline_id
)
Ci
::
Pipeline
.
find_by
(
id:
pipeline_id
).
try
do
|
pipeline
|
...
...
app/workers/pipeline_update_worker.rb
View file @
f019a07d
...
...
@@ -2,7 +2,7 @@ class PipelineUpdateWorker
include
ApplicationWorker
include
PipelineQueue
enqueue_in
group: :
processing
queue_namespace
:pipeline_
processing
def
perform
(
pipeline_id
)
Ci
::
Pipeline
.
find_by
(
id:
pipeline_id
)
...
...
app/workers/stage_update_worker.rb
View file @
f019a07d
...
...
@@ -2,7 +2,7 @@ class StageUpdateWorker
include
ApplicationWorker
include
PipelineQueue
enqueue_in
group: :
processing
queue_namespace
:pipeline_
processing
def
perform
(
stage_id
)
Ci
::
Stage
.
find_by
(
id:
stage_id
).
try
do
|
stage
|
...
...
app/workers/update_head_pipeline_for_merge_request_worker.rb
View file @
f019a07d
class
UpdateHeadPipelineForMergeRequestWorker
include
ApplicationWorker
sidekiq_options
queue:
'pipeline_default'
include
PipelineQueue
def
perform
(
merge_request_id
)
merge_request
=
MergeRequest
.
find
(
merge_request_id
)
...
...
changelogs/unreleased-ee/3501-fix-rebase-in-ie.yml
0 → 100644
View file @
f019a07d
---
title
:
Fix Merge Rquest widget rebase action in Internet Explorer
merge_request
:
3732
author
:
type
:
fixed
changelogs/unreleased-ee/39734-fix-protected-refs-roles.yml
0 → 100644
View file @
f019a07d
---
title
:
Prevent adding same role multiple times on repeated clicks
merge_request
:
3700
author
:
type
:
fixed
changelogs/unreleased-ee/add-eeu-to-usage-ping.yml
0 → 100644
View file @
f019a07d
---
title
:
Record EE Ultimate usage pings correctly
merge_request
:
author
:
type
:
fixed
changelogs/unreleased-ee/check-environment-regex.yml
0 → 100644
View file @
f019a07d
---
title
:
Fix validation of environment scope for Ci::Variable
merge_request
:
3641
author
:
type
:
fixed
changelogs/unreleased/25317-prioritize-author-date-over-commit.yml
0 → 100644
View file @
f019a07d
---
title
:
Show authored date rather than committed date on the commit list
merge_request
:
author
:
type
:
fixed
config/initializers/sidekiq.rb
View file @
f019a07d
...
...
@@ -46,6 +46,8 @@ Sidekiq.configure_server do |config|
Gitlab
::
SidekiqThrottler
.
execute!
Gitlab
::
SidekiqVersioning
.
install!
config
=
Gitlab
::
Database
.
config
||
Rails
.
application
.
config
.
database_configuration
[
Rails
.
env
]
config
[
'pool'
]
=
Sidekiq
.
options
[
:concurrency
]
...
...
@@ -72,19 +74,3 @@ Sidekiq.configure_client do |config|
chain
.
add
Gitlab
::
SidekiqStatus
::
ClientMiddleware
end
end
# The Sidekiq client API always adds the queue to the Sidekiq queue
# list, but mail_room and gitlab-shell do not. This is only necessary
# for monitoring.
begin
queues
=
Gitlab
::
SidekiqConfig
.
worker_queues
Sidekiq
.
redis
do
|
conn
|
conn
.
pipelined
do
queues
.
each
do
|
queue
|
conn
.
sadd
(
'queues'
,
queue
)
end
end
end
rescue
Redis
::
BaseError
,
SocketError
,
Errno
::
ENOENT
,
Errno
::
EADDRNOTAVAIL
,
Errno
::
EAFNOSUPPORT
,
Errno
::
ECONNRESET
,
Errno
::
ECONNREFUSED
end
config/sidekiq_queues.yml
View file @
f019a07d
...
...
@@ -25,8 +25,6 @@
- [new_note, 2]
- [new_issue, 2]
- [new_merge_request, 2]
- [build, 2]
- [pipeline, 2]
- [pipeline_processing, 5]
- [pipeline_creation, 4]
- [pipeline_default, 3]
...
...
@@ -38,11 +36,12 @@
- [mailers, 2]
- [invalid_gpg_signature_update, 2]
- [create_gpg_signature, 2]
- [rebase, 2]
- [upload_checksum, 1]
- [repository_fork, 1]
- [repository_import, 1]
- [github_importer, 1]
- [github_import
er
_advance_stage, 1]
- [github_import_advance_stage, 1]
- [project_service, 1]
- [delete_user, 1]
- [delete_merged_branches, 1]
...
...
@@ -68,13 +67,15 @@
- [gcp_cluster, 1]
- [project_migrate_hashed_storage, 1]
- [storage_migrator, 1]
# EE specific queues
# EE-specific queues
- [ldap_group_sync, 2]
- [geo, 1]
- [repository_update_mirror, 1]
- [repository_update_remote_mirror, 1]
- [project_update_repository_storage, 1]
- [admin_emails, 1]
- [geo_base_scheduler, 1]
# Parent class of geo_repository_shard_sync and cronjob:geo_file_download_dispatch
-
[
geo_project_sync
,
1
]
-
[
geo_file_download
,
1
]
-
[
geo_repository_shard_sync
,
1
]
...
...
db/post_migrate/20171213160445_migrate_github_importer_advance_stage_sidekiq_queue.rb
0 → 100644
View file @
f019a07d
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class
MigrateGithubImporterAdvanceStageSidekiqQueue
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
def
up
sidekiq_queue_migrate
'github_importer_advance_stage'
,
to:
'github_import_advance_stage'
end
def
down
sidekiq_queue_migrate
'github_import_advance_stage'
,
to:
'github_importer_advance_stage'
end
end
db/schema.rb
View file @
f019a07d
...
...
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord
::
Schema
.
define
(
version:
201712
06221519
)
do
ActiveRecord
::
Schema
.
define
(
version:
201712
13160445
)
do
# These are extensions that must be enabled in order to support this database
enable_extension
"plpgsql"
...
...
doc/administration/operations/extra_sidekiq_processes.md
View file @
f019a07d
...
...
@@ -18,6 +18,12 @@ Each separate argument denotes a group of queues that have to be processed by a
Sidekiq process. Multiple queues can be processed by the same process by
separating them with a comma instead of a space.
Instead of a queue, a queue namespace can also be provided, to have the process
automatically listen on all queues in that namespace without needing to
explicitly list all the queue names. For more information about queue namespaces,
see the relevant section in the
[
Sidekiq style guide
](
../../development/sidekiq_style_guide.md#queue-namespaces
)
.
For example, say you want to start 2 extra processes: one to process the
"process_commit" queue, and one to process the "post_receive" queue. This can be
done as follows:
...
...
@@ -90,10 +96,10 @@ default value is "development".
## All Queues With Exceptions
You're able to run all queues in
`sidekiq_queues.yml`
file on a single or
You're able to run all queues in
`sidekiq_queues.yml`
file on a single or
multiple processes with exceptions using the
`--negate`
flag.
For example, say you want to run a single process for all queues,
For example, say you want to run a single process for all queues,
except "process_commit" and "post_receive". You can do so by executing:
```
bash
...
...
doc/development/sidekiq_style_guide.md
View file @
f019a07d
...
...
@@ -9,25 +9,54 @@ All workers should include `ApplicationWorker` instead of `Sidekiq::Worker`,
which adds some convenience methods and automatically sets the queue based on
the worker's name.
## De
fault Queue
## De
dicated Queues
Use of the "default" queue is not allowed. Every worker should use a queue that
matches the worker's purpose the closest. For example, workers that are to be
executed periodically should use the "cronjob" queue.
All workers should use their own queue, which is automatically set based on the
worker class name. For a worker named
`ProcessSomethingWorker`
, the queue name
would be
`process_something`
. If you're not sure what queue a worker uses,
you can find it using
`SomeWorker.queue`
. There is almost never a reason to
manually override the queue name using
`sidekiq_options queue: :some_queue`
.
A list of all available queues can be found in
`config/sidekiq_queues.yml`
.
## Queue Namespaces
## Dedicated Queues
While different workers cannot share a queue, they can share a queue namespace.
Most workers should use their own queue, which is automatically set based on the
worker class name. For a worker named
`ProcessSomethingWorker`
, the queue name
would be
`process_something`
. If you're not sure what a worker's queue name is,
you can find it using
`SomeWorker.queue`
.
Defining a queue namespace for a worker makes it possible to start a Sidekiq
process that automatically handles jobs for all workers in that namespace,
without needing to explicitly list all their queue names. If, for example, all
workers that are managed by sidekiq-cron use the
`cronjob`
queue namespace, we
can spin up a Sidekiq process specifically for these kinds of scheduled jobs.
If a new worker using the
`cronjob`
namespace is added later on, the Sidekiq
process will automatically pick up jobs for that worker too (after having been
restarted), without the need to change any configuration.
A queue namespace can be set using the
`queue_namespace`
DSL class method:
```
ruby
class
SomeScheduledTaskWorker
include
ApplicationWorker
queue_namespace
:cronjob
# ...
end
```
Behind the scenes, this will set
`SomeScheduledTaskWorker.queue`
to
`cronjob:some_scheduled_task`
. Commonly used namespaces will have their own
concern module that can easily be included into the worker class, and that may
set other Sidekiq options besides the queue namespace.
`CronjobQueue`
, for
example, sets the namespace, but also disables retries.
`bundle exec sidekiq`
is namespace-aware, and will automatically listen on all
queues in a namespace (technically: all queues prefixed with the namespace name)
when a namespace is provided instead of a simple queue name in the
`--queue`
(
`-q`
) option, or in the
`:queues:`
section in
`config/sidekiq_queues.yml`
.
In some cases multiple workers do use the same queue. For example, the variou
s
workers for updating CI pipelines all use the
`pipeline`
queue. Adding workers
t
o existing queues should be done with care, as adding more workers can lead to
slow jobs blocking work (even for different jobs) on the shared queue
.
Note that adding a worker to an existing namespace should be done with care, a
s
the extra jobs will take resources away from jobs from workers that were already
t
here, if the resources available to the Sidekiq process handling the namespace
are not adjusted appropriately
.
## Tests
...
...
@@ -36,7 +65,7 @@ tests should be placed in `spec/workers`.
## Removing or renaming queues
Try to avoid renaming or removing queues in minor and patch releases.
Try to avoid renaming or removing
workers and their
queues in minor and patch releases.
During online update instance can have pending jobs and removing the queue can
lead to those jobs being stuck forever. If you can't write migration for those
Sidekiq jobs, please consider doing rename or remove queue in major release only.
ee/app/assets/javascripts/protected_branches/protected_branch_access_dropdown.js
View file @
f019a07d
...
...
@@ -145,8 +145,8 @@ export default class ProtectedBranchAccessDropdown {
addSelectedItem
(
selectedItem
)
{
let
itemToAdd
=
{};
// If the item already exists, just use it
let
index
=
-
1
;
let
alreadyAdded
=
false
;
const
selectedItems
=
this
.
getAllSelectedItems
();
// Compare IDs based on selectedItem.type
...
...
@@ -155,6 +155,10 @@ export default class ProtectedBranchAccessDropdown {
switch
(
selectedItem
.
type
)
{
case
LEVEL_TYPES
.
ROLE
:
comparator
=
LEVEL_ID_PROP
.
ROLE
;
// If the item already exists, just use it
if
(
item
[
comparator
]
===
selectedItem
.
id
)
{
alreadyAdded
=
true
;
}
break
;
case
LEVEL_TYPES
.
GROUP
:
comparator
=
LEVEL_ID_PROP
.
GROUP
;
...
...
@@ -171,6 +175,10 @@ export default class ProtectedBranchAccessDropdown {
}
});
if
(
alreadyAdded
)
{
return
;
}
if
(
index
!==
-
1
&&
selectedItems
[
index
].
_destroy
)
{
delete
selectedItems
[
index
].
_destroy
;
return
;
...
...
ee/app/assets/javascripts/protected_tags/protected_tag_access_dropdown.js
View file @
f019a07d
...
...
@@ -140,8 +140,8 @@ export default class ProtectedTagAccessDropdown {
addSelectedItem
(
selectedItem
)
{
let
itemToAdd
=
{};
// If the item already exists, just use it
let
index
=
-
1
;
let
alreadyAdded
=
false
;
const
selectedItems
=
this
.
getAllSelectedItems
();
// Compare IDs based on selectedItem.type
...
...
@@ -150,6 +150,10 @@ export default class ProtectedTagAccessDropdown {
switch
(
selectedItem
.
type
)
{
case
LEVEL_TYPES
.
ROLE
:
comparator
=
LEVEL_ID_PROP
.
ROLE
;
// If the item already exists, just use it
if
(
item
[
comparator
]
===
selectedItem
.
id
)
{
alreadyAdded
=
true
;
}
break
;
case
LEVEL_TYPES
.
GROUP
:
comparator
=
LEVEL_ID_PROP
.
GROUP
;
...
...
@@ -166,6 +170,10 @@ export default class ProtectedTagAccessDropdown {
}
});
if
(
alreadyAdded
)
{
return
;
}
if
(
index
!==
-
1
&&
selectedItems
[
index
].
_destroy
)
{
delete
selectedItems
[
index
].
_destroy
;
return
;
...
...
ee/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue
View file @
f019a07d
...
...
@@ -23,7 +23,7 @@
data
()
{
return
{
isMakingRequest
:
false
,
rebasingError
:
''
,
rebasingError
:
null
,
};
},
computed
:
{
...
...
@@ -39,14 +39,11 @@
showDisabledButton
()
{
return
[
'
failed
'
,
'
loading
'
].
includes
(
this
.
status
);
},
hasRebasingError
()
{
return
this
.
rebasingError
.
length
;
},
},
methods
:
{
rebase
()
{
this
.
isMakingRequest
=
true
;
this
.
rebasingError
=
''
;
this
.
rebasingError
=
null
;
this
.
service
.
rebase
()
.
then
(()
=>
{
...
...
@@ -117,7 +114,7 @@
Rebase
</button>
<span
v-if=
"!
hasR
ebasingError"
v-if=
"!
r
ebasingError"
class=
"bold"
>
Fast-forward merge is not possible.
Rebase the source branch onto the target branch or merge target
...
...
ee/app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js
View file @
f019a07d
import
Vue
from
'
vue
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
CEWidgetService
from
'
~/vue_merge_request_widget/services/mr_widget_service
'
;
...
...
@@ -6,36 +6,31 @@ export default class MRWidgetService extends CEWidgetService {
constructor
(
mr
)
{
super
(
mr
);
// Set as a text/plain request so BE doesn't try to parse
// See https://gitlab.com/gitlab-org/gitlab-ce/issues/34534
this
.
approvalsResource
=
Vue
.
resource
(
mr
.
approvalsPath
,
{},
{},
{
headers
:
{
'
Content-Type
'
:
'
text/plain
'
,
},
});
this
.
rebaseResource
=
Vue
.
resource
(
mr
.
rebasePath
);
this
.
approvalsPath
=
mr
.
approvalsPath
;
this
.
rebasePath
=
mr
.
rebasePath
;
}
fetchApprovals
()
{
return
this
.
approvalsResource
.
get
(
)
.
then
(
res
=>
res
.
json
()
);
return
axios
.
get
(
this
.
approvalsPath
)
.
then
(
res
=>
res
.
data
);
}
approveMergeRequest
()
{
return
this
.
approvalsResource
.
save
(
)
.
then
(
res
=>
res
.
json
()
);
return
axios
.
post
(
this
.
approvalsPath
)
.
then
(
res
=>
res
.
data
);
}
unapproveMergeRequest
()
{
return
this
.
approvalsResource
.
delete
(
)
.
then
(
res
=>
res
.
json
()
);
return
axios
.
delete
(
this
.
approvalsPath
)
.
then
(
res
=>
res
.
data
);
}
rebase
()
{
return
this
.
rebaseResource
.
save
(
);
return
axios
.
post
(
this
.
rebasePath
);
}
fetchReport
(
endpoint
)
{
// eslint-disable-line
return
Vue
.
http
.
get
(
endpoint
).
then
(
res
=>
res
.
json
());
return
axios
.
get
(
endpoint
)
.
then
(
res
=>
res
.
data
);
}
}
ee/app/workers/rebase_worker.rb
View file @
f019a07d
class
RebaseWorker
include
ApplicationWorker
sidekiq_options
queue: :merge
def
perform
(
merge_request_id
,
current_user_id
)
current_user
=
User
.
find
(
current_user_id
)
merge_request
=
MergeRequest
.
find
(
merge_request_id
)
...
...
lib/gitlab/regex.rb
View file @
f019a07d
...
...
@@ -38,7 +38,7 @@ module Gitlab
end
def
environment_name_regex_chars
'a-zA-Z0-9_/\\$\\{\\}\\. -'
'a-zA-Z0-9_/\\$\\{\\}\\.
\\
-'
end
def
environment_name_regex
...
...
lib/gitlab/sidekiq_cluster/cli.rb
View file @
f019a07d
...
...
@@ -33,8 +33,13 @@ module Gitlab
queue_groups
=
SidekiqCluster
.
parse_queues
(
argv
)
all_queues
=
SidekiqConfig
.
worker_queues
(
@rails_path
)
queue_groups
.
map!
do
|
queues
|
SidekiqConfig
.
expand_queues
(
queues
,
all_queues
)
end
if
@negate_queues
all_queues
=
SidekiqConfig
.
config_queues
(
@rails_path
)
queue_groups
.
map!
{
|
queues
|
all_queues
-
queues
}
end
...
...
lib/gitlab/sidekiq_config.rb
View file @
f019a07d
require
'yaml'
require
'set'
module
Gitlab
module
SidekiqConfig
def
self
.
redis_queues
@redis_queues
||=
Sidekiq
::
Queue
.
all
.
map
(
&
:name
)
# This method is called by `bin/sidekiq-cluster` in EE, which runs outside
# of bundler/Rails context, so we cannot use any gem or Rails methods.
def
self
.
worker_queues
(
rails_path
=
Rails
.
root
.
to_s
)
@worker_queues
||=
{}
@worker_queues
[
rails_path
]
||=
YAML
.
load_file
(
File
.
join
(
rails_path
,
'app/workers/all_queues.yml'
))
end
# This method is called by `bin/sidekiq-cluster` in EE, which runs outside
# of bundler/Rails context, so we cannot use any gem or Rails methods.
def
self
.
config_queues
(
rails_path
=
Rails
.
root
.
to_s
)
def
self
.
expand_queues
(
queues
,
all_queues
=
self
.
worker_queues
)
return
[]
if
queues
.
empty?
queues_set
=
all_queues
.
to_set
queues
.
flat_map
do
|
queue
|
[
queue
,
*
queues_set
.
grep
(
/\A
#{
queue
}
:/
)]
end
end
def
self
.
redis_queues
# Not memoized, because this can change during the life of the application
Sidekiq
::
Queue
.
all
.
map
(
&
:name
)
end
def
self
.
config_queues
@config_queues
||=
begin
config
=
YAML
.
load_file
(
File
.
join
(
rails_path
,
'config'
,
'
sidekiq_queues.yml'
))
config
=
YAML
.
load_file
(
Rails
.
root
.
join
(
'config/
sidekiq_queues.yml'
))
config
[
:queues
].
map
(
&
:first
)
end
end
...
...
@@ -25,14 +44,6 @@ module Gitlab
find_workers
(
Rails
.
root
.
join
(
'ee'
,
'app'
,
'workers'
))
end
def
self
.
default_queues
[
ActionMailer
::
DeliveryJob
.
queue_name
,
'default'
]
end
def
self
.
worker_queues
@worker_queues
||=
(
workers
.
map
(
&
:queue
)
+
default_queues
).
uniq
end
def
self
.
find_workers
(
root
)
concerns
=
root
.
join
(
'concerns'
).
to_s
...
...
@@ -45,7 +56,7 @@ module Gitlab
ns
.
camelize
.
constantize
end
# Skip
concern
s
# Skip
things that aren't worker
s
workers
.
select
{
|
w
|
w
<
Sidekiq
::
Worker
}
end
end
...
...
lib/gitlab/sidekiq_versioning.rb
0 → 100644
View file @
f019a07d
module
Gitlab
module
SidekiqVersioning
def
self
.
install!
Sidekiq
::
Manager
.
prepend
SidekiqVersioning
::
Manager
# The Sidekiq client API always adds the queue to the Sidekiq queue
# list, but mail_room and gitlab-shell do not. This is only necessary
# for monitoring.
begin
queues
=
SidekiqConfig
.
worker_queues
if
queues
.
any?
Sidekiq
.
redis
do
|
conn
|
conn
.
pipelined
do
queues
.
each
do
|
queue
|
conn
.
sadd
(
'queues'
,
queue
)
end
end
end
end
rescue
::
Redis
::
BaseError
,
SocketError
,
Errno
::
ENOENT
,
Errno
::
EADDRNOTAVAIL
,
Errno
::
EAFNOSUPPORT
,
Errno
::
ECONNRESET
,
Errno
::
ECONNREFUSED
end
end
end
end
lib/gitlab/sidekiq_versioning/manager.rb
0 → 100644
View file @
f019a07d
module
Gitlab
module
SidekiqVersioning
module
Manager
def
initialize
(
options
=
{})
options
[
:strict
]
=
false
options
[
:queues
]
=
SidekiqConfig
.
expand_queues
(
options
[
:queues
])
Sidekiq
.
logger
.
info
"Listening on queues
#{
options
[
:queues
].
uniq
.
sort
}
"
super
end
end
end
end
lib/gitlab/usage_data.rb
View file @
f019a07d
...
...
@@ -140,6 +140,8 @@ module Gitlab
def
license_edition
(
plan
)
case
plan
when
'ultimate'
'EEU'
when
'premium'
'EEP'
when
'starter'
...
...
rubocop/cop/include_sidekiq_worker.rb
0 → 100644
View file @
f019a07d
require_relative
'../spec_helpers'
module
RuboCop
module
Cop
# Cop that makes sure workers include `ApplicationWorker`, not `Sidekiq::Worker`.
class
IncludeSidekiqWorker
<
RuboCop
::
Cop
::
Cop
include
SpecHelpers
MSG
=
'Include `ApplicationWorker`, not `Sidekiq::Worker`.'
.
freeze
def_node_matcher
:includes_sidekiq_worker?
,
<<~
PATTERN
(send nil :include (const (const nil :Sidekiq) :Worker))
PATTERN
def
on_send
(
node
)
return
if
in_spec?
(
node
)
return
unless
includes_sidekiq_worker?
(
node
)
add_offense
(
node
.
arguments
.
first
,
:expression
)
end
def
autocorrect
(
node
)
lambda
do
|
corrector
|
corrector
.
replace
(
node
.
source_range
,
'ApplicationWorker'
)
end
end
end
end
end
rubocop/cop/sidekiq_options_queue.rb
0 → 100644
View file @
f019a07d
require_relative
'../spec_helpers'
module
RuboCop
module
Cop
# Cop that prevents manually setting a queue in Sidekiq workers.
class
SidekiqOptionsQueue
<
RuboCop
::
Cop
::
Cop
include
SpecHelpers
MSG
=
'Do not manually set a queue; `ApplicationWorker` sets one automatically.'
.
freeze
def_node_matcher
:sidekiq_options?
,
<<~
PATTERN
(send nil :sidekiq_options $...)
PATTERN
def
on_send
(
node
)
return
if
in_spec?
(
node
)
return
unless
sidekiq_options?
(
node
)
node
.
arguments
.
first
.
each_node
(
:pair
)
do
|
pair
|
key_name
=
pair
.
key
.
children
[
0
]
add_offense
(
pair
,
:expression
)
if
key_name
==
:queue
end
end
end
end
end
rubocop/rubocop.rb
View file @
f019a07d
...
...
@@ -3,10 +3,12 @@ require_relative 'cop/active_record_serialize'
require_relative
'cop/custom_error_class'
require_relative
'cop/gem_fetcher'
require_relative
'cop/in_batches'
require_relative
'cop/include_sidekiq_worker'
require_relative
'cop/line_break_after_guard_clauses'
require_relative
'cop/polymorphic_associations'
require_relative
'cop/project_path_helper'
require_relative
'cop/redirect_with_status'
require_relative
'cop/sidekiq_options_queue'
require_relative
'cop/migration/add_column'
require_relative
'cop/migration/add_concurrent_foreign_key'
require_relative
'cop/migration/add_concurrent_index'
...
...
spec/ee/spec/lib/ee/gitlab/regex_spec.rb
0 → 100644
View file @
f019a07d
# coding: utf-8
require
'spec_helper'
describe
Gitlab
::
Regex
do
describe
'.environment_scope_regex'
do
subject
{
described_class
.
environment_scope_regex
}
it
{
is_expected
.
to
match
(
'foo'
)
}
it
{
is_expected
.
to
match
(
'foo*Z'
)
}
it
{
is_expected
.
not_to
match
(
'!!()()'
)
}
end
end
spec/ee/spec/models/concerns/has_environment_scope_spec.rb
View file @
f019a07d
...
...
@@ -6,7 +6,7 @@ describe HasEnvironmentScope do
it
{
is_expected
.
to
allow_value
(
'*'
).
for
(
:environment_scope
)
}
it
{
is_expected
.
to
allow_value
(
'review/*'
).
for
(
:environment_scope
)
}
it
{
is_expected
.
not_to
allow_value
(
''
).
for
(
:environment_scope
)
}
it
{
is_expected
.
not_to
allow_value
(
'
<>
'
).
for
(
:environment_scope
)
}
it
{
is_expected
.
not_to
allow_value
(
'
!!()()
'
).
for
(
:environment_scope
)
}
it
do
is_expected
.
to
validate_uniqueness_of
(
:key
)
...
...
spec/ee/spec/models/ee/project_spec.rb
View file @
f019a07d
...
...
@@ -759,7 +759,7 @@ describe Project do
context
'when environment scope is exactly matched'
do
before
do
cluster
.
update
(
environment_scope:
'review/name'
)
cluster
.
update
!
(
environment_scope:
'review/name'
)
end
it_behaves_like
'matching environment scope'
...
...
@@ -767,7 +767,7 @@ describe Project do
context
'when environment scope is matched by wildcard'
do
before
do
cluster
.
update
(
environment_scope:
'review/*'
)
cluster
.
update
!
(
environment_scope:
'review/*'
)
end
it_behaves_like
'matching environment scope'
...
...
@@ -775,7 +775,7 @@ describe Project do
context
'when environment scope does not match'
do
before
do
cluster
.
update
(
environment_scope:
'review/*/special'
)
cluster
.
update
!
(
environment_scope:
'review/*/special'
)
end
it_behaves_like
'not matching environment scope'
...
...
@@ -789,14 +789,14 @@ describe Project do
end
it
'does not treat it as wildcard'
do
cluster
.
update
(
environment_scope:
'foo_bar/*'
)
cluster
.
update
!
(
environment_scope:
'foo_bar/*'
)
is_expected
.
to
eq
(
default_cluster
.
platform_kubernetes
)
end
it
'matches literally for _'
do
cluster
.
update
(
environment_scope:
'foo_bar/*'
)
environment
.
update
(
name:
'foo_bar/test'
)
cluster
.
update
!
(
environment_scope:
'foo_bar/*'
)
environment
.
update
!
(
name:
'foo_bar/test'
)
is_expected
.
to
eq
(
cluster
.
platform_kubernetes
)
end
...
...
@@ -819,8 +819,8 @@ describe Project do
is_expected
.
to
eq
(
default_cluster
.
platform_kubernetes
)
end
it
'matches literally for
_
'
do
cluster
.
update
(
environment_scope:
'foo%bar/*'
)
it
'matches literally for
%
'
do
cluster
.
update
_attribute
(
:environment_scope
,
'foo%bar/*'
)
environment
.
update_attribute
(
:name
,
'foo%bar/test'
)
is_expected
.
to
eq
(
cluster
.
platform_kubernetes
)
...
...
spec/features/commits_spec.rb
View file @
f019a07d
...
...
@@ -197,7 +197,7 @@ describe 'Commits' do
commits
=
project
.
repository
.
commits
(
branch_name
)
commits
.
each
do
|
commit
|
expect
(
page
).
to
have_content
(
"
committed
#{
commit
.
committ
ed_date
.
strftime
(
"%b %d, %Y"
)
}
"
)
expect
(
page
).
to
have_content
(
"
authored
#{
commit
.
author
ed_date
.
strftime
(
"%b %d, %Y"
)
}
"
)
end
end
...
...
spec/javascripts/datetime_utility_spec.js
View file @
f019a07d
import
*
as
datetimeUtility
from
'
~/lib/utils/datetime_utility
'
;
(()
=>
{
describe
(
'
Date time utils
'
,
()
=>
{
describe
(
'
timeFor
'
,
()
=>
{
it
(
'
returns `past due` when in past
'
,
()
=>
{
const
date
=
new
Date
();
date
.
setFullYear
(
date
.
getFullYear
()
-
1
);
expect
(
gl
.
utils
.
timeFor
(
date
),
).
toBe
(
'
Past due
'
);
});
it
(
'
returns remaining time when in the future
'
,
()
=>
{
const
date
=
new
Date
();
date
.
setFullYear
(
date
.
getFullYear
()
+
1
);
// Add a day to prevent a transient error. If date is even 1 second
// short of a full year, timeFor will return '11 months remaining'
date
.
setDate
(
date
.
getDate
()
+
1
);
expect
(
gl
.
utils
.
timeFor
(
date
),
).
toBe
(
'
1 year remaining
'
);
});
describe
(
'
Date time utils
'
,
()
=>
{
describe
(
'
timeFor
'
,
()
=>
{
it
(
'
returns `past due` when in past
'
,
()
=>
{
const
date
=
new
Date
();
date
.
setFullYear
(
date
.
getFullYear
()
-
1
);
expect
(
datetimeUtility
.
timeFor
(
date
),
).
toBe
(
'
Past due
'
);
});
describe
(
'
get day name
'
,
()
=>
{
it
(
'
should return Sunday
'
,
()
=>
{
const
day
=
gl
.
utils
.
getDayName
(
new
Date
(
'
07/17/2016
'
));
expect
(
day
).
toBe
(
'
Sunday
'
);
});
it
(
'
should return Monday
'
,
()
=>
{
const
day
=
gl
.
utils
.
getDayName
(
new
Date
(
'
07/18/2016
'
));
expect
(
day
).
toBe
(
'
Monday
'
);
});
it
(
'
should return Tuesday
'
,
()
=>
{
const
day
=
gl
.
utils
.
getDayName
(
new
Date
(
'
07/19/2016
'
));
expect
(
day
).
toBe
(
'
Tuesday
'
);
});
it
(
'
should return Wednesday
'
,
()
=>
{
const
day
=
gl
.
utils
.
getDayName
(
new
Date
(
'
07/20/2016
'
));
expect
(
day
).
toBe
(
'
Wednesday
'
);
});
it
(
'
should return Thursday
'
,
()
=>
{
const
day
=
gl
.
utils
.
getDayName
(
new
Date
(
'
07/21/2016
'
));
expect
(
day
).
toBe
(
'
Thursday
'
);
});
it
(
'
should return Friday
'
,
()
=>
{
const
day
=
gl
.
utils
.
getDayName
(
new
Date
(
'
07/22/2016
'
));
expect
(
day
).
toBe
(
'
Friday
'
);
});
it
(
'
should return Saturday
'
,
()
=>
{
const
day
=
gl
.
utils
.
getDayName
(
new
Date
(
'
07/23/2016
'
));
expect
(
day
).
toBe
(
'
Saturday
'
);
});
});
it
(
'
returns remaining time when in the future
'
,
()
=>
{
const
date
=
new
Date
();
date
.
setFullYear
(
date
.
getFullYear
()
+
1
);
// Add a day to prevent a transient error. If date is even 1 second
// short of a full year, timeFor will return '11 months remaining'
date
.
setDate
(
date
.
getDate
()
+
1
);
describe
(
'
get day difference
'
,
()
=>
{
it
(
'
should return 7
'
,
()
=>
{
const
firstDay
=
new
Date
(
'
07/01/2016
'
);
const
secondDay
=
new
Date
(
'
07/08/2016
'
);
const
difference
=
gl
.
utils
.
getDayDifference
(
firstDay
,
secondDay
);
expect
(
difference
).
toBe
(
7
);
});
it
(
'
should return 31
'
,
()
=>
{
const
firstDay
=
new
Date
(
'
07/01/2016
'
);
const
secondDay
=
new
Date
(
'
08/01/2016
'
);
const
difference
=
gl
.
utils
.
getDayDifference
(
firstDay
,
secondDay
);
expect
(
difference
).
toBe
(
31
);
});
it
(
'
should return 365
'
,
()
=>
{
const
firstDay
=
new
Date
(
'
07/02/2015
'
);
const
secondDay
=
new
Date
(
'
07/01/2016
'
);
const
difference
=
gl
.
utils
.
getDayDifference
(
firstDay
,
secondDay
);
expect
(
difference
).
toBe
(
365
);
});
expect
(
datetimeUtility
.
timeFor
(
date
),
).
toBe
(
'
1 year remaining
'
);
});
});
describe
(
'
timeIntervalInWords
'
,
()
=>
{
it
(
'
should return string with number of minutes and seconds
'
,
()
=>
{
expect
(
datetimeUtility
.
timeIntervalInWords
(
9.54
)).
toEqual
(
'
9 seconds
'
);
expect
(
datetimeUtility
.
timeIntervalInWords
(
1
)).
toEqual
(
'
1 second
'
);
expect
(
datetimeUtility
.
timeIntervalInWords
(
200
)).
toEqual
(
'
3 minutes 20 seconds
'
);
expect
(
datetimeUtility
.
timeIntervalInWords
(
6008
)).
toEqual
(
'
100 minutes 8 seconds
'
);
describe
(
'
get day name
'
,
()
=>
{
it
(
'
should return Sunday
'
,
()
=>
{
const
day
=
datetimeUtility
.
getDayName
(
new
Date
(
'
07/17/2016
'
));
expect
(
day
).
toBe
(
'
Sunday
'
);
});
it
(
'
should return Monday
'
,
()
=>
{
const
day
=
datetimeUtility
.
getDayName
(
new
Date
(
'
07/18/2016
'
));
expect
(
day
).
toBe
(
'
Monday
'
);
});
it
(
'
should return Tuesday
'
,
()
=>
{
const
day
=
datetimeUtility
.
getDayName
(
new
Date
(
'
07/19/2016
'
));
expect
(
day
).
toBe
(
'
Tuesday
'
);
});
it
(
'
should return Wednesday
'
,
()
=>
{
const
day
=
datetimeUtility
.
getDayName
(
new
Date
(
'
07/20/2016
'
));
expect
(
day
).
toBe
(
'
Wednesday
'
);
});
it
(
'
should return Thursday
'
,
()
=>
{
const
day
=
datetimeUtility
.
getDayName
(
new
Date
(
'
07/21/2016
'
));
expect
(
day
).
toBe
(
'
Thursday
'
);
});
it
(
'
should return Friday
'
,
()
=>
{
const
day
=
datetimeUtility
.
getDayName
(
new
Date
(
'
07/22/2016
'
));
expect
(
day
).
toBe
(
'
Friday
'
);
});
it
(
'
should return Saturday
'
,
()
=>
{
const
day
=
datetimeUtility
.
getDayName
(
new
Date
(
'
07/23/2016
'
));
expect
(
day
).
toBe
(
'
Saturday
'
);
});
});
describe
(
'
dateInWords
'
,
()
=>
{
const
date
=
new
Date
(
'
07/01/2016
'
);
describe
(
'
get day difference
'
,
()
=>
{
it
(
'
should return 7
'
,
()
=>
{
const
firstDay
=
new
Date
(
'
07/01/2016
'
);
const
secondDay
=
new
Date
(
'
07/08/2016
'
);
const
difference
=
datetimeUtility
.
getDayDifference
(
firstDay
,
secondDay
);
expect
(
difference
).
toBe
(
7
);
});
it
(
'
should return date in words
'
,
()
=>
{
expect
(
datetimeUtility
.
dateInWords
(
date
)).
toEqual
(
'
July 1, 2016
'
);
it
(
'
should return 31
'
,
()
=>
{
const
firstDay
=
new
Date
(
'
07/01/2016
'
);
const
secondDay
=
new
Date
(
'
08/01/2016
'
);
const
difference
=
datetimeUtility
.
getDayDifference
(
firstDay
,
secondDay
);
expect
(
difference
).
toBe
(
31
);
});
it
(
'
should return abbreviated month name
'
,
()
=>
{
expect
(
datetimeUtility
.
dateInWords
(
date
,
true
)).
toEqual
(
'
Jul 1, 2016
'
);
it
(
'
should return 365
'
,
()
=>
{
const
firstDay
=
new
Date
(
'
07/02/2015
'
);
const
secondDay
=
new
Date
(
'
07/01/2016
'
);
const
difference
=
datetimeUtility
.
getDayDifference
(
firstDay
,
secondDay
);
expect
(
difference
).
toBe
(
365
);
});
});
})();
});
describe
(
'
timeIntervalInWords
'
,
()
=>
{
it
(
'
should return string with number of minutes and seconds
'
,
()
=>
{
expect
(
datetimeUtility
.
timeIntervalInWords
(
9.54
)).
toEqual
(
'
9 seconds
'
);
expect
(
datetimeUtility
.
timeIntervalInWords
(
1
)).
toEqual
(
'
1 second
'
);
expect
(
datetimeUtility
.
timeIntervalInWords
(
200
)).
toEqual
(
'
3 minutes 20 seconds
'
);
expect
(
datetimeUtility
.
timeIntervalInWords
(
6008
)).
toEqual
(
'
100 minutes 8 seconds
'
);
});
});
describe
(
'
dateInWords
'
,
()
=>
{
const
date
=
new
Date
(
'
07/01/2016
'
);
it
(
'
should return date in words
'
,
()
=>
{
expect
(
datetimeUtility
.
dateInWords
(
date
)).
toEqual
(
'
July 1, 2016
'
);
});
it
(
'
should return abbreviated month name
'
,
()
=>
{
expect
(
datetimeUtility
.
dateInWords
(
date
,
true
)).
toEqual
(
'
Jul 1, 2016
'
);
});
});
spec/javascripts/deploy_keys/components/key_spec.js
View file @
f019a07d
import
Vue
from
'
vue
'
;
import
DeployKeysStore
from
'
~/deploy_keys/store
'
;
import
key
from
'
~/deploy_keys/components/key.vue
'
;
import
{
getTimeago
}
from
'
~/lib/utils/datetime_utility
'
;
describe
(
'
Deploy keys key
'
,
()
=>
{
let
vm
;
...
...
@@ -37,7 +38,7 @@ describe('Deploy keys key', () => {
it
(
'
renders human friendly formatted created date
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.key-created-at
'
).
textContent
.
trim
(),
).
toBe
(
`created
${
g
l
.
utils
.
g
etTimeago
().
format
(
deployKey
.
created_at
)}
`
);
).
toBe
(
`created
${
getTimeago
().
format
(
deployKey
.
created_at
)}
`
);
});
it
(
'
shows edit button
'
,
()
=>
{
...
...
spec/javascripts/notes_spec.js
View file @
f019a07d
...
...
@@ -222,7 +222,6 @@ import '~/notes';
notes
.
note_ids
=
[];
notes
.
updatedNotesTrackingMap
=
{};
spyOn
(
gl
.
utils
,
'
localTimeAgo
'
);
spyOn
(
Notes
,
'
isNewNote
'
).
and
.
callThrough
();
spyOn
(
Notes
,
'
isUpdatedNote
'
).
and
.
callThrough
();
spyOn
(
Notes
,
'
animateAppendNote
'
).
and
.
callThrough
();
...
...
@@ -349,7 +348,6 @@ import '~/notes';
]);
notes
.
note_ids
=
[];
spyOn
(
gl
.
utils
,
'
localTimeAgo
'
);
spyOn
(
Notes
,
'
isNewNote
'
);
spyOn
(
Notes
,
'
animateAppendNote
'
);
Notes
.
isNewNote
.
and
.
returnValue
(
true
);
...
...
spec/javascripts/vue_mr_widget/components/mr_widget_deployment_spec.js
View file @
f019a07d
...
...
@@ -2,6 +2,7 @@ import Vue from 'vue';
import
*
as
urlUtils
from
'
~/lib/utils/url_utility
'
;
import
deploymentComponent
from
'
~/vue_merge_request_widget/components/mr_widget_deployment
'
;
import
MRWidgetService
from
'
~/vue_merge_request_widget/services/mr_widget_service
'
;
import
{
getTimeago
}
from
'
~/lib/utils/datetime_utility
'
;
const
deploymentMockData
=
[
{
...
...
@@ -49,7 +50,7 @@ describe('MRWidgetDeployment', () => {
describe
(
'
formatDate
'
,
()
=>
{
it
(
'
should work
'
,
()
=>
{
const
readable
=
g
l
.
utils
.
g
etTimeago
().
format
(
deployment
.
deployed_at
);
const
readable
=
getTimeago
().
format
(
deployment
.
deployed_at
);
expect
(
vm
.
formatDate
(
deployment
.
deployed_at
)).
toEqual
(
readable
);
});
});
...
...
spec/javascripts/vue_mr_widget/ee_mr_widget_options_spec.js
View file @
f019a07d
import
Vue
from
'
vue
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
mrWidgetOptions
from
'
ee/vue_merge_request_widget/mr_widget_options
'
;
import
MRWidgetService
from
'
ee/vue_merge_request_widget/services/mr_widget_service
'
;
import
MRWidgetStore
from
'
ee/vue_merge_request_widget/stores/mr_widget_store
'
;
...
...
@@ -49,21 +51,16 @@ describe('ee merge request widget options', () => {
});
describe
(
'
with successful request
'
,
()
=>
{
const
interceptor
=
(
request
,
next
)
=>
{
if
(
request
.
url
===
'
path.json
'
)
{
next
(
request
.
respondWith
(
JSON
.
stringify
(
securityIssues
),
{
status
:
200
,
}));
}
};
let
mock
;
beforeEach
(()
=>
{
Vue
.
http
.
interceptors
.
push
(
interceptor
);
mock
=
mock
=
new
MockAdapter
(
axios
);
mock
.
onGet
(
'
path.json
'
).
reply
(
200
,
securityIssues
);
vm
=
mountComponent
(
Component
);
});
afterEach
(()
=>
{
Vue
.
http
.
interceptors
=
_
.
without
(
Vue
.
http
.
interceptors
,
interceptor
);
mock
.
reset
(
);
});
it
(
'
should render provided data
'
,
(
done
)
=>
{
...
...
@@ -77,21 +74,16 @@ describe('ee merge request widget options', () => {
});
describe
(
'
with empty successful request
'
,
()
=>
{
const
emptyInterceptor
=
(
request
,
next
)
=>
{
if
(
request
.
url
===
'
path.json
'
)
{
next
(
request
.
respondWith
(
JSON
.
stringify
([]),
{
status
:
200
,
}));
}
};
let
mock
;
beforeEach
(()
=>
{
Vue
.
http
.
interceptors
.
push
(
emptyInterceptor
);
mock
=
mock
=
new
MockAdapter
(
axios
);
mock
.
onGet
(
'
path.json
'
).
reply
(
200
,
[]);
vm
=
mountComponent
(
Component
);
});
afterEach
(()
=>
{
Vue
.
http
.
interceptors
=
_
.
without
(
Vue
.
http
.
interceptors
,
emptyInterceptor
);
mock
.
reset
(
);
});
it
(
'
should render provided data
'
,
(
done
)
=>
{
...
...
@@ -105,21 +97,16 @@ describe('ee merge request widget options', () => {
});
describe
(
'
with failed request
'
,
()
=>
{
const
errorInterceptor
=
(
request
,
next
)
=>
{
if
(
request
.
url
===
'
path.json
'
)
{
next
(
request
.
respondWith
(
JSON
.
stringify
([]),
{
status
:
500
,
}));
}
};
let
mock
;
beforeEach
(()
=>
{
Vue
.
http
.
interceptors
.
push
(
errorInterceptor
);
mock
=
mock
=
new
MockAdapter
(
axios
);
mock
.
onGet
(
'
path.json
'
).
reply
(
500
,
[]);
vm
=
mountComponent
(
Component
);
});
afterEach
(()
=>
{
Vue
.
http
.
interceptors
=
_
.
without
(
Vue
.
http
.
interceptors
,
errorInterceptor
);
mock
.
reset
(
);
});
it
(
'
should render error indicator
'
,
(
done
)
=>
{
...
...
@@ -157,27 +144,17 @@ describe('ee merge request widget options', () => {
});
describe
(
'
with successful request
'
,
()
=>
{
const
interceptor
=
(
request
,
next
)
=>
{
if
(
request
.
url
===
'
head.json
'
)
{
next
(
request
.
respondWith
(
JSON
.
stringify
(
headIssues
),
{
status
:
200
,
}));
}
if
(
request
.
url
===
'
base.json
'
)
{
next
(
request
.
respondWith
(
JSON
.
stringify
(
baseIssues
),
{
status
:
200
,
}));
}
};
let
mock
;
beforeEach
(()
=>
{
Vue
.
http
.
interceptors
.
push
(
interceptor
);
mock
=
mock
=
new
MockAdapter
(
axios
);
mock
.
onGet
(
'
head.json
'
).
reply
(
200
,
headIssues
);
mock
.
onGet
(
'
base.json
'
).
reply
(
200
,
baseIssues
);
vm
=
mountComponent
(
Component
);
});
afterEach
(()
=>
{
Vue
.
http
.
interceptors
=
_
.
without
(
Vue
.
http
.
interceptors
,
interceptor
);
mock
.
reset
(
);
});
it
(
'
should render provided data
'
,
(
done
)
=>
{
...
...
@@ -218,27 +195,17 @@ describe('ee merge request widget options', () => {
});
describe
(
'
with empty successful request
'
,
()
=>
{
const
emptyInterceptor
=
(
request
,
next
)
=>
{
if
(
request
.
url
===
'
head.json
'
)
{
next
(
request
.
respondWith
(
JSON
.
stringify
([]),
{
status
:
200
,
}));
}
if
(
request
.
url
===
'
base.json
'
)
{
next
(
request
.
respondWith
(
JSON
.
stringify
([]),
{
status
:
200
,
}));
}
};
let
mock
;
beforeEach
(()
=>
{
Vue
.
http
.
interceptors
.
push
(
emptyInterceptor
);
mock
=
mock
=
new
MockAdapter
(
axios
);
mock
.
onGet
(
'
head.json
'
).
reply
(
200
,
[]);
mock
.
onGet
(
'
base.json
'
).
reply
(
200
,
[]);
vm
=
mountComponent
(
Component
);
});
afterEach
(()
=>
{
Vue
.
http
.
interceptors
=
_
.
without
(
Vue
.
http
.
interceptors
,
emptyInterceptor
);
mock
.
reset
(
);
});
it
(
'
should render provided data
'
,
(
done
)
=>
{
...
...
@@ -252,27 +219,17 @@ describe('ee merge request widget options', () => {
});
describe
(
'
with failed request
'
,
()
=>
{
const
errorInterceptor
=
(
request
,
next
)
=>
{
if
(
request
.
url
===
'
head.json
'
)
{
next
(
request
.
respondWith
(
JSON
.
stringify
([]),
{
status
:
500
,
}));
}
if
(
request
.
url
===
'
base.json
'
)
{
next
(
request
.
respondWith
(
JSON
.
stringify
([]),
{
status
:
500
,
}));
}
};
let
mock
;
beforeEach
(()
=>
{
Vue
.
http
.
interceptors
.
push
(
errorInterceptor
);
mock
=
mock
=
new
MockAdapter
(
axios
);
mock
.
onGet
(
'
head.json
'
).
reply
(
500
,
[]);
mock
.
onGet
(
'
base.json
'
).
reply
(
500
,
[]);
vm
=
mountComponent
(
Component
);
});
afterEach
(()
=>
{
Vue
.
http
.
interceptors
=
_
.
without
(
Vue
.
http
.
interceptors
,
errorInterceptor
);
mock
.
reset
(
);
});
it
(
'
should render error indicator
'
,
(
done
)
=>
{
...
...
@@ -308,27 +265,17 @@ describe('ee merge request widget options', () => {
});
describe
(
'
with successful request
'
,
()
=>
{
const
interceptor
=
(
request
,
next
)
=>
{
if
(
request
.
url
===
'
head.json
'
)
{
next
(
request
.
respondWith
(
JSON
.
stringify
(
headPerformance
),
{
status
:
200
,
}));
}
if
(
request
.
url
===
'
base.json
'
)
{
next
(
request
.
respondWith
(
JSON
.
stringify
(
basePerformance
),
{
status
:
200
,
}));
}
};
let
mock
;
beforeEach
(()
=>
{
Vue
.
http
.
interceptors
.
push
(
interceptor
);
mock
=
mock
=
new
MockAdapter
(
axios
);
mock
.
onGet
(
'
head.json
'
).
reply
(
200
,
headPerformance
);
mock
.
onGet
(
'
base.json
'
).
reply
(
200
,
basePerformance
);
vm
=
mountComponent
(
Component
);
});
afterEach
(()
=>
{
Vue
.
http
.
interceptors
=
_
.
without
(
Vue
.
http
.
interceptors
,
interceptor
);
mock
.
reset
(
);
});
it
(
'
should render provided data
'
,
(
done
)
=>
{
...
...
@@ -370,27 +317,17 @@ describe('ee merge request widget options', () => {
});
describe
(
'
with empty successful request
'
,
()
=>
{
const
emptyInterceptor
=
(
request
,
next
)
=>
{
if
(
request
.
url
===
'
head.json
'
)
{
next
(
request
.
respondWith
(
JSON
.
stringify
([]),
{
status
:
200
,
}));
}
if
(
request
.
url
===
'
base.json
'
)
{
next
(
request
.
respondWith
(
JSON
.
stringify
([]),
{
status
:
200
,
}));
}
};
let
mock
;
beforeEach
(()
=>
{
Vue
.
http
.
interceptors
.
push
(
emptyInterceptor
);
mock
=
mock
=
new
MockAdapter
(
axios
);
mock
.
onGet
(
'
head.json
'
).
reply
(
200
,
[]);
mock
.
onGet
(
'
base.json
'
).
reply
(
200
,
[]);
vm
=
mountComponent
(
Component
);
});
afterEach
(()
=>
{
Vue
.
http
.
interceptors
=
_
.
without
(
Vue
.
http
.
interceptors
,
emptyInterceptor
);
mock
.
reset
(
);
});
it
(
'
should render provided data
'
,
(
done
)
=>
{
...
...
@@ -404,27 +341,17 @@ describe('ee merge request widget options', () => {
});
describe
(
'
with failed request
'
,
()
=>
{
const
errorInterceptor
=
(
request
,
next
)
=>
{
if
(
request
.
url
===
'
head.json
'
)
{
next
(
request
.
respondWith
(
JSON
.
stringify
([]),
{
status
:
500
,
}));
}
if
(
request
.
url
===
'
base.json
'
)
{
next
(
request
.
respondWith
(
JSON
.
stringify
([]),
{
status
:
500
,
}));
}
};
let
mock
;
beforeEach
(()
=>
{
Vue
.
http
.
interceptors
.
push
(
errorInterceptor
);
mock
=
mock
=
new
MockAdapter
(
axios
);
mock
.
onGet
(
'
head.json
'
).
reply
(
500
,
[]);
mock
.
onGet
(
'
base.json
'
).
reply
(
500
,
[]);
vm
=
mountComponent
(
Component
);
});
afterEach
(()
=>
{
Vue
.
http
.
interceptors
=
_
.
without
(
Vue
.
http
.
interceptors
,
errorInterceptor
);
mock
.
reset
(
);
});
it
(
'
should render error indicator
'
,
(
done
)
=>
{
...
...
spec/javascripts/vue_shared/components/time_ago_tooltip_spec.js
View file @
f019a07d
import
Vue
from
'
vue
'
;
import
timeagoTooltip
from
'
~/vue_shared/components/time_ago_tooltip.vue
'
;
import
'
~/lib/utils/datetime_utility
'
;
import
{
formatDate
,
getTimeago
}
from
'
~/lib/utils/datetime_utility
'
;
describe
(
'
Time ago with tooltip component
'
,
()
=>
{
let
TimeagoTooltip
;
...
...
@@ -24,10 +24,10 @@ describe('Time ago with tooltip component', () => {
expect
(
vm
.
$el
.
tagName
).
toEqual
(
'
TIME
'
);
expect
(
vm
.
$el
.
getAttribute
(
'
data-original-title
'
),
).
toEqual
(
gl
.
utils
.
formatDate
(
'
2017-05-08T14:57:39.781Z
'
));
).
toEqual
(
formatDate
(
'
2017-05-08T14:57:39.781Z
'
));
expect
(
vm
.
$el
.
getAttribute
(
'
data-placement
'
)).
toEqual
(
'
top
'
);
const
timeago
=
g
l
.
utils
.
g
etTimeago
();
const
timeago
=
getTimeago
();
expect
(
vm
.
$el
.
textContent
.
trim
()).
toEqual
(
timeago
.
format
(
'
2017-05-08T14:57:39.781Z
'
));
});
...
...
spec/lib/gitlab/sidekiq_cluster/cli_spec.rb
View file @
f019a07d
...
...
@@ -11,28 +11,41 @@ describe Gitlab::SidekiqCluster::CLI do
end
context
'with arguments'
do
it
'starts the Sidekiq workers'
do
expect
(
Gitlab
::
SidekiqCluster
).
to
receive
(
:start
).
and_return
([])
before
do
expect
(
cli
).
to
receive
(
:write_pid
)
expect
(
cli
).
to
receive
(
:trap_signals
)
expect
(
cli
).
to
receive
(
:start_loop
)
end
it
'starts the Sidekiq workers'
do
expect
(
Gitlab
::
SidekiqCluster
).
to
receive
(
:start
)
.
with
([[
'foo'
]],
'test'
,
Dir
.
pwd
,
dryrun:
false
)
.
and_return
([])
cli
.
run
(
%w(foo)
)
end
context
'with --negate flag'
do
it
'starts Sidekiq workers for all queues
on sidekiq_queues.yml except the ones o
n argv'
do
expect
(
Gitlab
::
SidekiqConfig
).
to
receive
(
:
config
_queues
).
and_return
([
'baz'
])
it
'starts Sidekiq workers for all queues
in all_queues.yml except the ones i
n argv'
do
expect
(
Gitlab
::
SidekiqConfig
).
to
receive
(
:
worker
_queues
).
and_return
([
'baz'
])
expect
(
Gitlab
::
SidekiqCluster
).
to
receive
(
:start
)
.
with
([[
'baz'
]],
'test'
,
Dir
.
pwd
,
dryrun:
false
)
.
and_return
([])
expect
(
cli
).
to
receive
(
:write_pid
)
expect
(
cli
).
to
receive
(
:trap_signals
)
expect
(
cli
).
to
receive
(
:start_loop
)
cli
.
run
(
%w(foo -n)
)
end
end
context
'queue namespace expansion'
do
it
'starts Sidekiq workers for all queues in all_queues.yml with a namespace in argv'
do
expect
(
Gitlab
::
SidekiqConfig
).
to
receive
(
:worker_queues
).
and_return
([
'cronjob:foo'
,
'cronjob:bar'
])
expect
(
Gitlab
::
SidekiqCluster
).
to
receive
(
:start
)
.
with
([[
'cronjob'
,
'cronjob:foo'
,
'cronjob:bar'
]],
'test'
,
Dir
.
pwd
,
dryrun:
false
)
.
and_return
([])
cli
.
run
(
%w(cronjob)
)
end
end
end
end
...
...
spec/lib/gitlab/sidekiq_config_spec.rb
View file @
f019a07d
...
...
@@ -23,7 +23,7 @@ describe Gitlab::SidekiqConfig do
expect
(
queues
).
to
include
(
'post_receive'
)
expect
(
queues
).
to
include
(
'merge'
)
expect
(
queues
).
to
include
(
'cronjob'
)
expect
(
queues
).
to
include
(
'cronjob
:stuck_import_jobs
'
)
expect
(
queues
).
to
include
(
'mailers'
)
expect
(
queues
).
to
include
(
'default'
)
end
...
...
@@ -35,4 +35,25 @@ describe Gitlab::SidekiqConfig do
expect
(
queues
).
to
include
(
'ldap_group_sync'
)
end
end
describe
'.expand_queues'
do
it
'expands queue namespaces to concrete queue names'
do
queues
=
described_class
.
expand_queues
(
%w[cronjob]
)
expect
(
queues
).
to
include
(
'cronjob:stuck_import_jobs'
)
expect
(
queues
).
to
include
(
'cronjob:stuck_merge_jobs'
)
end
it
'lets concrete queue names pass through'
do
queues
=
described_class
.
expand_queues
(
%w[post_receive]
)
expect
(
queues
).
to
include
(
'post_receive'
)
end
it
'lets unknown queues pass through'
do
queues
=
described_class
.
expand_queues
(
%w[unknown]
)
expect
(
queues
).
to
include
(
'unknown'
)
end
end
end
spec/lib/gitlab/sidekiq_versioning/manager_spec.rb
0 → 100644
View file @
f019a07d
require
'spec_helper'
describe
Gitlab
::
SidekiqVersioning
::
Manager
do
before
do
Sidekiq
::
Manager
.
prepend
described_class
end
describe
'#initialize'
do
it
'listens on all expanded queues'
do
manager
=
Sidekiq
::
Manager
.
new
(
queues:
%w[post_receive repository_fork cronjob unknown]
)
queues
=
manager
.
options
[
:queues
]
expect
(
queues
).
to
include
(
'post_receive'
)
expect
(
queues
).
to
include
(
'repository_fork'
)
expect
(
queues
).
to
include
(
'cronjob'
)
expect
(
queues
).
to
include
(
'cronjob:stuck_import_jobs'
)
expect
(
queues
).
to
include
(
'cronjob:stuck_merge_jobs'
)
expect
(
queues
).
to
include
(
'unknown'
)
end
end
end
spec/lib/gitlab/sidekiq_versioning_spec.rb
0 → 100644
View file @
f019a07d
require
'spec_helper'
describe
Gitlab
::
SidekiqVersioning
,
:sidekiq
,
:redis
do
let
(
:foo_worker
)
do
Class
.
new
do
def
self
.
name
'FooWorker'
end
include
ApplicationWorker
end
end
let
(
:bar_worker
)
do
Class
.
new
do
def
self
.
name
'BarWorker'
end
include
ApplicationWorker
end
end
before
do
allow
(
Gitlab
::
SidekiqConfig
).
to
receive
(
:workers
).
and_return
([
foo_worker
,
bar_worker
])
allow
(
Gitlab
::
SidekiqConfig
).
to
receive
(
:worker_queues
).
and_return
([
foo_worker
.
queue
,
bar_worker
.
queue
])
end
describe
'.install!'
do
it
'prepends SidekiqVersioning::Manager into Sidekiq::Manager'
do
described_class
.
install!
expect
(
Sidekiq
::
Manager
).
to
include
(
Gitlab
::
SidekiqVersioning
::
Manager
)
end
it
'registers all versionless and versioned queues with Redis'
do
described_class
.
install!
queues
=
Sidekiq
::
Queue
.
all
.
map
(
&
:name
)
expect
(
queues
).
to
include
(
'foo'
)
expect
(
queues
).
to
include
(
'bar'
)
end
end
end
spec/rubocop/cop/include_sidekiq_worker_spec.rb
0 → 100644
View file @
f019a07d
require
'spec_helper'
require
'rubocop'
require
'rubocop/rspec/support'
require_relative
'../../../rubocop/cop/include_sidekiq_worker'
describe
RuboCop
::
Cop
::
IncludeSidekiqWorker
do
include
CopHelper
subject
(
:cop
)
{
described_class
.
new
}
context
'when `Sidekiq::Worker` is included'
do
let
(
:source
)
{
'include Sidekiq::Worker'
}
let
(
:correct_source
)
{
'include ApplicationWorker'
}
it
'registers an offense '
do
inspect_source
(
cop
,
source
)
aggregate_failures
do
expect
(
cop
.
offenses
.
size
).
to
eq
(
1
)
expect
(
cop
.
offenses
.
map
(
&
:line
)).
to
eq
([
1
])
expect
(
cop
.
highlights
).
to
eq
([
'Sidekiq::Worker'
])
end
end
it
'autocorrects to the right version'
do
autocorrected
=
autocorrect_source
(
cop
,
source
)
expect
(
autocorrected
).
to
eq
(
correct_source
)
end
end
end
spec/rubocop/cop/sidekiq_options_queue_spec.rb
0 → 100644
View file @
f019a07d
require
'spec_helper'
require
'rubocop'
require
'rubocop/rspec/support'
require_relative
'../../../rubocop/cop/sidekiq_options_queue'
describe
RuboCop
::
Cop
::
SidekiqOptionsQueue
do
include
CopHelper
subject
(
:cop
)
{
described_class
.
new
}
it
'registers an offense when `sidekiq_options` is used with the `queue` option'
do
inspect_source
(
cop
,
'sidekiq_options queue: "some_queue"'
)
aggregate_failures
do
expect
(
cop
.
offenses
.
size
).
to
eq
(
1
)
expect
(
cop
.
offenses
.
map
(
&
:line
)).
to
eq
([
1
])
expect
(
cop
.
highlights
).
to
eq
([
'queue: "some_queue"'
])
end
end
it
'does not register an offense when `sidekiq_options` is used with another option'
do
inspect_source
(
cop
,
'sidekiq_options retry: false'
)
expect
(
cop
.
offenses
).
to
be_empty
end
end
spec/workers/concerns/application_worker_spec.rb
View file @
f019a07d
...
...
@@ -17,6 +17,14 @@ describe ApplicationWorker do
end
end
describe
'.queue_namespace'
do
it
'sets the queue name based on the class name'
do
worker
.
queue_namespace
:some_namespace
expect
(
worker
.
queue
).
to
eq
(
'some_namespace:foo_bar_dummy'
)
end
end
describe
'.queue'
do
it
'returns the queue name'
do
worker
.
sidekiq_options
queue: :some_queue
...
...
spec/workers/concerns/cluster_queue_spec.rb
View file @
f019a07d
...
...
@@ -14,6 +14,6 @@ describe ClusterQueue do
it
'sets a default pipelines queue automatically'
do
expect
(
worker
.
sidekiq_options
[
'queue'
])
.
to
eq
:gcp_cluster
.
to
eq
'gcp_cluster:dummy'
end
end
spec/workers/concerns/cronjob_queue_spec.rb
View file @
f019a07d
...
...
@@ -13,7 +13,7 @@ describe CronjobQueue do
end
it
'sets the queue name of a worker'
do
expect
(
worker
.
sidekiq_options
[
'queue'
].
to_s
).
to
eq
(
'cronjob'
)
expect
(
worker
.
sidekiq_options
[
'queue'
].
to_s
).
to
eq
(
'cronjob
:dummy
'
)
end
it
'disables retrying of failed jobs'
do
...
...
spec/workers/concerns/geo_queue_spec.rb
View file @
f019a07d
...
...
@@ -13,6 +13,6 @@ describe GeoQueue do
end
it
'sets the queue name of a worker'
do
expect
(
worker
.
sidekiq_options
[
'queue'
].
to_s
).
to
eq
(
'geo'
)
expect
(
worker
.
sidekiq_options
[
'queue'
].
to_s
).
to
eq
(
'geo
:dummy
'
)
end
end
spec/workers/concerns/gitlab/github_import/queue_spec.rb
View file @
f019a07d
...
...
@@ -11,6 +11,6 @@ describe Gitlab::GithubImport::Queue do
include
Gitlab
::
GithubImport
::
Queue
end
expect
(
worker
.
sidekiq_options
[
'queue'
]).
to
eq
(
'github_importer'
)
expect
(
worker
.
sidekiq_options
[
'queue'
]).
to
eq
(
'github_importer
:dummy
'
)
end
end
spec/workers/concerns/pipeline_queue_spec.rb
View file @
f019a07d
...
...
@@ -14,15 +14,6 @@ describe PipelineQueue do
it
'sets a default pipelines queue automatically'
do
expect
(
worker
.
sidekiq_options
[
'queue'
])
.
to
eq
'pipeline_default'
end
describe
'.enqueue_in'
do
it
'sets a custom sidekiq queue with prefix and group'
do
worker
.
enqueue_in
(
group: :processing
)
expect
(
worker
.
sidekiq_options
[
'queue'
])
.
to
eq
'pipeline_processing'
end
.
to
eq
'pipeline_default:dummy'
end
end
spec/workers/concerns/repository_check_queue_spec.rb
View file @
f019a07d
...
...
@@ -13,7 +13,7 @@ describe RepositoryCheckQueue do
end
it
'sets the queue name of a worker'
do
expect
(
worker
.
sidekiq_options
[
'queue'
].
to_s
).
to
eq
(
'repository_check'
)
expect
(
worker
.
sidekiq_options
[
'queue'
].
to_s
).
to
eq
(
'repository_check
:dummy
'
)
end
it
'disables retrying of failed jobs'
do
...
...
spec/workers/every_sidekiq_worker_spec.rb
View file @
f019a07d
require
'spec_helper'
describe
'Every Sidekiq worker'
do
it
'includes ApplicationWorker'
do
expect
(
Gitlab
::
SidekiqConfig
.
workers
).
to
all
(
include
(
ApplicationWorker
))
end
it
'does not use the default queue'
do
expect
(
Gitlab
::
SidekiqConfig
.
workers
.
map
(
&
:queue
)).
not_to
include
(
'default'
)
end
it
'uses the cronjob queue when the worker runs as a cronjob'
do
expect
(
Gitlab
::
SidekiqConfig
.
cron_workers
.
map
(
&
:queue
)).
to
all
(
eq
(
'cronjob'
))
expect
(
Gitlab
::
SidekiqConfig
.
cron_workers
.
map
(
&
:queue
)).
to
all
(
start_with
(
'cronjob:'
))
end
it
'has its queue in app/workers/all_queues.yml'
,
:aggregate_failures
do
file_worker_queues
=
Gitlab
::
SidekiqConfig
.
worker_queues
.
to_set
worker_queues
=
Gitlab
::
SidekiqConfig
.
workers
.
map
(
&
:queue
).
to_set
worker_queues
<<
ActionMailer
::
DeliveryJob
.
queue_name
worker_queues
<<
'default'
missing_from_file
=
worker_queues
-
file_worker_queues
expect
(
missing_from_file
).
to
be_empty
,
"expected
#{
missing_from_file
.
to_a
.
inspect
}
to be in app/workers/all_queues.yml"
unncessarily_in_file
=
file_worker_queues
-
worker_queues
expect
(
unncessarily_in_file
).
to
be_empty
,
"expected
#{
unncessarily_in_file
.
to_a
.
inspect
}
not to be in app/workers/all_queues.yml"
end
it
'defines the queue in the Sidekiq configuration file'
do
config_queue_names
=
Gitlab
::
SidekiqConfig
.
config_queues
.
to_set
it
'has its queue or namespace in config/sidekiq_queues.yml'
,
:aggregate_failures
do
config_queues
=
Gitlab
::
SidekiqConfig
.
config_queues
.
to_set
Gitlab
::
SidekiqConfig
.
workers
.
each
do
|
worker
|
queue
=
worker
.
queue
queue_namespace
=
queue
.
split
(
':'
).
first
expect
(
Gitlab
::
SidekiqConfig
.
worker_queues
).
to
all
(
be_in
(
config_queue_names
))
expect
(
config_queues
).
to
include
(
queue
).
or
(
include
(
queue_namespace
))
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment