Commit cf9c3f71 authored by Sean McGivern's avatar Sean McGivern

Merge branch 'ce-to-ee-2018-11-20' into 'master'

CE upstream - 2018-11-20 13:22 UTC

Closes gitlab-ce#54189, #8488, and gitlab-ce#54236

See merge request gitlab-org/gitlab-ee!8533
parents ed4707a2 2eaaca51
...@@ -2,10 +2,6 @@ ...@@ -2,10 +2,6 @@
documentation](doc/development/changelog.md) for instructions on adding your own documentation](doc/development/changelog.md) for instructions on adding your own
entry. entry.
## 11.4.7 (2018-11-20)
- No changes.
## 11.4.6 (2018-11-18) ## 11.4.6 (2018-11-18)
### Security (1 change) ### Security (1 change)
...@@ -15,9 +11,8 @@ entry. ...@@ -15,9 +11,8 @@ entry.
## 11.4.5 (2018-11-04) ## 11.4.5 (2018-11-04)
### Fixed (5 changes, 1 of them is from the community) ### Fixed (4 changes, 1 of them is from the community)
- Fix stuck job warning message. !8060
- fix link to enable usage ping from convdev index. !22545 (Anand Capur) - fix link to enable usage ping from convdev index. !22545 (Anand Capur)
- Update gitlab-ui dependency to 1.8.0-hotfix.1 to fix IE11 bug. - Update gitlab-ui dependency to 1.8.0-hotfix.1 to fix IE11 bug.
- Remove duplicate escape in job sidebar. - Remove duplicate escape in job sidebar.
...@@ -324,7 +319,6 @@ entry. ...@@ -324,7 +319,6 @@ entry.
- Fix loading issue on some merge request discussion. !21982 - Fix loading issue on some merge request discussion. !21982
- Fix project deletion when there is a export available. !22276 - Fix project deletion when there is a export available. !22276
- No changes.
## 11.3.3 (2018-10-04) ## 11.3.3 (2018-10-04)
......
...@@ -103,6 +103,12 @@ picked into the stable branches) up to the 19th of the month. Such merge ...@@ -103,6 +103,12 @@ picked into the stable branches) up to the 19th of the month. Such merge
requests should have the ~"feature flag" label assigned, and don't require a requests should have the ~"feature flag" label assigned, and don't require a
corresponding exception request to be created. corresponding exception request to be created.
In order to build the final package and present the feature for self-hosted
customers, the feature flag should be removed. This should happen before the
22nd, ideally _at least_ 2 days before. That means MRs with feature
flags being picked at the 19th would have a quite tight schedule, so picking
these _earlier_ is preferable.
While rare, release managers may decide to reject picking a change into a stable While rare, release managers may decide to reject picking a change into a stable
branch, even when feature flags are used. This might be necessary if the changes branch, even when feature flags are used. This might be necessary if the changes
are deemed problematic, too invasive, or there simply isn't enough time to are deemed problematic, too invasive, or there simply isn't enough time to
......
...@@ -158,10 +158,16 @@ class GfmAutoComplete { ...@@ -158,10 +158,16 @@ class GfmAutoComplete {
// Team Members // Team Members
$input.atwho({ $input.atwho({
at: '@', at: '@',
alias: 'users',
displayTpl(value) { displayTpl(value) {
let tmpl = GfmAutoComplete.Loading.template; let tmpl = GfmAutoComplete.Loading.template;
if (value.username != null) { const { avatarTag, username, title } = value;
tmpl = GfmAutoComplete.Members.template; if (username != null) {
tmpl = GfmAutoComplete.Members.templateFunction({
avatarTag,
username,
title,
});
} }
return tmpl; return tmpl;
}, },
...@@ -572,8 +578,9 @@ GfmAutoComplete.Emoji = { ...@@ -572,8 +578,9 @@ GfmAutoComplete.Emoji = {
}; };
// Team Members // Team Members
GfmAutoComplete.Members = { GfmAutoComplete.Members = {
// eslint-disable-next-line no-template-curly-in-string templateFunction({ avatarTag, username, title }) {
template: '<li>${avatarTag} ${username} <small>${title}</small></li>', return `<li>${avatarTag} ${username} <small>${_.escape(title)}</small></li>`;
},
}; };
GfmAutoComplete.Labels = { GfmAutoComplete.Labels = {
template: template:
......
...@@ -10,6 +10,7 @@ export default class UserOverviewBlock { ...@@ -10,6 +10,7 @@ export default class UserOverviewBlock {
limit: DEFAULT_LIMIT, limit: DEFAULT_LIMIT,
...options.requestParams, ...options.requestParams,
}; };
this.postRenderCallback = options.postRenderCallback;
this.loadData(); this.loadData();
} }
...@@ -43,5 +44,9 @@ export default class UserOverviewBlock { ...@@ -43,5 +44,9 @@ export default class UserOverviewBlock {
} }
loadingEl.classList.add('hide'); loadingEl.classList.add('hide');
if (this.postRenderCallback) {
this.postRenderCallback.call(this);
}
} }
} }
...@@ -2,7 +2,8 @@ import $ from 'jquery'; ...@@ -2,7 +2,8 @@ import $ from 'jquery';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import Activities from '~/activities'; import Activities from '~/activities';
import { localTimeAgo } from '~/lib/utils/datetime_utility'; import { localTimeAgo } from '~/lib/utils/datetime_utility';
import { __, sprintf } from '~/locale'; import AjaxCache from '~/lib/utils/ajax_cache';
import { __ } from '~/locale';
import flash from '~/flash'; import flash from '~/flash';
import ActivityCalendar from './activity_calendar'; import ActivityCalendar from './activity_calendar';
import UserOverviewBlock from './user_overview_block'; import UserOverviewBlock from './user_overview_block';
...@@ -62,23 +63,20 @@ import UserOverviewBlock from './user_overview_block'; ...@@ -62,23 +63,20 @@ import UserOverviewBlock from './user_overview_block';
* </div> * </div>
*/ */
const CALENDAR_TEMPLATES = { const CALENDAR_TEMPLATE = `
activity: ` <div class="clearfix calendar">
<div class="clearfix calendar"> <div class="js-contrib-calendar"></div>
<div class="js-contrib-calendar"></div> <div class="calendar-hint bottom-right"></div>
<div class="calendar-hint bottom-right"></div> </div>
</div> `;
`,
overview: `
<div class="clearfix calendar">
<div class="calendar-hint"></div>
<div class="js-contrib-calendar prepend-top-20"></div>
</div>
`,
};
const CALENDAR_PERIOD_6_MONTHS = 6; const CALENDAR_PERIOD_6_MONTHS = 6;
const CALENDAR_PERIOD_12_MONTHS = 12; const CALENDAR_PERIOD_12_MONTHS = 12;
/* computation based on
* width = (group + 1) * this.daySizeWithSpace + this.getExtraWidthPadding(group);
* (see activity_calendar.js)
*/
const OVERVIEW_CALENDAR_BREAKPOINT = 918;
export default class UserTabs { export default class UserTabs {
constructor({ defaultAction, action, parentEl }) { constructor({ defaultAction, action, parentEl }) {
...@@ -105,6 +103,12 @@ export default class UserTabs { ...@@ -105,6 +103,12 @@ export default class UserTabs {
.off('shown.bs.tab', '.nav-links a[data-toggle="tab"]') .off('shown.bs.tab', '.nav-links a[data-toggle="tab"]')
.on('shown.bs.tab', '.nav-links a[data-toggle="tab"]', event => this.tabShown(event)) .on('shown.bs.tab', '.nav-links a[data-toggle="tab"]', event => this.tabShown(event))
.on('click', '.gl-pagination a', event => this.changeProjectsPage(event)); .on('click', '.gl-pagination a', event => this.changeProjectsPage(event));
window.addEventListener('resize', () => this.onResize());
}
onResize() {
this.loadActivityCalendar();
} }
changeProjectsPage(e) { changeProjectsPage(e) {
...@@ -167,8 +171,6 @@ export default class UserTabs { ...@@ -167,8 +171,6 @@ export default class UserTabs {
return; return;
} }
this.loadActivityCalendar('activity');
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
new Activities('#activity'); new Activities('#activity');
...@@ -180,10 +182,10 @@ export default class UserTabs { ...@@ -180,10 +182,10 @@ export default class UserTabs {
return; return;
} }
this.loadActivityCalendar('overview'); this.loadActivityCalendar();
UserTabs.renderMostRecentBlocks('#js-overview .activities-block', { UserTabs.renderMostRecentBlocks('#js-overview .activities-block', {
requestParams: { limit: 5 }, requestParams: { limit: 10 },
}); });
UserTabs.renderMostRecentBlocks('#js-overview .projects-block', { UserTabs.renderMostRecentBlocks('#js-overview .projects-block', {
requestParams: { limit: 10, skip_pagination: true }, requestParams: { limit: 10, skip_pagination: true },
...@@ -198,52 +200,39 @@ export default class UserTabs { ...@@ -198,52 +200,39 @@ export default class UserTabs {
container, container,
url: $(`${container} .overview-content-list`).data('href'), url: $(`${container} .overview-content-list`).data('href'),
...options, ...options,
postRenderCallback: () => localTimeAgo($('.js-timeago', container)),
}); });
} }
loadActivityCalendar(action) { loadActivityCalendar() {
const monthsAgo = action === 'overview' ? CALENDAR_PERIOD_6_MONTHS : CALENDAR_PERIOD_12_MONTHS;
const $calendarWrap = this.$parentEl.find('.tab-pane.active .user-calendar'); const $calendarWrap = this.$parentEl.find('.tab-pane.active .user-calendar');
const calendarPath = $calendarWrap.data('calendarPath'); const calendarPath = $calendarWrap.data('calendarPath');
AjaxCache.retrieve(calendarPath)
.then(data => UserTabs.renderActivityCalendar(data, $calendarWrap))
.catch(() => flash(__('There was an error loading users activity calendar.')));
}
static renderActivityCalendar(data, $calendarWrap) {
const monthsAgo = UserTabs.getVisibleCalendarPeriod($calendarWrap);
const calendarActivitiesPath = $calendarWrap.data('calendarActivitiesPath'); const calendarActivitiesPath = $calendarWrap.data('calendarActivitiesPath');
const utcOffset = $calendarWrap.data('utcOffset'); const utcOffset = $calendarWrap.data('utcOffset');
let utcFormatted = 'UTC'; const calendarHint = __('Issues, merge requests, pushes and comments.');
if (utcOffset !== 0) {
utcFormatted = `UTC${utcOffset > 0 ? '+' : ''}${utcOffset / 3600}`;
}
axios $calendarWrap.html(CALENDAR_TEMPLATE);
.get(calendarPath)
.then(({ data }) => { $calendarWrap.find('.calendar-hint').text(calendarHint);
$calendarWrap.html(CALENDAR_TEMPLATES[action]);
// eslint-disable-next-line no-new
let calendarHint = ''; new ActivityCalendar(
'.tab-pane.active .js-contrib-calendar',
if (action === 'activity') { '.tab-pane.active .user-calendar-activities',
calendarHint = sprintf( data,
__( calendarActivitiesPath,
'Summary of issues, merge requests, push events, and comments (Timezone: %{utcFormatted})', utcOffset,
), 0,
{ utcFormatted }, monthsAgo,
); );
} else if (action === 'overview') {
calendarHint = __('Issues, merge requests, pushes and comments.');
}
$calendarWrap.find('.calendar-hint').text(calendarHint);
// eslint-disable-next-line no-new
new ActivityCalendar(
'.tab-pane.active .js-contrib-calendar',
'.tab-pane.active .user-calendar-activities',
data,
calendarActivitiesPath,
utcOffset,
0,
monthsAgo,
);
})
.catch(() => flash(__('There was an error loading users activity calendar.')));
} }
toggleLoading(status) { toggleLoading(status) {
...@@ -267,4 +256,11 @@ export default class UserTabs { ...@@ -267,4 +256,11 @@ export default class UserTabs {
getCurrentAction() { getCurrentAction() {
return this.$parentEl.find('.nav-links a.active').data('action'); return this.$parentEl.find('.nav-links a.active').data('action');
} }
static getVisibleCalendarPeriod($calendarWrap) {
const width = $calendarWrap.width();
return width < OVERVIEW_CALENDAR_BREAKPOINT
? CALENDAR_PERIOD_6_MONTHS
: CALENDAR_PERIOD_12_MONTHS;
}
} }
...@@ -34,14 +34,7 @@ export default { ...@@ -34,14 +34,7 @@ export default {
fileSizeReadable() { fileSizeReadable() {
return numberToHumanSize(this.fileSize); return numberToHumanSize(this.fileSize);
}, },
dimensionStyles() {
if (!this.isLoaded) return {};
return {
width: `${this.width}px`,
height: `${this.height}px`,
};
},
hasFileSize() { hasFileSize() {
return this.fileSize > 0; return this.fileSize > 0;
}, },
...@@ -89,7 +82,6 @@ export default { ...@@ -89,7 +82,6 @@ export default {
<div> <div>
<div <div
:class="innerCssClasses" :class="innerCssClasses"
:style="dimensionStyles"
class="position-relative" class="position-relative"
> >
<img <img
......
...@@ -25,7 +25,7 @@ export default { ...@@ -25,7 +25,7 @@ export default {
swipeMaxWidth: undefined, swipeMaxWidth: undefined,
swipeMaxHeight: undefined, swipeMaxHeight: undefined,
swipeBarPos: 1, swipeBarPos: 1,
swipeWrapWidth: undefined, swipeWrapWidth: 0,
}; };
}, },
computed: { computed: {
...@@ -63,7 +63,7 @@ export default { ...@@ -63,7 +63,7 @@ export default {
leftValue = clientWidth - spaceLeft; leftValue = clientWidth - spaceLeft;
} }
this.swipeWrapWidth = this.swipeMaxWidth - leftValue; this.swipeWrapWidth = (leftValue / clientWidth) * 100;
this.swipeBarPos = leftValue; this.swipeBarPos = leftValue;
}, },
startDrag() { startDrag() {
...@@ -81,7 +81,6 @@ export default { ...@@ -81,7 +81,6 @@ export default {
// Add 2 for border width // Add 2 for border width
this.swipeMaxWidth = this.swipeMaxWidth =
Math.max(this.swipeOldImgInfo.renderedWidth, this.swipeNewImgInfo.renderedWidth) + 2; Math.max(this.swipeOldImgInfo.renderedWidth, this.swipeNewImgInfo.renderedWidth) + 2;
this.swipeWrapWidth = this.swipeMaxWidth;
this.swipeMaxHeight = this.swipeMaxHeight =
Math.max(this.swipeOldImgInfo.renderedHeight, this.swipeNewImgInfo.renderedHeight) + 2; Math.max(this.swipeOldImgInfo.renderedHeight, this.swipeNewImgInfo.renderedHeight) + 2;
...@@ -107,10 +106,6 @@ export default { ...@@ -107,10 +106,6 @@ export default {
<div class="swipe view"> <div class="swipe view">
<div <div
ref="swipeFrame" ref="swipeFrame"
:style="{
'width': swipeMaxPixelWidth,
'height': swipeMaxPixelHeight,
}"
class="swipe-frame"> class="swipe-frame">
<image-viewer <image-viewer
key="swipeOldImg" key="swipeOldImg"
...@@ -123,14 +118,17 @@ export default { ...@@ -123,14 +118,17 @@ export default {
<div <div
ref="swipeWrap" ref="swipeWrap"
:style="{ :style="{
'width': swipeWrapPixelWidth, width: `${swipeWrapWidth}%`
'height': swipeMaxPixelHeight,
}" }"
class="swipe-wrap"> class="swipe-wrap"
>
<image-viewer <image-viewer
key="swipeNewImg" key="swipeNewImg"
:render-info="false" :render-info="false"
:path="newPath" :path="newPath"
:style="{
width: swipeMaxPixelWidth
}"
class="frame added" class="frame added"
@imgLoaded="swipeNewImgLoaded" @imgLoaded="swipeNewImgLoaded"
> >
......
...@@ -19,18 +19,18 @@ export default { ...@@ -19,18 +19,18 @@ export default {
</script> </script>
<template> <template>
<div class="two-up view"> <div class="two-up view d-flex">
<image-viewer <image-viewer
:path="oldPath" :path="oldPath"
:render-info="true" :render-info="true"
inner-css-classes="frame deleted" inner-css-classes="frame deleted"
class="wrap" class="wrap w-50"
/> />
<image-viewer <image-viewer
:path="newPath" :path="newPath"
:render-info="true" :render-info="true"
:inner-css-classes="['frame', 'added']" :inner-css-classes="['frame', 'added']"
class="wrap" class="wrap w-50"
> >
<slot <slot
slot="image-overlay" slot="image-overlay"
......
...@@ -253,19 +253,6 @@ ...@@ -253,19 +253,6 @@
right: 7px; right: 7px;
} }
.frame {
top: 0;
right: 0;
position: absolute;
&.deleted {
margin: 0;
display: block;
top: 13px;
right: 7px;
}
}
.swipe-bar { .swipe-bar {
display: block; display: block;
height: 100%; height: 100%;
...@@ -435,7 +422,7 @@ ...@@ -435,7 +422,7 @@
.onion-skin.view { .onion-skin.view {
.swipe-wrap { .swipe-wrap {
top: 0; top: 0;
right: 0; left: 0;
} }
.frame.deleted { .frame.deleted {
......
...@@ -178,7 +178,7 @@ class GroupDescendantsFinder ...@@ -178,7 +178,7 @@ class GroupDescendantsFinder
end end
def sort def sort
params.fetch(:sort, 'id_asc') params.fetch(:sort, 'created_desc')
end end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
......
...@@ -1053,11 +1053,19 @@ class Repository ...@@ -1053,11 +1053,19 @@ class Repository
end end
def cache def cache
@cache ||= Gitlab::RepositoryCache.new(self) @cache ||= if is_wiki
Gitlab::RepositoryCache.new(self, extra_namespace: 'wiki')
else
Gitlab::RepositoryCache.new(self)
end
end end
def request_store_cache def request_store_cache
@request_store_cache ||= Gitlab::RepositoryCache.new(self, backend: Gitlab::SafeRequestStore) @request_store_cache ||= if is_wiki
Gitlab::RepositoryCache.new(self, extra_namespace: 'wiki', backend: Gitlab::SafeRequestStore)
else
Gitlab::RepositoryCache.new(self, backend: Gitlab::SafeRequestStore)
end
end end
def tags_sorted_by_committed_date def tags_sorted_by_committed_date
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
.project-header.d-flex.flex-row.flex-wrap.align-items-center.append-bottom-8 .project-header.d-flex.flex-row.flex-wrap.align-items-center.append-bottom-8
.project-title-row.d-flex.align-items-center .project-title-row.d-flex.align-items-center
.avatar-container.project-avatar.float-none .avatar-container.project-avatar.float-none
= project_icon(@project, alt: @project.name, class: 'avatar avatar-tile') = project_icon(@project, alt: @project.name, class: 'avatar avatar-tile s24', width: 24, height: 24)
%h1.project-title.d-flex.align-items-baseline.qa-project-name %h1.project-title.d-flex.align-items-baseline.qa-project-name
= @project.name = @project.name
.project-metadata.d-flex.flex-row.flex-wrap.align-items-baseline .project-metadata.d-flex.flex-row.flex-wrap.align-items-baseline
......
- diff_file = viewer.diff_file - diff_file = viewer.diff_file
- url = url_for(safe_params.merge(action: :diff_for_path, old_path: diff_file.old_path, new_path: diff_file.new_path, file_identifier: diff_file.file_identifier)) - url = url_for(safe_params.merge(action: :diff_for_path, old_path: diff_file.old_path, new_path: diff_file.new_path, file_identifier: diff_file.file_identifier))
.nothing-here-block.diff-collapsed{ data: { diff_for_path: url } } .nothing-here-block.diff-collapsed{ data: { diff_for_path: url } }
This diff is collapsed. = _("This diff is collapsed.")
%button.click-to-expand.btn.btn-link Click to expand it. %button.click-to-expand.btn.btn-link= _("Click to expand it.")
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
.files-changed-inner .files-changed-inner
.inline-parallel-buttons.d-none.d-sm-none.d-md-block .inline-parallel-buttons.d-none.d-sm-none.d-md-block
- if !diffs_expanded? && diff_files.any? { |diff_file| diff_file.collapsed? } - if !diffs_expanded? && diff_files.any? { |diff_file| diff_file.collapsed? }
= link_to 'Expand all', url_for(safe_params.merge(expanded: 1, format: nil)), class: 'btn btn-default' = link_to _('Expand all'), url_for(safe_params.merge(expanded: 1, format: nil)), class: 'btn btn-default'
- if show_whitespace_toggle - if show_whitespace_toggle
- if current_controller?(:commit) - if current_controller?(:commit)
= commit_diff_whitespace_link(diffs.project, @commit, class: 'd-none d-sm-inline-block') = commit_diff_whitespace_link(diffs.project, @commit, class: 'd-none d-sm-inline-block')
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
- blob = diff_file.blob - blob = diff_file.blob
.file-actions.d-none.d-sm-block .file-actions.d-none.d-sm-block
- if blob&.readable_text? - if blob&.readable_text?
= link_to '#', class: 'js-toggle-diff-comments btn active has-tooltip', title: "Toggle comments for this file", disabled: @diff_notes_disabled do = link_to '#', class: 'js-toggle-diff-comments btn active has-tooltip', title: _("Toggle comments for this file"), disabled: @diff_notes_disabled do
= icon('comment') = icon('comment')
\ \
- if editable_diff?(diff_file) - if editable_diff?(diff_file)
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
= diff_file.file_path = diff_file.file_path
- if diff_file.deleted_file? - if diff_file.deleted_file?
deleted = _("deleted")
= copy_file_path_button(diff_file.file_path) = copy_file_path_button(diff_file.file_path)
......
.nothing-here-block .nothing-here-block
This #{viewer.switcher_title} could not be displayed because #{diff_render_error_reason(viewer)}. = _("This %{viewer} could not be displayed because %{reason}.") % { viewer: viewer.switcher_title, reason: diff_render_error_reason(viewer) }
You can You can
= diff_render_error_options(viewer).to_sentence(two_words_connector: ' or ', last_word_connector: ', or ').html_safe = diff_render_error_options(viewer).to_sentence(two_words_connector: ' or ', last_word_connector: ', or ').html_safe
......
...@@ -38,4 +38,4 @@ ...@@ -38,4 +38,4 @@
\-#{diff_file.removed_lines} \-#{diff_file.removed_lines}
%li.dropdown-menu-empty-item.hidden %li.dropdown-menu-empty-item.hidden
%a %a
No files found. = _("No files found.")
- too_big = diff_file.diff_lines.count > Commit::DIFF_SAFE_LINES - too_big = diff_file.diff_lines.count > Commit::DIFF_SAFE_LINES
- if too_big - if too_big
.suppressed-container .suppressed-container
%a.show-suppressed-diff.js-show-suppressed-diff Changes suppressed. Click to show. %a.show-suppressed-diff.js-show-suppressed-diff= _("Changes suppressed. Click to show.")
%table.text-file.diff-wrap-lines.code.js-syntax-highlight.commit-diff{ data: diff_view_data, class: too_big ? 'hide' : '' } %table.text-file.diff-wrap-lines.code.js-syntax-highlight.commit-diff{ data: diff_view_data, class: too_big ? 'hide' : '' }
= render partial: "projects/diffs/line", = render partial: "projects/diffs/line",
......
.alert.alert-warning .alert.alert-warning
%h4 %h4
Too many changes to show. = _("Too many changes to show.")
.float-right .float-right
- if current_controller?(:commit) - if current_controller?(:commit)
= link_to "Plain diff", project_commit_path(@project, @commit, format: :diff), class: "btn btn-sm" = link_to _("Plain diff"), project_commit_path(@project, @commit, format: :diff), class: "btn btn-sm"
= link_to "Email patch", project_commit_path(@project, @commit, format: :patch), class: "btn btn-sm" = link_to _("Email patch"), project_commit_path(@project, @commit, format: :patch), class: "btn btn-sm"
- elsif current_controller?('projects/merge_requests/diffs') && @merge_request&.persisted? - elsif current_controller?('projects/merge_requests/diffs') && @merge_request&.persisted?
= link_to "Plain diff", merge_request_path(@merge_request, format: :diff), class: "btn btn-sm" = link_to _("Plain diff"), merge_request_path(@merge_request, format: :diff), class: "btn btn-sm"
= link_to "Email patch", merge_request_path(@merge_request, format: :patch), class: "btn btn-sm" = link_to _("Email patch"), merge_request_path(@merge_request, format: :patch), class: "btn btn-sm"
%p %p
To preserve performance only = _("To preserve performance only <strong>%{display_size} of ${real_size}</strong> files are displayed.").html_safe % { display_size: diff_files.size, real_size: diff_files.real_size }
%strong #{diff_files.size} of #{diff_files.real_size}
files are displayed.
.nothing-here-block .nothing-here-block
File added = _("File added")
.nothing-here-block .nothing-here-block
File deleted = _("File deleted")
- diff_file = viewer.diff_file - diff_file = viewer.diff_file
.nothing-here-block .nothing-here-block
File mode changed from #{diff_file.a_mode} to #{diff_file.b_mode} = _("File mode changed from %{a_mode} to %{b_mode}") % { a_mode: diff_file.a_mode, b_mode: diff_file.b_mode }
.nothing-here-block .nothing-here-block
No preview for this file type = _("No preview for this file type")
.nothing-here-block .nothing-here-block
This diff was suppressed by a .gitattributes entry. = _("This diff was suppressed by a .gitattributes entry.")
.nothing-here-block .nothing-here-block
File moved = _("File moved")
- if environment.external_url && can?(current_user, :read_environment, environment) - if environment.external_url && can?(current_user, :read_environment, environment)
= link_to environment.external_url, target: '_blank', rel: 'noopener noreferrer', class: 'btn external-url has-tooltip qa-view-deployment', title: s_('Environments|Open live environment') do = link_to environment.external_url, target: '_blank', rel: 'noopener noreferrer', class: 'btn external-url has-tooltip qa-view-deployment', title: s_('Environments|Open live environment') do
= sprite_icon('external-link') = sprite_icon('external-link')
View deployment = _("View deployment")
.row.prepend-top-default.append-bottom-default .row.prepend-top-default.append-bottom-default
.col-lg-3 .col-lg-3
%h4.prepend-top-0 %h4.prepend-top-0
Environments = _("Environments")
%p %p
Environments allow you to track deployments of your application - link_to_read_more = link_to(_("Read more about environments"), help_page_path("ci/environments"))
= succeed "." do = _("Environments allow you to track deployments of your application %{link_to_read_more}.").html_safe % { link_to_read_more: link_to_read_more }
= link_to "Read more about environments", help_page_path("ci/environments")
= form_for [@project.namespace.becomes(Namespace), @project, @environment], html: { class: 'col-lg-9' } do |f| = form_for [@project.namespace.becomes(Namespace), @project, @environment], html: { class: 'col-lg-9' } do |f|
= form_errors(@environment) = form_errors(@environment)
.form-group .form-group
= f.label :name, 'Name', class: 'label-bold' = f.label :name, _('Name'), class: 'label-bold'
= f.text_field :name, required: true, class: 'form-control' = f.text_field :name, required: true, class: 'form-control'
.form-group .form-group
= f.label :external_url, 'External URL', class: 'label-bold' = f.label :external_url, _('External URL'), class: 'label-bold'
= f.url_field :external_url, class: 'form-control' = f.url_field :external_url, class: 'form-control'
.form-actions .form-actions
= f.submit 'Save', class: 'btn btn-success' = f.submit _('Save'), class: 'btn btn-save'
= link_to 'Cancel', project_environments_path(@project), class: 'btn btn-cancel' = link_to _('Cancel'), project_environments_path(@project), class: 'btn btn-cancel'
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
- return unless can?(current_user, :read_environment, environment) - return unless can?(current_user, :read_environment, environment)
= link_to environment_metrics_path(environment), title: 'See metrics', class: 'btn metrics-button' do = link_to environment_metrics_path(environment), title: _('See metrics'), class: 'btn metrics-button' do
= sprite_icon('chart') = sprite_icon('chart')
Monitoring = _("Monitoring")
- @no_container = true - @no_container = true
- page_title "Edit", @environment.name, "Environments" - page_title _("Edit"), @environment.name, _("Environments")
%div{ class: container_class } %div{ class: container_class }
%h3.page-title %h3.page-title
Edit environment = _('Edit environment')
%hr %hr
= render 'form' = render 'form'
- @no_container = true - @no_container = true
- page_title "Environments" - page_title _("Environments")
#environments-folder-list-view{ data: { endpoint: folder_project_environments_path(@project, @folder, format: :json), #environments-folder-list-view{ data: { endpoint: folder_project_environments_path(@project, @folder, format: :json),
"folder-name" => @folder, "folder-name" => @folder,
......
- @no_container = true - @no_container = true
- page_title "Environments" - page_title _("Environments")
- add_to_breadcrumbs("Pipelines", project_pipelines_path(@project)) - add_to_breadcrumbs(_("Pipelines"), project_pipelines_path(@project))
#environments-list-view{ data: { environments_data: environments_list_data, #environments-list-view{ data: { environments_data: environments_list_data,
"can-create-deployment" => can?(current_user, :create_deployment, @project).to_s, "can-create-deployment" => can?(current_user, :create_deployment, @project).to_s,
......
- @no_container = true - @no_container = true
- page_title "Metrics for environment", @environment.name - page_title _("Metrics for environment"), @environment.name
.prometheus-container{ class: container_class } .prometheus-container{ class: container_class }
#prometheus-graphs{ data: metrics_data(@project, @environment) } #prometheus-graphs{ data: metrics_data(@project, @environment) }
- @no_container = true - @no_container = true
- breadcrumb_title "Environments" - breadcrumb_title _("Environments")
- page_title 'New Environment' - page_title _("New Environment")
%div{ class: container_class } %div{ class: container_class }
%h3.page-title %h3.page-title
New environment = _("New environment")
%hr %hr
= render 'form' = render 'form'
- @no_container = true - @no_container = true
- add_to_breadcrumbs "Environments", project_environments_path(@project) - add_to_breadcrumbs _("Environments"), project_environments_path(@project)
- breadcrumb_title @environment.name - breadcrumb_title @environment.name
- page_title "Environments" - page_title _("Environments")
%div{ class: container_class } %div{ class: container_class }
- if can?(current_user, :stop_environment, @environment) - if can?(current_user, :stop_environment, @environment)
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
.modal-content .modal-content
.modal-header .modal-header
%h4.modal-title.d-flex.mw-100 %h4.modal-title.d-flex.mw-100
Stopping = s_("Environments|Stopping")
%span.has-tooltip.text-truncate.ml-1.mr-1.flex-fill{ title: @environment.name, data: { container: '#stop-environment-modal' } } %span.has-tooltip.text-truncate.ml-1.mr-1.flex-fill{ title: @environment.name, data: { container: '#stop-environment-modal' } }
= @environment.name = @environment.name
? ?
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
= render 'projects/environments/external_url', environment: @environment = render 'projects/environments/external_url', environment: @environment
= render 'projects/environments/metrics_button', environment: @environment = render 'projects/environments/metrics_button', environment: @environment
- if can?(current_user, :update_environment, @environment) - if can?(current_user, :update_environment, @environment)
= link_to 'Edit', edit_project_environment_path(@project, @environment), class: 'btn' = link_to _('Edit'), edit_project_environment_path(@project, @environment), class: 'btn'
- if can?(current_user, :stop_environment, @environment) - if can?(current_user, :stop_environment, @environment)
= button_tag class: 'btn btn-danger', type: 'button', data: { toggle: 'modal', = button_tag class: 'btn btn-danger', type: 'button', data: { toggle: 'modal',
target: '#stop-environment-modal' } do target: '#stop-environment-modal' } do
...@@ -52,21 +52,19 @@ ...@@ -52,21 +52,19 @@
.empty-state .empty-state
.text-content .text-content
%h4.state-title %h4.state-title
You don't have any deployments right now. = _("You don't have any deployments right now.")
%p.blank-state-text %p.blank-state-text
Define environments in the deploy stage(s) in = _("Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here.").html_safe
%code .gitlab-ci.yml
to track deployments here.
.text-center .text-center
= link_to _("Read more"), help_page_path("ci/environments"), class: "btn btn-success" = link_to _("Read more"), help_page_path("ci/environments"), class: "btn btn-success"
- else - else
.table-holder .table-holder
.ci-table.environments{ role: 'grid' } .ci-table.environments{ role: 'grid' }
.gl-responsive-table-row.table-row-header{ role: 'row' } .gl-responsive-table-row.table-row-header{ role: 'row' }
.table-section.section-10{ role: 'columnheader' } ID .table-section.section-10{ role: 'columnheader' }= _('ID')
.table-section.section-30{ role: 'columnheader' } Commit .table-section.section-30{ role: 'columnheader' }= _('Commit')
.table-section.section-25{ role: 'columnheader' } Job .table-section.section-25{ role: 'columnheader' }= _('Job')
.table-section.section-15{ role: 'columnheader' } Created .table-section.section-15{ role: 'columnheader' }= _('Created')
= render @deployments = render @deployments
......
- @no_container = true - @no_container = true
- page_title "Terminal for environment", @environment.name - page_title _("Terminal for environment"), @environment.name
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= stylesheet_link_tag "xterm.css" = stylesheet_link_tag "xterm.css"
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
.row .row
.col-sm-6 .col-sm-6
%h3.page-title %h3.page-title
Terminal for environment = _("Terminal for environment")
= @environment.name = @environment.name
.col-sm-6 .col-sm-6
......
- @no_container = true - @no_container = true
- page_title "Charts" - page_title _("Contribution Charts")
.repo-charts{ class: container_class } .repo-charts{ class: container_class }
%h4.sub-header %h4.sub-header
......
- @no_container = true - @no_container = true
- breadcrumb_title "CI / CD Charts" - page_title _("CI / CD Charts")
- page_title _("Charts"), _("Pipelines")
%div{ class: container_class } %div{ class: container_class }
.sub-header-block .sub-header-block
......
#js-authenticate-u2f #js-authenticate-u2f
%a.btn.btn-block.btn-info#js-login-2fa-device{ href: '#' } Sign in via 2FA code %a.btn.btn-block.btn-info#js-login-2fa-device{ href: '#' }= _("Sign in via 2FA code")
-# haml-lint:disable InlineJavaScript -# haml-lint:disable InlineJavaScript
%script#js-authenticate-u2f-in-progress{ type: "text/template" } %script#js-authenticate-u2f-in-progress{ type: "text/template" }
%p Trying to communicate with your device. Plug it in (if you haven't already) and press the button on the device now. %p= _("Trying to communicate with your device. Plug it in (if you haven't already) and press the button on the device now.")
%script#js-authenticate-u2f-error{ type: "text/template" } %script#js-authenticate-u2f-error{ type: "text/template" }
%div %div
%p <%= error_message %> (error code: <%= error_code %>) %p <%= error_message %> (#{_("error code:")} <%= error_code %>)
%a.btn.btn-block.btn-warning#js-u2f-try-again Try again? %a.btn.btn-block.btn-warning#js-u2f-try-again= _("Try again?")
%script#js-authenticate-u2f-authenticated{ type: "text/template" } %script#js-authenticate-u2f-authenticated{ type: "text/template" }
%div %div
%p We heard back from your U2F device. You have been authenticated. %p= _("We heard back from your U2F device. You have been authenticated.")
= form_tag(new_user_session_path, method: :post, id: 'js-login-u2f-form') do |f| = form_tag(new_user_session_path, method: :post, id: 'js-login-u2f-form') do |f|
- resource_params = params[resource_name].presence || params - resource_params = params[resource_name].presence || params
= hidden_field_tag 'user[remember_me]', resource_params.fetch(:remember_me, 0) = hidden_field_tag 'user[remember_me]', resource_params.fetch(:remember_me, 0)
......
...@@ -2,39 +2,39 @@ ...@@ -2,39 +2,39 @@
-# haml-lint:disable InlineJavaScript -# haml-lint:disable InlineJavaScript
%script#js-register-u2f-not-supported{ type: "text/template" } %script#js-register-u2f-not-supported{ type: "text/template" }
%p Your browser doesn't support U2F. Please use Google Chrome desktop (version 41 or newer). %p= _("Your browser doesn't support U2F. Please use Google Chrome desktop (version 41 or newer).")
%script#js-register-u2f-setup{ type: "text/template" } %script#js-register-u2f-setup{ type: "text/template" }
- if current_user.two_factor_otp_enabled? - if current_user.two_factor_otp_enabled?
.row.append-bottom-10 .row.append-bottom-10
.col-md-4 .col-md-4
%button#js-setup-u2f-device.btn.btn-info.btn-block Set up new U2F device %button#js-setup-u2f-device.btn.btn-info.btn-block= _("Set up new U2F device")
.col-md-8 .col-md-8
%p Your U2F device needs to be set up. Plug it in (if not already) and click the button on the left. %p= _("Your U2F device needs to be set up. Plug it in (if not already) and click the button on the left.")
- else - else
.row.append-bottom-10 .row.append-bottom-10
.col-md-4 .col-md-4
%button#js-setup-u2f-device.btn.btn-info.btn-block{ disabled: true } Set up new U2F device %button#js-setup-u2f-device.btn.btn-info.btn-block{ disabled: true }= _("Set up new U2F device")
.col-md-8 .col-md-8
%p.text-warning You need to register a two-factor authentication app before you can set up a U2F device. %p.text-warning= _("You need to register a two-factor authentication app before you can set up a U2F device.")
%script#js-register-u2f-in-progress{ type: "text/template" } %script#js-register-u2f-in-progress{ type: "text/template" }
%p Trying to communicate with your device. Plug it in (if you haven't already) and press the button on the device now. %p= _("Trying to communicate with your device. Plug it in (if you haven't already) and press the button on the device now.")
%script#js-register-u2f-error{ type: "text/template" } %script#js-register-u2f-error{ type: "text/template" }
%div %div
%p %p
%span <%= error_message %> (error code: <%= error_code %>) %span <%= error_message %> (#{_("error code:")} <%= error_code %>)
%a.btn.btn-warning#js-u2f-try-again Try again? %a.btn.btn-warning#js-u2f-try-again= _("Try again?")
%script#js-register-u2f-registered{ type: "text/template" } %script#js-register-u2f-registered{ type: "text/template" }
.row.append-bottom-10 .row.append-bottom-10
.col-md-12 .col-md-12
%p Your device was successfully set up! Give it a name and register it with the GitLab server. %p= _("Your device was successfully set up! Give it a name and register it with the GitLab server.")
= form_tag(create_u2f_profile_two_factor_auth_path, method: :post) do = form_tag(create_u2f_profile_two_factor_auth_path, method: :post) do
.row.append-bottom-10 .row.append-bottom-10
.col-md-3 .col-md-3
= text_field_tag 'u2f_registration[name]', nil, class: 'form-control', placeholder: "Pick a name" = text_field_tag 'u2f_registration[name]', nil, class: 'form-control', placeholder: _("Pick a name")
.col-md-3 .col-md-3
= hidden_field_tag 'u2f_registration[device_response]', nil, class: 'form-control', required: true, id: "js-device-response" = hidden_field_tag 'u2f_registration[device_response]', nil, class: 'form-control', required: true, id: "js-device-response"
= submit_tag "Register U2F device", class: "btn btn-success" = submit_tag _("Register U2F device"), class: "btn btn-success"
.row
.col-12
.calendar-block.prepend-top-default.append-bottom-default
.user-calendar.d-none.d-sm-block{ data: { calendar_path: user_calendar_path(@user, :json), calendar_activities_path: user_calendar_activities_path, utc_offset: Time.zone.utc_offset } }
%h4.center.light
= spinner nil, true
.user-calendar-activities.d-none.d-sm-block
.row .row
.col-md-12.col-lg-6 .col-md-12.col-lg-6
.calendar-block
.content-block.hide-bottom-border
%h4
= s_('UserProfile|Activity')
.user-calendar.d-none.d-sm-block.text-left{ data: { calendar_path: user_calendar_path(@user, :json), calendar_activities_path: user_calendar_activities_path, utc_offset: Time.zone.utc_offset } }
%h4.center.light
%i.fa.fa-spinner.fa-spin
.user-calendar-activities.d-none.d-sm-block
- if can?(current_user, :read_cross_project) - if can?(current_user, :read_cross_project)
.activities-block .activities-block
.border-bottom.prepend-top-16 .prepend-top-16
%h5 .d-flex.align-items-center.border-bottom
= s_('UserProfile|Recent contributions') %h4.flex-grow
= s_('UserProfile|Activity')
= link_to s_('UserProfile|View all'), user_activity_path, class: "hide js-view-all"
.overview-content-list{ data: { href: user_path } } .overview-content-list{ data: { href: user_path } }
.center.light.loading .center.light.loading
%i.fa.fa-spinner.fa-spin = spinner nil, true
.prepend-top-10
= link_to s_('UserProfile|View all'), user_activity_path, class: "hide js-view-all"
.col-md-12.col-lg-6 .col-md-12.col-lg-6
.projects-block .projects-block
.border-bottom.prepend-top-16 .prepend-top-16
%h4 .d-flex.align-items-center.border-bottom
= s_('UserProfile|Personal projects') %h4.flex-grow
= s_('UserProfile|Personal projects')
= link_to s_('UserProfile|View all'), user_projects_path, class: "hide js-view-all"
.overview-content-list{ data: { href: user_projects_path } } .overview-content-list{ data: { href: user_projects_path } }
.center.light.loading .center.light.loading
%i.fa.fa-spinner.fa-spin = spinner nil, true
.prepend-top-10
= link_to s_('UserProfile|View all'), user_projects_path, class: "hide js-view-all"
...@@ -124,12 +124,6 @@ ...@@ -124,12 +124,6 @@
- if profile_tab?(:activity) - if profile_tab?(:activity)
#activity.tab-pane #activity.tab-pane
.row-content-block.calendar-block.white.second-block.d-none.d-sm-block
.user-calendar{ data: { calendar_path: user_calendar_path(@user, :json), calendar_activities_path: user_calendar_activities_path, utc_offset: Time.zone.utc_offset } }
%h4.center.light
%i.fa.fa-spinner.fa-spin
.user-calendar-activities
- if can?(current_user, :read_cross_project) - if can?(current_user, :read_cross_project)
%h4.prepend-top-20 %h4.prepend-top-20
= s_('UserProfile|Most Recent Activity') = s_('UserProfile|Most Recent Activity')
......
---
title: UI improvements to user's profile
merge_request: 22977
author:
type: other
---
title: Fix default sorting for subgroups and projects list
merge_request: 23058
author: Jacopo Beschi @jacopo-beschi
type: fixed
---
title: Fixes to AWS documentation spelling and grammar
merge_request: 23198
author: Brendan O'Leary
type: other
---
title: Drop default value on status column in deployments table
merge_request: 22971
author:
type: other
---
title: Enable even more frozen string for lib/gitlab
merge_request:
author: gfyoung
type: performance
---
title: Change breadcrumb title for contribution charts
merge_request: 23071
author: George Tsiolis
type: changed
---
title: Fix project identicon aligning Harry Kiselev
merge_request: 23166
author: Harry Kiselev
type: other
---
title: Escape user fullname while rendering autocomplete template to prevent XSS
merge_request:
author:
type: security
---
title: Prevent templated services from being imported
merge_request:
author:
type: security
...@@ -15,10 +15,10 @@ docs_paths_to_review = docs_paths_requiring_review(helper.all_changed_files) ...@@ -15,10 +15,10 @@ docs_paths_to_review = docs_paths_requiring_review(helper.all_changed_files)
unless docs_paths_to_review.empty? unless docs_paths_to_review.empty?
message 'This merge request adds or changes files that require a ' \ message 'This merge request adds or changes files that require a ' \
'review from the docs team.' 'review from the Docs team.'
markdown(<<~MARKDOWN) markdown(<<~MARKDOWN)
## Docs Review ## Docs review
The following files require a review from the Documentation team: The following files require a review from the Documentation team:
...@@ -32,24 +32,15 @@ the documentation. GitLabbers are also welcome to use the [#docs](https://gitlab ...@@ -32,24 +32,15 @@ the documentation. GitLabbers are also welcome to use the [#docs](https://gitlab
Who to ping [based on DevOps stages](https://about.gitlab.com/handbook/product/categories/#devops-stages): Who to ping [based on DevOps stages](https://about.gitlab.com/handbook/product/categories/#devops-stages):
| Stage | Tech writer | | Tech writer | Stage(s) |
| ------------- | ----------- | | ------------ | ------------------------------------------------------------ |
| ~Create | `@marcia` | | `@marcia` | ~Create ~Release |
| ~Configure | `@eread` | | `@axil` | ~Distribution ~Gitaly ~Gitter ~Monitoring ~Packaging ~Secure |
| ~Distribution | `@axil` | | `@eread` | ~Manage ~Configure ~Geo ~Verify |
| ~Geo | `@eread` | | `@mikelewis` | ~Plan |
| ~Gitaly | `@axil` |
| ~Gitter | `@axil` |
| ~Manage | `@eread` |
| ~Monitoring | `@axil` |
| ~Packaging | `@axil` |
| ~Plan | `@mikelewis`|
| ~Release | `marcia` |
| ~Secure | `@axil` |
| ~Verify | `@eread` |
If you are not sure which category the change falls within, or the change is not If you are not sure which category the change falls within, or the change is not
part of one of these categories, you can mention the whole team with `@gl-docsteam`. part of one of these categories, you can mention one of the usernames above.
MARKDOWN MARKDOWN
unless gitlab.mr_labels.include?('Documentation') unless gitlab.mr_labels.include?('Documentation')
......
# frozen_string_literal: true
class DropDefaultValueOnStatusDeployments < ActiveRecord::Migration
DOWNTIME = false
DEPLOYMENT_STATUS_SUCCESS = 2 # Equivalent to Deployment.state_machine.states['success'].value
def up
change_column_default :deployments, :status, nil
end
def down
change_column_default :deployments, :status, DEPLOYMENT_STATUS_SUCCESS
end
end
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20181107054254) do ActiveRecord::Schema.define(version: 20181112103239) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
...@@ -924,7 +924,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do ...@@ -924,7 +924,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.string "on_stop" t.string "on_stop"
t.integer "status", limit: 2, default: 2, null: false t.integer "status", limit: 2, null: false
t.datetime_with_timezone "finished_at" t.datetime_with_timezone "finished_at"
t.index ["created_at"], name: "index_deployments_on_created_at", using: :btree t.index ["created_at"], name: "index_deployments_on_created_at", using: :btree
t.index ["deployable_type", "deployable_id"], name: "index_deployments_on_deployable_type_and_deployable_id", using: :btree t.index ["deployable_type", "deployable_id"], name: "index_deployments_on_deployable_type_and_deployable_id", using: :btree
......
...@@ -134,9 +134,9 @@ should be more than enough. ...@@ -134,9 +134,9 @@ should be more than enough.
When removing an index make sure to use the method `remove_concurrent_index` instead When removing an index make sure to use the method `remove_concurrent_index` instead
of the regular `remove_index` method. The `remove_concurrent_index` method of the regular `remove_index` method. The `remove_concurrent_index` method
automatically drops concurrent indexes when using PostgreSQL, removing the automatically drops concurrent indexes when using PostgreSQL, removing the
need for downtime. To use this method you must disable transactions by calling need for downtime. To use this method you must disable single-transaction mode
the method `disable_ddl_transaction!` in the body of your migration class like by calling the method `disable_ddl_transaction!` in the body of your migration
so: class like so:
```ruby ```ruby
class MyMigration < ActiveRecord::Migration class MyMigration < ActiveRecord::Migration
......
...@@ -9,7 +9,7 @@ in [significantly degraded performance](https://gitlab.com/gitlab-org/gitlab-ee/ ...@@ -9,7 +9,7 @@ in [significantly degraded performance](https://gitlab.com/gitlab-org/gitlab-ee/
GitLab on AWS can leverage many of the services that are already GitLab on AWS can leverage many of the services that are already
configurable with High Availability. These services have a lot of configurable with High Availability. These services have a lot of
flexibility and are able to adopt to most companies, best of all is the flexibility and are able to adapt to most companies, best of all is the
ability to automate both vertical and horizontal scaling. ability to automate both vertical and horizontal scaling.
In this article we'll go through a basic HA setup where we'll start by In this article we'll go through a basic HA setup where we'll start by
...@@ -55,9 +55,9 @@ and from the Actions dropdown choose Edit DNS Hostnames and select Yes. ...@@ -55,9 +55,9 @@ and from the Actions dropdown choose Edit DNS Hostnames and select Yes.
### Subnet ### Subnet
Now let's create some subnets in different Availability Zones. Make sure Now let's create some subnets in different Availability Zones. Make sure
that each subnet is associated the the VPC we just created, that it has that each subnet is associated to the VPC we just created, that it has
a distinct VPC and lastly that CIDR blocks don't overlap. This will also a distinct VPC and lastly that CIDR blocks don't overlap. This will also
allow us to enable multi AZ for redundancy. allow us to enable multi-AZ for redundancy.
We will create private and public subnets to match load balancers and We will create private and public subnets to match load balancers and
RDS instances as well. RDS instances as well.
...@@ -98,7 +98,7 @@ traffic from any destination. ...@@ -98,7 +98,7 @@ traffic from any destination.
![Subnet Config](img/ig-rt.png) ![Subnet Config](img/ig-rt.png)
Before leaving this screen select the next tab to the rgiht which is Before leaving this screen select the next tab to the right which is
Subnet Associations and add our public subnets. If you followed our Subnet Associations and add our public subnets. If you followed our
naming convention they should be easy to find. naming convention they should be easy to find.
...@@ -106,8 +106,8 @@ naming convention they should be easy to find. ...@@ -106,8 +106,8 @@ naming convention they should be easy to find.
## Database with RDS ## Database with RDS
For our database server we will use Amazon RDS which offers Multi AZ For our database server we will use Amazon RDS which offers Multi-AZ
for redundancy. Lets start by creating a subnet group and then we'll for redundancy. Let's start by creating a subnet group and then we'll
create the actual RDS instance. create the actual RDS instance.
### Subnet Group ### Subnet Group
...@@ -122,7 +122,7 @@ the VPC ID dropdown and at the bottom we can add our private subnets. ...@@ -122,7 +122,7 @@ the VPC ID dropdown and at the bottom we can add our private subnets.
Select the RDS service from the Database section and create a new Select the RDS service from the Database section and create a new
PostgreSQL instance. After choosing between a Production or PostgreSQL instance. After choosing between a Production or
Development instance we'll start with the actual configuration. On the Development instance we'll start with the actual configuration. On the
image bellow we have the settings for this article but note the image below we have the settings for this article but note the
following two options which are of particular interest for HA: following two options which are of particular interest for HA:
1. Multi-AZ-Deployment is recommended as redundancy. Read more at 1. Multi-AZ-Deployment is recommended as redundancy. Read more at
...@@ -133,7 +133,7 @@ IOPS (SSD) is best suited for HA. Read more about it at ...@@ -133,7 +133,7 @@ IOPS (SSD) is best suited for HA. Read more about it at
![RDS Instance Specs](img/instance_specs.png) ![RDS Instance Specs](img/instance_specs.png)
The rest of the setting on this page request a DB identifier, username The rest of the setting on this page request a DB identifier, username,
and a master password. We've chosen to use `gitlab-ha`, `gitlab` and a and a master password. We've chosen to use `gitlab-ha`, `gitlab` and a
very secure password respectively. Keep these in hand for later. very secure password respectively. Keep these in hand for later.
...@@ -152,7 +152,7 @@ EC is an in-memory hosted caching solution. Redis maintains its own ...@@ -152,7 +152,7 @@ EC is an in-memory hosted caching solution. Redis maintains its own
persistence and is used for certain types of application. persistence and is used for certain types of application.
Let's choose the ElastiCache service in the Database section from our Let's choose the ElastiCache service in the Database section from our
AWS console. Now lets create a cache subnet group which will be very AWS console. Now let's create a cache subnet group which will be very
similar to the RDS subnet group. Make sure to select our VPC and its similar to the RDS subnet group. Make sure to select our VPC and its
private subnets. private subnets.
...@@ -160,7 +160,7 @@ private subnets. ...@@ -160,7 +160,7 @@ private subnets.
Now press the Launch a Cache Cluster and choose Redis for our Now press the Launch a Cache Cluster and choose Redis for our
DB engine. You'll be able to configure details such as replication, DB engine. You'll be able to configure details such as replication,
Multi AZ and node types. The second section will allow us to choose our Multi-AZ and node types. The second section will allow us to choose our
subnet and security group and subnet and security group and
![Redis Cluster details](img/redis-cluster-det.png) ![Redis Cluster details](img/redis-cluster-det.png)
...@@ -274,7 +274,7 @@ username, and password. ...@@ -274,7 +274,7 @@ username, and password.
gitlab_rails['db_password'] = "mypassword" gitlab_rails['db_password'] = "mypassword"
gitlab_rails['db_host'] = "<rds-endpoint>" gitlab_rails['db_host'] = "<rds-endpoint>"
Next we only need to configure the Redis section by adding the host and Next, we only need to configure the Redis section by adding the host and
uncommenting the port. uncommenting the port.
...@@ -285,7 +285,7 @@ to make the EFS integration easier to manage. ...@@ -285,7 +285,7 @@ to make the EFS integration easier to manage.
gitlab_rails['redis_host'] = "<redis-endpoint>" gitlab_rails['redis_host'] = "<redis-endpoint>"
gitlab_rails['redis_port'] = 6379 gitlab_rails['redis_port'] = 6379
Finally run reconfigure, you might find it useful to run a check and Finally, run reconfigure. You might find it useful to run a check and
a service status to make sure everything has been set up correctly. a service status to make sure everything has been set up correctly.
sudo gitlab-ctl reconfigure sudo gitlab-ctl reconfigure
...@@ -321,10 +321,10 @@ The Load Balancer Health will allow us to indicate where to ping and what ...@@ -321,10 +321,10 @@ The Load Balancer Health will allow us to indicate where to ping and what
makes up a healthy or unhealthy instance. makes up a healthy or unhealthy instance.
We won't add the instance on the next session because we'll destroy it We won't add the instance on the next session because we'll destroy it
momentarily as we'll be using the image we where creating. We will keep momentarily as we'll be using the image we were creating. We will keep
the Enable Cross-Zone and Enable Connection Draining active. the Enable Cross-Zone and Enable Connection Draining active.
After we finish creating the Load Balancer we can re visit our Security After we finish creating the Load Balancer we can revisit our Security
Groups to improve access only through the ELB and any other requirement Groups to improve access only through the ELB and any other requirement
you might have. you might have.
...@@ -363,7 +363,7 @@ After this is launched we are able to start creating our Auto Scaling ...@@ -363,7 +363,7 @@ After this is launched we are able to start creating our Auto Scaling
Group. Start by giving it a name and assigning it our VPC and private Group. Start by giving it a name and assigning it our VPC and private
subnets. We also want to always start with two instances and if you subnets. We also want to always start with two instances and if you
scroll down to Advanced Details we can choose to receive traffic from ELBs. scroll down to Advanced Details we can choose to receive traffic from ELBs.
Lets enable that option and select our ELB. We also want to use the ELB's Let's enable that option and select our ELB. We also want to use the ELB's
health check. health check.
![Auto scaling](img/auto-scaling-det.png) ![Auto scaling](img/auto-scaling-det.png)
...@@ -388,9 +388,9 @@ we where aiming for. ...@@ -388,9 +388,9 @@ we where aiming for.
After you're done with the policies section have some fun trying to break After you're done with the policies section have some fun trying to break
instances. You should be able to see how the Auto Scaling Group and the instances. You should be able to see how the Auto Scaling Group and the
EC2 screen start bringing them up again. EC2 screen starts bringing them up again.
High Availability is a very big area, we went mostly through scaling and High Availability is a vast area, we went mostly through scaling and
some redundancy options but it might also imply Geographic replication. some redundancy options but it might also imply Geographic replication.
There is a lot of ground yet to cover so have a read through these other There is a lot of ground yet to cover so have a read through these other
resources and feel free to open an issue to request additional material. resources and feel free to open an issue to request additional material.
......
...@@ -235,7 +235,7 @@ There might be configuration options available for [`gitlab.yml`][yaml]. View th ...@@ -235,7 +235,7 @@ There might be configuration options available for [`gitlab.yml`][yaml]. View th
```sh ```sh
cd /home/git/gitlab cd /home/git/gitlab
git diff origin/11-1-stable:config/gitlab.yml.example origin/11-3-stable:config/gitlab.yml.example git diff origin/11-2-stable:config/gitlab.yml.example origin/11-3-stable:config/gitlab.yml.example
``` ```
#### Nginx configuration #### Nginx configuration
...@@ -246,10 +246,10 @@ Ensure you're still up-to-date with the latest NGINX configuration changes: ...@@ -246,10 +246,10 @@ Ensure you're still up-to-date with the latest NGINX configuration changes:
cd /home/git/gitlab cd /home/git/gitlab
# For HTTPS configurations # For HTTPS configurations
git diff origin/11-1-stable:lib/support/nginx/gitlab-ssl origin/11-3-stable:lib/support/nginx/gitlab-ssl git diff origin/11-2-stable:lib/support/nginx/gitlab-ssl origin/11-3-stable:lib/support/nginx/gitlab-ssl
# For HTTP configurations # For HTTP configurations
git diff origin/11-1-stable:lib/support/nginx/gitlab origin/11-3-stable:lib/support/nginx/gitlab git diff origin/11-2-stable:lib/support/nginx/gitlab origin/11-3-stable:lib/support/nginx/gitlab
``` ```
If you are using Strict-Transport-Security in your installation to continue using it you must enable it in your Nginx If you are using Strict-Transport-Security in your installation to continue using it you must enable it in your Nginx
...@@ -283,7 +283,7 @@ There might be new configuration options available for [`gitlab.default.example` ...@@ -283,7 +283,7 @@ There might be new configuration options available for [`gitlab.default.example`
```sh ```sh
cd /home/git/gitlab cd /home/git/gitlab
git diff origin/11-1-stable:lib/support/init.d/gitlab.default.example origin/11-3-stable:lib/support/init.d/gitlab.default.example git diff origin/11-2-stable:lib/support/init.d/gitlab.default.example origin/11-3-stable:lib/support/init.d/gitlab.default.example
``` ```
Ensure you're still up-to-date with the latest init script changes: Ensure you're still up-to-date with the latest init script changes:
......
...@@ -235,7 +235,7 @@ There might be configuration options available for [`gitlab.yml`][yaml]. View th ...@@ -235,7 +235,7 @@ There might be configuration options available for [`gitlab.yml`][yaml]. View th
```sh ```sh
cd /home/git/gitlab cd /home/git/gitlab
git diff origin/11-1-stable:config/gitlab.yml.example origin/11-4-stable:config/gitlab.yml.example git diff origin/11-3-stable:config/gitlab.yml.example origin/11-4-stable:config/gitlab.yml.example
``` ```
#### Nginx configuration #### Nginx configuration
...@@ -246,10 +246,10 @@ Ensure you're still up-to-date with the latest NGINX configuration changes: ...@@ -246,10 +246,10 @@ Ensure you're still up-to-date with the latest NGINX configuration changes:
cd /home/git/gitlab cd /home/git/gitlab
# For HTTPS configurations # For HTTPS configurations
git diff origin/11-1-stable:lib/support/nginx/gitlab-ssl origin/11-4-stable:lib/support/nginx/gitlab-ssl git diff origin/11-3-stable:lib/support/nginx/gitlab-ssl origin/11-4-stable:lib/support/nginx/gitlab-ssl
# For HTTP configurations # For HTTP configurations
git diff origin/11-1-stable:lib/support/nginx/gitlab origin/11-4-stable:lib/support/nginx/gitlab git diff origin/11-3-stable:lib/support/nginx/gitlab origin/11-4-stable:lib/support/nginx/gitlab
``` ```
If you are using Strict-Transport-Security in your installation to continue using it you must enable it in your Nginx If you are using Strict-Transport-Security in your installation to continue using it you must enable it in your Nginx
...@@ -283,7 +283,7 @@ There might be new configuration options available for [`gitlab.default.example` ...@@ -283,7 +283,7 @@ There might be new configuration options available for [`gitlab.default.example`
```sh ```sh
cd /home/git/gitlab cd /home/git/gitlab
git diff origin/11-1-stable:lib/support/init.d/gitlab.default.example origin/11-4-stable:lib/support/init.d/gitlab.default.example git diff origin/11-3-stable:lib/support/init.d/gitlab.default.example origin/11-4-stable:lib/support/init.d/gitlab.default.example
``` ```
Ensure you're still up-to-date with the latest init script changes: Ensure you're still up-to-date with the latest init script changes:
......
...@@ -28,7 +28,7 @@ module Gitlab ...@@ -28,7 +28,7 @@ module Gitlab
end end
def extract_authn_context(document) def extract_authn_context(document)
REXML::XPath.first(document, "//saml:AuthnStatement/saml:AuthnContext/saml:AuthnContextClassRef/text()").to_s REXML::XPath.first(document, "//*[name()='saml:AuthnStatement' or name()='saml2:AuthnStatement']/*[name()='saml:AuthnContext' or name()='saml2:AuthnContext']/*[name()='saml:AuthnContextClassRef' or name()='saml2:AuthnContextClassRef']/text()").to_s
end end
end end
end end
......
...@@ -42,7 +42,7 @@ module Gitlab ...@@ -42,7 +42,7 @@ module Gitlab
end end
def self.cache_key_for_project(project) def self.cache_key_for_project(project)
"#{Gitlab::Redis::Cache::CACHE_NAMESPACE}:projects/#{project.id}/pipeline_status/#{project.commit&.sha}" "#{Gitlab::Redis::Cache::CACHE_NAMESPACE}:project:#{project.id}:pipeline_status:#{project.commit&.sha}"
end end
def self.update_for_pipeline(pipeline) def self.update_for_pipeline(pipeline)
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Ci module Ci
class Config class Config
......
...@@ -165,6 +165,8 @@ excluded_attributes: ...@@ -165,6 +165,8 @@ excluded_attributes:
- :encrypted_token_iv - :encrypted_token_iv
- :encrypted_url - :encrypted_url
- :encrypted_url_iv - :encrypted_url_iv
services:
- :template
methods: methods:
labels: labels:
......
# frozen_string_literal: true
# Inspired by https://github.com/peek/peek-pg/blob/master/lib/peek/views/pg.rb # Inspired by https://github.com/peek/peek-pg/blob/master/lib/peek/views/pg.rb
# PEEK_DB_CLIENT is a constant set in config/initializers/peek.rb # PEEK_DB_CLIENT is a constant set in config/initializers/peek.rb
module Gitlab module Gitlab
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Popen module Popen
class Runner class Runner
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Profiler module Profiler
class TotalTimeFlatPrinter < RubyProf::FlatPrinter class TotalTimeFlatPrinter < RubyProf::FlatPrinter
......
# frozen_string_literal: true
module Gitlab module Gitlab
module ProjectAuthorizations module ProjectAuthorizations
# Calculating new project authorizations when supporting nested groups. # Calculating new project authorizations when supporting nested groups.
......
# frozen_string_literal: true
module Gitlab module Gitlab
module ProjectAuthorizations module ProjectAuthorizations
# Calculating new project authorizations when not supporting nested groups. # Calculating new project authorizations when not supporting nested groups.
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Prometheus module Prometheus
module AdditionalMetricsParser module AdditionalMetricsParser
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Prometheus module Prometheus
class Metric class Metric
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Prometheus module Prometheus
class MetricGroup class MetricGroup
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Prometheus module Prometheus
ParsingError = Class.new(StandardError) ParsingError = Class.new(StandardError)
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Prometheus module Prometheus
module Queries module Queries
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Prometheus module Prometheus
module Queries module Queries
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Prometheus module Prometheus
module Queries module Queries
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Prometheus module Prometheus
module Queries module Queries
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Prometheus module Prometheus
module Queries module Queries
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Prometheus module Prometheus
module Queries module Queries
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Prometheus module Prometheus
module Queries module Queries
......
# frozen_string_literal: true
module Gitlab module Gitlab
module QueryLimiting module QueryLimiting
class ActiveSupportSubscriber < ActiveSupport::Subscriber class ActiveSupportSubscriber < ActiveSupport::Subscriber
......
# frozen_string_literal: true
module Gitlab module Gitlab
module QueryLimiting module QueryLimiting
class Transaction class Transaction
...@@ -68,7 +70,7 @@ module Gitlab ...@@ -68,7 +70,7 @@ module Gitlab
def error_message def error_message
header = 'Too many SQL queries were executed' header = 'Too many SQL queries were executed'
header += " in #{action}" if action header = "#{header} in #{action}" if action
"#{header}: a maximum of #{THRESHOLD} is allowed but #{count} SQL queries were executed" "#{header}: a maximum of #{THRESHOLD} is allowed but #{count} SQL queries were executed"
end end
......
# frozen_string_literal: true
module Gitlab module Gitlab
module QuickActions module QuickActions
class CommandDefinition class CommandDefinition
......
# frozen_string_literal: true
module Gitlab module Gitlab
module QuickActions module QuickActions
module Dsl module Dsl
......
# frozen_string_literal: true
module Gitlab module Gitlab
module QuickActions module QuickActions
# This class takes an array of commands that should be extracted from a # This class takes an array of commands that should be extracted from a
......
# frozen_string_literal: true
module Gitlab module Gitlab
module QuickActions module QuickActions
# This class takes spend command argument # This class takes spend command argument
......
# frozen_string_literal: true
module Gitlab module Gitlab
module QuickActions module QuickActions
class SubstitutionDefinition < CommandDefinition class SubstitutionDefinition < CommandDefinition
......
# frozen_string_literal: true
# please require all dependencies below: # please require all dependencies below:
require_relative 'wrapper' unless defined?(::Rails) && ::Rails.root.present? require_relative 'wrapper' unless defined?(::Rails) && ::Rails.root.present?
......
# frozen_string_literal: true
# please require all dependencies below: # please require all dependencies below:
require_relative 'wrapper' unless defined?(::Gitlab::Redis::Wrapper) require_relative 'wrapper' unless defined?(::Gitlab::Redis::Wrapper)
......
# frozen_string_literal: true
# please require all dependencies below: # please require all dependencies below:
require_relative 'wrapper' unless defined?(::Gitlab::Redis::Wrapper) require_relative 'wrapper' unless defined?(::Gitlab::Redis::Wrapper)
......
# frozen_string_literal: true
# This file should only be used by sub-classes, not directly by any clients of the sub-classes # This file should only be used by sub-classes, not directly by any clients of the sub-classes
# please require all dependencies below: # please require all dependencies below:
require 'active_support/core_ext/hash/keys' require 'active_support/core_ext/hash/keys'
......
...@@ -7,13 +7,13 @@ module Gitlab ...@@ -7,13 +7,13 @@ module Gitlab
def initialize(repository, extra_namespace: nil, backend: Rails.cache) def initialize(repository, extra_namespace: nil, backend: Rails.cache)
@repository = repository @repository = repository
@namespace = "#{repository.full_path}:#{repository.project.id}" @namespace = "project:#{repository.project.id}"
@namespace = "#{@namespace}:#{extra_namespace}" if extra_namespace @namespace = "#{@namespace}:#{extra_namespace}" if extra_namespace
@backend = backend @backend = backend
end end
def cache_key(type) def cache_key(type)
"#{type}:#{namespace}" "#{namespace}:#{type}"
end end
def expire(key) def expire(key)
......
# frozen_string_literal: true
require 'ruby-prof' require 'ruby-prof'
module Gitlab module Gitlab
......
# frozen_string_literal: true
module Gitlab module Gitlab
module RequestProfiler module RequestProfiler
class Profile class Profile
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Sanitizers module Sanitizers
module SVG module SVG
......
# frozen_string_literal: true
# Generated from: # Generated from:
# SVG element list: https://www.w3.org/TR/SVG/eltindex.html # SVG element list: https://www.w3.org/TR/SVG/eltindex.html
# SVG Attribute list: https://www.w3.org/TR/SVG/attindex.html # SVG Attribute list: https://www.w3.org/TR/SVG/attindex.html
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Search module Search
class ParsedQuery class ParsedQuery
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Search module Search
class Query < SimpleDelegator class Query < SimpleDelegator
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Serializer module Serializer
module Ci module Ci
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Serializer module Serializer
class Pagination class Pagination
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Sherlock module Sherlock
# A collection of transactions recorded by Sherlock. # A collection of transactions recorded by Sherlock.
......
# frozen_string_literal: true
module Gitlab module Gitlab
module Sherlock module Sherlock
class FileSample class FileSample
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment