summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/application.js5
-rw-r--r--app/assets/javascripts/build.js2
-rw-r--r--app/assets/javascripts/cycle_analytics.js.es66
-rw-r--r--app/assets/javascripts/dispatcher.js.es63
-rw-r--r--app/assets/javascripts/gl_field_errors.js.es67
-rw-r--r--app/assets/javascripts/members.js.es61
-rw-r--r--app/assets/javascripts/merge_request_tabs.js22
-rw-r--r--app/assets/stylesheets/framework/animations.scss4
-rw-r--r--app/assets/stylesheets/framework/common.scss2
-rw-r--r--app/assets/stylesheets/framework/dropdowns.scss2
-rw-r--r--app/assets/stylesheets/framework/logo.scss2
-rw-r--r--app/assets/stylesheets/framework/modal.scss2
-rw-r--r--app/assets/stylesheets/framework/sidebar.scss8
-rw-r--r--app/assets/stylesheets/framework/tw_bootstrap_variables.scss122
-rw-r--r--app/assets/stylesheets/framework/variables.scss44
-rw-r--r--app/assets/stylesheets/mailers/devise.scss10
-rw-r--r--app/assets/stylesheets/pages/cycle_analytics.scss18
-rw-r--r--app/assets/stylesheets/pages/diff.scss4
-rw-r--r--app/assets/stylesheets/pages/environments.scss8
-rw-r--r--app/assets/stylesheets/pages/events.scss2
-rw-r--r--app/assets/stylesheets/pages/login.scss41
-rw-r--r--app/assets/stylesheets/pages/merge_conflicts.scss2
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss13
-rw-r--r--app/assets/stylesheets/pages/note_form.scss2
-rw-r--r--app/assets/stylesheets/pages/notes.scss2
-rw-r--r--app/assets/stylesheets/pages/projects.scss16
-rw-r--r--app/assets/stylesheets/pages/status.scss2
-rw-r--r--app/assets/stylesheets/pages/tree.scss4
-rw-r--r--app/controllers/groups/group_members_controller.rb4
-rw-r--r--app/controllers/import/gitlab_projects_controller.rb4
-rw-r--r--app/controllers/projects/project_members_controller.rb6
-rw-r--r--app/finders/labels_finder.rb8
-rw-r--r--app/models/ci/build.rb4
-rw-r--r--app/models/ci/pipeline.rb6
-rw-r--r--app/models/ci/runner.rb6
-rw-r--r--app/models/ci/runner_project.rb4
-rw-r--r--app/models/ci/trigger.rb4
-rw-r--r--app/models/ci/trigger_request.rb6
-rw-r--r--app/models/ci/variable.rb2
-rw-r--r--app/models/commit_status.rb2
-rw-r--r--app/models/concerns/protected_branch_access.rb5
-rw-r--r--app/models/email.rb6
-rw-r--r--app/models/group.rb2
-rw-r--r--app/models/issue.rb8
-rw-r--r--app/models/members/group_member.rb2
-rw-r--r--app/models/members/project_member.rb2
-rw-r--r--app/models/merge_request.rb4
-rw-r--r--app/models/merge_request_diff.rb8
-rw-r--r--app/models/project.rb8
-rw-r--r--app/models/repository.rb27
-rw-r--r--app/models/user.rb10
-rw-r--r--app/services/merge_requests/assign_issues_service.rb2
-rw-r--r--app/services/notes/create_service.rb6
-rw-r--r--app/services/protected_branches/api_create_service.rb29
-rw-r--r--app/services/protected_branches/api_update_service.rb47
-rw-r--r--app/views/admin/runners/index.html.haml2
-rw-r--r--app/views/admin/runners/show.html.haml2
-rw-r--r--app/views/devise/sessions/_new_base.html.haml2
-rw-r--r--app/views/devise/sessions/two_factor.html.haml2
-rw-r--r--app/views/devise/shared/_tabs_ldap.html.haml2
-rw-r--r--app/views/devise/shared/_tabs_normal.html.haml5
-rw-r--r--app/views/import/gitlab_projects/new.html.haml4
-rw-r--r--app/views/projects/boards/components/_card.html.haml2
-rw-r--r--app/views/projects/compare/_form.html.haml2
-rw-r--r--app/views/projects/edit.html.haml116
-rw-r--r--app/views/projects/issues/show.html.haml2
-rw-r--r--app/views/projects/merge_requests/_show.html.haml68
-rw-r--r--app/views/projects/merge_requests/show/_commits.html.haml2
-rw-r--r--app/views/projects/milestones/show.html.haml2
-rw-r--r--app/views/projects/new.html.haml5
-rw-r--r--app/views/projects/notes/_note.html.haml2
-rw-r--r--app/views/projects/runners/_specific_runners.html.haml2
-rw-r--r--app/workers/admin_email_worker.rb3
-rw-r--r--app/workers/build_coverage_worker.rb2
-rw-r--r--app/workers/build_email_worker.rb1
-rw-r--r--app/workers/build_finished_worker.rb1
-rw-r--r--app/workers/build_hooks_worker.rb2
-rw-r--r--app/workers/build_success_worker.rb2
-rw-r--r--app/workers/clear_database_cache_worker.rb1
-rw-r--r--app/workers/concerns/build_queue.rb8
-rw-r--r--app/workers/concerns/cronjob_queue.rb9
-rw-r--r--app/workers/concerns/dedicated_sidekiq_queue.rb9
-rw-r--r--app/workers/concerns/pipeline_queue.rb8
-rw-r--r--app/workers/concerns/repository_check_queue.rb8
-rw-r--r--app/workers/delete_user_worker.rb1
-rw-r--r--app/workers/email_receiver_worker.rb3
-rw-r--r--app/workers/emails_on_push_worker.rb2
-rw-r--r--app/workers/expire_build_artifacts_worker.rb1
-rw-r--r--app/workers/expire_build_instance_artifacts_worker.rb1
-rw-r--r--app/workers/git_garbage_collect_worker.rb3
-rw-r--r--app/workers/gitlab_shell_worker.rb3
-rw-r--r--app/workers/group_destroy_worker.rb3
-rw-r--r--app/workers/import_export_project_cleanup_worker.rb3
-rw-r--r--app/workers/irker_worker.rb1
-rw-r--r--app/workers/merge_worker.rb3
-rw-r--r--app/workers/new_note_worker.rb3
-rw-r--r--app/workers/pipeline_hooks_worker.rb2
-rw-r--r--app/workers/pipeline_metrics_worker.rb3
-rw-r--r--app/workers/pipeline_process_worker.rb3
-rw-r--r--app/workers/pipeline_success_worker.rb2
-rw-r--r--app/workers/pipeline_update_worker.rb3
-rw-r--r--app/workers/post_receive.rb3
-rw-r--r--app/workers/project_cache_worker.rb3
-rw-r--r--app/workers/project_destroy_worker.rb3
-rw-r--r--app/workers/project_export_worker.rb3
-rw-r--r--app/workers/project_service_worker.rb3
-rw-r--r--app/workers/project_web_hook_worker.rb3
-rw-r--r--app/workers/prune_old_events_worker.rb1
-rw-r--r--app/workers/remove_expired_group_links_worker.rb1
-rw-r--r--app/workers/remove_expired_members_worker.rb1
-rw-r--r--app/workers/repository_archive_cache_worker.rb3
-rw-r--r--app/workers/repository_check/batch_worker.rb21
-rw-r--r--app/workers/repository_check/clear_worker.rb3
-rw-r--r--app/workers/repository_check/single_repository_worker.rb3
-rw-r--r--app/workers/repository_fork_worker.rb3
-rw-r--r--app/workers/repository_import_worker.rb3
-rw-r--r--app/workers/requests_profiles_worker.rb3
-rw-r--r--app/workers/stuck_ci_builds_worker.rb1
-rw-r--r--app/workers/system_hook_worker.rb3
-rw-r--r--app/workers/trending_projects_worker.rb3
-rw-r--r--app/workers/update_merge_requests_worker.rb1
121 files changed, 591 insertions, 371 deletions
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index b966a568bbd..c6c3c82e1ee 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -83,14 +83,15 @@
};
// Disable button if text field is empty
- window.disableButtonIfEmptyField = function(field_selector, button_selector) {
+ window.disableButtonIfEmptyField = function(field_selector, button_selector, event_name) {
+ event_name = event_name || 'input';
var closest_submit, field;
field = $(field_selector);
closest_submit = field.closest('form').find(button_selector);
if (rstrip(field.val()) === "") {
closest_submit.disable();
}
- return field.on('input', function() {
+ return field.on(event_name, function() {
if (rstrip($(this).val()) === "") {
return closest_submit.disable();
} else {
diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js
index 97462a5959c..f4c387a1a05 100644
--- a/app/assets/javascripts/build.js
+++ b/app/assets/javascripts/build.js
@@ -148,7 +148,7 @@
};
Build.prototype.translateSidebar = function(e) {
- var newPosition = this.sidebarTranslationLimits.max - document.body.scrollTop;
+ var newPosition = this.sidebarTranslationLimits.max - (document.body.scrollTop || document.documentElement.scrollTop);
if (newPosition < this.sidebarTranslationLimits.min) newPosition = this.sidebarTranslationLimits.min;
this.$sidebar.css({
top: newPosition
diff --git a/app/assets/javascripts/cycle_analytics.js.es6 b/app/assets/javascripts/cycle_analytics.js.es6
index bd9accacb8c..20791bab942 100644
--- a/app/assets/javascripts/cycle_analytics.js.es6
+++ b/app/assets/javascripts/cycle_analytics.js.es6
@@ -36,7 +36,11 @@
method: 'GET',
dataType: 'json',
contentType: 'application/json',
- data: { start_date: options.startDate }
+ data: {
+ cycle_analytics: {
+ start_date: options.startDate
+ }
+ }
}).done((data) => {
this.decorateData(data);
this.initDropdown();
diff --git a/app/assets/javascripts/dispatcher.js.es6 b/app/assets/javascripts/dispatcher.js.es6
index afc0d6f8c62..a1fe57562fa 100644
--- a/app/assets/javascripts/dispatcher.js.es6
+++ b/app/assets/javascripts/dispatcher.js.es6
@@ -117,6 +117,9 @@
new ZenMode();
shortcut_handler = new ShortcutsNavigation();
break;
+ case 'projects:commit:builds':
+ new gl.Pipelines();
+ break;
case 'projects:commits:show':
case 'projects:activity':
shortcut_handler = new ShortcutsNavigation();
diff --git a/app/assets/javascripts/gl_field_errors.js.es6 b/app/assets/javascripts/gl_field_errors.js.es6
index 8657e7b4abf..8e8f9f29ab3 100644
--- a/app/assets/javascripts/gl_field_errors.js.es6
+++ b/app/assets/javascripts/gl_field_errors.js.es6
@@ -137,8 +137,11 @@
}
initValidators () {
- // select all non-hidden inputs in form
- this.state.inputs = this.form.find(':input:not([type=hidden])').toArray()
+ // register selectors here as needed
+ const validateSelectors = [':text', ':password', '[type=email]']
+ .map((selector) => `input${selector}`).join(',');
+
+ this.state.inputs = this.form.find(validateSelectors).toArray()
.filter((input) => !input.classList.contains(customValidationFlag))
.map((input) => new GlFieldError({ input, formErrors: this }));
diff --git a/app/assets/javascripts/members.js.es6 b/app/assets/javascripts/members.js.es6
index a0cd20f21e8..2bdd0f7a637 100644
--- a/app/assets/javascripts/members.js.es6
+++ b/app/assets/javascripts/members.js.es6
@@ -10,6 +10,7 @@
$('.project_member, .group_member').off('ajax:success').on('ajax:success', this.removeRow);
$('.js-member-update-control').off('change').on('change', this.formSubmit);
$('.js-edit-member-form').off('ajax:success').on('ajax:success', this.formSuccess);
+ disableButtonIfEmptyField('#user_ids', 'input[name=commit]', 'change');
}
removeRow(e) {
diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js
index fd21aa1fefa..3dde979185b 100644
--- a/app/assets/javascripts/merge_request_tabs.js
+++ b/app/assets/javascripts/merge_request_tabs.js
@@ -282,6 +282,7 @@
document.querySelector("div#builds").innerHTML = data.html;
gl.utils.localTimeAgo($('.js-timeago', 'div#builds'));
_this.buildsLoaded = true;
+ if (!this.pipelines) this.pipelines = new gl.Pipelines();
return _this.scrollToElement("#builds");
};
})(this)
@@ -388,28 +389,25 @@
// So we dont affix the tabs on these
if (Breakpoints.get().getBreakpointSize() === 'xs' || !$tabs.length) return;
- var tabsWidth = $tabs.outerWidth(),
- $diffTabs = $('#diff-notes-app'),
- offsetTop = $tabs.offset().top - ($('.navbar-fixed-top').height() + $('.layout-nav').height());
+ var $diffTabs = $('#diff-notes-app'),
+ $fixedNav = $('.navbar-fixed-top'),
+ $layoutNav = $('.layout-nav');
$tabs.off('affix.bs.affix affix-top.bs.affix')
.affix({
offset: {
- top: offsetTop
+ top: function () {
+ var tabsTop = $diffTabs.offset().top - $tabs.height();
+ tabsTop = tabsTop - ($fixedNav.height() + $layoutNav.height());
+
+ return tabsTop;
+ }
}
}).on('affix.bs.affix', function () {
- $tabs.css({
- left: $tabs.offset().left,
- width: tabsWidth
- });
$diffTabs.css({
marginTop: $tabs.height()
});
}).on('affix-top.bs.affix', function () {
- $tabs.css({
- left: '',
- width: ''
- });
$diffTabs.css({
marginTop: ''
});
diff --git a/app/assets/stylesheets/framework/animations.scss b/app/assets/stylesheets/framework/animations.scss
index 1e9a45c19b8..98d3889cd44 100644
--- a/app/assets/stylesheets/framework/animations.scss
+++ b/app/assets/stylesheets/framework/animations.scss
@@ -1,10 +1,10 @@
// This file is based off animate.css 3.5.1, available here:
// https://github.com/daneden/animate.css/blob/3.5.1/animate.css
-//
+//
// animate.css - http://daneden.me/animate
// Version - 3.5.1
// Licensed under the MIT license - http://opensource.org/licenses/MIT
-//
+//
// Copyright (c) 2016 Daniel Eden
.animated {
diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss
index 81e4e264560..800e2dba018 100644
--- a/app/assets/stylesheets/framework/common.scss
+++ b/app/assets/stylesheets/framework/common.scss
@@ -372,3 +372,5 @@ table {
margin-right: -$gl-padding;
border-top: 1px solid $border-color;
}
+
+.hide-bottom-border { border-bottom: none !important; }
diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss
index a839371a6f2..224bc58f7a7 100644
--- a/app/assets/stylesheets/framework/dropdowns.scss
+++ b/app/assets/stylesheets/framework/dropdowns.scss
@@ -402,7 +402,7 @@
.dropdown-content {
max-height: 215px;
- overflow-y: scroll;
+ overflow-y: auto;
}
.dropdown-footer {
diff --git a/app/assets/stylesheets/framework/logo.scss b/app/assets/stylesheets/framework/logo.scss
index a90e45bb5f4..429cfbe7235 100644
--- a/app/assets/stylesheets/framework/logo.scss
+++ b/app/assets/stylesheets/framework/logo.scss
@@ -61,7 +61,7 @@
10%, 80% {
fill: $tanuki-red;
}
-
+
20%, 90% {
fill: lighten($tanuki-red, 25%);
}
diff --git a/app/assets/stylesheets/framework/modal.scss b/app/assets/stylesheets/framework/modal.scss
index 8374f30d0b2..8cd49280e1c 100644
--- a/app/assets/stylesheets/framework/modal.scss
+++ b/app/assets/stylesheets/framework/modal.scss
@@ -3,7 +3,7 @@
padding: 15px;
.form-actions {
- margin: -$gl-padding+1;
+ margin: -$gl-padding + 1;
margin-top: 15px;
}
diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss
index ec52f326eb9..1d8e64a0e4b 100644
--- a/app/assets/stylesheets/framework/sidebar.scss
+++ b/app/assets/stylesheets/framework/sidebar.scss
@@ -185,6 +185,10 @@ header.header-sidebar-pinned {
@media (min-width: $screen-sm-min) {
padding-right: $sidebar_collapsed_width;
+
+ .merge-request-tabs-holder.affix {
+ right: $sidebar_collapsed_width;
+ }
}
.sidebar-collapsed-icon {
@@ -207,6 +211,10 @@ header.header-sidebar-pinned {
@media (min-width: $screen-md-min) {
padding-right: $gutter_width;
+
+ .merge-request-tabs-holder.affix {
+ right: $gutter_width;
+ }
}
&.with-overlay {
diff --git a/app/assets/stylesheets/framework/tw_bootstrap_variables.scss b/app/assets/stylesheets/framework/tw_bootstrap_variables.scss
index 915aa631ef8..44fe37d3a4a 100644
--- a/app/assets/stylesheets/framework/tw_bootstrap_variables.scss
+++ b/app/assets/stylesheets/framework/tw_bootstrap_variables.scss
@@ -16,21 +16,21 @@
// $gray-light: lighten($gray-base, 46.7%) // #777
// $gray-lighter: lighten($gray-base, 93.5%) // #eee
-$brand-primary: $gl-primary;
-$brand-success: $gl-success;
-$brand-info: $gl-info;
-$brand-warning: $gl-warning;
-$brand-danger: $gl-danger;
+$brand-primary: $gl-primary;
+$brand-success: $gl-success;
+$brand-info: $gl-info;
+$brand-warning: $gl-warning;
+$brand-danger: $gl-danger;
-$border-radius-base: 3px !default;
-$border-radius-large: 3px !default;
-$border-radius-small: 3px !default;
+$border-radius-base: 3px !default;
+$border-radius-large: 3px !default;
+$border-radius-small: 3px !default;
//== Scaffolding
//
-$text-color: $gl-text-color;
-$link-color: $gl-link-color;
+$text-color: $gl-text-color;
+$link-color: $gl-link-color;
//== Typography
@@ -38,112 +38,112 @@ $link-color: $gl-link-color;
//## Font, line-height, and color for body text, headings, and more.
$font-family-sans-serif: $regular_font;
-$font-family-monospace: $monospace_font;
-$font-size-base: $gl-font-size;
+$font-family-monospace: $monospace_font;
+$font-size-base: $gl-font-size;
//== Components
//
//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
-$padding-base-vertical: $gl-vert-padding;
-$padding-base-horizontal: $gl-padding;
-$component-active-color: #fff;
-$component-active-bg: $brand-info;
+$padding-base-vertical: $gl-vert-padding;
+$padding-base-horizontal: $gl-padding;
+$component-active-color: #fff;
+$component-active-bg: $brand-info;
//== Forms
//
//##
-$input-color: $text-color;
-$input-border: $border-color;
-$input-border-focus: $focus-border-color;
-$legend-color: $text-color;
+$input-color: $text-color;
+$input-border: $border-color;
+$input-border-focus: $focus-border-color;
+$legend-color: $text-color;
//== Pagination
//
//##
-$pagination-color: $gl-gray;
-$pagination-bg: #fff;
-$pagination-border: $border-color;
+$pagination-color: $gl-gray;
+$pagination-bg: #fff;
+$pagination-border: $border-color;
-$pagination-hover-color: $gl-gray;
-$pagination-hover-bg: $row-hover;
-$pagination-hover-border: $border-color;
+$pagination-hover-color: $gl-gray;
+$pagination-hover-bg: $row-hover;
+$pagination-hover-border: $border-color;
-$pagination-active-color: $blue-dark;
-$pagination-active-bg: #fff;
-$pagination-active-border: $border-color;
+$pagination-active-color: $blue-dark;
+$pagination-active-bg: #fff;
+$pagination-active-border: $border-color;
-$pagination-disabled-color: #cdcdcd;
-$pagination-disabled-bg: $background-color;
-$pagination-disabled-border: $border-color;
+$pagination-disabled-color: #cdcdcd;
+$pagination-disabled-bg: $background-color;
+$pagination-disabled-border: $border-color;
//== Form states and alerts
//
//## Define colors for form feedback states and, by default, alerts.
-$state-success-text: #fff;
-$state-success-bg: $brand-success;
-$state-success-border: $brand-success;
+$state-success-text: #fff;
+$state-success-bg: $brand-success;
+$state-success-border: $brand-success;
-$state-info-text: #fff;
-$state-info-bg: $brand-info;
-$state-info-border: $brand-info;
+$state-info-text: #fff;
+$state-info-bg: $brand-info;
+$state-info-border: $brand-info;
-$state-warning-text: #fff;
-$state-warning-bg: $brand-warning;
-$state-warning-border: $brand-warning;
+$state-warning-text: #fff;
+$state-warning-bg: $brand-warning;
+$state-warning-border: $brand-warning;
-$state-danger-text: #fff;
-$state-danger-bg: $brand-danger;
-$state-danger-border: $brand-danger;
+$state-danger-text: #fff;
+$state-danger-bg: $brand-danger;
+$state-danger-border: $brand-danger;
//== Alerts
//
//## Define alert colors, border radius, and padding.
-$alert-border-radius: 0;
+$alert-border-radius: 0;
//== Panels
//
//##
-$panel-border-radius: 2px;
-$panel-default-text: $text-color;
-$panel-default-border: $border-color;
+$panel-border-radius: 2px;
+$panel-default-text: $text-color;
+$panel-default-border: $border-color;
$panel-default-heading-bg: $background-color;
-$panel-footer-bg: $background-color;
-$panel-inner-border: $border-color;
+$panel-footer-bg: $background-color;
+$panel-inner-border: $border-color;
//== Wells
//
//##
-$well-bg: $gray-light;
-$well-border: #eee;
+$well-bg: $gray-light;
+$well-border: #eee;
//== Code
//
//##
-$code-color: #c7254e;
-$code-bg: #f9f2f4;
+$code-color: #c7254e;
+$code-bg: #f9f2f4;
-$kbd-color: #fff;
-$kbd-bg: #333;
+$kbd-color: #fff;
+$kbd-bg: #333;
//== Buttons
//
//##
-$btn-default-color: $gl-text-color;
-$btn-default-bg: #fff;
-$btn-default-border: #e7e9ed;
+$btn-default-color: $gl-text-color;
+$btn-default-bg: #fff;
+$btn-default-border: #e7e9ed;
//== Nav
//
@@ -153,8 +153,8 @@ $nav-link-padding: 13px $gl-padding;
//== Code
//
//##
-$pre-bg: $background-color !default;
-$pre-color: $gl-gray !default;
+$pre-bg: $background-color !default;
+$pre-color: $gl-gray !default;
$pre-border-color: $border-color;
$table-bg-accent: $background-color;
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index eafe84570a8..b271f8cf332 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -84,39 +84,39 @@ $warning-message-border: #f0e2bb;
/*
* UI elements
*/
-$border-color: #e5e5e5;
-$focus-border-color: #3aabf0;
-$table-border-color: #f0f0f0;
-$background-color: $gray-light;
+$border-color: #e5e5e5;
+$focus-border-color: #3aabf0;
+$table-border-color: #f0f0f0;
+$background-color: $gray-light;
$dark-background-color: #f5f5f5;
-$table-text-gray: #8f8f8f;
+$table-text-gray: #8f8f8f;
/*
* Text
*/
-$gl-font-size: 15px;
-$gl-title-color: #333;
-$gl-text-color: #5c5c5c;
-$gl-text-color-light: #8c8c8c;
-$gl-text-green: #4a2;
-$gl-text-red: #d12f19;
-$gl-text-orange: #d90;
-$gl-link-color: #3084bb;
-$gl-dark-link-color: #333;
+$gl-font-size: 15px;
+$gl-title-color: #333;
+$gl-text-color: #5c5c5c;
+$gl-text-color-light: #8c8c8c;
+$gl-text-green: #4a2;
+$gl-text-red: #d12f19;
+$gl-text-orange: #d90;
+$gl-link-color: #3084bb;
+$gl-dark-link-color: #333;
$gl-placeholder-color: #8f8f8f;
-$gl-icon-color: $gl-placeholder-color;
-$gl-grayish-blue: #7f8fa4;
-$gl-gray: $gl-text-color;
-$gl-gray-dark: #313236;
-$gl-gray-light: $gl-placeholder-color;
-$gl-header-color: #4c4e54;
+$gl-icon-color: $gl-placeholder-color;
+$gl-grayish-blue: #7f8fa4;
+$gl-gray: $gl-text-color;
+$gl-gray-dark: #313236;
+$gl-gray-light: $gl-placeholder-color;
+$gl-header-color: #4c4e54;
/*
* Lists
*/
-$list-font-size: $gl-font-size;
+$list-font-size: $gl-font-size;
$list-title-color: $gl-title-color;
-$list-text-color: $gl-text-color;
+$list-text-color: $gl-text-color;
$list-text-height: 42px;
/*
diff --git a/app/assets/stylesheets/mailers/devise.scss b/app/assets/stylesheets/mailers/devise.scss
index 9495c5b3f37..b2bce482fde 100644
--- a/app/assets/stylesheets/mailers/devise.scss
+++ b/app/assets/stylesheets/mailers/devise.scss
@@ -5,13 +5,13 @@
// Styles defined here are embedded directly into the resulting email HTML via
// the `premailer` gem.
-$body-background-color: #363636;
+$body-background-color: #363636;
$message-background-color: #fafafa;
-$header-color: #6b4fbb;
-$body-color: #444;
-$cta-color: #e14329;
-$footer-link-color: #7e7e7e;
+$header-color: #6b4fbb;
+$body-color: #444;
+$cta-color: #e14329;
+$footer-link-color: #7e7e7e;
$font-family: Helvetica, Arial, sans-serif;
diff --git a/app/assets/stylesheets/pages/cycle_analytics.scss b/app/assets/stylesheets/pages/cycle_analytics.scss
index d732008de3d..572e1e7d558 100644
--- a/app/assets/stylesheets/pages/cycle_analytics.scss
+++ b/app/assets/stylesheets/pages/cycle_analytics.scss
@@ -9,15 +9,15 @@
padding: 24px 0;
border-bottom: none;
position: relative;
-
+
@media (max-width: $screen-sm-min) {
padding: 6px 0 24px;
- }
+ }
}
.column {
text-align: center;
-
+
@media (max-width: $screen-sm-min) {
padding: 15px 0;
}
@@ -36,7 +36,7 @@
&:last-child {
text-align: right;
-
+
@media (max-width: $screen-sm-min) {
text-align: center;
}
@@ -51,7 +51,7 @@
.bordered-box {
border: 1px solid $border-color;
border-radius: $border-radius-default;
-
+
}
.content-list {
@@ -73,10 +73,10 @@
font-weight: 600;
color: $gl-title-color;
}
-
+
&.text {
color: $layout-link-gray;
-
+
&.value-col {
color: $gl-title-color;
}
@@ -108,13 +108,13 @@
.svg-container {
text-align: center;
-
+
svg {
width: 136px;
height: 136px;
}
}
-
+
.inner-content {
@media (max-width: $screen-sm-min) {
padding: 0 28px;
diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss
index fe6421f8b3f..f8e3ca29a2b 100644
--- a/app/assets/stylesheets/pages/diff.scss
+++ b/app/assets/stylesheets/pages/diff.scss
@@ -222,12 +222,12 @@
top: 13px;
right: 7px;
}
-
+
.frame {
top: 0;
right: 0;
position: absolute;
-
+
&.deleted {
margin: 0;
display: block;
diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss
index 12ee0a5dc3d..fc49ff780fc 100644
--- a/app/assets/stylesheets/pages/environments.scss
+++ b/app/assets/stylesheets/pages/environments.scss
@@ -37,10 +37,10 @@
.branch-name {
color: $gl-dark-link-color;
}
-
+
.stop-env-link {
color: $table-text-gray;
-
+
.stop-env-icon {
font-size: 14px;
}
@@ -48,11 +48,11 @@
.deployment {
.build-column {
-
+
.build-link {
color: $gl-dark-link-color;
}
-
+
.avatar {
float: none;
}
diff --git a/app/assets/stylesheets/pages/events.scss b/app/assets/stylesheets/pages/events.scss
index 5d9a76dac05..3004959ff7b 100644
--- a/app/assets/stylesheets/pages/events.scss
+++ b/app/assets/stylesheets/pages/events.scss
@@ -142,7 +142,7 @@
.event-last-push {
overflow: auto;
width: 100%;
-
+
.event-last-push-text {
@include str-truncated(100%);
padding: 4px 0;
diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss
index bdb13bee178..2be9453aaee 100644
--- a/app/assets/stylesheets/pages/login.scss
+++ b/app/assets/stylesheets/pages/login.scss
@@ -143,6 +143,7 @@
&:not(.active) {
background-color: $gray-light;
+ border-left: 1px solid $border-color;
}
a {
@@ -170,6 +171,31 @@
}
}
+ // Ldap configurations may need more tabs & the tab labels are user generated (arbitrarily long).
+ // These styles prevent this from breaking the layout, and only applied when providers are configured.
+
+ .new-session-tabs.custom-provider-tabs {
+ flex-wrap: wrap;
+
+ li {
+ min-width: 85px;
+ flex-basis: auto;
+
+ // This styles tab elements that have wrapped to a second line. We cannot easily predict when this will happen.
+ // We are making somewhat of an assumption about the configuration here: that users do not have more than
+ // 3 LDAP servers configured (in addition to standard login) and they are not using especially long names for any
+ // of them. If either condition is false, this will work as expected. If both are true, there may be a missing border
+ // above one of the bottom row elements. If you know a better way, please implement it!
+ &:nth-child(n+5) {
+ border-top: 1px solid $border-color;
+ }
+ }
+
+ a {
+ font-size: 16px;
+ }
+ }
+
.form-control {
&:active, &:focus {
@@ -203,6 +229,7 @@
.login-page {
.col-sm-5.pull-right {
float: none !important;
+ margin-bottom: 45px;
}
}
}
@@ -244,7 +271,11 @@
}
.navless-container {
- padding: 65px; // height of footer + bottom padding of email confirmation link
+ padding: 65px 15px; // height of footer + bottom padding of email confirmation link
+
+ @media (max-width: $screen-xs-max) {
+ padding: 0 15px 65px;
+ }
}
}
@@ -255,6 +286,13 @@
.new_user {
position: relative;
padding-bottom: 35px;
+
+ @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) {
+ .forgot-password {
+ float: none !important;
+ margin-top: 5px;
+ }
+ }
}
.move-submit-down {
@@ -263,3 +301,4 @@
bottom: 0;
}
}
+
diff --git a/app/assets/stylesheets/pages/merge_conflicts.scss b/app/assets/stylesheets/pages/merge_conflicts.scss
index eed2b0ab7cc..2e917361b25 100644
--- a/app/assets/stylesheets/pages/merge_conflicts.scss
+++ b/app/assets/stylesheets/pages/merge_conflicts.scss
@@ -254,7 +254,7 @@ $colors: (
border-top: solid 2px $border-green-extra-light;
}
}
-
+
.editor {
pre {
height: 350px;
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index 35a1877df95..70afa568554 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -183,11 +183,11 @@
.ci-coverage {
float: right;
}
-
+
.stop-env-container {
color: $gl-text-color;
float: right;
-
+
a {
color: $gl-text-color;
}
@@ -438,11 +438,18 @@
}
}
-.merge-request-tabs {
+.merge-request-tabs-holder {
background-color: #fff;
&.affix {
top: 100px;
+ left: 0;
z-index: 9;
+ transition: right .15s;
+ }
+
+ &:not(.affix) .container-fluid {
+ padding-left: 0;
+ padding-right: 0;
}
}
diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss
index 17f28959414..25c1bbdc1c9 100644
--- a/app/assets/stylesheets/pages/note_form.scss
+++ b/app/assets/stylesheets/pages/note_form.scss
@@ -8,7 +8,7 @@
.diff-file .diff-content {
tr.line_holder:hover > td .line_note_link {
opacity: 1.0;
- filter: alpha(opacity=100);
+ filter: alpha(opacity = 100);
}
}
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index fffcdc812a7..faa0fc82ca8 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -458,7 +458,7 @@ ul.notes {
.discussion-next-btn {
svg {
margin: 0;
-
+
path {
fill: $gray-darkest;
}
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 1062d7effb0..fe7cf3c87e3 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -13,9 +13,18 @@
.new_project,
.edit-project {
+
fieldset {
- &.features .control-label {
- font-weight: normal;
+
+ &.features {
+
+ .label-light {
+ margin-bottom: 0;
+ }
+
+ .help-block {
+ margin-top: 0;
+ }
}
.form-group {
@@ -40,6 +49,7 @@
}
.input-group > div {
+
&:last-child {
padding-right: 0;
}
@@ -47,6 +57,7 @@
@media (max-width: $screen-xs-max) {
.input-group > div {
+
margin-bottom: 14px;
&:last-child {
@@ -60,6 +71,7 @@
}
.input-group-addon {
+
&.static-namespace {
height: 35px;
border-radius: 3px;
diff --git a/app/assets/stylesheets/pages/status.scss b/app/assets/stylesheets/pages/status.scss
index f1d53c7b8bc..01426e28e92 100644
--- a/app/assets/stylesheets/pages/status.scss
+++ b/app/assets/stylesheets/pages/status.scss
@@ -74,7 +74,7 @@
.ci-status-icon-success_with_warning {
color: $gl-warning;
}
-
+
.ci-status-icon-running {
color: $blue-normal;
}
diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss
index 6ea7a2b5498..84dcd6835d5 100644
--- a/app/assets/stylesheets/pages/tree.scss
+++ b/app/assets/stylesheets/pages/tree.scss
@@ -29,11 +29,11 @@
.last-commit {
@include str-truncated(506px);
-
+
@media (min-width: $screen-sm-max) and (max-width: $screen-md-max) {
@include str-truncated(450px);
}
-
+
}
.commit-history-link-spacer {
diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb
index 18cd800c619..940a3ad20ba 100644
--- a/app/controllers/groups/group_members_controller.rb
+++ b/app/controllers/groups/group_members_controller.rb
@@ -21,6 +21,10 @@ class Groups::GroupMembersController < Groups::ApplicationController
end
def create
+ if params[:user_ids].blank?
+ return redirect_to(group_group_members_path(@group), alert: 'No users specified.')
+ end
+
@group.add_users(
params[:user_ids].split(','),
params[:access_level],
diff --git a/app/controllers/import/gitlab_projects_controller.rb b/app/controllers/import/gitlab_projects_controller.rb
index 3ec173abcdb..36d246d185b 100644
--- a/app/controllers/import/gitlab_projects_controller.rb
+++ b/app/controllers/import/gitlab_projects_controller.rb
@@ -2,8 +2,8 @@ class Import::GitlabProjectsController < Import::BaseController
before_action :verify_gitlab_project_import_enabled
def new
- @namespace_id = project_params[:namespace_id]
- @namespace_name = Namespace.find(project_params[:namespace_id]).name
+ @namespace = Namespace.find(project_params[:namespace_id])
+ return render_404 unless current_user.can?(:create_projects, @namespace)
@path = project_params[:path]
end
diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb
index 2a07d154853..d08f490de18 100644
--- a/app/controllers/projects/project_members_controller.rb
+++ b/app/controllers/projects/project_members_controller.rb
@@ -25,6 +25,10 @@ class Projects::ProjectMembersController < Projects::ApplicationController
end
def create
+ if params[:user_ids].blank?
+ return redirect_to(namespace_project_project_members_path(@project.namespace, @project), alert: 'No users or groups specified.')
+ end
+
@project.team.add_users(
params[:user_ids].split(','),
params[:access_level],
@@ -32,7 +36,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController
current_user: current_user
)
- redirect_to namespace_project_project_members_path(@project.namespace, @project)
+ redirect_to namespace_project_project_members_path(@project.namespace, @project), notice: 'Users were successfully added.'
end
def update
diff --git a/app/finders/labels_finder.rb b/app/finders/labels_finder.rb
index 6ace14a4bb5..95e62cdb02a 100644
--- a/app/finders/labels_finder.rb
+++ b/app/finders/labels_finder.rb
@@ -35,8 +35,10 @@ class LabelsFinder < UnionFinder
end
def with_title(items)
- items = items.where(title: title) if title
- items
+ return items if title.nil?
+ return items.none if title.blank?
+
+ items.where(title: title)
end
def group_id
@@ -52,7 +54,7 @@ class LabelsFinder < UnionFinder
end
def title
- params[:title].presence || params[:name].presence
+ params[:title] || params[:name]
end
def project
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index a6b606d13de..bf5f92f8462 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -3,8 +3,8 @@ module Ci
include TokenAuthenticatable
include AfterCommitQueue
- belongs_to :runner, class_name: 'Ci::Runner'
- belongs_to :trigger_request, class_name: 'Ci::TriggerRequest'
+ belongs_to :runner
+ belongs_to :trigger_request
belongs_to :erased_by, class_name: 'User'
serialize :options
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index d5c1e03b461..adda3b8f40c 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -7,12 +7,12 @@ module Ci
self.table_name = 'ci_commits'
- belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
+ belongs_to :project, foreign_key: :gl_project_id
belongs_to :user
has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id
- has_many :builds, class_name: 'Ci::Build', foreign_key: :commit_id
- has_many :trigger_requests, dependent: :destroy, class_name: 'Ci::TriggerRequest', foreign_key: :commit_id
+ has_many :builds, foreign_key: :commit_id
+ has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id
validates_presence_of :sha, unless: :importing?
validates_presence_of :ref, unless: :importing?
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index 44cb19ece3b..123930273e0 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -6,9 +6,9 @@ module Ci
AVAILABLE_SCOPES = %w[specific shared active paused online]
FORM_EDITABLE = %i[description tag_list active run_untagged locked]
- has_many :builds, class_name: 'Ci::Build'
- has_many :runner_projects, dependent: :destroy, class_name: 'Ci::RunnerProject'
- has_many :projects, through: :runner_projects, class_name: '::Project', foreign_key: :gl_project_id
+ has_many :builds
+ has_many :runner_projects, dependent: :destroy
+ has_many :projects, through: :runner_projects, foreign_key: :gl_project_id
has_one :last_build, ->() { order('id DESC') }, class_name: 'Ci::Build'
diff --git a/app/models/ci/runner_project.rb b/app/models/ci/runner_project.rb
index 4b44ffa886e..1f9baeca5b1 100644
--- a/app/models/ci/runner_project.rb
+++ b/app/models/ci/runner_project.rb
@@ -2,8 +2,8 @@ module Ci
class RunnerProject < ActiveRecord::Base
extend Ci::Model
- belongs_to :runner, class_name: 'Ci::Runner'
- belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
+ belongs_to :runner
+ belongs_to :project, foreign_key: :gl_project_id
validates_uniqueness_of :runner_id, scope: :gl_project_id
end
diff --git a/app/models/ci/trigger.rb b/app/models/ci/trigger.rb
index a0b19b51a12..62889fe80d8 100644
--- a/app/models/ci/trigger.rb
+++ b/app/models/ci/trigger.rb
@@ -4,8 +4,8 @@ module Ci
acts_as_paranoid
- belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
- has_many :trigger_requests, dependent: :destroy, class_name: 'Ci::TriggerRequest'
+ belongs_to :project, foreign_key: :gl_project_id
+ has_many :trigger_requests, dependent: :destroy
validates_presence_of :token
validates_uniqueness_of :token
diff --git a/app/models/ci/trigger_request.rb b/app/models/ci/trigger_request.rb
index fc674871743..2b807731d0d 100644
--- a/app/models/ci/trigger_request.rb
+++ b/app/models/ci/trigger_request.rb
@@ -2,9 +2,9 @@ module Ci
class TriggerRequest < ActiveRecord::Base
extend Ci::Model
- belongs_to :trigger, class_name: 'Ci::Trigger'
- belongs_to :pipeline, class_name: 'Ci::Pipeline', foreign_key: :commit_id
- has_many :builds, class_name: 'Ci::Build'
+ belongs_to :trigger
+ belongs_to :pipeline, foreign_key: :commit_id
+ has_many :builds
serialize :variables
diff --git a/app/models/ci/variable.rb b/app/models/ci/variable.rb
index 6959223aed9..94d9e2b3208 100644
--- a/app/models/ci/variable.rb
+++ b/app/models/ci/variable.rb
@@ -2,7 +2,7 @@ module Ci
class Variable < ActiveRecord::Base
extend Ci::Model
- belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
+ belongs_to :project, foreign_key: :gl_project_id
validates_uniqueness_of :key, scope: :gl_project_id
validates :key,
diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb
index 7b554be4f9a..4cb3a69416e 100644
--- a/app/models/commit_status.rb
+++ b/app/models/commit_status.rb
@@ -5,7 +5,7 @@ class CommitStatus < ActiveRecord::Base
self.table_name = 'ci_builds'
- belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
+ belongs_to :project, foreign_key: :gl_project_id
belongs_to :pipeline, class_name: 'Ci::Pipeline', foreign_key: :commit_id
belongs_to :user
diff --git a/app/models/concerns/protected_branch_access.rb b/app/models/concerns/protected_branch_access.rb
index 5a7b36070e7..7fd0905ee81 100644
--- a/app/models/concerns/protected_branch_access.rb
+++ b/app/models/concerns/protected_branch_access.rb
@@ -1,6 +1,11 @@
module ProtectedBranchAccess
extend ActiveSupport::Concern
+ included do
+ scope :master, -> { where(access_level: Gitlab::Access::MASTER) }
+ scope :developer, -> { where(access_level: Gitlab::Access::DEVELOPER) }
+ end
+
def humanize
self.class.human_access_levels[self.access_level]
end
diff --git a/app/models/email.rb b/app/models/email.rb
index 32a412ab878..826d4f16edb 100644
--- a/app/models/email.rb
+++ b/app/models/email.rb
@@ -7,10 +7,8 @@ class Email < ActiveRecord::Base
validates :email, presence: true, uniqueness: true, email: true
validate :unique_email, if: ->(email) { email.email_changed? }
- before_validation :cleanup_email
-
- def cleanup_email
- self.email = self.email.downcase.strip
+ def email=(value)
+ write_attribute(:email, value.downcase.strip)
end
def unique_email
diff --git a/app/models/group.rb b/app/models/group.rb
index 00a595d2705..552e1154df6 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -6,7 +6,7 @@ class Group < Namespace
include AccessRequestable
include Referable
- has_many :group_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source, class_name: 'GroupMember'
+ has_many :group_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source
alias_method :members, :group_members
has_many :users, through: :group_members
has_many :owners,
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 133a5993815..89158a50353 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -211,7 +211,13 @@ class Issue < ActiveRecord::Base
note.all_references(current_user, extractor: ext)
end
- ext.merge_requests.select { |mr| mr.open? && mr.closes_issue?(self) }
+ merge_requests = ext.merge_requests.select(&:open?)
+ if merge_requests.any?
+ ids = MergeRequestsClosingIssues.where(merge_request_id: merge_requests.map(&:id), issue_id: id).pluck(:merge_request_id)
+ merge_requests.select { |mr| mr.id.in?(ids) }
+ else
+ []
+ end
end
def moved?
diff --git a/app/models/members/group_member.rb b/app/models/members/group_member.rb
index 1b54a85d064..204f34f0269 100644
--- a/app/models/members/group_member.rb
+++ b/app/models/members/group_member.rb
@@ -1,7 +1,7 @@
class GroupMember < Member
SOURCE_TYPE = 'Namespace'
- belongs_to :group, class_name: 'Group', foreign_key: 'source_id'
+ belongs_to :group, foreign_key: 'source_id'
# Make sure group member points only to group as it source
default_value_for :source_type, SOURCE_TYPE
diff --git a/app/models/members/project_member.rb b/app/models/members/project_member.rb
index e4880973117..008fff0857c 100644
--- a/app/models/members/project_member.rb
+++ b/app/models/members/project_member.rb
@@ -3,7 +3,7 @@ class ProjectMember < Member
include Gitlab::ShellAdapter
- belongs_to :project, class_name: 'Project', foreign_key: 'source_id'
+ belongs_to :project, foreign_key: 'source_id'
# Make sure project member points only to project as it source
default_value_for :source_type, SOURCE_TYPE
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index c476a3bb14e..4872f8b8649 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -6,8 +6,8 @@ class MergeRequest < ActiveRecord::Base
include Taskable
include Importable
- belongs_to :target_project, foreign_key: :target_project_id, class_name: "Project"
- belongs_to :source_project, foreign_key: :source_project_id, class_name: "Project"
+ belongs_to :target_project, class_name: "Project"
+ belongs_to :source_project, class_name: "Project"
belongs_to :merge_user, class_name: "User"
has_many :merge_request_diffs, dependent: :destroy
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index b8a10b7968e..dd65a9a8b86 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -299,8 +299,10 @@ class MergeRequestDiff < ActiveRecord::Base
end
def keep_around_commits
- repository.keep_around(start_commit_sha)
- repository.keep_around(head_commit_sha)
- repository.keep_around(base_commit_sha)
+ [repository, merge_request.source_project.repository].each do |repo|
+ repo.keep_around(start_commit_sha)
+ repo.keep_around(head_commit_sha)
+ repo.keep_around(base_commit_sha)
+ end
end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index af117f0acb0..fbf7012972e 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -63,11 +63,11 @@ class Project < ActiveRecord::Base
alias_attribute :title, :name
# Relations
- belongs_to :creator, foreign_key: 'creator_id', class_name: 'User'
+ belongs_to :creator, class_name: 'User'
belongs_to :group, -> { where(type: 'Group') }, foreign_key: 'namespace_id'
belongs_to :namespace
- has_one :last_event, -> {order 'events.created_at DESC'}, class_name: 'Event', foreign_key: 'project_id'
+ has_one :last_event, -> {order 'events.created_at DESC'}, class_name: 'Event'
has_many :boards, before_add: :validate_board_limit, dependent: :destroy
# Project services
@@ -116,7 +116,7 @@ class Project < ActiveRecord::Base
has_many :hooks, dependent: :destroy, class_name: 'ProjectHook'
has_many :protected_branches, dependent: :destroy
- has_many :project_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source, class_name: 'ProjectMember'
+ has_many :project_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source
alias_method :members, :project_members
has_many :users, through: :project_members
@@ -137,7 +137,7 @@ class Project < ActiveRecord::Base
has_one :import_data, dependent: :destroy, class_name: "ProjectImportData"
has_one :project_feature, dependent: :destroy
- has_many :commit_statuses, dependent: :destroy, class_name: 'CommitStatus', foreign_key: :gl_project_id
+ has_many :commit_statuses, dependent: :destroy, foreign_key: :gl_project_id
has_many :pipelines, dependent: :destroy, class_name: 'Ci::Pipeline', foreign_key: :gl_project_id
has_many :builds, class_name: 'Ci::Build', foreign_key: :gl_project_id # the builds are created from the commit_statuses
has_many :runner_projects, dependent: :destroy, class_name: 'Ci::RunnerProject', foreign_key: :gl_project_id
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 1b7f20a2134..4ae9c20726f 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -419,6 +419,17 @@ class Repository
@exists = nil
end
+ # expire cache that doesn't depend on repository data (when expiring)
+ def expire_content_cache
+ expire_tags_cache
+ expire_tag_count_cache
+ expire_branches_cache
+ expire_branch_count_cache
+ expire_root_ref_cache
+ expire_emptiness_caches
+ expire_exists_cache
+ end
+
# Runs code after a repository has been created.
def after_create
expire_exists_cache
@@ -434,14 +445,7 @@ class Repository
expire_cache if exists?
- # expire cache that don't depend on repository data (when expiring)
- expire_tags_cache
- expire_tag_count_cache
- expire_branches_cache
- expire_branch_count_cache
- expire_root_ref_cache
- expire_emptiness_caches
- expire_exists_cache
+ expire_content_cache
repository_event(:remove_repository)
end
@@ -473,14 +477,13 @@ class Repository
end
def before_import
- expire_emptiness_caches
- expire_exists_cache
+ expire_content_cache
end
# Runs code after a repository has been forked/imported.
def after_import
- expire_emptiness_caches
- expire_exists_cache
+ expire_content_cache
+ build_cache
end
# Runs code after a new commit has been pushed.
diff --git a/app/models/user.rb b/app/models/user.rb
index f367f4616fb..9e76df63d31 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -47,7 +47,7 @@ class User < ActiveRecord::Base
#
# Namespace for personal projects
- has_one :namespace, -> { where type: nil }, dependent: :destroy, foreign_key: :owner_id, class_name: "Namespace"
+ has_one :namespace, -> { where type: nil }, dependent: :destroy, foreign_key: :owner_id
# Profile
has_many :keys, dependent: :destroy
@@ -66,17 +66,17 @@ class User < ActiveRecord::Base
# Projects
has_many :groups_projects, through: :groups, source: :projects
has_many :personal_projects, through: :namespace, source: :projects
- has_many :project_members, -> { where(requested_at: nil) }, dependent: :destroy, class_name: 'ProjectMember'
+ has_many :project_members, -> { where(requested_at: nil) }, dependent: :destroy
has_many :projects, through: :project_members
has_many :created_projects, foreign_key: :creator_id, class_name: 'Project'
has_many :users_star_projects, dependent: :destroy
has_many :starred_projects, through: :users_star_projects, source: :project
- has_many :snippets, dependent: :destroy, foreign_key: :author_id, class_name: "Snippet"
+ has_many :snippets, dependent: :destroy, foreign_key: :author_id
has_many :issues, dependent: :destroy, foreign_key: :author_id
has_many :notes, dependent: :destroy, foreign_key: :author_id
has_many :merge_requests, dependent: :destroy, foreign_key: :author_id
- has_many :events, dependent: :destroy, foreign_key: :author_id, class_name: "Event"
+ has_many :events, dependent: :destroy, foreign_key: :author_id
has_many :subscriptions, dependent: :destroy
has_many :recent_events, -> { order "id DESC" }, foreign_key: :author_id, class_name: "Event"
has_many :assigned_issues, dependent: :destroy, foreign_key: :assignee_id, class_name: "Issue"
@@ -309,7 +309,7 @@ class User < ActiveRecord::Base
username
end
- def to_reference(_from_project = nil)
+ def to_reference(_from_project = nil, _target_project = nil)
"#{self.class.reference_prefix}#{username}"
end
diff --git a/app/services/merge_requests/assign_issues_service.rb b/app/services/merge_requests/assign_issues_service.rb
index f636e5fec4f..066efa1acc3 100644
--- a/app/services/merge_requests/assign_issues_service.rb
+++ b/app/services/merge_requests/assign_issues_service.rb
@@ -4,7 +4,7 @@ module MergeRequests
@assignable_issues ||= begin
if current_user == merge_request.author
closes_issues.select do |issue|
- !issue.assignee_id? && can?(current_user, :admin_issue, issue)
+ !issue.is_a?(ExternalIssue) && !issue.assignee_id? && can?(current_user, :admin_issue, issue)
end
else
[]
diff --git a/app/services/notes/create_service.rb b/app/services/notes/create_service.rb
index a36008c3ef5..723cc0e6834 100644
--- a/app/services/notes/create_service.rb
+++ b/app/services/notes/create_service.rb
@@ -7,8 +7,10 @@ module Notes
if note.award_emoji?
noteable = note.noteable
- todo_service.new_award_emoji(noteable, current_user)
- return noteable.create_award_emoji(note.award_emoji_name, current_user)
+ if noteable.user_can_award?(current_user, note.award_emoji_name)
+ todo_service.new_award_emoji(noteable, current_user)
+ return noteable.create_award_emoji(note.award_emoji_name, current_user)
+ end
end
# We execute commands (extracted from `params[:note]`) on the noteable
diff --git a/app/services/protected_branches/api_create_service.rb b/app/services/protected_branches/api_create_service.rb
new file mode 100644
index 00000000000..f2040dfa03a
--- /dev/null
+++ b/app/services/protected_branches/api_create_service.rb
@@ -0,0 +1,29 @@
+# The protected branches API still uses the `developers_can_push` and `developers_can_merge`
+# flags for backward compatibility, and so performs translation between that format and the
+# internal data model (separate access levels). The translation code is non-trivial, and so
+# lives in this service.
+module ProtectedBranches
+ class ApiCreateService < BaseService
+ def execute
+ push_access_level =
+ if params.delete(:developers_can_push)
+ Gitlab::Access::DEVELOPER
+ else
+ Gitlab::Access::MASTER
+ end
+
+ merge_access_level =
+ if params.delete(:developers_can_merge)
+ Gitlab::Access::DEVELOPER
+ else
+ Gitlab::Access::MASTER
+ end
+
+ @params.merge!(push_access_levels_attributes: [{ access_level: push_access_level }],
+ merge_access_levels_attributes: [{ access_level: merge_access_level }])
+
+ service = ProtectedBranches::CreateService.new(@project, @current_user, @params)
+ service.execute
+ end
+ end
+end
diff --git a/app/services/protected_branches/api_update_service.rb b/app/services/protected_branches/api_update_service.rb
new file mode 100644
index 00000000000..050cb3b738b
--- /dev/null
+++ b/app/services/protected_branches/api_update_service.rb
@@ -0,0 +1,47 @@
+# The protected branches API still uses the `developers_can_push` and `developers_can_merge`
+# flags for backward compatibility, and so performs translation between that format and the
+# internal data model (separate access levels). The translation code is non-trivial, and so
+# lives in this service.
+module ProtectedBranches
+ class ApiUpdateService < BaseService
+ def execute(protected_branch)
+ @developers_can_push = params.delete(:developers_can_push)
+ @developers_can_merge = params.delete(:developers_can_merge)
+
+ @protected_branch = protected_branch
+
+ protected_branch.transaction do
+ delete_redundant_access_levels
+
+ case @developers_can_push
+ when true
+ params.merge!(push_access_levels_attributes: [{ access_level: Gitlab::Access::DEVELOPER }])
+ when false
+ params.merge!(push_access_levels_attributes: [{ access_level: Gitlab::Access::MASTER }])
+ end
+
+ case @developers_can_merge
+ when true
+ params.merge!(merge_access_levels_attributes: [{ access_level: Gitlab::Access::DEVELOPER }])
+ when false
+ params.merge!(merge_access_levels_attributes: [{ access_level: Gitlab::Access::MASTER }])
+ end
+
+ service = ProtectedBranches::UpdateService.new(@project, @current_user, @params)
+ service.execute(protected_branch)
+ end
+ end
+
+ private
+
+ def delete_redundant_access_levels
+ unless @developers_can_merge.nil?
+ @protected_branch.merge_access_levels.destroy_all
+ end
+
+ unless @developers_can_push.nil?
+ @protected_branch.push_access_levels.destroy_all
+ end
+ end
+ end
+end
diff --git a/app/views/admin/runners/index.html.haml b/app/views/admin/runners/index.html.haml
index b760b42fde0..37bb6a3b0e0 100644
--- a/app/views/admin/runners/index.html.haml
+++ b/app/views/admin/runners/index.html.haml
@@ -75,4 +75,4 @@
- @runners.each do |runner|
= render "admin/runners/runner", runner: runner
- = paginate @runners
+ = paginate @runners, theme: "gitlab"
diff --git a/app/views/admin/runners/show.html.haml b/app/views/admin/runners/show.html.haml
index 10fea1996aa..73038164056 100644
--- a/app/views/admin/runners/show.html.haml
+++ b/app/views/admin/runners/show.html.haml
@@ -67,7 +67,7 @@
= form_for [:admin, project.namespace.becomes(Namespace), project, project.runner_projects.new] do |f|
= f.hidden_field :runner_id, value: @runner.id
= f.submit 'Enable', class: 'btn btn-xs'
- = paginate @projects
+ = paginate @projects, theme: "gitlab"
.col-md-6
%h4 Recent builds served by this Runner
diff --git a/app/views/devise/sessions/_new_base.html.haml b/app/views/devise/sessions/_new_base.html.haml
index 525e7d99d71..5fd896f6835 100644
--- a/app/views/devise/sessions/_new_base.html.haml
+++ b/app/views/devise/sessions/_new_base.html.haml
@@ -12,5 +12,5 @@
%label{for: "user_remember_me"}
= f.check_box :remember_me
%span Remember me
- .pull-right
+ .pull-right.forgot-password
= link_to "Forgot your password?", new_password_path(resource_name)
diff --git a/app/views/devise/sessions/two_factor.html.haml b/app/views/devise/sessions/two_factor.html.haml
index 0e865b807c1..fd77cdbee2e 100644
--- a/app/views/devise/sessions/two_factor.html.haml
+++ b/app/views/devise/sessions/two_factor.html.haml
@@ -10,7 +10,7 @@
= form_for(resource, as: resource_name, url: session_path(resource_name), method: :post, html: { class: 'edit_user show-gl-field-errors' }) do |f|
- resource_params = params[resource_name].presence || params
= f.hidden_field :remember_me, value: resource_params.fetch(:remember_me, 0)
- .form-group
+ %div
= f.label 'Two-Factor Authentication code', name: :otp_attempt
= f.text_field :otp_attempt, class: 'form-control', required: true, autofocus: true, autocomplete: 'off', title: 'This field is required.'
%p.help-block.hint Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes.
diff --git a/app/views/devise/shared/_tabs_ldap.html.haml b/app/views/devise/shared/_tabs_ldap.html.haml
index a057f126c45..1e957f0935f 100644
--- a/app/views/devise/shared/_tabs_ldap.html.haml
+++ b/app/views/devise/shared/_tabs_ldap.html.haml
@@ -1,4 +1,4 @@
-%ul.new-session-tabs.nav-links.nav-tabs
+%ul.new-session-tabs.nav-links.nav-tabs{ class: ('custom-provider-tabs' if form_based_providers.any?) }
- if crowd_enabled?
%li.active
= link_to "Crowd", "#crowd", 'data-toggle' => 'tab'
diff --git a/app/views/devise/shared/_tabs_normal.html.haml b/app/views/devise/shared/_tabs_normal.html.haml
index 79b1d447a92..05246303fb6 100644
--- a/app/views/devise/shared/_tabs_normal.html.haml
+++ b/app/views/devise/shared/_tabs_normal.html.haml
@@ -1,5 +1,6 @@
%ul.nav-links.new-session-tabs.nav-tabs{ role: 'tablist'}
%li.active{ role: 'presentation' }
%a{ href: '#login-pane', data: { toggle: 'tab' }, role: 'tab'} Sign in
- %li{ role: 'presentation'}
- %a{ href: '#register-pane', data: { toggle: 'tab' }, role: 'tab'} Register
+ - if signin_enabled? && signup_enabled?
+ %li{ role: 'presentation'}
+ %a{ href: '#register-pane', data: { toggle: 'tab' }, role: 'tab'} Register
diff --git a/app/views/import/gitlab_projects/new.html.haml b/app/views/import/gitlab_projects/new.html.haml
index 44e2653ca4a..767dffb5589 100644
--- a/app/views/import/gitlab_projects/new.html.haml
+++ b/app/views/import/gitlab_projects/new.html.haml
@@ -9,12 +9,12 @@
%p
Project will be imported as
%strong
- #{@namespace_name}/#{@path}
+ #{@namespace.name}/#{@path}
%p
To move or copy an entire GitLab project from another GitLab installation to this one, navigate to the original project's settings page, generate an export file, and upload it here.
.form-group
- = hidden_field_tag :namespace_id, @namespace_id
+ = hidden_field_tag :namespace_id, @namespace.id
= hidden_field_tag :path, @path
= label_tag :file, class: 'control-label' do
%span GitLab project export
diff --git a/app/views/projects/boards/components/_card.html.haml b/app/views/projects/boards/components/_card.html.haml
index d8f16022407..c6d718a1cd1 100644
--- a/app/views/projects/boards/components/_card.html.haml
+++ b/app/views/projects/boards/components/_card.html.haml
@@ -26,7 +26,7 @@
":title" => "label.description",
data: { container: 'body' } }
{{ label.title }}
- %a.has-tooltip{ ":href" => "'/' + issue.assignee.username",
+ %a.has-tooltip{ ":href" => "'#{root_path}' + issue.assignee.username",
":title" => "'Assigned to ' + issue.assignee.name",
"v-if" => "issue.assignee",
data: { container: 'body' } }
diff --git a/app/views/projects/compare/_form.html.haml b/app/views/projects/compare/_form.html.haml
index 76b68c544aa..7bde20c3286 100644
--- a/app/views/projects/compare/_form.html.haml
+++ b/app/views/projects/compare/_form.html.haml
@@ -10,7 +10,7 @@
= button_tag type: 'button', class: "form-control compare-dropdown-toggle js-compare-dropdown", required: true, data: { refs_url: refs_namespace_project_path(@project.namespace, @project), toggle: "dropdown", target: ".js-compare-from-dropdown", selected: params[:from], field_name: :from } do
.dropdown-toggle-text= params[:from] || 'Select branch/tag'
= render "ref_dropdown"
- .compare-ellipsis ...
+ .compare-ellipsis.inline ...
.form-group.dropdown.compare-form-group.to.js-compare-to-dropdown
.input-group.inline-input-group
%span.input-group-addon to
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index fb776e3a3e7..30473d14b9b 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -46,70 +46,70 @@
%h5.prepend-top-0
Feature Visibility
- = f.fields_for :project_feature do |feature_fields|
- .form_group.prepend-top-20
- .row
- .col-md-9
- = feature_fields.label :repository_access_level, "Repository", class: 'label-light'
- %span.help-block Push files to be stored in this project
- .col-md-3.js-repo-access-level
- = project_feature_access_select(:repository_access_level)
+ = f.fields_for :project_feature do |feature_fields|
+ .form_group.prepend-top-20
+ .row
+ .col-md-9
+ = feature_fields.label :repository_access_level, "Repository", class: 'label-light'
+ %span.help-block Push files to be stored in this project
+ .col-md-3.js-repo-access-level
+ = project_feature_access_select(:repository_access_level)
- .col-sm-12
- .row
- .col-md-9.project-feature-nested
- = feature_fields.label :merge_requests_access_level, "Merge requests", class: 'label-light'
- %span.help-block Submit changes to be merged upstream
- .col-md-3
- = project_feature_access_select(:merge_requests_access_level)
+ .col-sm-12
+ .row
+ .col-md-9.project-feature-nested
+ = feature_fields.label :merge_requests_access_level, "Merge requests", class: 'label-light'
+ %span.help-block Submit changes to be merged upstream
+ .col-md-3
+ = project_feature_access_select(:merge_requests_access_level)
- .row
- .col-md-9.project-feature-nested
- = feature_fields.label :builds_access_level, "Builds", class: 'label-light'
- %span.help-block Submit, test and deploy your changes before merge
- .col-md-3
- = project_feature_access_select(:builds_access_level)
+ .row
+ .col-md-9.project-feature-nested
+ = feature_fields.label :builds_access_level, "Builds", class: 'label-light'
+ %span.help-block Submit, test and deploy your changes before merge
+ .col-md-3
+ = project_feature_access_select(:builds_access_level)
- .row
- .col-md-9
- = feature_fields.label :snippets_access_level, "Snippets", class: 'label-light'
- %span.help-block Share code pastes with others out of Git repository
- .col-md-3
- = project_feature_access_select(:snippets_access_level)
+ .row
+ .col-md-9
+ = feature_fields.label :snippets_access_level, "Snippets", class: 'label-light'
+ %span.help-block Share code pastes with others out of Git repository
+ .col-md-3
+ = project_feature_access_select(:snippets_access_level)
- .row
- .col-md-9
- = feature_fields.label :issues_access_level, "Issues", class: 'label-light'
- %span.help-block Lightweight issue tracking system for this project
- .col-md-3
- = project_feature_access_select(:issues_access_level)
+ .row
+ .col-md-9
+ = feature_fields.label :issues_access_level, "Issues", class: 'label-light'
+ %span.help-block Lightweight issue tracking system for this project
+ .col-md-3
+ = project_feature_access_select(:issues_access_level)
- .row
- .col-md-9
- = feature_fields.label :wiki_access_level, "Wiki", class: 'label-light'
- %span.help-block Pages for project documentation
- .col-md-3
- = project_feature_access_select(:wiki_access_level)
-
- - if Gitlab.config.lfs.enabled && current_user.admin?
- .checkbox
- = f.label :lfs_enabled do
- = f.check_box :lfs_enabled
- %strong LFS
- %br
- %span.descr
- Git Large File Storage
- = link_to icon('question-circle'), help_page_path('workflow/lfs/manage_large_binaries_with_git_lfs')
+ .row
+ .col-md-9
+ = feature_fields.label :wiki_access_level, "Wiki", class: 'label-light'
+ %span.help-block Pages for project documentation
+ .col-md-3
+ = project_feature_access_select(:wiki_access_level)
- if Gitlab.config.lfs.enabled && current_user.admin?
- .form-group
- .checkbox
- = f.label :container_registry_enabled do
- = f.check_box :container_registry_enabled
- %strong Container Registry
- %br
- %span.descr Enable Container Registry for this project
- = link_to icon('question-circle'), help_page_path('user/project/container_registry'), target: '_blank'
+ .checkbox
+ = f.label :lfs_enabled do
+ = f.check_box :lfs_enabled
+ %strong LFS
+ %br
+ %span.descr
+ Git Large File Storage
+ = link_to icon('question-circle'), help_page_path('workflow/lfs/manage_large_binaries_with_git_lfs')
+
+ - if Gitlab.config.registry.enabled
+ .form-group
+ .checkbox
+ = f.label :container_registry_enabled do
+ = f.check_box :container_registry_enabled
+ %strong Container Registry
+ %br
+ %span.descr Enable Container Registry for this project
+ = link_to icon('question-circle'), help_page_path('user/project/container_registry'), target: '_blank'
= render 'merge_request_settings', f: f
%hr
@@ -288,4 +288,4 @@
Saving project.
%p Please wait a moment, this page will automatically refresh when ready.
-= render 'shared/confirm_modal', phrase: @project.path
+= render 'shared/confirm_modal', phrase: @project.path \ No newline at end of file
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index 6f3f238a436..bd629b5c519 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -53,7 +53,7 @@
.issue-details.issuable-details
- .detail-page-description.content-block
+ .detail-page-description.content-block{ class: ('hide-bottom-border' unless @issue.description.present? ) }
%h2.title
= markdown_field(@issue, :title)
- if @issue.description.present?
diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml
index 0e19d224fcd..f57abe73977 100644
--- a/app/views/projects/merge_requests/_show.html.haml
+++ b/app/views/projects/merge_requests/_show.html.haml
@@ -47,39 +47,41 @@
= link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal"
- if @commits_count.nonzero?
- %ul.merge-request-tabs.nav-links.no-top.no-bottom{ class: ("js-tabs-affix" unless ENV['RAILS_ENV'] == 'test') }
- %li.notes-tab
- = link_to namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#notes', action: 'notes', toggle: 'tab' } do
- Discussion
- %span.badge= @merge_request.mr_and_commit_notes.user.count
- - if @merge_request.source_project
- %li.commits-tab
- = link_to commits_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#commits', action: 'commits', toggle: 'tab' } do
- Commits
- %span.badge= @commits_count
- - if @pipeline
- %li.pipelines-tab
- = link_to pipelines_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: '#pipelines', action: 'pipelines', toggle: 'tab' } do
- Pipelines
- %span.badge= @pipelines.size
- %li.builds-tab
- = link_to builds_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: '#builds', action: 'builds', toggle: 'tab' } do
- Builds
- %span.badge= @statuses.size
- %li.diffs-tab
- = link_to diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#diffs', action: 'diffs', toggle: 'tab' } do
- Changes
- %span.badge= @merge_request.diff_size
- %li#resolve-count-app.line-resolve-all-container.pull-right.prepend-top-10.hidden-xs{ "v-cloak" => true }
- %resolve-count{ "inline-template" => true, ":logged-out" => "#{current_user.nil?}" }
- .line-resolve-all{ "v-show" => "discussionCount > 0",
- ":class" => "{ 'has-next-btn': !loggedOut && resolvedDiscussionCount !== discussionCount }" }
- %span.line-resolve-btn.is-disabled{ type: "button",
- ":class" => "{ 'is-active': resolvedDiscussionCount === discussionCount }" }
- = render "shared/icons/icon_status_success.svg"
- %span.line-resolve-text
- {{ resolvedDiscussionCount }}/{{ discussionCount }} {{ discussionCount | pluralize 'discussion' }} resolved
- = render "discussions/jump_to_next"
+ .merge-request-tabs-holder{ class: ("js-tabs-affix" unless ENV['RAILS_ENV'] == 'test') }
+ %div{ class: container_class }
+ %ul.merge-request-tabs.nav-links.no-top.no-bottom
+ %li.notes-tab
+ = link_to namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#notes', action: 'notes', toggle: 'tab' } do
+ Discussion
+ %span.badge= @merge_request.mr_and_commit_notes.user.count
+ - if @merge_request.source_project
+ %li.commits-tab
+ = link_to commits_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#commits', action: 'commits', toggle: 'tab' } do
+ Commits
+ %span.badge= @commits_count
+ - if @pipeline
+ %li.pipelines-tab
+ = link_to pipelines_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: '#pipelines', action: 'pipelines', toggle: 'tab' } do
+ Pipelines
+ %span.badge= @pipelines.size
+ %li.builds-tab
+ = link_to builds_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: '#builds', action: 'builds', toggle: 'tab' } do
+ Builds
+ %span.badge= @statuses.size
+ %li.diffs-tab
+ = link_to diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#diffs', action: 'diffs', toggle: 'tab' } do
+ Changes
+ %span.badge= @merge_request.diff_size
+ %li#resolve-count-app.line-resolve-all-container.pull-right.prepend-top-10.hidden-xs{ "v-cloak" => true }
+ %resolve-count{ "inline-template" => true, ":logged-out" => "#{current_user.nil?}" }
+ .line-resolve-all{ "v-show" => "discussionCount > 0",
+ ":class" => "{ 'has-next-btn': !loggedOut && resolvedDiscussionCount !== discussionCount }" }
+ %span.line-resolve-btn.is-disabled{ type: "button",
+ ":class" => "{ 'is-active': resolvedDiscussionCount === discussionCount }" }
+ = render "shared/icons/icon_status_success.svg"
+ %span.line-resolve-text
+ {{ resolvedDiscussionCount }}/{{ discussionCount }} {{ discussionCount | pluralize 'discussion' }} resolved
+ = render "discussions/jump_to_next"
.tab-content#diff-notes-app
#notes.notes.tab-pane.voting_notes
diff --git a/app/views/projects/merge_requests/show/_commits.html.haml b/app/views/projects/merge_requests/show/_commits.html.haml
index 0b05785430b..61020516bcf 100644
--- a/app/views/projects/merge_requests/show/_commits.html.haml
+++ b/app/views/projects/merge_requests/show/_commits.html.haml
@@ -3,4 +3,4 @@
Most recent commits displayed first
%ol#commits-list.list-unstyled
- = render "projects/commits/commits", project: @merge_request.project
+ = render "projects/commits/commits", project: @merge_request.source_project
diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml
index c83818e9199..f9ba77e87b5 100644
--- a/app/views/projects/milestones/show.html.haml
+++ b/app/views/projects/milestones/show.html.haml
@@ -31,7 +31,7 @@
= link_to namespace_project_milestone_path(@project.namespace, @project, @milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-grouped btn-danger" do
Delete
- .detail-page-description.milestone-detail
+ .detail-page-description.milestone-detail{ class: ('hide-bottom-border' unless @milestone.description.present? ) }
%h2.title
= markdown_field(@milestone, :title)
%div
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index 399ccf15b7f..932603f03b0 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -127,6 +127,11 @@
}
});
+ $('#new_project').submit(function(){
+ var $path = $('#project_path');
+ $path.val($path.val().trim());
+ });
+
$('#project_path').keyup(function(){
if($(this).val().length !=0) {
$('.btn_import_gitlab_project').attr('disabled', false);
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index 73fe6a715fa..ab719e38904 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -57,7 +57,7 @@
= link_to '#', title: 'Edit comment', class: 'note-action-button js-note-edit' do
= icon('pencil', class: 'link-highlight')
= link_to namespace_project_note_path(note.project.namespace, note.project, note), title: 'Remove comment', method: :delete, data: { confirm: 'Are you sure you want to remove this comment?' }, remote: true, class: 'note-action-button hidden-xs js-note-delete danger' do
- = icon('trash-o')
+ = icon('trash-o', class: 'danger-highlight')
.note-body{class: note_editable ? 'js-task-list-container' : ''}
.note-text.md
= preserve do
diff --git a/app/views/projects/runners/_specific_runners.html.haml b/app/views/projects/runners/_specific_runners.html.haml
index 858af78f7bf..51b0939564e 100644
--- a/app/views/projects/runners/_specific_runners.html.haml
+++ b/app/views/projects/runners/_specific_runners.html.haml
@@ -26,4 +26,4 @@
%h4.underlined-title Available specific runners
%ul.bordered-list.available-specific-runners
= render partial: 'runner', collection: @assignable_runners, as: :runner
- = paginate @assignable_runners
+ = paginate @assignable_runners, theme: "gitlab"
diff --git a/app/workers/admin_email_worker.rb b/app/workers/admin_email_worker.rb
index 667fff031dd..c2dc955b27c 100644
--- a/app/workers/admin_email_worker.rb
+++ b/app/workers/admin_email_worker.rb
@@ -1,7 +1,6 @@
class AdminEmailWorker
include Sidekiq::Worker
-
- sidekiq_options retry: false # this job auto-repeats via sidekiq-cron
+ include CronjobQueue
def perform
repository_check_failed_count = Project.where(last_repository_check_failed: true).count
diff --git a/app/workers/build_coverage_worker.rb b/app/workers/build_coverage_worker.rb
index 0680645a8db..def0ab1dde1 100644
--- a/app/workers/build_coverage_worker.rb
+++ b/app/workers/build_coverage_worker.rb
@@ -1,6 +1,6 @@
class BuildCoverageWorker
include Sidekiq::Worker
- sidekiq_options queue: :default
+ include BuildQueue
def perform(build_id)
Ci::Build.find_by(id: build_id)
diff --git a/app/workers/build_email_worker.rb b/app/workers/build_email_worker.rb
index 1c7a04a66a8..5fdb1f2baa0 100644
--- a/app/workers/build_email_worker.rb
+++ b/app/workers/build_email_worker.rb
@@ -1,5 +1,6 @@
class BuildEmailWorker
include Sidekiq::Worker
+ include BuildQueue
def perform(build_id, recipients, push_data)
recipients.each do |recipient|
diff --git a/app/workers/build_finished_worker.rb b/app/workers/build_finished_worker.rb
index e7286b77ac5..466410bf08c 100644
--- a/app/workers/build_finished_worker.rb
+++ b/app/workers/build_finished_worker.rb
@@ -1,5 +1,6 @@
class BuildFinishedWorker
include Sidekiq::Worker
+ include BuildQueue
def perform(build_id)
Ci::Build.find_by(id: build_id).try do |build|
diff --git a/app/workers/build_hooks_worker.rb b/app/workers/build_hooks_worker.rb
index e22ececb3fd..9965af935d4 100644
--- a/app/workers/build_hooks_worker.rb
+++ b/app/workers/build_hooks_worker.rb
@@ -1,6 +1,6 @@
class BuildHooksWorker
include Sidekiq::Worker
- sidekiq_options queue: :default
+ include BuildQueue
def perform(build_id)
Ci::Build.find_by(id: build_id)
diff --git a/app/workers/build_success_worker.rb b/app/workers/build_success_worker.rb
index 500d357ce31..e0ad5268664 100644
--- a/app/workers/build_success_worker.rb
+++ b/app/workers/build_success_worker.rb
@@ -1,6 +1,6 @@
class BuildSuccessWorker
include Sidekiq::Worker
- sidekiq_options queue: :default
+ include BuildQueue
def perform(build_id)
Ci::Build.find_by(id: build_id).try do |build|
diff --git a/app/workers/clear_database_cache_worker.rb b/app/workers/clear_database_cache_worker.rb
index c541daba50e..c4cb4733482 100644
--- a/app/workers/clear_database_cache_worker.rb
+++ b/app/workers/clear_database_cache_worker.rb
@@ -1,6 +1,7 @@
# This worker clears all cache fields in the database, working in batches.
class ClearDatabaseCacheWorker
include Sidekiq::Worker
+ include DedicatedSidekiqQueue
BATCH_SIZE = 1000
diff --git a/app/workers/concerns/build_queue.rb b/app/workers/concerns/build_queue.rb
new file mode 100644
index 00000000000..cf0ead40a8b
--- /dev/null
+++ b/app/workers/concerns/build_queue.rb
@@ -0,0 +1,8 @@
+# Concern for setting Sidekiq settings for the various CI build workers.
+module BuildQueue
+ extend ActiveSupport::Concern
+
+ included do
+ sidekiq_options queue: :build
+ end
+end
diff --git a/app/workers/concerns/cronjob_queue.rb b/app/workers/concerns/cronjob_queue.rb
new file mode 100644
index 00000000000..e918bb011e0
--- /dev/null
+++ b/app/workers/concerns/cronjob_queue.rb
@@ -0,0 +1,9 @@
+# Concern that sets various Sidekiq settings for workers executed using a
+# cronjob.
+module CronjobQueue
+ extend ActiveSupport::Concern
+
+ included do
+ sidekiq_options queue: :cronjob, retry: false
+ end
+end
diff --git a/app/workers/concerns/dedicated_sidekiq_queue.rb b/app/workers/concerns/dedicated_sidekiq_queue.rb
new file mode 100644
index 00000000000..132bae6022b
--- /dev/null
+++ b/app/workers/concerns/dedicated_sidekiq_queue.rb
@@ -0,0 +1,9 @@
+# Concern that sets the queue of a Sidekiq worker based on the worker's class
+# name/namespace.
+module DedicatedSidekiqQueue
+ extend ActiveSupport::Concern
+
+ included do
+ sidekiq_options queue: name.sub(/Worker\z/, '').underscore.tr('/', '_')
+ end
+end
diff --git a/app/workers/concerns/pipeline_queue.rb b/app/workers/concerns/pipeline_queue.rb
new file mode 100644
index 00000000000..ca3860e1d38
--- /dev/null
+++ b/app/workers/concerns/pipeline_queue.rb
@@ -0,0 +1,8 @@
+# Concern for setting Sidekiq settings for the various CI pipeline workers.
+module PipelineQueue
+ extend ActiveSupport::Concern
+
+ included do
+ sidekiq_options queue: :pipeline
+ end
+end
diff --git a/app/workers/concerns/repository_check_queue.rb b/app/workers/concerns/repository_check_queue.rb
new file mode 100644
index 00000000000..a597321ccf4
--- /dev/null
+++ b/app/workers/concerns/repository_check_queue.rb
@@ -0,0 +1,8 @@
+# Concern for setting Sidekiq settings for the various repository check workers.
+module RepositoryCheckQueue
+ extend ActiveSupport::Concern
+
+ included do
+ sidekiq_options queue: :repository_check, retry: false
+ end
+end
diff --git a/app/workers/delete_user_worker.rb b/app/workers/delete_user_worker.rb
index 6ff361e4d80..3194c389b3d 100644
--- a/app/workers/delete_user_worker.rb
+++ b/app/workers/delete_user_worker.rb
@@ -1,5 +1,6 @@
class DeleteUserWorker
include Sidekiq::Worker
+ include DedicatedSidekiqQueue
def perform(current_user_id, delete_user_id, options = {})
delete_user = User.find(delete_user_id)
diff --git a/app/workers/email_receiver_worker.rb b/app/workers/email_receiver_worker.rb
index 842eebdea9e..d3f7e479a8d 100644
--- a/app/workers/email_receiver_worker.rb
+++ b/app/workers/email_receiver_worker.rb
@@ -1,7 +1,6 @@
class EmailReceiverWorker
include Sidekiq::Worker
-
- sidekiq_options queue: :incoming_email
+ include DedicatedSidekiqQueue
def perform(raw)
return unless Gitlab::IncomingEmail.enabled?
diff --git a/app/workers/emails_on_push_worker.rb b/app/workers/emails_on_push_worker.rb
index 1dc7e0adef7..b9cd49985dc 100644
--- a/app/workers/emails_on_push_worker.rb
+++ b/app/workers/emails_on_push_worker.rb
@@ -1,7 +1,7 @@
class EmailsOnPushWorker
include Sidekiq::Worker
+ include DedicatedSidekiqQueue
- sidekiq_options queue: :mailers
attr_reader :email, :skip_premailer
def perform(project_id, recipients, push_data, options = {})
diff --git a/app/workers/expire_build_artifacts_worker.rb b/app/workers/expire_build_artifacts_worker.rb
index 174eabff9fd..a27585fd389 100644
--- a/app/workers/expire_build_artifacts_worker.rb
+++ b/app/workers/expire_build_artifacts_worker.rb
@@ -1,5 +1,6 @@
class ExpireBuildArtifactsWorker
include Sidekiq::Worker
+ include CronjobQueue
def perform
Rails.logger.info 'Scheduling removal of build artifacts'
diff --git a/app/workers/expire_build_instance_artifacts_worker.rb b/app/workers/expire_build_instance_artifacts_worker.rb
index d9e2cc37bb3..eb403c134d1 100644
--- a/app/workers/expire_build_instance_artifacts_worker.rb
+++ b/app/workers/expire_build_instance_artifacts_worker.rb
@@ -1,5 +1,6 @@
class ExpireBuildInstanceArtifactsWorker
include Sidekiq::Worker
+ include DedicatedSidekiqQueue
def perform(build_id)
build = Ci::Build
diff --git a/app/workers/git_garbage_collect_worker.rb b/app/workers/git_garbage_collect_worker.rb
index a6cefd4d601..65f8093b5b0 100644
--- a/app/workers/git_garbage_collect_worker.rb
+++ b/app/workers/git_garbage_collect_worker.rb
@@ -1,8 +1,9 @@
class GitGarbageCollectWorker
include Sidekiq::Worker
include Gitlab::ShellAdapter
+ include DedicatedSidekiqQueue
- sidekiq_options queue: :gitlab_shell, retry: false
+ sidekiq_options retry: false
def perform(project_id)
project = Project.find(project_id)
diff --git a/app/workers/gitlab_shell_worker.rb b/app/workers/gitlab_shell_worker.rb
index cfeda88bbc5..964287a1793 100644
--- a/app/workers/gitlab_shell_worker.rb
+++ b/app/workers/gitlab_shell_worker.rb
@@ -1,8 +1,7 @@
class GitlabShellWorker
include Sidekiq::Worker
include Gitlab::ShellAdapter
-
- sidekiq_options queue: :gitlab_shell
+ include DedicatedSidekiqQueue
def perform(action, *arg)
gitlab_shell.send(action, *arg)
diff --git a/app/workers/group_destroy_worker.rb b/app/workers/group_destroy_worker.rb
index 5048746f09b..a49a5fd0855 100644
--- a/app/workers/group_destroy_worker.rb
+++ b/app/workers/group_destroy_worker.rb
@@ -1,7 +1,6 @@
class GroupDestroyWorker
include Sidekiq::Worker
-
- sidekiq_options queue: :default
+ include DedicatedSidekiqQueue
def perform(group_id, user_id)
begin
diff --git a/app/workers/import_export_project_cleanup_worker.rb b/app/workers/import_export_project_cleanup_worker.rb
index 72e3a9ae734..7957ed807ab 100644
--- a/app/workers/import_export_project_cleanup_worker.rb
+++ b/app/workers/import_export_project_cleanup_worker.rb
@@ -1,7 +1,6 @@
class ImportExportProjectCleanupWorker
include Sidekiq::Worker
-
- sidekiq_options queue: :default
+ include CronjobQueue
def perform
ImportExportCleanUpService.new.execute
diff --git a/app/workers/irker_worker.rb b/app/workers/irker_worker.rb
index 19f38358eb5..7e44b241743 100644
--- a/app/workers/irker_worker.rb
+++ b/app/workers/irker_worker.rb
@@ -3,6 +3,7 @@ require 'socket'
class IrkerWorker
include Sidekiq::Worker
+ include DedicatedSidekiqQueue
def perform(project_id, chans, colors, push_data, settings)
project = Project.find(project_id)
diff --git a/app/workers/merge_worker.rb b/app/workers/merge_worker.rb
index c87c0a252b1..79efca4f2f9 100644
--- a/app/workers/merge_worker.rb
+++ b/app/workers/merge_worker.rb
@@ -1,7 +1,6 @@
class MergeWorker
include Sidekiq::Worker
-
- sidekiq_options queue: :default
+ include DedicatedSidekiqQueue
def perform(merge_request_id, current_user_id, params)
params = params.with_indifferent_access
diff --git a/app/workers/new_note_worker.rb b/app/workers/new_note_worker.rb
index 1b3232cd365..c3e62bb88c0 100644
--- a/app/workers/new_note_worker.rb
+++ b/app/workers/new_note_worker.rb
@@ -1,7 +1,6 @@
class NewNoteWorker
include Sidekiq::Worker
-
- sidekiq_options queue: :default
+ include DedicatedSidekiqQueue
def perform(note_id, note_params)
note = Note.find(note_id)
diff --git a/app/workers/pipeline_hooks_worker.rb b/app/workers/pipeline_hooks_worker.rb
index ab5e9f6daad..7e36eacebf8 100644
--- a/app/workers/pipeline_hooks_worker.rb
+++ b/app/workers/pipeline_hooks_worker.rb
@@ -1,6 +1,6 @@
class PipelineHooksWorker
include Sidekiq::Worker
- sidekiq_options queue: :default
+ include PipelineQueue
def perform(pipeline_id)
Ci::Pipeline.find_by(id: pipeline_id)
diff --git a/app/workers/pipeline_metrics_worker.rb b/app/workers/pipeline_metrics_worker.rb
index 7bb92df3bbd..34f6ef161fb 100644
--- a/app/workers/pipeline_metrics_worker.rb
+++ b/app/workers/pipeline_metrics_worker.rb
@@ -1,7 +1,6 @@
class PipelineMetricsWorker
include Sidekiq::Worker
-
- sidekiq_options queue: :default
+ include PipelineQueue
def perform(pipeline_id)
Ci::Pipeline.find_by(id: pipeline_id).try do |pipeline|
diff --git a/app/workers/pipeline_process_worker.rb b/app/workers/pipeline_process_worker.rb
index f44227d7086..357e4a9a1c3 100644
--- a/app/workers/pipeline_process_worker.rb
+++ b/app/workers/pipeline_process_worker.rb
@@ -1,7 +1,6 @@
class PipelineProcessWorker
include Sidekiq::Worker
-
- sidekiq_options queue: :default
+ include PipelineQueue
def perform(pipeline_id)
Ci::Pipeline.find_by(id: pipeline_id)
diff --git a/app/workers/pipeline_success_worker.rb b/app/workers/pipeline_success_worker.rb
index 5dd443fea59..2aa6fff24da 100644
--- a/app/workers/pipeline_success_worker.rb
+++ b/app/workers/pipeline_success_worker.rb
@@ -1,6 +1,6 @@
class PipelineSuccessWorker
include Sidekiq::Worker
- sidekiq_options queue: :default
+ include PipelineQueue
def perform(pipeline_id)
Ci::Pipeline.find_by(id: pipeline_id).try do |pipeline|
diff --git a/app/workers/pipeline_update_worker.rb b/app/workers/pipeline_update_worker.rb
index 44a7f24e401..96c4152c674 100644
--- a/app/workers/pipeline_update_worker.rb
+++ b/app/workers/pipeline_update_worker.rb
@@ -1,7 +1,6 @@
class PipelineUpdateWorker
include Sidekiq::Worker
-
- sidekiq_options queue: :default
+ include PipelineQueue
def perform(pipeline_id)
Ci::Pipeline.find_by(id: pipeline_id)
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index a9a2b716005..eee0ca12af9 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -1,7 +1,6 @@
class PostReceive
include Sidekiq::Worker
-
- sidekiq_options queue: :post_receive
+ include DedicatedSidekiqQueue
def perform(repo_path, identifier, changes)
if path = Gitlab.config.repositories.storages.find { |p| repo_path.start_with?(p[1].to_s) }
diff --git a/app/workers/project_cache_worker.rb b/app/workers/project_cache_worker.rb
index 0d524e88dc3..71b274e0c99 100644
--- a/app/workers/project_cache_worker.rb
+++ b/app/workers/project_cache_worker.rb
@@ -5,8 +5,7 @@
# storage engine as much.
class ProjectCacheWorker
include Sidekiq::Worker
-
- sidekiq_options queue: :default
+ include DedicatedSidekiqQueue
LEASE_TIMEOUT = 15.minutes.to_i
diff --git a/app/workers/project_destroy_worker.rb b/app/workers/project_destroy_worker.rb
index 3062301a9b1..b462327490e 100644
--- a/app/workers/project_destroy_worker.rb
+++ b/app/workers/project_destroy_worker.rb
@@ -1,7 +1,6 @@
class ProjectDestroyWorker
include Sidekiq::Worker
-
- sidekiq_options queue: :default
+ include DedicatedSidekiqQueue
def perform(project_id, user_id, params)
begin
diff --git a/app/workers/project_export_worker.rb b/app/workers/project_export_worker.rb
index 615311e63f5..6009aa1b191 100644
--- a/app/workers/project_export_worker.rb
+++ b/app/workers/project_export_worker.rb
@@ -1,7 +1,8 @@
class ProjectExportWorker
include Sidekiq::Worker
+ include DedicatedSidekiqQueue
- sidekiq_options queue: :gitlab_shell, retry: 3
+ sidekiq_options retry: 3
def perform(current_user_id, project_id)
current_user = User.find(current_user_id)
diff --git a/app/workers/project_service_worker.rb b/app/workers/project_service_worker.rb
index 64d39c4d3f7..fdfdeab7b41 100644
--- a/app/workers/project_service_worker.rb
+++ b/app/workers/project_service_worker.rb
@@ -1,7 +1,6 @@
class ProjectServiceWorker
include Sidekiq::Worker
-
- sidekiq_options queue: :project_web_hook
+ include DedicatedSidekiqQueue
def perform(hook_id, data)
data = data.with_indifferent_access
diff --git a/app/workers/project_web_hook_worker.rb b/app/workers/project_web_hook_worker.rb
index fb878965288..efb85eafd15 100644
--- a/app/workers/project_web_hook_worker.rb
+++ b/app/workers/project_web_hook_worker.rb
@@ -1,7 +1,6 @@
class ProjectWebHookWorker
include Sidekiq::Worker
-
- sidekiq_options queue: :project_web_hook
+ include DedicatedSidekiqQueue
def perform(hook_id, data, hook_name)
data = data.with_indifferent_access
diff --git a/app/workers/prune_old_events_worker.rb b/app/workers/prune_old_events_worker.rb
index 5883cafe1d1..392abb9c21b 100644
--- a/app/workers/prune_old_events_worker.rb
+++ b/app/workers/prune_old_events_worker.rb
@@ -1,5 +1,6 @@
class PruneOldEventsWorker
include Sidekiq::Worker
+ include CronjobQueue
def perform
# Contribution calendar shows maximum 12 months of events.
diff --git a/app/workers/remove_expired_group_links_worker.rb b/app/workers/remove_expired_group_links_worker.rb
index 246c8b6650a..2a619f83410 100644
--- a/app/workers/remove_expired_group_links_worker.rb
+++ b/app/workers/remove_expired_group_links_worker.rb
@@ -1,5 +1,6 @@
class RemoveExpiredGroupLinksWorker
include Sidekiq::Worker
+ include CronjobQueue
def perform
ProjectGroupLink.expired.destroy_all
diff --git a/app/workers/remove_expired_members_worker.rb b/app/workers/remove_expired_members_worker.rb
index cf765af97ce..31f652e5f9b 100644
--- a/app/workers/remove_expired_members_worker.rb
+++ b/app/workers/remove_expired_members_worker.rb
@@ -1,5 +1,6 @@
class RemoveExpiredMembersWorker
include Sidekiq::Worker
+ include CronjobQueue
def perform
Member.expired.find_each do |member|
diff --git a/app/workers/repository_archive_cache_worker.rb b/app/workers/repository_archive_cache_worker.rb
index a2e49c61f59..e47069df189 100644
--- a/app/workers/repository_archive_cache_worker.rb
+++ b/app/workers/repository_archive_cache_worker.rb
@@ -1,7 +1,6 @@
class RepositoryArchiveCacheWorker
include Sidekiq::Worker
-
- sidekiq_options queue: :default
+ include CronjobQueue
def perform
RepositoryArchiveCleanUpService.new.execute
diff --git a/app/workers/repository_check/batch_worker.rb b/app/workers/repository_check/batch_worker.rb
index a3e16fa5212..c3e7491ec4e 100644
--- a/app/workers/repository_check/batch_worker.rb
+++ b/app/workers/repository_check/batch_worker.rb
@@ -1,14 +1,13 @@
module RepositoryCheck
class BatchWorker
include Sidekiq::Worker
-
+ include CronjobQueue
+
RUN_TIME = 3600
-
- sidekiq_options retry: false
-
+
def perform
start = Time.now
-
+
# This loop will break after a little more than one hour ('a little
# more' because `git fsck` may take a few minutes), or if it runs out of
# projects to check. By default sidekiq-cron will start a new
@@ -17,15 +16,15 @@ module RepositoryCheck
project_ids.each do |project_id|
break if Time.now - start >= RUN_TIME
break unless current_settings.repository_checks_enabled
-
+
next unless try_obtain_lease(project_id)
-
+
SingleRepositoryWorker.new.perform(project_id)
end
end
-
+
private
-
+
# Project.find_each does not support WHERE clauses and
# Project.find_in_batches does not support ordering. So we just build an
# array of ID's. This is OK because we do it only once an hour, because
@@ -39,7 +38,7 @@ module RepositoryCheck
reorder('last_repository_check_at ASC').limit(limit).pluck(:id)
never_checked_projects + old_check_projects
end
-
+
def try_obtain_lease(id)
# Use a 24-hour timeout because on servers/projects where 'git fsck' is
# super slow we definitely do not want to run it twice in parallel.
@@ -48,7 +47,7 @@ module RepositoryCheck
timeout: 24.hours
).try_obtain
end
-
+
def current_settings
# No caching of the settings! If we cache them and an admin disables
# this feature, an active RepositoryCheckWorker would keep going for up
diff --git a/app/workers/repository_check/clear_worker.rb b/app/workers/repository_check/clear_worker.rb
index b7202ddff34..1f1b38540ee 100644
--- a/app/workers/repository_check/clear_worker.rb
+++ b/app/workers/repository_check/clear_worker.rb
@@ -1,8 +1,7 @@
module RepositoryCheck
class ClearWorker
include Sidekiq::Worker
-
- sidekiq_options retry: false
+ include RepositoryCheckQueue
def perform
# Do small batched updates because these updates will be slow and locking
diff --git a/app/workers/repository_check/single_repository_worker.rb b/app/workers/repository_check/single_repository_worker.rb
index 98ddf5d0688..3d8bfc6fc6c 100644
--- a/app/workers/repository_check/single_repository_worker.rb
+++ b/app/workers/repository_check/single_repository_worker.rb
@@ -1,8 +1,7 @@
module RepositoryCheck
class SingleRepositoryWorker
include Sidekiq::Worker
-
- sidekiq_options retry: false
+ include RepositoryCheckQueue
def perform(project_id)
project = Project.find(project_id)
diff --git a/app/workers/repository_fork_worker.rb b/app/workers/repository_fork_worker.rb
index 61ed1c38ac4..efc99ec962a 100644
--- a/app/workers/repository_fork_worker.rb
+++ b/app/workers/repository_fork_worker.rb
@@ -1,8 +1,7 @@
class RepositoryForkWorker
include Sidekiq::Worker
include Gitlab::ShellAdapter
-
- sidekiq_options queue: :gitlab_shell
+ include DedicatedSidekiqQueue
def perform(project_id, forked_from_repository_storage_path, source_path, target_path)
Gitlab::Metrics.add_event(:fork_repository,
diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb
index d2ca8813ab9..c8a77e21c12 100644
--- a/app/workers/repository_import_worker.rb
+++ b/app/workers/repository_import_worker.rb
@@ -1,8 +1,7 @@
class RepositoryImportWorker
include Sidekiq::Worker
include Gitlab::ShellAdapter
-
- sidekiq_options queue: :gitlab_shell
+ include DedicatedSidekiqQueue
attr_accessor :project, :current_user
diff --git a/app/workers/requests_profiles_worker.rb b/app/workers/requests_profiles_worker.rb
index 9dd228a2483..703b025d76e 100644
--- a/app/workers/requests_profiles_worker.rb
+++ b/app/workers/requests_profiles_worker.rb
@@ -1,7 +1,6 @@
class RequestsProfilesWorker
include Sidekiq::Worker
-
- sidekiq_options queue: :default
+ include CronjobQueue
def perform
Gitlab::RequestProfiler.remove_all_profiles
diff --git a/app/workers/stuck_ci_builds_worker.rb b/app/workers/stuck_ci_builds_worker.rb
index 6828013b377..b70df5a1afa 100644
--- a/app/workers/stuck_ci_builds_worker.rb
+++ b/app/workers/stuck_ci_builds_worker.rb
@@ -1,5 +1,6 @@
class StuckCiBuildsWorker
include Sidekiq::Worker
+ include CronjobQueue
BUILD_STUCK_TIMEOUT = 1.day
diff --git a/app/workers/system_hook_worker.rb b/app/workers/system_hook_worker.rb
index a122c274763..baf2f12eeac 100644
--- a/app/workers/system_hook_worker.rb
+++ b/app/workers/system_hook_worker.rb
@@ -1,7 +1,6 @@
class SystemHookWorker
include Sidekiq::Worker
-
- sidekiq_options queue: :system_hook
+ include DedicatedSidekiqQueue
def perform(hook_id, data, hook_name)
SystemHook.find(hook_id).execute(data, hook_name)
diff --git a/app/workers/trending_projects_worker.rb b/app/workers/trending_projects_worker.rb
index df4c4a6628b..0531630d13a 100644
--- a/app/workers/trending_projects_worker.rb
+++ b/app/workers/trending_projects_worker.rb
@@ -1,7 +1,6 @@
class TrendingProjectsWorker
include Sidekiq::Worker
-
- sidekiq_options queue: :trending_projects
+ include CronjobQueue
def perform
Rails.logger.info('Refreshing trending projects')
diff --git a/app/workers/update_merge_requests_worker.rb b/app/workers/update_merge_requests_worker.rb
index 03f0528cdae..acc4d858136 100644
--- a/app/workers/update_merge_requests_worker.rb
+++ b/app/workers/update_merge_requests_worker.rb
@@ -1,5 +1,6 @@
class UpdateMergeRequestsWorker
include Sidekiq::Worker
+ include DedicatedSidekiqQueue
def perform(project_id, user_id, oldrev, newrev, ref)
project = Project.find_by(id: project_id)